feat(trading): game results table (#5801)
Co-authored-by: bwallacee <ben@vega.xyz>
This commit is contained in:
parent
8268acac6d
commit
98ff4f3c04
@ -4,7 +4,7 @@ import { CompetitionsHeader } from '../../components/competitions/competitions-h
|
||||
import { Intent, Loader, TradingButton } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
import { useGameCards } from '../../lib/hooks/use-game-cards';
|
||||
import { useCurrentEpochInfoQuery } from '../../lib/hooks/__generated__/Epoch';
|
||||
import { useEpochInfoQuery } from '../../lib/hooks/__generated__/Epoch';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Links } from '../../lib/links';
|
||||
import {
|
||||
@ -25,7 +25,7 @@ export const CompetitionsHome = () => {
|
||||
|
||||
usePageTitle(t('Competitions'));
|
||||
|
||||
const { data: epochData } = useCurrentEpochInfoQuery();
|
||||
const { data: epochData } = useEpochInfoQuery();
|
||||
const currentEpoch = Number(epochData?.epoch.id);
|
||||
|
||||
const { data: gamesData, loading: gamesLoading } = useGameCards({
|
||||
|
@ -1,12 +1,28 @@
|
||||
import { useState, type ButtonHTMLAttributes } from 'react';
|
||||
import { useState, type ButtonHTMLAttributes, useRef } from 'react';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import { Splash, truncateMiddle, Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import { DispatchMetricLabels, type DispatchMetric } from '@vegaprotocol/types';
|
||||
import {
|
||||
Splash,
|
||||
truncateMiddle,
|
||||
Loader,
|
||||
Dialog,
|
||||
Button,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
TransferStatus,
|
||||
type Asset,
|
||||
type RecurringTransfer,
|
||||
} from '@vegaprotocol/types';
|
||||
import classNames from 'classnames';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { Table } from '../../components/table';
|
||||
import { formatNumber, getDateTimeFormat } from '@vegaprotocol/utils';
|
||||
import {
|
||||
addDecimalsFormatNumberQuantum,
|
||||
formatNumber,
|
||||
getDateTimeFormat,
|
||||
} from '@vegaprotocol/utils';
|
||||
import {
|
||||
useTeam,
|
||||
type TeamStats as ITeamStats,
|
||||
@ -27,6 +43,19 @@ import {
|
||||
useGames,
|
||||
areTeamGames,
|
||||
} from '../../lib/hooks/use-games';
|
||||
import { useEpochInfoQuery } from '../../lib/hooks/__generated__/Epoch';
|
||||
import {
|
||||
type EnrichedTransfer,
|
||||
isScopedToTeams,
|
||||
useGameCards,
|
||||
} from '../../lib/hooks/use-game-cards';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
import {
|
||||
ActiveRewardCard,
|
||||
DispatchMetricInfo,
|
||||
} from '../../components/rewards-container/active-rewards';
|
||||
import { type MarketMap, useMarketsMapProvider } from '@vegaprotocol/markets';
|
||||
import format from 'date-fns/format';
|
||||
|
||||
export const CompetitionsTeam = () => {
|
||||
const t = useT();
|
||||
@ -49,6 +78,14 @@ const TeamPageContainer = ({ teamId }: { teamId: string | undefined }) => {
|
||||
|
||||
const { data: games, loading: gamesLoading } = useGames(teamId);
|
||||
|
||||
const { data: epochData, loading: epochLoading } = useEpochInfoQuery();
|
||||
const { data: transfersData, loading: transfersLoading } = useGameCards({
|
||||
currentEpoch: Number(epochData?.epoch.id),
|
||||
onlyActive: false,
|
||||
});
|
||||
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
|
||||
// only show spinner on first load so when users join teams its smoother
|
||||
if (!data && loading) {
|
||||
return (
|
||||
@ -74,6 +111,9 @@ const TeamPageContainer = ({ teamId }: { teamId: string | undefined }) => {
|
||||
members={members}
|
||||
games={areTeamGames(games) ? games : undefined}
|
||||
gamesLoading={gamesLoading}
|
||||
transfers={transfersData}
|
||||
transfersLoading={epochLoading || transfersLoading}
|
||||
allMarkets={markets || undefined}
|
||||
refetch={refetch}
|
||||
/>
|
||||
);
|
||||
@ -86,6 +126,9 @@ const TeamPage = ({
|
||||
members,
|
||||
games,
|
||||
gamesLoading,
|
||||
transfers,
|
||||
transfersLoading,
|
||||
allMarkets,
|
||||
refetch,
|
||||
}: {
|
||||
team: TeamType;
|
||||
@ -94,6 +137,9 @@ const TeamPage = ({
|
||||
members?: Member[];
|
||||
games?: TeamGame[];
|
||||
gamesLoading?: boolean;
|
||||
transfers?: EnrichedTransfer[];
|
||||
transfersLoading?: boolean;
|
||||
allMarkets?: MarketMap;
|
||||
refetch: () => void;
|
||||
}) => {
|
||||
const t = useT();
|
||||
@ -141,7 +187,13 @@ const TeamPage = ({
|
||||
</ToggleButton>
|
||||
</div>
|
||||
{showGames ? (
|
||||
<Games games={games} gamesLoading={gamesLoading} />
|
||||
<Games
|
||||
games={games}
|
||||
gamesLoading={gamesLoading}
|
||||
transfers={transfers}
|
||||
transfersLoading={transfersLoading}
|
||||
allMarkets={allMarkets}
|
||||
/>
|
||||
) : (
|
||||
<Members members={members} />
|
||||
)}
|
||||
@ -153,9 +205,15 @@ const TeamPage = ({
|
||||
const Games = ({
|
||||
games,
|
||||
gamesLoading,
|
||||
transfers,
|
||||
transfersLoading,
|
||||
allMarkets,
|
||||
}: {
|
||||
games?: TeamGame[];
|
||||
gamesLoading?: boolean;
|
||||
transfers?: EnrichedTransfer[];
|
||||
transfersLoading?: boolean;
|
||||
allMarkets?: MarketMap;
|
||||
}) => {
|
||||
const t = useT();
|
||||
|
||||
@ -171,40 +229,106 @@ const Games = ({
|
||||
return <p>{t('No game results available')}</p>;
|
||||
}
|
||||
|
||||
const dependable = (value: string | JSX.Element) => {
|
||||
if (transfersLoading) return <Loader size="small" />;
|
||||
return value;
|
||||
};
|
||||
|
||||
return (
|
||||
<Table
|
||||
columns={[
|
||||
{ name: 'rank', displayName: t('Rank') },
|
||||
{
|
||||
name: 'epoch',
|
||||
displayName: t('Epoch'),
|
||||
headerClassName: 'hidden md:table-cell',
|
||||
className: 'hidden md:table-cell',
|
||||
},
|
||||
{
|
||||
name: 'endtime',
|
||||
displayName: t('End time'),
|
||||
},
|
||||
{ name: 'type', displayName: t('Type') },
|
||||
{ name: 'amount', displayName: t('Amount earned') },
|
||||
{
|
||||
name: 'asset',
|
||||
displayName: t('Reward asset'),
|
||||
},
|
||||
{ name: 'daily', displayName: t('Daily reward amount') },
|
||||
{ name: 'rank', displayName: t('Rank') },
|
||||
{ name: 'amount', displayName: t('Amount earned this epoch') },
|
||||
{ name: 'total', displayName: t('Cumulative amount earned') },
|
||||
{
|
||||
name: 'participatingTeams',
|
||||
displayName: t('No. of participating teams'),
|
||||
headerClassName: 'hidden md:table-cell',
|
||||
className: 'hidden md:table-cell',
|
||||
},
|
||||
{
|
||||
name: 'participatingMembers',
|
||||
displayName: t('No. of participating members'),
|
||||
headerClassName: 'hidden md:table-cell',
|
||||
className: 'hidden md:table-cell',
|
||||
},
|
||||
]}
|
||||
data={games.map((game) => ({
|
||||
rank: game.team.rank,
|
||||
epoch: game.epoch,
|
||||
type: DispatchMetricLabels[game.team.rewardMetric as DispatchMetric],
|
||||
amount: formatNumber(game.team.totalRewardsEarned),
|
||||
participatingTeams: game.entities.length,
|
||||
participatingMembers: game.numberOfParticipants,
|
||||
}))}
|
||||
noCollapse={true}
|
||||
].map((c) => ({ ...c, headerClassName: 'text-left' }))}
|
||||
data={games.map((game) => {
|
||||
let transfer = transfers?.find((t) => {
|
||||
if (!isScopedToTeams(t)) return false;
|
||||
|
||||
const idMatch = t.transfer.gameId === game.id;
|
||||
const metricMatch =
|
||||
t.transfer.kind.dispatchStrategy?.dispatchMetric ===
|
||||
game.team.rewardMetric;
|
||||
|
||||
const start = t.transfer.kind.startEpoch <= game.epoch;
|
||||
const end = t.transfer.kind.endEpoch
|
||||
? t.transfer.kind.endEpoch >= game.epoch
|
||||
: true;
|
||||
|
||||
const rejected = t.transfer.status === TransferStatus.STATUS_REJECTED;
|
||||
|
||||
return idMatch && metricMatch && start && end && !rejected;
|
||||
});
|
||||
if (!transfer || !isScopedToTeams(transfer)) transfer = undefined;
|
||||
const asset = transfer?.transfer.asset;
|
||||
|
||||
const dailyAmount =
|
||||
asset && transfer
|
||||
? addDecimalsFormatNumberQuantum(
|
||||
transfer.transfer.amount,
|
||||
asset.decimals,
|
||||
asset.quantum
|
||||
)
|
||||
: '-';
|
||||
|
||||
const earnedAmount = asset
|
||||
? addDecimalsFormatNumberQuantum(
|
||||
game.team.rewardEarned,
|
||||
asset.decimals,
|
||||
asset.quantum
|
||||
)
|
||||
: '-';
|
||||
|
||||
const totalAmount = asset
|
||||
? addDecimalsFormatNumberQuantum(
|
||||
game.team.totalRewardsEarned,
|
||||
asset.decimals,
|
||||
asset.quantum
|
||||
)
|
||||
: '-';
|
||||
|
||||
const assetSymbol = asset ? <RewardAssetCell asset={asset} /> : '-';
|
||||
|
||||
return {
|
||||
id: game.id,
|
||||
amount: dependable(earnedAmount),
|
||||
asset: dependable(assetSymbol),
|
||||
daily: dependable(dailyAmount),
|
||||
endtime: <EndTimeCell epoch={game.epoch} />,
|
||||
epoch: game.epoch,
|
||||
participatingMembers: game.numberOfParticipants,
|
||||
participatingTeams: game.entities.length,
|
||||
rank: game.team.rank,
|
||||
total: totalAmount,
|
||||
// type: DispatchMetricLabels[game.team.rewardMetric as DispatchMetric],
|
||||
type: dependable(
|
||||
<GameTypeCell transfer={transfer} allMarkets={allMarkets} />
|
||||
),
|
||||
};
|
||||
})}
|
||||
noCollapse={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -286,3 +410,126 @@ const ToggleButton = ({
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const EndTimeCell = ({ epoch }: { epoch?: number }) => {
|
||||
const { data, loading } = useEpochInfoQuery({
|
||||
variables: {
|
||||
epochId: epoch ? epoch.toString() : undefined,
|
||||
},
|
||||
fetchPolicy: 'cache-and-network',
|
||||
});
|
||||
|
||||
if (loading) return <Loader size="small" />;
|
||||
if (data) {
|
||||
return format(
|
||||
new Date(data.epoch.timestamps.expiry),
|
||||
'yyyy/MM/dd hh:mm:ss'
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const RewardAssetCell = ({ asset }: { asset: Asset }) => {
|
||||
const open = useAssetDetailsDialogStore((state) => state.open);
|
||||
const ref = useRef<HTMLButtonElement>(null);
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
open(asset.id, ref.current);
|
||||
}}
|
||||
className="border-b border-dashed border-vega-clight-200 dark:border-vega-cdark-200 text-left text-nowrap whitespace-nowrap"
|
||||
>
|
||||
{asset.symbol}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
const GameTypeCell = ({
|
||||
transfer,
|
||||
allMarkets,
|
||||
}: {
|
||||
transfer?: EnrichedTransfer;
|
||||
allMarkets?: MarketMap;
|
||||
}) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const ref = useRef<HTMLButtonElement>(null);
|
||||
if (!transfer) return '-';
|
||||
return (
|
||||
<>
|
||||
<ActiveRewardCardDialog
|
||||
open={open}
|
||||
onChange={(isOpen) => setOpen(isOpen)}
|
||||
trigger={ref.current}
|
||||
transfer={transfer}
|
||||
allMarkets={allMarkets}
|
||||
/>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setOpen(true);
|
||||
}}
|
||||
ref={ref}
|
||||
className="border-b border-dashed border-vega-clight-200 dark:border-vega-cdark-200 text-left md:truncate md:max-w-[25vw]"
|
||||
>
|
||||
<DispatchMetricInfo transferNode={transfer} allMarkets={allMarkets} />
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const ActiveRewardCardDialog = ({
|
||||
open,
|
||||
onChange,
|
||||
trigger,
|
||||
transfer,
|
||||
allMarkets,
|
||||
}: {
|
||||
open: boolean;
|
||||
onChange: (isOpen: boolean) => void;
|
||||
trigger?: HTMLElement | null;
|
||||
transfer: EnrichedTransfer;
|
||||
allMarkets?: MarketMap;
|
||||
}) => {
|
||||
const t = useT();
|
||||
const { data } = useEpochInfoQuery();
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
title={t('Game details')}
|
||||
onChange={(isOpen) => onChange(isOpen)}
|
||||
icon={<VegaIcon name={VegaIconNames.INFO} />}
|
||||
onCloseAutoFocus={(e) => {
|
||||
/**
|
||||
* This mimics radix's default behaviour that focuses the dialog's
|
||||
* trigger after closing itself
|
||||
*/
|
||||
if (trigger) {
|
||||
e.preventDefault();
|
||||
trigger.focus();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="py-5 max-w-[454px]">
|
||||
<ActiveRewardCard
|
||||
transferNode={transfer}
|
||||
currentEpoch={Number(data?.epoch.id)}
|
||||
kind={transfer.transfer.kind as RecurringTransfer}
|
||||
allMarkets={allMarkets}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/4">
|
||||
<Button
|
||||
data-testid="close-asset-details-dialog"
|
||||
fill={true}
|
||||
size="sm"
|
||||
onClick={() => onChange(false)}
|
||||
>
|
||||
{t('Close')}
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ import { useEffect } from 'react';
|
||||
import { useT } from '../../../lib/use-t';
|
||||
import { matchPath, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Routes } from '../../../lib/links';
|
||||
import { useCurrentEpochInfoQuery } from '../../../lib/hooks/__generated__/Epoch';
|
||||
import { useEpochInfoQuery } from '../../../lib/hooks/__generated__/Epoch';
|
||||
|
||||
const REFETCH_INTERVAL = 60 * 60 * 1000; // 1h
|
||||
const NON_ELIGIBLE_REFERRAL_SET_TOAST_ID = 'non-eligible-referral-set';
|
||||
@ -23,7 +23,7 @@ const useNonEligibleReferralSet = () => {
|
||||
data: epochData,
|
||||
loading: epochLoading,
|
||||
refetch: epochRefetch,
|
||||
} = useCurrentEpochInfoQuery();
|
||||
} = useEpochInfoQuery();
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
|
@ -34,7 +34,7 @@ import {
|
||||
} from './hooks/use-referral';
|
||||
import { ApplyCodeForm, ApplyCodeFormContainer } from './apply-code-form';
|
||||
import { useReferralProgram } from './hooks/use-referral-program';
|
||||
import { useCurrentEpochInfoQuery } from '../../lib/hooks/__generated__/Epoch';
|
||||
import { useEpochInfoQuery } from '../../lib/hooks/__generated__/Epoch';
|
||||
import { QUSDTooltip } from './qusd-tooltip';
|
||||
import { CodeTile, StatTile, Tile } from './tile';
|
||||
import { areTeamGames, useGames } from '../../lib/hooks/use-games';
|
||||
@ -95,7 +95,7 @@ export const useStats = ({
|
||||
program: ReturnType<typeof useReferralProgram>;
|
||||
}) => {
|
||||
const { benefitTiers } = program;
|
||||
const { data: epochData } = useCurrentEpochInfoQuery({
|
||||
const { data: epochData } = useEpochInfoQuery({
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
const { data: statsData } = useReferralSetStatsQuery({
|
||||
|
@ -1,49 +1,19 @@
|
||||
import { type TransferNode } from '@vegaprotocol/types';
|
||||
import {
|
||||
ActiveRewardCard,
|
||||
isActiveReward,
|
||||
} from '../rewards-container/active-rewards';
|
||||
import { ActiveRewardCard } from '../rewards-container/active-rewards';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { useAssetsMapProvider } from '@vegaprotocol/assets';
|
||||
import { type EnrichedTransfer } from '../../lib/hooks/use-game-cards';
|
||||
import { useMarketsMapProvider } from '@vegaprotocol/markets';
|
||||
|
||||
export const GamesContainer = ({
|
||||
data,
|
||||
currentEpoch,
|
||||
}: {
|
||||
data: TransferNode[];
|
||||
data: EnrichedTransfer[];
|
||||
currentEpoch: number;
|
||||
}) => {
|
||||
const t = useT();
|
||||
// Re-load markets and assets in the games container to ensure that the
|
||||
// the cards are updated (not grayed out) when the user navigates to the games page
|
||||
const { data: assets } = useAssetsMapProvider();
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
|
||||
const enrichedTransfers = data
|
||||
.filter((node) => isActiveReward(node, currentEpoch))
|
||||
.map((node) => {
|
||||
if (node.transfer.kind.__typename !== 'RecurringTransfer') {
|
||||
return node;
|
||||
}
|
||||
|
||||
const asset =
|
||||
assets &&
|
||||
assets[
|
||||
node.transfer.kind.dispatchStrategy?.dispatchMetricAssetId || ''
|
||||
];
|
||||
|
||||
const marketsInScope =
|
||||
node.transfer.kind.dispatchStrategy?.marketIdsInScope?.map(
|
||||
(id) => markets && markets[id]
|
||||
);
|
||||
|
||||
return { ...node, asset, markets: marketsInScope };
|
||||
});
|
||||
|
||||
if (!enrichedTransfers || !enrichedTransfers.length) return null;
|
||||
|
||||
if (!enrichedTransfers || enrichedTransfers.length === 0) {
|
||||
if (!data || data.length === 0) {
|
||||
return (
|
||||
<p className="mb-6 text-muted">
|
||||
{t('There are currently no games available.')}
|
||||
@ -53,7 +23,7 @@ export const GamesContainer = ({
|
||||
|
||||
return (
|
||||
<div className="mb-12 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{enrichedTransfers.map((game, i) => {
|
||||
{data.map((game, i) => {
|
||||
// TODO: Remove `kind` prop from ActiveRewardCard
|
||||
const { transfer } = game;
|
||||
if (
|
||||
|
@ -73,6 +73,7 @@ query ActiveRewards(
|
||||
reference
|
||||
status
|
||||
timestamp
|
||||
gameId
|
||||
kind {
|
||||
... on RecurringTransfer {
|
||||
startEpoch
|
||||
|
@ -18,7 +18,7 @@ export type ActiveRewardsQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ActiveRewardsQuery = { __typename?: 'Query', transfersConnection?: { __typename?: 'TransferConnection', edges?: Array<{ __typename?: 'TransferEdge', node: { __typename?: 'TransferNode', transfer: { __typename?: 'Transfer', amount: string, id: string, from: string, fromAccountType: Types.AccountType, to: string, toAccountType: Types.AccountType, reference?: string | null, status: Types.TransferStatus, timestamp: any, reason?: string | null, asset?: { __typename?: 'Asset', id: string, symbol: string, decimals: number, name: string, quantum: string, status: Types.AssetStatus } | null, kind: { __typename?: 'OneOffGovernanceTransfer' } | { __typename?: 'OneOffTransfer' } | { __typename?: 'RecurringGovernanceTransfer' } | { __typename?: 'RecurringTransfer', startEpoch: number, endEpoch?: number | null, dispatchStrategy?: { __typename?: 'DispatchStrategy', dispatchMetric: Types.DispatchMetric, dispatchMetricAssetId: string, marketIdsInScope?: Array<string> | null, entityScope: Types.EntityScope, individualScope?: Types.IndividualScope | null, teamScope?: Array<string | null> | null, nTopPerformers?: string | null, stakingRequirement: string, notionalTimeWeightedAveragePositionRequirement: string, windowLength: number, lockPeriod: number, distributionStrategy: Types.DistributionStrategy, rankTable?: Array<{ __typename?: 'RankTable', startRank: number, shareRatio: number } | null> | null } | null } }, fees?: Array<{ __typename?: 'TransferFee', transferId: string, amount: string, epoch: number } | null> | null } } | null> | null } | null };
|
||||
export type ActiveRewardsQuery = { __typename?: 'Query', transfersConnection?: { __typename?: 'TransferConnection', edges?: Array<{ __typename?: 'TransferEdge', node: { __typename?: 'TransferNode', transfer: { __typename?: 'Transfer', amount: string, id: string, from: string, fromAccountType: Types.AccountType, to: string, toAccountType: Types.AccountType, reference?: string | null, status: Types.TransferStatus, timestamp: any, gameId?: string | null, reason?: string | null, asset?: { __typename?: 'Asset', id: string, symbol: string, decimals: number, name: string, quantum: string, status: Types.AssetStatus } | null, kind: { __typename?: 'OneOffGovernanceTransfer' } | { __typename?: 'OneOffTransfer' } | { __typename?: 'RecurringGovernanceTransfer' } | { __typename?: 'RecurringTransfer', startEpoch: number, endEpoch?: number | null, dispatchStrategy?: { __typename?: 'DispatchStrategy', dispatchMetric: Types.DispatchMetric, dispatchMetricAssetId: string, marketIdsInScope?: Array<string> | null, entityScope: Types.EntityScope, individualScope?: Types.IndividualScope | null, teamScope?: Array<string | null> | null, nTopPerformers?: string | null, stakingRequirement: string, notionalTimeWeightedAveragePositionRequirement: string, windowLength: number, lockPeriod: number, distributionStrategy: Types.DistributionStrategy, rankTable?: Array<{ __typename?: 'RankTable', startRank: number, shareRatio: number } | null> | null } | null } }, fees?: Array<{ __typename?: 'TransferFee', transferId: string, amount: string, epoch: number } | null> | null } } | null> | null } | null };
|
||||
|
||||
export type RewardsHistoryQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
@ -144,6 +144,7 @@ export const ActiveRewardsDocument = gql`
|
||||
reference
|
||||
status
|
||||
timestamp
|
||||
gameId
|
||||
kind {
|
||||
... on RecurringTransfer {
|
||||
startEpoch
|
||||
|
@ -251,12 +251,7 @@ const StatusIndicator = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const ActiveRewardCard = ({
|
||||
transferNode,
|
||||
currentEpoch,
|
||||
kind,
|
||||
allMarkets,
|
||||
}: {
|
||||
type ActiveRewardCardProps = {
|
||||
transferNode: TransferNode & {
|
||||
asset?: AssetFieldsFragment | null;
|
||||
markets?: (MarketFieldsFragment | null)[];
|
||||
@ -264,7 +259,13 @@ export const ActiveRewardCard = ({
|
||||
currentEpoch: number;
|
||||
kind: RecurringTransfer;
|
||||
allMarkets?: Record<string, MarketFieldsFragment | null>;
|
||||
}) => {
|
||||
};
|
||||
export const ActiveRewardCard = ({
|
||||
transferNode,
|
||||
currentEpoch,
|
||||
kind,
|
||||
allMarkets,
|
||||
}: ActiveRewardCardProps) => {
|
||||
const t = useT();
|
||||
|
||||
const { transfer } = transferNode;
|
||||
@ -485,6 +486,62 @@ export const ActiveRewardCard = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const DispatchMetricInfo = ({
|
||||
transferNode,
|
||||
allMarkets,
|
||||
}: {
|
||||
transferNode: ActiveRewardCardProps['transferNode'];
|
||||
allMarkets?: ActiveRewardCardProps['allMarkets'];
|
||||
}) => {
|
||||
const dispatchStrategy =
|
||||
transferNode.transfer.kind.__typename === 'RecurringTransfer'
|
||||
? transferNode.transfer.kind.dispatchStrategy
|
||||
: null;
|
||||
|
||||
const dispatchAsset = transferNode.transfer.asset;
|
||||
|
||||
const marketIdsInScope = dispatchStrategy?.marketIdsInScope;
|
||||
const firstMarketData = transferNode.markets?.[0];
|
||||
const specificMarkets = useMemo(() => {
|
||||
if (
|
||||
!firstMarketData ||
|
||||
!marketIdsInScope ||
|
||||
marketIdsInScope.length === 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
if (marketIdsInScope.length > 1) {
|
||||
const marketNames =
|
||||
allMarkets &&
|
||||
marketIdsInScope
|
||||
.map((id) => allMarkets[id]?.tradableInstrument?.instrument?.name)
|
||||
.join(', ');
|
||||
|
||||
return (
|
||||
<Tooltip description={marketNames}>
|
||||
<span>Specific markets</span>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
const name = firstMarketData?.tradableInstrument?.instrument?.name;
|
||||
if (name) {
|
||||
return <span>{name}</span>;
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [firstMarketData, marketIdsInScope, allMarkets]);
|
||||
|
||||
if (!dispatchStrategy) return null;
|
||||
|
||||
return (
|
||||
<span data-testid="dispatch-metric-info">
|
||||
{DispatchMetricLabels[dispatchStrategy.dispatchMetric]} •{' '}
|
||||
<span>{specificMarkets || dispatchAsset?.name}</span>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const RewardRequirements = ({
|
||||
dispatchStrategy,
|
||||
assetDecimalPlaces = 0,
|
||||
|
@ -93,6 +93,9 @@ export const Table = forwardRef<
|
||||
key={i}
|
||||
className={classNames(dataEntry['className'] as string, {
|
||||
'max-md:flex flex-col w-full': !noCollapse,
|
||||
// collapsed (mobile) row divider
|
||||
'first:border-t-0 max-md:border-t border-vega-clight-500 dark:border-vega-cdark-500 first:mt-0 mt-1':
|
||||
!noCollapse,
|
||||
})}
|
||||
onClick={() => {
|
||||
if (onRowClick) {
|
||||
|
@ -8,10 +8,13 @@ from fixtures.market import setup_continuous_market
|
||||
from conftest import auth_setup, init_page, init_vega, risk_accepted_setup
|
||||
from wallet_config import PARTY_A, PARTY_B, PARTY_C, PARTY_D, MM_WALLET
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function
|
||||
request.addfinalizer(
|
||||
lambda: cleanup_container(vega_instance)
|
||||
) # Register the cleanup function
|
||||
yield vega_instance
|
||||
|
||||
|
||||
@ -125,7 +128,7 @@ def setup_teams_and_games(vega: VegaServiceNull):
|
||||
n_top_performers=1,
|
||||
amount=100,
|
||||
factor=1.0,
|
||||
window_length=15
|
||||
window_length=15,
|
||||
)
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
@ -213,23 +216,22 @@ def create_team(vega: VegaServiceNull):
|
||||
|
||||
|
||||
def test_team_page_games_table(team_page: Page):
|
||||
team_page.pause()
|
||||
team_page.get_by_test_id("games-toggle").click()
|
||||
expect(team_page.get_by_test_id("games-toggle")).to_have_text("Results (10)")
|
||||
expect(team_page.get_by_test_id("rank-0")).to_have_text("1")
|
||||
expect(team_page.get_by_test_id("epoch-0")).to_have_text("19")
|
||||
expect(team_page.get_by_test_id("type-0")
|
||||
).to_have_text("Price maker fees paid")
|
||||
#TODO skipped as the amount is wrong
|
||||
#expect(team_page.get_by_test_id("amount-0")).to_have_text("74") # 50,000,000 on 74.1
|
||||
expect(team_page.get_by_test_id("type-0")).to_have_text(
|
||||
"Price maker fees paid • tDAI "
|
||||
)
|
||||
# TODO skipped as the amount is wrong
|
||||
# expect(team_page.get_by_test_id("amount-0")).to_have_text("74") # 50,000,000 on 74.1
|
||||
expect(team_page.get_by_test_id("participatingTeams-0")).to_have_text("2")
|
||||
expect(team_page.get_by_test_id("participatingMembers-0")).to_have_text("3")
|
||||
|
||||
|
||||
def test_team_page_members_table(team_page: Page):
|
||||
team_page.get_by_test_id("members-toggle").click()
|
||||
expect(team_page.get_by_test_id("members-toggle")
|
||||
).to_have_text("Members (4)")
|
||||
expect(team_page.get_by_test_id("members-toggle")).to_have_text("Members (4)")
|
||||
expect(team_page.get_by_test_id("referee-0")).to_be_visible()
|
||||
expect(team_page.get_by_test_id("joinedAt-0")).to_be_visible()
|
||||
expect(team_page.get_by_test_id("joinedAtEpoch-0")).to_have_text("9")
|
||||
@ -267,8 +269,7 @@ def test_leaderboard(competitions_page: Page, setup_teams_and_games):
|
||||
competitions_page.get_by_test_id("rank-0").locator(".text-yellow-300")
|
||||
).to_have_count(1)
|
||||
expect(
|
||||
competitions_page.get_by_test_id(
|
||||
"rank-1").locator(".text-vega-clight-500")
|
||||
competitions_page.get_by_test_id("rank-1").locator(".text-vega-clight-500")
|
||||
).to_have_count(1)
|
||||
expect(competitions_page.get_by_test_id("team-0")).to_have_text(team_name)
|
||||
expect(competitions_page.get_by_test_id("status-1")).to_have_text("Open")
|
||||
@ -282,17 +283,16 @@ def test_leaderboard(competitions_page: Page, setup_teams_and_games):
|
||||
|
||||
|
||||
def test_game_card(competitions_page: Page):
|
||||
expect(competitions_page.get_by_test_id(
|
||||
"active-rewards-card")).to_have_count(2)
|
||||
expect(competitions_page.get_by_test_id("active-rewards-card")).to_have_count(2)
|
||||
game_1 = competitions_page.get_by_test_id("active-rewards-card").first
|
||||
expect(game_1).to_be_visible()
|
||||
expect(game_1.get_by_test_id("entity-scope")).to_have_text("Individual")
|
||||
expect(game_1.get_by_test_id("locked-for")).to_have_text("1 epoch")
|
||||
expect(game_1.get_by_test_id("reward-value")).to_have_text("100.00")
|
||||
expect(game_1.get_by_test_id("distribution-strategy")
|
||||
).to_have_text("Pro rata")
|
||||
expect(game_1.get_by_test_id("dispatch-metric-info")
|
||||
).to_have_text("Price maker fees paid • tDAI")
|
||||
expect(game_1.get_by_test_id("distribution-strategy")).to_have_text("Pro rata")
|
||||
expect(game_1.get_by_test_id("dispatch-metric-info")).to_have_text(
|
||||
"Price maker fees paid • tDAI"
|
||||
)
|
||||
expect(game_1.get_by_test_id("assessed-over")).to_have_text("15 epochs")
|
||||
expect(game_1.get_by_test_id("scope")).to_have_text("In team")
|
||||
expect(game_1.get_by_test_id("staking-requirement")).to_have_text("0.00")
|
||||
|
@ -1,9 +1,10 @@
|
||||
query CurrentEpochInfo {
|
||||
epoch {
|
||||
query EpochInfo($epochId: ID) {
|
||||
epoch(id: $epochId) {
|
||||
id
|
||||
timestamps {
|
||||
start
|
||||
end
|
||||
expiry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ fragment GameFields on Game {
|
||||
id
|
||||
epoch
|
||||
numberOfParticipants
|
||||
rewardAssetId
|
||||
entities {
|
||||
... on TeamGameEntity {
|
||||
...TeamEntity
|
||||
|
36
apps/trading/lib/hooks/__generated__/Epoch.ts
generated
36
apps/trading/lib/hooks/__generated__/Epoch.ts
generated
@ -3,47 +3,51 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type CurrentEpochInfoQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
export type EpochInfoQueryVariables = Types.Exact<{
|
||||
epochId?: Types.InputMaybe<Types.Scalars['ID']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type CurrentEpochInfoQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string, timestamps: { __typename?: 'EpochTimestamps', start?: any | null, end?: any | null } } };
|
||||
export type EpochInfoQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string, timestamps: { __typename?: 'EpochTimestamps', start?: any | null, end?: any | null, expiry?: any | null } } };
|
||||
|
||||
|
||||
export const CurrentEpochInfoDocument = gql`
|
||||
query CurrentEpochInfo {
|
||||
epoch {
|
||||
export const EpochInfoDocument = gql`
|
||||
query EpochInfo($epochId: ID) {
|
||||
epoch(id: $epochId) {
|
||||
id
|
||||
timestamps {
|
||||
start
|
||||
end
|
||||
expiry
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useCurrentEpochInfoQuery__
|
||||
* __useEpochInfoQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useCurrentEpochInfoQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useCurrentEpochInfoQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* To run a query within a React component, call `useEpochInfoQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useEpochInfoQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useCurrentEpochInfoQuery({
|
||||
* const { data, loading, error } = useEpochInfoQuery({
|
||||
* variables: {
|
||||
* epochId: // value for 'epochId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useCurrentEpochInfoQuery(baseOptions?: Apollo.QueryHookOptions<CurrentEpochInfoQuery, CurrentEpochInfoQueryVariables>) {
|
||||
export function useEpochInfoQuery(baseOptions?: Apollo.QueryHookOptions<EpochInfoQuery, EpochInfoQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<CurrentEpochInfoQuery, CurrentEpochInfoQueryVariables>(CurrentEpochInfoDocument, options);
|
||||
return Apollo.useQuery<EpochInfoQuery, EpochInfoQueryVariables>(EpochInfoDocument, options);
|
||||
}
|
||||
export function useCurrentEpochInfoLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<CurrentEpochInfoQuery, CurrentEpochInfoQueryVariables>) {
|
||||
export function useEpochInfoLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<EpochInfoQuery, EpochInfoQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<CurrentEpochInfoQuery, CurrentEpochInfoQueryVariables>(CurrentEpochInfoDocument, options);
|
||||
return Apollo.useLazyQuery<EpochInfoQuery, EpochInfoQueryVariables>(EpochInfoDocument, options);
|
||||
}
|
||||
export type CurrentEpochInfoQueryHookResult = ReturnType<typeof useCurrentEpochInfoQuery>;
|
||||
export type CurrentEpochInfoLazyQueryHookResult = ReturnType<typeof useCurrentEpochInfoLazyQuery>;
|
||||
export type CurrentEpochInfoQueryResult = Apollo.QueryResult<CurrentEpochInfoQuery, CurrentEpochInfoQueryVariables>;
|
||||
export type EpochInfoQueryHookResult = ReturnType<typeof useEpochInfoQuery>;
|
||||
export type EpochInfoLazyQueryHookResult = ReturnType<typeof useEpochInfoLazyQuery>;
|
||||
export type EpochInfoQueryResult = Apollo.QueryResult<EpochInfoQuery, EpochInfoQueryVariables>;
|
5
apps/trading/lib/hooks/__generated__/Games.ts
generated
5
apps/trading/lib/hooks/__generated__/Games.ts
generated
@ -5,14 +5,14 @@ import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type TeamEntityFragment = { __typename?: 'TeamGameEntity', rank: number, volume: string, rewardMetric: Types.DispatchMetric, rewardEarned: string, totalRewardsEarned: string, team: { __typename?: 'TeamParticipation', teamId: string, membersParticipating: Array<{ __typename?: 'IndividualGameEntity', individual: string, rank: number }> } };
|
||||
|
||||
export type GameFieldsFragment = { __typename?: 'Game', id: string, epoch: number, numberOfParticipants: number, entities: Array<{ __typename?: 'IndividualGameEntity' } | { __typename?: 'TeamGameEntity', rank: number, volume: string, rewardMetric: Types.DispatchMetric, rewardEarned: string, totalRewardsEarned: string, team: { __typename?: 'TeamParticipation', teamId: string, membersParticipating: Array<{ __typename?: 'IndividualGameEntity', individual: string, rank: number }> } }> };
|
||||
export type GameFieldsFragment = { __typename?: 'Game', id: string, epoch: number, numberOfParticipants: number, rewardAssetId: string, entities: Array<{ __typename?: 'IndividualGameEntity' } | { __typename?: 'TeamGameEntity', rank: number, volume: string, rewardMetric: Types.DispatchMetric, rewardEarned: string, totalRewardsEarned: string, team: { __typename?: 'TeamParticipation', teamId: string, membersParticipating: Array<{ __typename?: 'IndividualGameEntity', individual: string, rank: number }> } }> };
|
||||
|
||||
export type GamesQueryVariables = Types.Exact<{
|
||||
epochFrom?: Types.InputMaybe<Types.Scalars['Int']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GamesQuery = { __typename?: 'Query', games: { __typename?: 'GamesConnection', edges?: Array<{ __typename?: 'GameEdge', node: { __typename?: 'Game', id: string, epoch: number, numberOfParticipants: number, entities: Array<{ __typename?: 'IndividualGameEntity' } | { __typename?: 'TeamGameEntity', rank: number, volume: string, rewardMetric: Types.DispatchMetric, rewardEarned: string, totalRewardsEarned: string, team: { __typename?: 'TeamParticipation', teamId: string, membersParticipating: Array<{ __typename?: 'IndividualGameEntity', individual: string, rank: number }> } }> } } | null> | null } };
|
||||
export type GamesQuery = { __typename?: 'Query', games: { __typename?: 'GamesConnection', edges?: Array<{ __typename?: 'GameEdge', node: { __typename?: 'Game', id: string, epoch: number, numberOfParticipants: number, rewardAssetId: string, entities: Array<{ __typename?: 'IndividualGameEntity' } | { __typename?: 'TeamGameEntity', rank: number, volume: string, rewardMetric: Types.DispatchMetric, rewardEarned: string, totalRewardsEarned: string, team: { __typename?: 'TeamParticipation', teamId: string, membersParticipating: Array<{ __typename?: 'IndividualGameEntity', individual: string, rank: number }> } }> } } | null> | null } };
|
||||
|
||||
export const TeamEntityFragmentDoc = gql`
|
||||
fragment TeamEntity on TeamGameEntity {
|
||||
@ -35,6 +35,7 @@ export const GameFieldsFragmentDoc = gql`
|
||||
id
|
||||
epoch
|
||||
numberOfParticipants
|
||||
rewardAssetId
|
||||
entities {
|
||||
... on TeamGameEntity {
|
||||
...TeamEntity
|
||||
|
@ -2,12 +2,35 @@ import compact from 'lodash/compact';
|
||||
import { useActiveRewardsQuery } from '../../components/rewards-container/__generated__/Rewards';
|
||||
import { isActiveReward } from '../../components/rewards-container/active-rewards';
|
||||
import {
|
||||
type RecurringTransfer,
|
||||
type TransferNode,
|
||||
EntityScope,
|
||||
IndividualScope,
|
||||
type TransferNode,
|
||||
} from '@vegaprotocol/types';
|
||||
import {
|
||||
type AssetFieldsFragment,
|
||||
useAssetsMapProvider,
|
||||
} from '@vegaprotocol/assets';
|
||||
import {
|
||||
type MarketFieldsFragment,
|
||||
useMarketsMapProvider,
|
||||
} from '@vegaprotocol/markets';
|
||||
import { type ApolloError } from '@apollo/client';
|
||||
|
||||
const isScopedToTeams = (node: TransferNode) =>
|
||||
export type EnrichedTransfer = TransferNode & {
|
||||
asset?: AssetFieldsFragment | null;
|
||||
markets?: (MarketFieldsFragment | null)[];
|
||||
};
|
||||
|
||||
type RecurringTransferKind = EnrichedTransfer & {
|
||||
transfer: {
|
||||
kind: RecurringTransfer;
|
||||
};
|
||||
};
|
||||
|
||||
export const isScopedToTeams = (
|
||||
node: TransferNode
|
||||
): node is RecurringTransferKind =>
|
||||
node.transfer.kind.__typename === 'RecurringTransfer' &&
|
||||
// scoped to teams
|
||||
(node.transfer.kind.dispatchStrategy?.entityScope ===
|
||||
@ -25,7 +48,7 @@ export const useGameCards = ({
|
||||
}: {
|
||||
currentEpoch: number;
|
||||
onlyActive: boolean;
|
||||
}) => {
|
||||
}): { data: EnrichedTransfer[]; loading: boolean; error?: ApolloError } => {
|
||||
const { data, loading, error } = useActiveRewardsQuery({
|
||||
variables: {
|
||||
isReward: true,
|
||||
@ -33,16 +56,37 @@ export const useGameCards = ({
|
||||
fetchPolicy: 'cache-and-network',
|
||||
});
|
||||
|
||||
const { data: assets, loading: assetsLoading } = useAssetsMapProvider();
|
||||
const { data: markets, loading: marketsLoading } = useMarketsMapProvider();
|
||||
|
||||
const games = compact(data?.transfersConnection?.edges?.map((n) => n?.node))
|
||||
.map((n) => n as TransferNode)
|
||||
.filter((node) => {
|
||||
const active = onlyActive ? isActiveReward(node, currentEpoch) : true;
|
||||
return active && isScopedToTeams(node);
|
||||
})
|
||||
.map((node) => {
|
||||
if (node.transfer.kind.__typename !== 'RecurringTransfer') {
|
||||
return node;
|
||||
}
|
||||
|
||||
const asset =
|
||||
assets &&
|
||||
assets[
|
||||
node.transfer.kind.dispatchStrategy?.dispatchMetricAssetId || ''
|
||||
];
|
||||
|
||||
const marketsInScope =
|
||||
node.transfer.kind.dispatchStrategy?.marketIdsInScope?.map(
|
||||
(id) => markets && markets[id]
|
||||
);
|
||||
|
||||
return { ...node, asset, markets: marketsInScope };
|
||||
});
|
||||
|
||||
return {
|
||||
data: games,
|
||||
loading,
|
||||
loading: loading || assetsLoading || marketsLoading,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
} from './__generated__/Games';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
||||
import { useCurrentEpochInfoQuery } from './__generated__/Epoch';
|
||||
import { useEpochInfoQuery } from './__generated__/Epoch';
|
||||
import { type ApolloError } from '@apollo/client';
|
||||
|
||||
const TAKE_EPOCHS = 30; // TODO: should this be DEFAULT_AGGREGATION_EPOCHS?
|
||||
@ -39,7 +39,7 @@ export const useGames = (teamId?: string, epochFrom?: number): GamesData => {
|
||||
data: epochData,
|
||||
loading: epochLoading,
|
||||
error: epochError,
|
||||
} = useCurrentEpochInfoQuery({
|
||||
} = useEpochInfoQuery({
|
||||
skip: Boolean(epochFrom),
|
||||
});
|
||||
|
||||
|
@ -455,5 +455,12 @@
|
||||
"Go back to the team's profile": "Go back to the team's profile",
|
||||
"Go back to the competitions": "Go back to the competitions",
|
||||
"Your team ID:": "Your team ID:",
|
||||
"Changes successfully saved to your team.": "Changes successfully saved to your team."
|
||||
"Changes successfully saved to your team.": "Changes successfully saved to your team.",
|
||||
"Results {{games}}": "Results {{games}}",
|
||||
"End time": "End time",
|
||||
"Reward asset": "Reward asset",
|
||||
"Daily reward amount": "Daily reward amount",
|
||||
"Amount earned this epoch": "Amount earned this epoch",
|
||||
"Cumulative amount earned": "Cumulative amount earned",
|
||||
"Game details": "Game details"
|
||||
}
|
||||
|
@ -47,8 +47,9 @@ export const marketsProvider = makeDataProvider<
|
||||
errorPolicy: 'all',
|
||||
});
|
||||
|
||||
export type MarketMap = Record<string, Market>;
|
||||
export const marketsMapProvider = makeDerivedDataProvider<
|
||||
Record<string, Market>,
|
||||
MarketMap,
|
||||
never,
|
||||
undefined
|
||||
>(
|
||||
@ -59,7 +60,7 @@ export const marketsMapProvider = makeDerivedDataProvider<
|
||||
markets[market.id] = market;
|
||||
return markets;
|
||||
},
|
||||
{} as Record<string, Market>
|
||||
{} as MarketMap
|
||||
);
|
||||
}
|
||||
);
|
||||
|
24
libs/types/src/__generated__/types.ts
generated
24
libs/types/src/__generated__/types.ts
generated
@ -1640,6 +1640,8 @@ export type Game = {
|
||||
id: Scalars['ID'];
|
||||
/** Number of participants that took part in the game during the epoch. */
|
||||
numberOfParticipants: Scalars['Int'];
|
||||
/** ID of asset in which the rewards were paid. */
|
||||
rewardAssetId: Scalars['ID'];
|
||||
};
|
||||
|
||||
/** Edge type containing the game metrics and cursor information returned by a GameConnection */
|
||||
@ -1704,10 +1706,14 @@ export type IndividualGameEntity = {
|
||||
rank: Scalars['Int'];
|
||||
/** The rewards earned by the individual during the epoch */
|
||||
rewardEarned: Scalars['String'];
|
||||
/** The rewards earned by the individual during the epoch in quantum value */
|
||||
rewardEarnedQuantum: Scalars['String'];
|
||||
/** The reward metric applied to the game */
|
||||
rewardMetric: DispatchMetric;
|
||||
/** Total rewards earned by the individual during the game */
|
||||
totalRewardsEarned: Scalars['String'];
|
||||
/** Total rewards earned by the individual during the game in quantum value */
|
||||
totalRewardsEarnedQuantum: Scalars['String'];
|
||||
/** The volume traded by the individual */
|
||||
volume: Scalars['String'];
|
||||
};
|
||||
@ -4733,10 +4739,18 @@ export type QuantumRewardsPerEpoch = {
|
||||
__typename?: 'QuantumRewardsPerEpoch';
|
||||
/** Epoch for which this information is valid. */
|
||||
epoch: Scalars['Int'];
|
||||
/** Total of rewards accumulated over the epoch period expressed in quantum value. */
|
||||
/** Total of rewards accumulated over the epoch period expressed in quantum value. */
|
||||
totalQuantumRewards: Scalars['String'];
|
||||
};
|
||||
|
||||
export type QuantumVolumesPerEpoch = {
|
||||
__typename?: 'QuantumVolumesPerEpoch';
|
||||
/** Epoch for which this information is valid. */
|
||||
epoch: Scalars['Int'];
|
||||
/** Total volume across all markets, accumulated over the epoch period, expressed in quantum value. */
|
||||
totalQuantumVolumes: Scalars['String'];
|
||||
};
|
||||
|
||||
/** Queries allow a caller to read data and filter data via GraphQL. */
|
||||
export type Query = {
|
||||
__typename?: 'Query';
|
||||
@ -6412,12 +6426,16 @@ export type TeamGameEntity = {
|
||||
rank: Scalars['Int'];
|
||||
/** Total rewards earned by the team during the epoch */
|
||||
rewardEarned: Scalars['String'];
|
||||
/** Total rewards earned by the team during the epoch in quantum value */
|
||||
rewardEarnedQuantum: Scalars['String'];
|
||||
/** Reward metric applied to the game. */
|
||||
rewardMetric: DispatchMetric;
|
||||
/** Breakdown of the team members and their contributions to the total team metrics. */
|
||||
team: TeamParticipation;
|
||||
/** Total rewards earned by the team for the game */
|
||||
totalRewardsEarned: Scalars['String'];
|
||||
/** Total rewards earned by the team for the game in quantum value */
|
||||
totalRewardsEarnedQuantum: Scalars['String'];
|
||||
/** Total volume traded by the team */
|
||||
volume: Scalars['String'];
|
||||
};
|
||||
@ -6431,6 +6449,8 @@ export type TeamMemberStatistics = {
|
||||
partyId: Scalars['String'];
|
||||
/** List of rewards over the requested epoch period, expressed in quantum value for each epoch */
|
||||
quantumRewards: Array<QuantumRewardsPerEpoch>;
|
||||
/** List of trading volume totals per epoch, for the requested epoch period, expressed in quantum value */
|
||||
quantumVolumes: Array<QuantumVolumesPerEpoch>;
|
||||
/** Total number of games played. */
|
||||
totalGamesPlayed: Scalars['Int'];
|
||||
/** Total of rewards accumulated over the requested epoch period, expressed in quantum value. */
|
||||
@ -6533,6 +6553,8 @@ export type TeamStatistics = {
|
||||
gamesPlayed: Array<Scalars['String']>;
|
||||
/** List of rewards over the requested epoch period, expressed in quantum value for each epoch */
|
||||
quantumRewards: Array<QuantumRewardsPerEpoch>;
|
||||
/** List of trading volume totals per epoch, over the requested epoch period, expressed in quantum value */
|
||||
quantumVolumes: Array<QuantumVolumesPerEpoch>;
|
||||
/** Team ID the statistics are related to. */
|
||||
teamId: Scalars['String'];
|
||||
/** Total of games played. */
|
||||
|
Loading…
Reference in New Issue
Block a user