fix(trading): teams snags (#5707)
Co-authored-by: bwallacee <ben@vega.xyz>
This commit is contained in:
parent
2002731c52
commit
42a98b6a35
@ -31,7 +31,7 @@ export const CompetitionsCreateTeam = () => {
|
|||||||
<div className="mx-auto md:w-2/3 max-w-xl">
|
<div className="mx-auto md:w-2/3 max-w-xl">
|
||||||
<Box className="flex flex-col gap-4">
|
<Box className="flex flex-col gap-4">
|
||||||
<h1 className="calt text-2xl lg:text-3xl xl:text-4xl">
|
<h1 className="calt text-2xl lg:text-3xl xl:text-4xl">
|
||||||
{t('Create a team')}
|
{isSolo ? t('Create solo team') : t('Create a team')}
|
||||||
</h1>
|
</h1>
|
||||||
{pubKey && !isReadOnly ? (
|
{pubKey && !isReadOnly ? (
|
||||||
<CreateTeamFormContainer isSolo={isSolo} />
|
<CreateTeamFormContainer isSolo={isSolo} />
|
||||||
@ -125,7 +125,7 @@ const CreateTeamFormContainer = ({ isSolo }: { isSolo: boolean }) => {
|
|||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
status={status}
|
status={status}
|
||||||
err={err}
|
err={err}
|
||||||
isSolo={isSolo}
|
isCreatingSoloTeam={isSolo}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -31,10 +31,7 @@ export const CompetitionsHome = () => {
|
|||||||
currentEpoch,
|
currentEpoch,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: teamsData, loading: teamsLoading } = useTeams({
|
const { data: teamsData, loading: teamsLoading } = useTeams();
|
||||||
sortByField: ['totalQuantumRewards'],
|
|
||||||
order: 'desc',
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
|
@ -38,12 +38,11 @@ export const CompetitionsTeam = () => {
|
|||||||
const TeamPageContainer = ({ teamId }: { teamId: string | undefined }) => {
|
const TeamPageContainer = ({ teamId }: { teamId: string | undefined }) => {
|
||||||
const t = useT();
|
const t = useT();
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
const { team, partyTeam, stats, members, games, loading, refetch } = useTeam(
|
const { data, team, partyTeam, stats, members, games, loading, refetch } =
|
||||||
teamId,
|
useTeam(teamId, pubKey || undefined);
|
||||||
pubKey || undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
if (loading) {
|
// only show spinner on first load so when users join teams its smoother
|
||||||
|
if (!data && loading) {
|
||||||
return (
|
return (
|
||||||
<Splash>
|
<Splash>
|
||||||
<Loader />
|
<Loader />
|
||||||
@ -100,9 +99,11 @@ const TeamPage = ({
|
|||||||
>
|
>
|
||||||
{team.name}
|
{team.name}
|
||||||
</h1>
|
</h1>
|
||||||
|
<div className="flex gap-2">
|
||||||
<JoinTeam team={team} partyTeam={partyTeam} refetch={refetch} />
|
<JoinTeam team={team} partyTeam={partyTeam} refetch={refetch} />
|
||||||
<UpdateTeamButton team={team} />
|
<UpdateTeamButton team={team} />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<TeamStats stats={stats} members={members} games={games} />
|
<TeamStats stats={stats} members={members} games={games} />
|
||||||
<section>
|
<section>
|
||||||
@ -184,7 +185,10 @@ const Members = ({ members }: { members?: Member[] }) => {
|
|||||||
|
|
||||||
const data = orderBy(
|
const data = orderBy(
|
||||||
members.map((m) => ({
|
members.map((m) => ({
|
||||||
referee: <RefereeLink pubkey={m.referee} />,
|
referee: <RefereeLink pubkey={m.referee} isCreator={m.isCreator} />,
|
||||||
|
rewards: formatNumber(m.totalQuantumRewards),
|
||||||
|
volume: formatNumber(m.totalQuantumVolume),
|
||||||
|
gamesPlayed: formatNumber(m.totalGamesPlayed),
|
||||||
joinedAt: getDateTimeFormat().format(new Date(m.joinedAt)),
|
joinedAt: getDateTimeFormat().format(new Date(m.joinedAt)),
|
||||||
joinedAtEpoch: Number(m.joinedAtEpoch),
|
joinedAtEpoch: Number(m.joinedAtEpoch),
|
||||||
})),
|
})),
|
||||||
@ -195,7 +199,10 @@ const Members = ({ members }: { members?: Member[] }) => {
|
|||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
columns={[
|
columns={[
|
||||||
{ name: 'referee', displayName: t('Referee') },
|
{ name: 'referee', displayName: t('Member ID') },
|
||||||
|
{ name: 'rewards', displayName: t('Rewards earned') },
|
||||||
|
{ name: 'volume', displayName: t('Total volume') },
|
||||||
|
{ name: 'gamesPlayed', displayName: t('Games played') },
|
||||||
{
|
{
|
||||||
name: 'joinedAt',
|
name: 'joinedAt',
|
||||||
displayName: t('Joined at'),
|
displayName: t('Joined at'),
|
||||||
@ -211,14 +218,24 @@ const Members = ({ members }: { members?: Member[] }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const RefereeLink = ({ pubkey }: { pubkey: string }) => {
|
const RefereeLink = ({
|
||||||
|
pubkey,
|
||||||
|
isCreator,
|
||||||
|
}: {
|
||||||
|
pubkey: string;
|
||||||
|
isCreator: boolean;
|
||||||
|
}) => {
|
||||||
|
const t = useT();
|
||||||
const linkCreator = useLinks(DApp.Explorer);
|
const linkCreator = useLinks(DApp.Explorer);
|
||||||
const link = linkCreator(EXPLORER_PARTIES.replace(':id', pubkey));
|
const link = linkCreator(EXPLORER_PARTIES.replace(':id', pubkey));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<Link to={link} target="_blank" className="underline underline-offset-4">
|
<Link to={link} target="_blank" className="underline underline-offset-4">
|
||||||
{truncateMiddle(pubkey)}
|
{truncateMiddle(pubkey)}
|
||||||
</Link>
|
</Link>{' '}
|
||||||
|
<span className="text-muted text-xs">{isCreator ? t('Owner') : ''}</span>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,10 +17,7 @@ export const CompetitionsTeams = () => {
|
|||||||
|
|
||||||
usePageTitle([t('Competitions'), t('Teams')]);
|
usePageTitle([t('Competitions'), t('Teams')]);
|
||||||
|
|
||||||
const { data: teamsData, loading: teamsLoading } = useTeams({
|
const { data: teamsData, loading: teamsLoading } = useTeams();
|
||||||
sortByField: ['totalQuantumRewards'],
|
|
||||||
order: 'desc',
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const [filter, setFilter] = useState<string | null | undefined>(undefined);
|
const [filter, setFilter] = useState<string | null | undefined>(undefined);
|
||||||
|
@ -98,7 +98,7 @@ const UpdateTeamFormContainer = ({
|
|||||||
type={TransactionType.UpdateReferralSet}
|
type={TransactionType.UpdateReferralSet}
|
||||||
status={status}
|
status={status}
|
||||||
err={err}
|
err={err}
|
||||||
isSolo={team.closed}
|
isCreatingSoloTeam={team.closed}
|
||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
defaultValues={defaultValues}
|
defaultValues={defaultValues}
|
||||||
/>
|
/>
|
||||||
|
@ -6,11 +6,7 @@ import {
|
|||||||
VegaIcon,
|
VegaIcon,
|
||||||
VegaIconNames,
|
VegaIconNames,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import {
|
import { useSimpleTransaction, useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
useSimpleTransaction,
|
|
||||||
useVegaWallet,
|
|
||||||
type Status,
|
|
||||||
} from '@vegaprotocol/wallet';
|
|
||||||
import { useT } from '../../lib/use-t';
|
import { useT } from '../../lib/use-t';
|
||||||
import { type Team } from '../../lib/hooks/use-team';
|
import { type Team } from '../../lib/hooks/use-team';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -27,19 +23,8 @@ export const JoinTeam = ({
|
|||||||
refetch: () => void;
|
refetch: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { pubKey, isReadOnly } = useVegaWallet();
|
const { pubKey, isReadOnly } = useVegaWallet();
|
||||||
const { send, status } = useSimpleTransaction({
|
|
||||||
onSuccess: refetch,
|
|
||||||
});
|
|
||||||
const [confirmDialog, setConfirmDialog] = useState<JoinType>();
|
const [confirmDialog, setConfirmDialog] = useState<JoinType>();
|
||||||
|
|
||||||
const joinTeam = () => {
|
|
||||||
send({
|
|
||||||
joinTeam: {
|
|
||||||
id: team.teamId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<JoinButton
|
<JoinButton
|
||||||
@ -56,11 +41,10 @@ export const JoinTeam = ({
|
|||||||
{confirmDialog !== undefined && (
|
{confirmDialog !== undefined && (
|
||||||
<DialogContent
|
<DialogContent
|
||||||
type={confirmDialog}
|
type={confirmDialog}
|
||||||
status={status}
|
|
||||||
team={team}
|
team={team}
|
||||||
partyTeam={partyTeam}
|
partyTeam={partyTeam}
|
||||||
onConfirm={joinTeam}
|
|
||||||
onCancel={() => setConfirmDialog(undefined)}
|
onCancel={() => setConfirmDialog(undefined)}
|
||||||
|
refetch={refetch}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
@ -110,7 +94,7 @@ export const JoinButton = ({
|
|||||||
// Not creator of the team, but still can't switch because
|
// Not creator of the team, but still can't switch because
|
||||||
// creators cannot leave their own team
|
// creators cannot leave their own team
|
||||||
return (
|
return (
|
||||||
<Tooltip description="As a team creator, you cannot switch teams">
|
<Tooltip description={t('As a team creator, you cannot switch teams')}>
|
||||||
<Button intent={Intent.Primary} disabled={true}>
|
<Button intent={Intent.Primary} disabled={true}>
|
||||||
{t('Switch team')}{' '}
|
{t('Switch team')}{' '}
|
||||||
</Button>
|
</Button>
|
||||||
@ -149,21 +133,39 @@ export const JoinButton = ({
|
|||||||
|
|
||||||
const DialogContent = ({
|
const DialogContent = ({
|
||||||
type,
|
type,
|
||||||
status,
|
|
||||||
team,
|
team,
|
||||||
partyTeam,
|
partyTeam,
|
||||||
onConfirm,
|
|
||||||
onCancel,
|
onCancel,
|
||||||
|
refetch,
|
||||||
}: {
|
}: {
|
||||||
type: JoinType;
|
type: JoinType;
|
||||||
status: Status;
|
|
||||||
team: Team;
|
team: Team;
|
||||||
partyTeam?: Team;
|
partyTeam?: Team;
|
||||||
onConfirm: () => void;
|
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
|
refetch: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const t = useT();
|
const t = useT();
|
||||||
|
|
||||||
|
const { send, status, error } = useSimpleTransaction({
|
||||||
|
onSuccess: refetch,
|
||||||
|
});
|
||||||
|
|
||||||
|
const joinTeam = () => {
|
||||||
|
send({
|
||||||
|
joinTeam: {
|
||||||
|
id: team.teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<p className="text-vega-red break-words first-letter:capitalize">
|
||||||
|
{error}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (status === 'requested') {
|
if (status === 'requested') {
|
||||||
return <p>{t('Confirm in wallet...')}</p>;
|
return <p>{t('Confirm in wallet...')}</p>;
|
||||||
}
|
}
|
||||||
@ -213,7 +215,7 @@ const DialogContent = ({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="flex justify-between gap-2">
|
<div className="flex justify-between gap-2">
|
||||||
<Button onClick={onConfirm} intent={Intent.Success}>
|
<Button onClick={joinTeam} intent={Intent.Success}>
|
||||||
{t('Confirm')}
|
{t('Confirm')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={onCancel} intent={Intent.Danger}>
|
<Button onClick={onCancel} intent={Intent.Danger}>
|
||||||
|
@ -28,8 +28,8 @@ export type FormFields = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export enum TransactionType {
|
export enum TransactionType {
|
||||||
CreateReferralSet,
|
CreateReferralSet = 'CreateReferralSet',
|
||||||
UpdateReferralSet,
|
UpdateReferralSet = 'UpdateReferralSet',
|
||||||
}
|
}
|
||||||
|
|
||||||
const prepareTransaction = (
|
const prepareTransaction = (
|
||||||
@ -75,14 +75,14 @@ export const TeamForm = ({
|
|||||||
type,
|
type,
|
||||||
status,
|
status,
|
||||||
err,
|
err,
|
||||||
isSolo,
|
isCreatingSoloTeam,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
defaultValues,
|
defaultValues,
|
||||||
}: {
|
}: {
|
||||||
type: TransactionType;
|
type: TransactionType;
|
||||||
status: ReturnType<typeof useReferralSetTransaction>['status'];
|
status: ReturnType<typeof useReferralSetTransaction>['status'];
|
||||||
err: ReturnType<typeof useReferralSetTransaction>['err'];
|
err: ReturnType<typeof useReferralSetTransaction>['err'];
|
||||||
isSolo: boolean;
|
isCreatingSoloTeam: boolean;
|
||||||
onSubmit: ReturnType<typeof useReferralSetTransaction>['onSubmit'];
|
onSubmit: ReturnType<typeof useReferralSetTransaction>['onSubmit'];
|
||||||
defaultValues?: FormFields;
|
defaultValues?: FormFields;
|
||||||
}) => {
|
}) => {
|
||||||
@ -96,7 +96,7 @@ export const TeamForm = ({
|
|||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm<FormFields>({
|
} = useForm<FormFields>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
private: isSolo,
|
private: isCreatingSoloTeam,
|
||||||
...defaultValues,
|
...defaultValues,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -109,12 +109,7 @@ export const TeamForm = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(sendTransaction)}>
|
<form onSubmit={handleSubmit(sendTransaction)}>
|
||||||
<input
|
<input type="hidden" {...register('id')} />
|
||||||
type="hidden"
|
|
||||||
{...register('id', {
|
|
||||||
disabled: true,
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<TradingFormGroup label={t('Team name')} labelFor="name">
|
<TradingFormGroup label={t('Team name')} labelFor="name">
|
||||||
<TradingInput {...register('name', { required: t('Required') })} />
|
<TradingInput {...register('name', { required: t('Required') })} />
|
||||||
{errors.name?.message && (
|
{errors.name?.message && (
|
||||||
@ -160,6 +155,10 @@ export const TeamForm = ({
|
|||||||
</TradingInputError>
|
</TradingInputError>
|
||||||
)}
|
)}
|
||||||
</TradingFormGroup>
|
</TradingFormGroup>
|
||||||
|
{
|
||||||
|
// allow changing to private/public if editing, but don't show these options if making a solo team
|
||||||
|
(type === TransactionType.UpdateReferralSet || !isCreatingSoloTeam) && (
|
||||||
|
<>
|
||||||
<TradingFormGroup
|
<TradingFormGroup
|
||||||
label={t('Make team private')}
|
label={t('Make team private')}
|
||||||
labelFor="private"
|
labelFor="private"
|
||||||
@ -176,7 +175,6 @@ export const TeamForm = ({
|
|||||||
onCheckedChange={(value) => {
|
onCheckedChange={(value) => {
|
||||||
field.onChange(value);
|
field.onChange(value);
|
||||||
}}
|
}}
|
||||||
disabled={isSolo}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@ -193,11 +191,12 @@ export const TeamForm = ({
|
|||||||
<TextArea
|
<TextArea
|
||||||
{...register('allowList', {
|
{...register('allowList', {
|
||||||
required: t('Required'),
|
required: t('Required'),
|
||||||
disabled: isSolo,
|
|
||||||
validate: {
|
validate: {
|
||||||
allowList: (value) => {
|
allowList: (value) => {
|
||||||
const publicKeys = parseAllowListText(value);
|
const publicKeys = parseAllowListText(value);
|
||||||
if (publicKeys.every((pk) => isValidVegaPublicKey(pk))) {
|
if (
|
||||||
|
publicKeys.every((pk) => isValidVegaPublicKey(pk))
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return t('Invalid public key found in allow list');
|
return t('Invalid public key found in allow list');
|
||||||
@ -212,7 +211,14 @@ export const TeamForm = ({
|
|||||||
)}
|
)}
|
||||||
</TradingFormGroup>
|
</TradingFormGroup>
|
||||||
)}
|
)}
|
||||||
{err && <p className="text-danger text-xs mb-4 capitalize">{err}</p>}
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{err && (
|
||||||
|
<p className="text-danger text-xs mb-4 first-letter:capitalize">
|
||||||
|
{err}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
<SubmitButton type={type} status={status} />
|
<SubmitButton type={type} status={status} />
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
@ -246,7 +252,7 @@ const SubmitButton = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseAllowListText = (str: string) => {
|
const parseAllowListText = (str: string = '') => {
|
||||||
return str
|
return str
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((v) => v.trim())
|
.map((v) => v.trim())
|
||||||
|
@ -2,8 +2,10 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
|
|||||||
import { type Team } from '../../lib/hooks/use-team';
|
import { type Team } from '../../lib/hooks/use-team';
|
||||||
import { Intent, TradingAnchorButton } from '@vegaprotocol/ui-toolkit';
|
import { Intent, TradingAnchorButton } from '@vegaprotocol/ui-toolkit';
|
||||||
import { Links } from '../../lib/links';
|
import { Links } from '../../lib/links';
|
||||||
|
import { useT } from '../../lib/use-t';
|
||||||
|
|
||||||
export const UpdateTeamButton = ({ team }: { team: Team }) => {
|
export const UpdateTeamButton = ({ team }: { team: Team }) => {
|
||||||
|
const t = useT();
|
||||||
const { pubKey, isReadOnly } = useVegaWallet();
|
const { pubKey, isReadOnly } = useVegaWallet();
|
||||||
|
|
||||||
if (pubKey && !isReadOnly && pubKey === team.referrer) {
|
if (pubKey && !isReadOnly && pubKey === team.referrer) {
|
||||||
@ -12,7 +14,9 @@ export const UpdateTeamButton = ({ team }: { team: Team }) => {
|
|||||||
data-testid="update-team-button"
|
data-testid="update-team-button"
|
||||||
href={Links.COMPETITIONS_UPDATE_TEAM(team.teamId)}
|
href={Links.COMPETITIONS_UPDATE_TEAM(team.teamId)}
|
||||||
intent={Intent.Info}
|
intent={Intent.Info}
|
||||||
/>
|
>
|
||||||
|
{t('Update team')}
|
||||||
|
</TradingAnchorButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
|
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
|
||||||
VEGA_VERSION=v0.74.0-preview.7
|
VEGA_VERSION=v0.74.0-preview.8
|
||||||
LOCAL_SERVER=false
|
LOCAL_SERVER=false
|
||||||
|
@ -137,6 +137,7 @@ def create_team(vega: VegaServiceNull):
|
|||||||
return team_name
|
return team_name
|
||||||
|
|
||||||
def test_team_page_games_table(team_page: Page):
|
def test_team_page_games_table(team_page: Page):
|
||||||
|
team_page.pause()
|
||||||
team_page.get_by_test_id("games-toggle").click()
|
team_page.get_by_test_id("games-toggle").click()
|
||||||
expect(team_page.get_by_test_id("games-toggle")).to_have_text("Games (1)")
|
expect(team_page.get_by_test_id("games-toggle")).to_have_text("Games (1)")
|
||||||
expect(team_page.get_by_test_id("rank-0")).to_have_text("1")
|
expect(team_page.get_by_test_id("rank-0")).to_have_text("1")
|
||||||
@ -152,7 +153,7 @@ def test_team_page_games_table(team_page: Page):
|
|||||||
|
|
||||||
def test_team_page_members_table(team_page: Page):
|
def test_team_page_members_table(team_page: Page):
|
||||||
team_page.get_by_test_id("members-toggle").click()
|
team_page.get_by_test_id("members-toggle").click()
|
||||||
expect(team_page.get_by_test_id("members-toggle")).to_have_text("Members (3)")
|
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("referee-0")).to_be_visible()
|
||||||
expect(team_page.get_by_test_id("joinedAt-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("8")
|
expect(team_page.get_by_test_id("joinedAtEpoch-0")).to_have_text("8")
|
||||||
@ -161,7 +162,7 @@ def test_team_page_headline(team_page: Page, setup_teams_and_games
|
|||||||
):
|
):
|
||||||
team_name = setup_teams_and_games["team_name"]
|
team_name = setup_teams_and_games["team_name"]
|
||||||
expect(team_page.get_by_test_id("team-name")).to_have_text(team_name)
|
expect(team_page.get_by_test_id("team-name")).to_have_text(team_name)
|
||||||
expect(team_page.get_by_test_id("members-count-stat")).to_have_text("3")
|
expect(team_page.get_by_test_id("members-count-stat")).to_have_text("4")
|
||||||
|
|
||||||
expect(team_page.get_by_test_id("total-games-stat")).to_have_text(
|
expect(team_page.get_by_test_id("total-games-stat")).to_have_text(
|
||||||
"1"
|
"1"
|
||||||
|
@ -17,7 +17,7 @@ fragment TeamStatsFields on TeamStatistics {
|
|||||||
totalGamesPlayed
|
totalGamesPlayed
|
||||||
quantumRewards {
|
quantumRewards {
|
||||||
epoch
|
epoch
|
||||||
total_quantum_rewards
|
totalQuantumRewards
|
||||||
}
|
}
|
||||||
gamesPlayed
|
gamesPlayed
|
||||||
}
|
}
|
||||||
@ -51,6 +51,13 @@ fragment TeamGameFields on Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment TeamMemberStatsFields on TeamMemberStatistics {
|
||||||
|
partyId
|
||||||
|
totalQuantumVolume
|
||||||
|
totalQuantumRewards
|
||||||
|
totalGamesPlayed
|
||||||
|
}
|
||||||
|
|
||||||
query Team($teamId: ID!, $partyId: ID, $aggregationEpochs: Int) {
|
query Team($teamId: ID!, $partyId: ID, $aggregationEpochs: Int) {
|
||||||
teams(teamId: $teamId) {
|
teams(teamId: $teamId) {
|
||||||
edges {
|
edges {
|
||||||
@ -87,4 +94,14 @@ query Team($teamId: ID!, $partyId: ID, $aggregationEpochs: Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
teamMembersStatistics(
|
||||||
|
teamId: $teamId
|
||||||
|
aggregationEpochs: $aggregationEpochs
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...TeamMemberStatsFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
26
apps/trading/lib/hooks/__generated__/Team.ts
generated
26
apps/trading/lib/hooks/__generated__/Team.ts
generated
@ -5,7 +5,7 @@ import * as Apollo from '@apollo/client';
|
|||||||
const defaultOptions = {} as const;
|
const defaultOptions = {} as const;
|
||||||
export type TeamFieldsFragment = { __typename?: 'Team', teamId: string, referrer: string, name: string, teamUrl: string, avatarUrl: string, createdAt: any, createdAtEpoch: number, closed: boolean, allowList: Array<string> };
|
export type TeamFieldsFragment = { __typename?: 'Team', teamId: string, referrer: string, name: string, teamUrl: string, avatarUrl: string, createdAt: any, createdAtEpoch: number, closed: boolean, allowList: Array<string> };
|
||||||
|
|
||||||
export type TeamStatsFieldsFragment = { __typename?: 'TeamStatistics', teamId: string, totalQuantumVolume: string, totalQuantumRewards: string, totalGamesPlayed: number, gamesPlayed: Array<string>, quantumRewards: Array<{ __typename?: 'QuantumRewardsPerEpoch', epoch: number, total_quantum_rewards: string }> };
|
export type TeamStatsFieldsFragment = { __typename?: 'TeamStatistics', teamId: string, totalQuantumVolume: string, totalQuantumRewards: string, totalGamesPlayed: number, gamesPlayed: Array<string>, quantumRewards: Array<{ __typename?: 'QuantumRewardsPerEpoch', epoch: number, totalQuantumRewards: string }> };
|
||||||
|
|
||||||
export type TeamRefereeFieldsFragment = { __typename?: 'TeamReferee', teamId: string, referee: string, joinedAt: any, joinedAtEpoch: number };
|
export type TeamRefereeFieldsFragment = { __typename?: 'TeamReferee', teamId: string, referee: string, joinedAt: any, joinedAtEpoch: number };
|
||||||
|
|
||||||
@ -13,6 +13,8 @@ export type TeamEntityFragment = { __typename?: 'TeamGameEntity', rank: number,
|
|||||||
|
|
||||||
export type TeamGameFieldsFragment = { __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 } }> };
|
export type TeamGameFieldsFragment = { __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 } }> };
|
||||||
|
|
||||||
|
export type TeamMemberStatsFieldsFragment = { __typename?: 'TeamMemberStatistics', partyId: string, totalQuantumVolume: string, totalQuantumRewards: string, totalGamesPlayed: number };
|
||||||
|
|
||||||
export type TeamQueryVariables = Types.Exact<{
|
export type TeamQueryVariables = Types.Exact<{
|
||||||
teamId: Types.Scalars['ID'];
|
teamId: Types.Scalars['ID'];
|
||||||
partyId?: Types.InputMaybe<Types.Scalars['ID']>;
|
partyId?: Types.InputMaybe<Types.Scalars['ID']>;
|
||||||
@ -20,7 +22,7 @@ export type TeamQueryVariables = Types.Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type TeamQuery = { __typename?: 'Query', teams?: { __typename?: 'TeamConnection', edges: Array<{ __typename?: 'TeamEdge', node: { __typename?: 'Team', teamId: string, referrer: string, name: string, teamUrl: string, avatarUrl: string, createdAt: any, createdAtEpoch: number, closed: boolean, allowList: Array<string> } }> } | null, partyTeams?: { __typename?: 'TeamConnection', edges: Array<{ __typename?: 'TeamEdge', node: { __typename?: 'Team', teamId: string, referrer: string, name: string, teamUrl: string, avatarUrl: string, createdAt: any, createdAtEpoch: number, closed: boolean, allowList: Array<string> } }> } | null, teamsStatistics?: { __typename?: 'TeamsStatisticsConnection', edges: Array<{ __typename?: 'TeamStatisticsEdge', node: { __typename?: 'TeamStatistics', teamId: string, totalQuantumVolume: string, totalQuantumRewards: string, totalGamesPlayed: number, gamesPlayed: Array<string>, quantumRewards: Array<{ __typename?: 'QuantumRewardsPerEpoch', epoch: number, total_quantum_rewards: string }> } }> } | null, teamReferees?: { __typename?: 'TeamRefereeConnection', edges: Array<{ __typename?: 'TeamRefereeEdge', node: { __typename?: 'TeamReferee', teamId: string, referee: string, joinedAt: any, joinedAtEpoch: number } }> } | null, 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 } }> } } | null> | null } };
|
export type TeamQuery = { __typename?: 'Query', teams?: { __typename?: 'TeamConnection', edges: Array<{ __typename?: 'TeamEdge', node: { __typename?: 'Team', teamId: string, referrer: string, name: string, teamUrl: string, avatarUrl: string, createdAt: any, createdAtEpoch: number, closed: boolean, allowList: Array<string> } }> } | null, partyTeams?: { __typename?: 'TeamConnection', edges: Array<{ __typename?: 'TeamEdge', node: { __typename?: 'Team', teamId: string, referrer: string, name: string, teamUrl: string, avatarUrl: string, createdAt: any, createdAtEpoch: number, closed: boolean, allowList: Array<string> } }> } | null, teamsStatistics?: { __typename?: 'TeamsStatisticsConnection', edges: Array<{ __typename?: 'TeamStatisticsEdge', node: { __typename?: 'TeamStatistics', teamId: string, totalQuantumVolume: string, totalQuantumRewards: string, totalGamesPlayed: number, gamesPlayed: Array<string>, quantumRewards: Array<{ __typename?: 'QuantumRewardsPerEpoch', epoch: number, totalQuantumRewards: string }> } }> } | null, teamReferees?: { __typename?: 'TeamRefereeConnection', edges: Array<{ __typename?: 'TeamRefereeEdge', node: { __typename?: 'TeamReferee', teamId: string, referee: string, joinedAt: any, joinedAtEpoch: number } }> } | null, 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 } }> } } | null> | null }, teamMembersStatistics?: { __typename?: 'TeamMembersStatisticsConnection', edges: Array<{ __typename?: 'TeamMemberStatisticsEdge', node: { __typename?: 'TeamMemberStatistics', partyId: string, totalQuantumVolume: string, totalQuantumRewards: string, totalGamesPlayed: number } }> } | null };
|
||||||
|
|
||||||
export const TeamFieldsFragmentDoc = gql`
|
export const TeamFieldsFragmentDoc = gql`
|
||||||
fragment TeamFields on Team {
|
fragment TeamFields on Team {
|
||||||
@ -43,7 +45,7 @@ export const TeamStatsFieldsFragmentDoc = gql`
|
|||||||
totalGamesPlayed
|
totalGamesPlayed
|
||||||
quantumRewards {
|
quantumRewards {
|
||||||
epoch
|
epoch
|
||||||
total_quantum_rewards
|
totalQuantumRewards
|
||||||
}
|
}
|
||||||
gamesPlayed
|
gamesPlayed
|
||||||
}
|
}
|
||||||
@ -80,6 +82,14 @@ export const TeamGameFieldsFragmentDoc = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
${TeamEntityFragmentDoc}`;
|
${TeamEntityFragmentDoc}`;
|
||||||
|
export const TeamMemberStatsFieldsFragmentDoc = gql`
|
||||||
|
fragment TeamMemberStatsFields on TeamMemberStatistics {
|
||||||
|
partyId
|
||||||
|
totalQuantumVolume
|
||||||
|
totalQuantumRewards
|
||||||
|
totalGamesPlayed
|
||||||
|
}
|
||||||
|
`;
|
||||||
export const TeamDocument = gql`
|
export const TeamDocument = gql`
|
||||||
query Team($teamId: ID!, $partyId: ID, $aggregationEpochs: Int) {
|
query Team($teamId: ID!, $partyId: ID, $aggregationEpochs: Int) {
|
||||||
teams(teamId: $teamId) {
|
teams(teamId: $teamId) {
|
||||||
@ -117,11 +127,19 @@ export const TeamDocument = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
teamMembersStatistics(teamId: $teamId, aggregationEpochs: $aggregationEpochs) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...TeamMemberStatsFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
${TeamFieldsFragmentDoc}
|
${TeamFieldsFragmentDoc}
|
||||||
${TeamStatsFieldsFragmentDoc}
|
${TeamStatsFieldsFragmentDoc}
|
||||||
${TeamRefereeFieldsFragmentDoc}
|
${TeamRefereeFieldsFragmentDoc}
|
||||||
${TeamGameFieldsFragmentDoc}`;
|
${TeamGameFieldsFragmentDoc}
|
||||||
|
${TeamMemberStatsFieldsFragmentDoc}`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __useTeamQuery__
|
* __useTeamQuery__
|
||||||
|
@ -6,17 +6,24 @@ import {
|
|||||||
type TeamStatsFieldsFragment,
|
type TeamStatsFieldsFragment,
|
||||||
type TeamRefereeFieldsFragment,
|
type TeamRefereeFieldsFragment,
|
||||||
type TeamEntityFragment,
|
type TeamEntityFragment,
|
||||||
|
type TeamMemberStatsFieldsFragment,
|
||||||
} from './__generated__/Team';
|
} from './__generated__/Team';
|
||||||
import { DEFAULT_AGGREGATION_EPOCHS } from './use-teams';
|
import { DEFAULT_AGGREGATION_EPOCHS } from './use-teams';
|
||||||
|
|
||||||
export type Team = TeamFieldsFragment;
|
export type Team = TeamFieldsFragment;
|
||||||
export type TeamStats = TeamStatsFieldsFragment;
|
export type TeamStats = TeamStatsFieldsFragment;
|
||||||
export type Member = TeamRefereeFieldsFragment;
|
export type Member = TeamRefereeFieldsFragment & {
|
||||||
|
isCreator: boolean;
|
||||||
|
totalGamesPlayed: number;
|
||||||
|
totalQuantumVolume: string;
|
||||||
|
totalQuantumRewards: string;
|
||||||
|
};
|
||||||
export type TeamEntity = TeamEntityFragment;
|
export type TeamEntity = TeamEntityFragment;
|
||||||
export type TeamGame = ReturnType<typeof useTeam>['games'][number];
|
export type TeamGame = ReturnType<typeof useTeam>['games'][number];
|
||||||
|
export type MemberStats = TeamMemberStatsFieldsFragment;
|
||||||
|
|
||||||
export const useTeam = (teamId?: string, partyId?: string) => {
|
export const useTeam = (teamId?: string, partyId?: string) => {
|
||||||
const { data, loading, error, refetch } = useTeamQuery({
|
const queryResult = useTeamQuery({
|
||||||
variables: {
|
variables: {
|
||||||
teamId: teamId || '',
|
teamId: teamId || '',
|
||||||
partyId,
|
partyId,
|
||||||
@ -26,7 +33,11 @@ export const useTeam = (teamId?: string, partyId?: string) => {
|
|||||||
fetchPolicy: 'cache-and-network',
|
fetchPolicy: 'cache-and-network',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { data } = queryResult;
|
||||||
|
|
||||||
const teamEdge = data?.teams?.edges.find((e) => e.node.teamId === teamId);
|
const teamEdge = data?.teams?.edges.find((e) => e.node.teamId === teamId);
|
||||||
|
const team = teamEdge?.node;
|
||||||
|
|
||||||
const partyTeam = data?.partyTeams?.edges?.length
|
const partyTeam = data?.partyTeams?.edges?.length
|
||||||
? data.partyTeams.edges[0].node
|
? data.partyTeams.edges[0].node
|
||||||
: undefined;
|
: undefined;
|
||||||
@ -34,9 +45,40 @@ export const useTeam = (teamId?: string, partyId?: string) => {
|
|||||||
const teamStatsEdge = data?.teamsStatistics?.edges.find(
|
const teamStatsEdge = data?.teamsStatistics?.edges.find(
|
||||||
(e) => e.node.teamId === teamId
|
(e) => e.node.teamId === teamId
|
||||||
);
|
);
|
||||||
const members = data?.teamReferees?.edges
|
|
||||||
|
const memberStats = data?.teamMembersStatistics?.edges.length
|
||||||
|
? data.teamMembersStatistics.edges.map((e) => e.node)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const members: Member[] = data?.teamReferees?.edges.length
|
||||||
|
? data.teamReferees.edges
|
||||||
.filter((e) => e.node.teamId === teamId)
|
.filter((e) => e.node.teamId === teamId)
|
||||||
.map((e) => e.node);
|
.map((e) => {
|
||||||
|
const member = e.node;
|
||||||
|
const stats = memberStats.find((m) => m.partyId === member.referee);
|
||||||
|
return {
|
||||||
|
...member,
|
||||||
|
isCreator: false,
|
||||||
|
totalQuantumVolume: stats ? stats.totalQuantumVolume : '0',
|
||||||
|
totalQuantumRewards: stats ? stats.totalQuantumRewards : '0',
|
||||||
|
totalGamesPlayed: stats ? stats.totalGamesPlayed : 0,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (team) {
|
||||||
|
const ownerStats = memberStats.find((m) => m.partyId === team.referrer);
|
||||||
|
members.unshift({
|
||||||
|
teamId: team.teamId,
|
||||||
|
referee: team.referrer,
|
||||||
|
joinedAt: team?.createdAt,
|
||||||
|
joinedAtEpoch: team?.createdAtEpoch,
|
||||||
|
isCreator: true,
|
||||||
|
totalQuantumVolume: ownerStats ? ownerStats.totalQuantumVolume : '0',
|
||||||
|
totalQuantumRewards: ownerStats ? ownerStats.totalQuantumRewards : '0',
|
||||||
|
totalGamesPlayed: ownerStats ? ownerStats.totalGamesPlayed : 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Find games where the current team participated in
|
// Find games where the current team participated in
|
||||||
const gamesWithTeam = compact(data?.games.edges).map((edge) => {
|
const gamesWithTeam = compact(data?.games.edges).map((edge) => {
|
||||||
@ -60,12 +102,9 @@ export const useTeam = (teamId?: string, partyId?: string) => {
|
|||||||
const games = orderBy(compact(gamesWithTeam), 'epoch', 'desc');
|
const games = orderBy(compact(gamesWithTeam), 'epoch', 'desc');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
...queryResult,
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
refetch,
|
|
||||||
stats: teamStatsEdge?.node,
|
stats: teamStatsEdge?.node,
|
||||||
team: teamEdge?.node,
|
team,
|
||||||
members,
|
members,
|
||||||
games,
|
games,
|
||||||
partyTeam,
|
partyTeam,
|
||||||
|
@ -1,34 +1,12 @@
|
|||||||
|
import orderBy from 'lodash/orderBy';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { type TeamsQuery, useTeamsQuery } from './__generated__/Teams';
|
import { useTeamsQuery } from './__generated__/Teams';
|
||||||
import {
|
import { useTeamsStatisticsQuery } from './__generated__/TeamsStatistics';
|
||||||
type TeamsStatisticsQuery,
|
|
||||||
useTeamsStatisticsQuery,
|
|
||||||
} from './__generated__/TeamsStatistics';
|
|
||||||
import compact from 'lodash/compact';
|
import compact from 'lodash/compact';
|
||||||
import sortBy from 'lodash/sortBy';
|
|
||||||
import { type ArrayElement } from 'type-fest/source/internal';
|
|
||||||
|
|
||||||
type SortableField = keyof Omit<
|
|
||||||
ArrayElement<NonNullable<TeamsQuery['teams']>['edges']>['node'] &
|
|
||||||
ArrayElement<
|
|
||||||
NonNullable<TeamsStatisticsQuery['teamsStatistics']>['edges']
|
|
||||||
>['node'],
|
|
||||||
'__typename'
|
|
||||||
>;
|
|
||||||
|
|
||||||
type UseTeamsArgs = {
|
|
||||||
aggregationEpochs?: number;
|
|
||||||
sortByField?: SortableField[];
|
|
||||||
order?: 'asc' | 'desc';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DEFAULT_AGGREGATION_EPOCHS = 10;
|
export const DEFAULT_AGGREGATION_EPOCHS = 10;
|
||||||
|
|
||||||
export const useTeams = ({
|
export const useTeams = (aggregationEpochs = DEFAULT_AGGREGATION_EPOCHS) => {
|
||||||
aggregationEpochs = DEFAULT_AGGREGATION_EPOCHS,
|
|
||||||
sortByField = ['createdAtEpoch'],
|
|
||||||
order = 'asc',
|
|
||||||
}: UseTeamsArgs) => {
|
|
||||||
const {
|
const {
|
||||||
data: teamsData,
|
data: teamsData,
|
||||||
loading: teamsLoading,
|
loading: teamsLoading,
|
||||||
@ -57,12 +35,8 @@ export const useTeams = ({
|
|||||||
...stats.find((s) => s.teamId === t.teamId),
|
...stats.find((s) => s.teamId === t.teamId),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const sorted = sortBy(data, sortByField);
|
return orderBy(data, (d) => Number(d.totalQuantumRewards || 0), 'desc');
|
||||||
if (order === 'desc') {
|
}, [teams, stats]);
|
||||||
return sorted.reverse();
|
|
||||||
}
|
|
||||||
return sorted;
|
|
||||||
}, [teams, sortByField, order, stats]);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
"Create": "Create",
|
"Create": "Create",
|
||||||
"Create a team": "Create a team",
|
"Create a team": "Create a team",
|
||||||
"Create a simple referral code to enjoy the referrer commission outlined in the current referral program": "Create a simple referral code to enjoy the referrer commission outlined in the current referral program",
|
"Create a simple referral code to enjoy the referrer commission outlined in the current referral program": "Create a simple referral code to enjoy the referrer commission outlined in the current referral program",
|
||||||
|
"Create solo team": "Create solo team",
|
||||||
"Make your referral code a Team to compete in Competitions with your friends, appear in leaderboards on the <0>Competitions Homepage</0>, and earn rewards": "Make your referral code a Team to compete in Competitions with your friends, appear in leaderboards on the <0>Competitions Homepage</0>, and earn rewards",
|
"Make your referral code a Team to compete in Competitions with your friends, appear in leaderboards on the <0>Competitions Homepage</0>, and earn rewards": "Make your referral code a Team to compete in Competitions with your friends, appear in leaderboards on the <0>Competitions Homepage</0>, and earn rewards",
|
||||||
"Current tier": "Current tier",
|
"Current tier": "Current tier",
|
||||||
"DISCLAIMER_P1": "Vega is a decentralised peer-to-peer protocol that can be used to trade derivatives with cryptoassets. The Vega Protocol is an implementation layer (layer one) protocol made of free, public, open-source or source-available software. Use of the Vega Protocol involves various risks, including but not limited to, losses while digital assets are supplied to the Vega Protocol and losses due to the fluctuation of prices of assets.",
|
"DISCLAIMER_P1": "Vega is a decentralised peer-to-peer protocol that can be used to trade derivatives with cryptoassets. The Vega Protocol is an implementation layer (layer one) protocol made of free, public, open-source or source-available software. Use of the Vega Protocol involves various risks, including but not limited to, losses while digital assets are supplied to the Vega Protocol and losses due to the fluctuation of prices of assets.",
|
||||||
@ -181,6 +182,7 @@
|
|||||||
"Markets": "Markets",
|
"Markets": "Markets",
|
||||||
"Members": "Members",
|
"Members": "Members",
|
||||||
"Members ({{count}})": "Members ({{count}})",
|
"Members ({{count}})": "Members ({{count}})",
|
||||||
|
"Member ID": "Member ID",
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Metamask Snap <0>quick start</0>": "Metamask Snap <0>quick start</0>",
|
"Metamask Snap <0>quick start</0>": "Metamask Snap <0>quick start</0>",
|
||||||
"Min. epochs": "Min. epochs",
|
"Min. epochs": "Min. epochs",
|
||||||
@ -363,6 +365,7 @@
|
|||||||
"Type": "Type",
|
"Type": "Type",
|
||||||
"Unknown": "Unknown",
|
"Unknown": "Unknown",
|
||||||
"Unknown settlement date": "Unknown settlement date",
|
"Unknown settlement date": "Unknown settlement date",
|
||||||
|
"Update team": "Update team",
|
||||||
"URL": "URL",
|
"URL": "URL",
|
||||||
"Use a comma separated list to allow only specific public keys to join the team": "Use a comma separated list to allow only specific public keys to join the team",
|
"Use a comma separated list to allow only specific public keys to join the team": "Use a comma separated list to allow only specific public keys to join the team",
|
||||||
"Vega chart": "Vega chart",
|
"Vega chart": "Vega chart",
|
||||||
|
2
libs/types/src/__generated__/types.ts
generated
2
libs/types/src/__generated__/types.ts
generated
@ -4682,7 +4682,7 @@ export type QuantumRewardsPerEpoch = {
|
|||||||
/** Epoch for which this information is valid. */
|
/** Epoch for which this information is valid. */
|
||||||
epoch: Scalars['Int'];
|
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. */
|
||||||
total_quantum_rewards: Scalars['String'];
|
totalQuantumRewards: Scalars['String'];
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Queries allow a caller to read data and filter data via GraphQL. */
|
/** Queries allow a caller to read data and filter data via GraphQL. */
|
||||||
|
Loading…
Reference in New Issue
Block a user