* feat: account hitory poc * feat(#469): update account history and chart * feat(#469): remove radix toggle group * fix: add use memo and some tweaks to make sure you pass undefined to cancel all * feat(#469): add new version pennant * feat(#469): style account history chart and no data splash * fix(#469): use splash only * fix(#469): sort assets list * feat(#469): new pennant version * fix: update query * fix: update query * Update libs/orders/src/lib/components/order-list/order-list.tsx * Update libs/assets/src/lib/asset-details-dialog.tsx * feat(#469): update test on trading positions tab * Update apps/trading-e2e/src/integration/trading-positions.cy.ts * fix: click on positions in portfolio * feat(#469): refactor with async renderer * feat(#469): refactor date range in account history Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
parent
cb80c6d417
commit
c5b6032184
@ -19,6 +19,7 @@ describe('positions', { tags: '@smoke' }, () => {
|
||||
|
||||
it('renders positions on portfolio page', () => {
|
||||
cy.visit('/#/portfolio');
|
||||
cy.getByTestId('Positions').click();
|
||||
cy.connectVegaWallet();
|
||||
validatePositionsDisplayed();
|
||||
});
|
||||
|
37
apps/trading/client-pages/portfolio/AccountHistory.graphql
Normal file
37
apps/trading/client-pages/portfolio/AccountHistory.graphql
Normal file
@ -0,0 +1,37 @@
|
||||
query AccountHistory(
|
||||
$partyId: ID!
|
||||
$assetId: ID!
|
||||
$accountTypes: [AccountType!]
|
||||
$dateRange: DateRange
|
||||
) {
|
||||
balanceChanges(
|
||||
filter: {
|
||||
partyIds: [$partyId]
|
||||
accountTypes: $accountTypes
|
||||
assetId: $assetId
|
||||
}
|
||||
dateRange: $dateRange
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
timestamp
|
||||
partyId
|
||||
balance
|
||||
marketId
|
||||
assetId
|
||||
accountType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query AccountsWithBalance($partyId: ID!, $dateRange: DateRange) {
|
||||
balanceChanges(filter: { partyIds: [$partyId] }, dateRange: $dateRange) {
|
||||
edges {
|
||||
node {
|
||||
assetId
|
||||
accountType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
115
apps/trading/client-pages/portfolio/__generated__/AccountHistory.ts
generated
Normal file
115
apps/trading/client-pages/portfolio/__generated__/AccountHistory.ts
generated
Normal file
@ -0,0 +1,115 @@
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type AccountHistoryQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
assetId: Types.Scalars['ID'];
|
||||
accountTypes?: Types.InputMaybe<Array<Types.AccountType> | Types.AccountType>;
|
||||
dateRange?: Types.InputMaybe<Types.DateRange>;
|
||||
}>;
|
||||
|
||||
|
||||
export type AccountHistoryQuery = { __typename?: 'Query', balanceChanges: { __typename?: 'AggregatedBalanceConnection', edges: Array<{ __typename?: 'AggregatedBalanceEdge', node: { __typename?: 'AggregatedBalance', timestamp: any, partyId?: string | null, balance: string, marketId?: string | null, assetId?: string | null, accountType?: Types.AccountType | null } } | null> } };
|
||||
|
||||
export type AccountsWithBalanceQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
dateRange?: Types.InputMaybe<Types.DateRange>;
|
||||
}>;
|
||||
|
||||
|
||||
export type AccountsWithBalanceQuery = { __typename?: 'Query', balanceChanges: { __typename?: 'AggregatedBalanceConnection', edges: Array<{ __typename?: 'AggregatedBalanceEdge', node: { __typename?: 'AggregatedBalance', assetId?: string | null, accountType?: Types.AccountType | null } } | null> } };
|
||||
|
||||
|
||||
export const AccountHistoryDocument = gql`
|
||||
query AccountHistory($partyId: ID!, $assetId: ID!, $accountTypes: [AccountType!], $dateRange: DateRange) {
|
||||
balanceChanges(
|
||||
filter: {partyIds: [$partyId], accountTypes: $accountTypes, assetId: $assetId}
|
||||
dateRange: $dateRange
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
timestamp
|
||||
partyId
|
||||
balance
|
||||
marketId
|
||||
assetId
|
||||
accountType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useAccountHistoryQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useAccountHistoryQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useAccountHistoryQuery` 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 } = useAccountHistoryQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* assetId: // value for 'assetId'
|
||||
* accountTypes: // value for 'accountTypes'
|
||||
* dateRange: // value for 'dateRange'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useAccountHistoryQuery(baseOptions: Apollo.QueryHookOptions<AccountHistoryQuery, AccountHistoryQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<AccountHistoryQuery, AccountHistoryQueryVariables>(AccountHistoryDocument, options);
|
||||
}
|
||||
export function useAccountHistoryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<AccountHistoryQuery, AccountHistoryQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<AccountHistoryQuery, AccountHistoryQueryVariables>(AccountHistoryDocument, options);
|
||||
}
|
||||
export type AccountHistoryQueryHookResult = ReturnType<typeof useAccountHistoryQuery>;
|
||||
export type AccountHistoryLazyQueryHookResult = ReturnType<typeof useAccountHistoryLazyQuery>;
|
||||
export type AccountHistoryQueryResult = Apollo.QueryResult<AccountHistoryQuery, AccountHistoryQueryVariables>;
|
||||
export const AccountsWithBalanceDocument = gql`
|
||||
query AccountsWithBalance($partyId: ID!, $dateRange: DateRange) {
|
||||
balanceChanges(filter: {partyIds: [$partyId]}, dateRange: $dateRange) {
|
||||
edges {
|
||||
node {
|
||||
assetId
|
||||
accountType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useAccountsWithBalanceQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useAccountsWithBalanceQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useAccountsWithBalanceQuery` 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 } = useAccountsWithBalanceQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* dateRange: // value for 'dateRange'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useAccountsWithBalanceQuery(baseOptions: Apollo.QueryHookOptions<AccountsWithBalanceQuery, AccountsWithBalanceQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<AccountsWithBalanceQuery, AccountsWithBalanceQueryVariables>(AccountsWithBalanceDocument, options);
|
||||
}
|
||||
export function useAccountsWithBalanceLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<AccountsWithBalanceQuery, AccountsWithBalanceQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<AccountsWithBalanceQuery, AccountsWithBalanceQueryVariables>(AccountsWithBalanceDocument, options);
|
||||
}
|
||||
export type AccountsWithBalanceQueryHookResult = ReturnType<typeof useAccountsWithBalanceQuery>;
|
||||
export type AccountsWithBalanceLazyQueryHookResult = ReturnType<typeof useAccountsWithBalanceLazyQuery>;
|
||||
export type AccountsWithBalanceQueryResult = Apollo.QueryResult<AccountsWithBalanceQuery, AccountsWithBalanceQueryVariables>;
|
@ -1,46 +0,0 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: AssetFields
|
||||
// ====================================================
|
||||
|
||||
export interface AssetFields_source_BuiltinAsset {
|
||||
__typename: "BuiltinAsset";
|
||||
}
|
||||
|
||||
export interface AssetFields_source_ERC20 {
|
||||
__typename: "ERC20";
|
||||
/**
|
||||
* The address of the ERC20 contract
|
||||
*/
|
||||
contractAddress: string;
|
||||
}
|
||||
|
||||
export type AssetFields_source = AssetFields_source_BuiltinAsset | AssetFields_source_ERC20;
|
||||
|
||||
export interface AssetFields {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The ID of the asset
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The symbol of the asset (e.g: GBP)
|
||||
*/
|
||||
symbol: string;
|
||||
/**
|
||||
* The full name of the asset (e.g: Great British Pound)
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The precision of the asset. Should match the decimal precision of the asset on its native chain, e.g: for ERC20 assets, it is often 18
|
||||
*/
|
||||
decimals: number;
|
||||
/**
|
||||
* The origin source of the asset (e.g: an ERC20 asset)
|
||||
*/
|
||||
source: AssetFields_source;
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import * as Schema from "@vegaprotocol/types";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: WithdrawFormQuery
|
||||
// ====================================================
|
||||
|
||||
export interface WithdrawFormQuery_party_withdrawals {
|
||||
__typename: "Withdrawal";
|
||||
/**
|
||||
* The Vega internal ID of the withdrawal
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Hash of the transaction on the foreign chain
|
||||
*/
|
||||
txHash: string | null;
|
||||
}
|
||||
|
||||
export interface WithdrawFormQuery_party_accounts_asset {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The ID of the asset
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The symbol of the asset (e.g: GBP)
|
||||
*/
|
||||
symbol: string;
|
||||
}
|
||||
|
||||
export interface WithdrawFormQuery_party_accounts {
|
||||
__typename: "Account";
|
||||
/**
|
||||
* Account type (General, Margin, etc)
|
||||
*/
|
||||
type: Schema.AccountType;
|
||||
/**
|
||||
* Balance as string - current account balance (approx. as balances can be updated several times per second)
|
||||
*/
|
||||
balance: string;
|
||||
/**
|
||||
* Asset, the 'currency'
|
||||
*/
|
||||
asset: WithdrawFormQuery_party_accounts_asset;
|
||||
}
|
||||
|
||||
export interface WithdrawFormQuery_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The list of all withdrawals initiated by the party
|
||||
*/
|
||||
withdrawals: WithdrawFormQuery_party_withdrawals[] | null;
|
||||
/**
|
||||
* Collateral accounts relating to a party
|
||||
*/
|
||||
accounts: WithdrawFormQuery_party_accounts[] | null;
|
||||
}
|
||||
|
||||
export interface WithdrawFormQuery_assets_source_BuiltinAsset {
|
||||
__typename: "BuiltinAsset";
|
||||
}
|
||||
|
||||
export interface WithdrawFormQuery_assets_source_ERC20 {
|
||||
__typename: "ERC20";
|
||||
/**
|
||||
* The address of the ERC20 contract
|
||||
*/
|
||||
contractAddress: string;
|
||||
}
|
||||
|
||||
export type WithdrawFormQuery_assets_source = WithdrawFormQuery_assets_source_BuiltinAsset | WithdrawFormQuery_assets_source_ERC20;
|
||||
|
||||
export interface WithdrawFormQuery_assets {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The ID of the asset
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The symbol of the asset (e.g: GBP)
|
||||
*/
|
||||
symbol: string;
|
||||
/**
|
||||
* The full name of the asset (e.g: Great British Pound)
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The precision of the asset. Should match the decimal precision of the asset on its native chain, e.g: for ERC20 assets, it is often 18
|
||||
*/
|
||||
decimals: number;
|
||||
/**
|
||||
* The origin source of the asset (e.g: an ERC20 asset)
|
||||
*/
|
||||
source: WithdrawFormQuery_assets_source;
|
||||
}
|
||||
|
||||
export interface WithdrawFormQuery {
|
||||
/**
|
||||
* An entity that is trading on the Vega network
|
||||
*/
|
||||
party: WithdrawFormQuery_party | null;
|
||||
/**
|
||||
* The list of all assets in use in the Vega network
|
||||
*/
|
||||
assets: WithdrawFormQuery_assets[] | null;
|
||||
}
|
||||
|
||||
export interface WithdrawFormQueryVariables {
|
||||
partyId: string;
|
||||
}
|
@ -0,0 +1,241 @@
|
||||
import {
|
||||
addDecimal,
|
||||
fromNanoSeconds,
|
||||
t,
|
||||
ThemeContext,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import compact from 'lodash/compact';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { useContext } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import type { AccountHistoryQuery } from './__generated__/AccountHistory';
|
||||
import { useAccountsWithBalanceQuery } from './__generated__/AccountHistory';
|
||||
import { useAccountHistoryQuery } from './__generated__/AccountHistory';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
|
||||
import { useAssetsDataProvider } from '@vegaprotocol/assets';
|
||||
import {
|
||||
AsyncRenderer,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
Splash,
|
||||
Toggle,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { AccountTypeMapping } from '@vegaprotocol/types';
|
||||
import { PriceChart } from 'pennant';
|
||||
import 'pennant/dist/style.css';
|
||||
|
||||
const DateRange = {
|
||||
RANGE_1D: '1D',
|
||||
RANGE_7D: '7D',
|
||||
RANGE_1M: '1M',
|
||||
RANGE_3M: '3M',
|
||||
RANGE_1Y: '1Y',
|
||||
RANGE_YTD: 'YTD',
|
||||
RANGE_ALL: 'All',
|
||||
};
|
||||
|
||||
const dateRangeToggleItems = Object.entries(DateRange).map(([_, value]) => ({
|
||||
label: t(value),
|
||||
value: value,
|
||||
}));
|
||||
|
||||
const calculateStartDate = (range: string): string | undefined => {
|
||||
const now = new Date();
|
||||
switch (range) {
|
||||
case DateRange.RANGE_1D:
|
||||
return new Date(now.setDate(now.getDate() - 1)).toISOString();
|
||||
case DateRange.RANGE_7D:
|
||||
return new Date(now.setDate(now.getDate() - 7)).toISOString();
|
||||
case DateRange.RANGE_1M:
|
||||
return new Date(now.setMonth(now.getMonth() - 1)).toISOString();
|
||||
case DateRange.RANGE_3M:
|
||||
return new Date(now.setMonth(now.getMonth() - 3)).toISOString();
|
||||
case DateRange.RANGE_1Y:
|
||||
return new Date(now.setFullYear(now.getFullYear() - 1)).toISOString();
|
||||
case DateRange.RANGE_YTD:
|
||||
return new Date(now.setMonth(0)).toISOString();
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const AccountHistoryContainer = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { data: assets } = useAssetsDataProvider();
|
||||
|
||||
if (!pubKey) {
|
||||
return <Splash>Connect wallet</Splash>;
|
||||
}
|
||||
|
||||
return (
|
||||
<AsyncRenderer loading={!assets} error={undefined} data={assets}>
|
||||
{assets && <AccountHistoryManager pubKey={pubKey} assetData={assets} />}
|
||||
</AsyncRenderer>
|
||||
);
|
||||
};
|
||||
|
||||
const AccountHistoryManager = ({
|
||||
pubKey,
|
||||
assetData,
|
||||
}: {
|
||||
pubKey: string;
|
||||
assetData: AssetFieldsFragment[];
|
||||
}) => {
|
||||
const [accountType, setAccountType] = useState<Schema.AccountType>(
|
||||
Schema.AccountType.ACCOUNT_TYPE_GENERAL
|
||||
);
|
||||
|
||||
const variablesForOneTimeQuery = useMemo(
|
||||
() => ({
|
||||
partyId: pubKey,
|
||||
}),
|
||||
[pubKey]
|
||||
);
|
||||
|
||||
const assetsWithBalanceHistory = useAccountsWithBalanceQuery({
|
||||
variables: variablesForOneTimeQuery,
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const assetsWithBalance = useMemo(
|
||||
() =>
|
||||
assetsWithBalanceHistory.data?.balanceChanges.edges.map(
|
||||
(e) => e?.node.assetId
|
||||
) || [],
|
||||
[assetsWithBalanceHistory.data?.balanceChanges.edges]
|
||||
);
|
||||
|
||||
const assets = useMemo(
|
||||
() =>
|
||||
assetData
|
||||
.filter((a) => assetsWithBalance.includes(a.id))
|
||||
.sort((a, b) => a.name.localeCompare(b.name)),
|
||||
[assetData, assetsWithBalance]
|
||||
);
|
||||
const [asset, setAsset] = useState<AssetFieldsFragment>(assets[0]);
|
||||
const [range, setRange] = useState<typeof DateRange[keyof typeof DateRange]>(
|
||||
DateRange.RANGE_1M
|
||||
);
|
||||
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
partyId: pubKey,
|
||||
assetId: asset?.id || '',
|
||||
accountTypes: accountType ? [accountType] : undefined,
|
||||
dateRange:
|
||||
range === 'All' ? undefined : { start: calculateStartDate(range) },
|
||||
}),
|
||||
[pubKey, asset, accountType, range]
|
||||
);
|
||||
|
||||
const { data } = useAccountHistoryQuery({
|
||||
variables,
|
||||
skip: !asset || !pubKey,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="h-full w-full flex flex-col gap-8">
|
||||
<div className="w-full flex flex-col-reverse lg:flex-row items-start lg:items-center justify-between gap-4 px-2">
|
||||
<div className="flex items-center gap-4 shrink-0">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
{accountType
|
||||
? `${
|
||||
AccountTypeMapping[
|
||||
accountType as keyof typeof Schema.AccountType
|
||||
]
|
||||
} Account`
|
||||
: t('Select account type')}
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
{Object.keys(Schema.AccountType).map((type) => (
|
||||
<DropdownMenuItem
|
||||
key={type}
|
||||
onClick={() => setAccountType(type as Schema.AccountType)}
|
||||
>
|
||||
{AccountTypeMapping[type as keyof typeof Schema.AccountType]}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
{asset ? asset.symbol : t('Select asset')}
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
{assets.map((a) => (
|
||||
<DropdownMenuItem key={a.id} onClick={() => setAsset(a)}>
|
||||
{a.symbol}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
<div className="pt-1 justify-items-end">
|
||||
<Toggle
|
||||
id="account-history-date-range"
|
||||
name="account-history-date-range"
|
||||
toggles={dateRangeToggleItems}
|
||||
checkedValue={range}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
setRange(e.target.value as keyof typeof DateRange)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-5/6 px-4">
|
||||
{asset && (
|
||||
<AccountHistoryChart
|
||||
data={data}
|
||||
accountType={accountType}
|
||||
asset={asset}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const AccountHistoryChart = ({
|
||||
data,
|
||||
accountType,
|
||||
asset,
|
||||
}: {
|
||||
data: AccountHistoryQuery | undefined;
|
||||
accountType: Schema.AccountType;
|
||||
asset: AssetFieldsFragment;
|
||||
}) => {
|
||||
const theme = useContext(ThemeContext);
|
||||
const values: { cols: string[]; rows: [Date, ...number[]][] } | null =
|
||||
useMemo(() => {
|
||||
if (!data?.balanceChanges.edges.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const valuesData = compact(data.balanceChanges.edges)
|
||||
.reduce((acc, edge) => {
|
||||
if (edge.node.accountType === accountType) {
|
||||
acc?.push({
|
||||
datetime: fromNanoSeconds(edge.node.timestamp),
|
||||
balance: Number(addDecimal(edge.node.balance, asset.decimals)),
|
||||
});
|
||||
}
|
||||
return acc;
|
||||
}, [] as { datetime: Date; balance: number }[])
|
||||
.reverse();
|
||||
return {
|
||||
cols: ['Date', `${asset.symbol} account balance`],
|
||||
rows: compact(valuesData).map((d) => [d.datetime, d.balance]),
|
||||
};
|
||||
}, [accountType, asset.decimals, asset.symbol, data?.balanceChanges.edges]);
|
||||
|
||||
if (!data || !values?.rows.length) {
|
||||
return <Splash> {t('No account history data')}</Splash>;
|
||||
}
|
||||
|
||||
return <PriceChart data={values} theme={theme} />;
|
||||
};
|
@ -13,6 +13,7 @@ import { LayoutPriority } from 'allotment';
|
||||
import { usePageTitleStore } from '../../stores';
|
||||
import { LedgerContainer } from '@vegaprotocol/ledger';
|
||||
import { AccountsContainer } from '../../components/accounts-container';
|
||||
import { AccountHistoryContainer } from './account-history-container';
|
||||
|
||||
export const Portfolio = () => {
|
||||
const { updateTitle } = usePageTitleStore((store) => ({
|
||||
@ -30,6 +31,11 @@ export const Portfolio = () => {
|
||||
<ResizableGridPanel minSize={75}>
|
||||
<PortfolioGridChild>
|
||||
<Tabs>
|
||||
<Tab id="account-history" name={t('Account history')}>
|
||||
<VegaWalletContainer>
|
||||
<AccountHistoryContainer />
|
||||
</VegaWalletContainer>
|
||||
</Tab>
|
||||
<Tab id="positions" name={t('Positions')}>
|
||||
<VegaWalletContainer>
|
||||
<PositionsContainer />
|
||||
|
@ -84,7 +84,9 @@ export const OrderList = forwardRef<AgGridReact, OrderListProps>(
|
||||
<OrderListTable
|
||||
{...props}
|
||||
cancelAll={() => {
|
||||
orderCancel.cancel({ marketId: props.marketId });
|
||||
orderCancel.cancel({
|
||||
marketId: props.marketId,
|
||||
});
|
||||
}}
|
||||
cancel={(order: Order) => {
|
||||
if (!order.market) return;
|
||||
|
@ -63,7 +63,7 @@
|
||||
"js-sha3": "^0.8.0",
|
||||
"lodash": "^4.17.21",
|
||||
"next": "12.2.3",
|
||||
"pennant": "^0.4.18",
|
||||
"pennant": "1.0.0",
|
||||
"react": "18.2.0",
|
||||
"react-copy-to-clipboard": "^5.0.4",
|
||||
"react-dom": "18.2.0",
|
||||
|
96
yarn.lock
96
yarn.lock
@ -2346,6 +2346,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-0.7.3.tgz#d274116678ffae87f6b60e90f88cc4083eefab86"
|
||||
integrity sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==
|
||||
|
||||
"@floating-ui/core@^1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.0.4.tgz#03066eaea8e9b2a2cd3f5aaa60f1e0f580ebe88e"
|
||||
integrity sha512-FPFLbg2b06MIw1dqk2SOEMAMX3xlrreGjcui5OTxfBDtaKTmh0kioOVjT8gcfl58juawL/yF+S+gnq8aUYQx/Q==
|
||||
|
||||
"@floating-ui/dom@^0.5.3":
|
||||
version "0.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-0.5.4.tgz#4eae73f78bcd4bd553ae2ade30e6f1f9c73fe3f1"
|
||||
@ -2353,6 +2358,13 @@
|
||||
dependencies:
|
||||
"@floating-ui/core" "^0.7.3"
|
||||
|
||||
"@floating-ui/dom@^1.0.5":
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.0.10.tgz#a2299e942a06ca35cfdaeb4d4709805c9bb9c032"
|
||||
integrity sha512-ZRe5ZmtGYCd82zrjWnnMW8hN5H1otedLh0Ur6rRo6f0exbEe6IlkVvo1RO7tgiMvbF0Df8hkhdm50VcVYqwP6g==
|
||||
dependencies:
|
||||
"@floating-ui/core" "^1.0.4"
|
||||
|
||||
"@floating-ui/react-dom@0.7.2":
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-0.7.2.tgz#0bf4ceccb777a140fc535c87eb5d6241c8e89864"
|
||||
@ -2361,6 +2373,13 @@
|
||||
"@floating-ui/dom" "^0.5.3"
|
||||
use-isomorphic-layout-effect "^1.1.1"
|
||||
|
||||
"@floating-ui/react-dom@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-1.0.1.tgz#ee3524eab740b9380a00f4c2629a758093414325"
|
||||
integrity sha512-UW0t1Gi8ikbDRr8cQPVcqIDMBwUEENe5V4wlHWdrJ5egFnRQFBV9JirauTBFI6S8sM1qFUC1i+qa3g87E6CLTw==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "^1.0.5"
|
||||
|
||||
"@gar/promisify@^1.0.1":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
|
||||
@ -7017,7 +7036,12 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.188.tgz#e4990c4c81f7c9b00c5ff8eae389c10f27980da5"
|
||||
integrity sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w==
|
||||
|
||||
"@types/lodash@^4.14.168", "@types/lodash@^4.14.171":
|
||||
"@types/lodash@^4.14.168":
|
||||
version "4.14.191"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa"
|
||||
integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==
|
||||
|
||||
"@types/lodash@^4.14.171":
|
||||
version "4.14.186"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.186.tgz#862e5514dd7bd66ada6c70ee5fce844b06c8ee97"
|
||||
integrity sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==
|
||||
@ -7072,7 +7096,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.3.tgz#d7f7ba828ad9e540270f01ce00d391c54e6e0abc"
|
||||
integrity sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg==
|
||||
|
||||
"@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.0.0":
|
||||
"@types/node@^14.14.20 || ^16.0.0":
|
||||
version "16.11.65"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.65.tgz#59500b86af757d6fcabd3dec32fecb6e357d7a45"
|
||||
integrity sha512-Vfz7wGMOr4jbQGiQHVJm8VjeQwM9Ya7mHe9LtQ264/Epf5n1KiZShOFqk++nBzw6a/ubgYdB9Od7P+MH/LjoWw==
|
||||
@ -7082,6 +7106,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.32.tgz#8074f7106731f1a12ba993fe8bad86ee73905014"
|
||||
integrity sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow==
|
||||
|
||||
"@types/node@^16.0.0":
|
||||
version "16.18.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.8.tgz#ffb2a4efa4eb4384811081776c52b054481cca54"
|
||||
integrity sha512-TrpoNiaPvBH5h8rQQenMtVsJXtGsVBRJrcp2Ik6oEt99jHfGvDLh20VTTq3ixTbjYujukYz1IlY4N8a8yfY0jA==
|
||||
|
||||
"@types/normalize-package-data@^2.4.0":
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
|
||||
@ -7144,13 +7173,20 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@18.0.6", "@types/react-dom@^18.0.0", "@types/react-dom@^18.0.5":
|
||||
"@types/react-dom@18.0.6", "@types/react-dom@^18.0.0":
|
||||
version "18.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.6.tgz#36652900024842b74607a17786b6662dd1e103a1"
|
||||
integrity sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@^18.0.5":
|
||||
version "18.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.9.tgz#ffee5e4bfc2a2f8774b15496474f8e7fe8d0b504"
|
||||
integrity sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-router-dom@5.3.1":
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.1.tgz#76700ccce6529413ec723024b71f01fc77a4a980"
|
||||
@ -7197,7 +7233,7 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^18.0.14":
|
||||
"@types/react@*":
|
||||
version "18.0.21"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.21.tgz#b8209e9626bb00a34c76f55482697edd2b43cc67"
|
||||
integrity sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==
|
||||
@ -7215,6 +7251,15 @@
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/react@^18.0.14":
|
||||
version "18.0.26"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.26.tgz#8ad59fc01fef8eaf5c74f4ea392621749f0b7917"
|
||||
integrity sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/resolve@1.17.1":
|
||||
version "1.17.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"
|
||||
@ -11183,10 +11228,15 @@ d3-array@2, d3-array@^2.3.0:
|
||||
dependencies:
|
||||
internmap "1 - 2"
|
||||
|
||||
d3-array@2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.3.3.tgz#e90c39fbaedccedf59fc30473092f99a0e14efa2"
|
||||
integrity sha512-syv3wp0U5aB6toP2zb2OdBkhTy1MWDsCAaYk6OXJZv+G4u7bSWEmYgxLoFyc88RQUhZYGCebW9a9UD1gFi5+MQ==
|
||||
d3-array@2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.8.0.tgz#f76e10ad47f1f4f75f33db5fc322eb9ffde5ef23"
|
||||
integrity sha512-6V272gsOeg7+9pTW1jSYOR1QE37g95I3my1hBmY+vOUNHRrk9yt4OTz/gK7PMkVAVDrYYq4mq3grTiZ8iJdNIw==
|
||||
|
||||
d3-axis@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-3.0.0.tgz#c42a4a13e8131d637b745fc2973824cfeaf93322"
|
||||
integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==
|
||||
|
||||
"d3-color@1 - 2":
|
||||
version "2.0.0"
|
||||
@ -18267,13 +18317,14 @@ pend@~1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
|
||||
|
||||
pennant@^0.4.18:
|
||||
version "0.4.18"
|
||||
resolved "https://registry.yarnpkg.com/pennant/-/pennant-0.4.18.tgz#da287bd74abb41483d9dc732b89ceded249ecb7c"
|
||||
integrity sha512-5CWfiPZLQrbx0EAU319tWjUH7iO+vt/wFfxqPLlAxsg6dyhO6Ix+oi8Z/FOgTaGMNey5tnDgDrZY9Jt3hej1aQ==
|
||||
pennant@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pennant/-/pennant-1.0.0.tgz#27ed6d628c2f9175c99b5bf787e138aff096fcb5"
|
||||
integrity sha512-qvN2kRN2j6uG/Rs4QHYvsIKDis8GMs7G496F527k8RqLgGZmXUfn3wDGwQ9Kxnz+IMo0c3dFhs9VJymXCMdkWg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@d3fc/d3fc-technical-indicator" "^8.0.1"
|
||||
"@floating-ui/react-dom" "^1.0.1"
|
||||
"@types/d3-array" "^2.9.0"
|
||||
"@types/d3-dispatch" "^2.0.0"
|
||||
"@types/d3-drag" "^2.0.0"
|
||||
@ -18292,7 +18343,8 @@ pennant@^0.4.18:
|
||||
"@types/react-virtualized-auto-sizer" "^1.0.0"
|
||||
allotment "1.17.0"
|
||||
classnames "^2.2.6"
|
||||
d3-array "2.3.3"
|
||||
d3-array "2.8.0"
|
||||
d3-axis "^3.0.0"
|
||||
d3-delaunay "^6.0.2"
|
||||
d3-dispatch "^2.0.0"
|
||||
d3-drag "^2.0.0"
|
||||
@ -20238,7 +20290,7 @@ sass@1.54.0:
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
sass@^1.42.1, sass@^1.49.9:
|
||||
sass@^1.42.1:
|
||||
version "1.55.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.55.0.tgz#0c4d3c293cfe8f8a2e8d3b666e1cf1bff8065d1c"
|
||||
integrity sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==
|
||||
@ -20247,6 +20299,15 @@ sass@^1.42.1, sass@^1.49.9:
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
sass@^1.49.9:
|
||||
version "1.56.2"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.56.2.tgz#9433b345ab3872996c82a53a58c014fd244fd095"
|
||||
integrity sha512-ciEJhnyCRwzlBCB+h5cCPM6ie/6f8HrhZMQOf5vlU60Y1bI1rx5Zb0vlDZvaycHsg/MqFfF1Eq2eokAa32iw8w==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
sax@~1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
@ -22005,7 +22066,12 @@ typescript@4.7.4:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
|
||||
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
|
||||
|
||||
typescript@^4.1.2, typescript@^4.4.3:
|
||||
typescript@^4.1.2:
|
||||
version "4.9.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78"
|
||||
integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==
|
||||
|
||||
typescript@^4.4.3:
|
||||
version "4.8.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6"
|
||||
integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==
|
||||
|
Loading…
Reference in New Issue
Block a user