Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ import {
} from './components/Snackbar/MessageSnackbar';
import { ApplicationContext } from './contexts/ApplicationContext';
import { SnackbarContext } from './contexts/SnackbarContext';
import { PoolContext } from './contexts/PoolContext';
import {
FF_EVENTS,
INamespace,
INewEventSet,
IStatus,
ITokenPool,
NAMESPACES_PATH,
} from './interfaces';
import { FF_Paths } from './interfaces/constants';
Expand All @@ -61,6 +63,9 @@ const App: React.FC = () => {
const [nodeID, setNodeID] = useState('');
const [nodeName, setNodeName] = useState('');
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
const [poolCache, setPoolCache] = useState<Map<string, ITokenPool>>(
new Map()
);
// Event Context
const [newEvents, setNewEvents] = useState<INewEventSet>(makeNewEventMap());
const [lastRefreshTime, setLastRefresh] = useState<string>(
Expand Down Expand Up @@ -191,18 +196,20 @@ const App: React.FC = () => {
<SnackbarContext.Provider
value={{ setMessage, setMessageType, reportFetchError }}
>
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<CssBaseline>
<Router />
<MessageSnackbar
{...{ message }}
{...{ setMessage }}
{...{ messageType }}
/>
</CssBaseline>
</ThemeProvider>
</StyledEngineProvider>
<PoolContext.Provider value={{ poolCache, setPoolCache }}>
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<CssBaseline>
<Router />
<MessageSnackbar
{...{ message }}
{...{ setMessage }}
{...{ messageType }}
/>
</CssBaseline>
</ThemeProvider>
</StyledEngineProvider>
</PoolContext.Provider>
</SnackbarContext.Provider>
</ApplicationContext.Provider>
);
Expand Down
10 changes: 5 additions & 5 deletions src/components/Lists/ApprovalList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useContext, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ApplicationContext } from '../../contexts/ApplicationContext';
import { ITokenApproval } from '../../interfaces';
import { ITokenApprovalWithPoolName } from '../../interfaces';
import { IDataListItem } from '../../interfaces/lists';
import { FFCopyButton } from '../Buttons/CopyButton';
import { PoolButton } from '../Buttons/PoolButton';
Expand All @@ -11,7 +11,7 @@ import { FFListTimestamp } from './FFListTimestamp';
import { FFSkeletonList } from './FFSkeletonList';

interface Props {
approval?: ITokenApproval;
approval?: ITokenApprovalWithPoolName;
}

export const ApprovalList: React.FC<Props> = ({ approval }) => {
Expand Down Expand Up @@ -39,11 +39,11 @@ export const ApprovalList: React.FC<Props> = ({ approval }) => {
},
{
label: t('pool'),
value: <FFListText color="primary" text={approval.pool} />,
value: <FFListText color="primary" text={approval.poolName} />,
button: (
<>
<PoolButton poolID={approval.pool} ns={selectedNamespace} />
<FFCopyButton value={approval.pool} />
<PoolButton poolID={approval.poolName} ns={selectedNamespace} />
<FFCopyButton value={approval.poolName} />
</>
),
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/Slides/ApprovalSlide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
import { Grid } from '@mui/material';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ITokenApproval } from '../../interfaces';
import { ITokenApprovalWithPoolName } from '../../interfaces';
import { DEFAULT_PADDING } from '../../theme';
import { getShortHash } from '../../utils';
import { ApprovalList } from '../Lists/ApprovalList';
import { DisplaySlide } from './DisplaySlide';
import { SlideHeader } from './SlideHeader';

interface Props {
approval: ITokenApproval;
approval: ITokenApprovalWithPoolName;
open: boolean;
onClose: () => void;
}
Expand Down
35 changes: 33 additions & 2 deletions src/components/Slides/EventSlide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ import {
FF_Paths,
IData,
IEvent,
ITokenApproval,
ITokenApprovalWithPoolName,
} from '../../interfaces';
import { DEFAULT_PADDING } from '../../theme';
import { fetchCatcher } from '../../utils';
import { fetchCatcher, fetchPool } from '../../utils';
import { BlockchainEventAccordion } from '../Accordions/BlockchainEventAccordion';
import { JsonViewAccordion } from '../Accordions/JsonViewerAccordion';
import { MessageAccordion } from '../Accordions/MessageAccordion';
Expand All @@ -45,6 +47,7 @@ import { TxList } from '../Lists/TxList';
import { DisplaySlide } from './DisplaySlide';
import { SlideHeader } from './SlideHeader';
import { SlideSectionHeader } from './SlideSectionHeader';
import { PoolContext } from '../../contexts/PoolContext';

interface Props {
event: IEvent;
Expand All @@ -56,9 +59,12 @@ export const EventSlide: React.FC<Props> = ({ event, open, onClose }) => {
const { t } = useTranslation();
const { selectedNamespace } = useContext(ApplicationContext);
const { reportFetchError } = useContext(SnackbarContext);
const { poolCache, setPoolCache } = useContext(PoolContext);
const [enrichedEvent, setEnrichedEvent] = useState<IEvent>();
const [messageData, setMessageData] = useState<IData[]>();
const { txID } = useParams<{ txID: string }>();
const [approvalWithName, setApprovalWithName] =
useState<ITokenApprovalWithPoolName>();

const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
Expand Down Expand Up @@ -100,6 +106,31 @@ export const EventSlide: React.FC<Props> = ({ event, open, onClose }) => {
}
}, [enrichedEvent, isMounted]);

useEffect(() => {
if (enrichedEvent && isMounted && enrichedEvent['tokenApproval']) {
fetchPoolName(enrichedEvent.tokenApproval).then(
(approvalWithName: ITokenApprovalWithPoolName) => {
setApprovalWithName(approvalWithName);
}
);
}
}, [enrichedEvent, isMounted]);

const fetchPoolName = async (
approval: ITokenApproval
): Promise<ITokenApprovalWithPoolName> => {
const pool = await fetchPool(
selectedNamespace,
approval.pool,
poolCache,
setPoolCache
);
return {
...approval,
poolName: pool ? pool.name : approval.pool,
};
};

return (
<>
<DisplaySlide open={open} onClose={onClose}>
Expand Down Expand Up @@ -199,7 +230,7 @@ export const EventSlide: React.FC<Props> = ({ event, open, onClose }) => {
<>
<SlideSectionHeader title={t('tokenApproval')} />
<Grid container item>
<ApprovalList approval={enrichedEvent.tokenApproval} />
<ApprovalList approval={approvalWithName} />
</Grid>
</>
)}
Expand Down
25 changes: 25 additions & 0 deletions src/contexts/PoolContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright © 2022 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { createContext, Dispatch, SetStateAction } from 'react';
import { ITokenPool } from '../interfaces';

export interface IPoolContext {
poolCache: Map<string, ITokenPool>;
setPoolCache: Dispatch<SetStateAction<Map<string, ITokenPool>>>;
}

export const PoolContext = createContext({} as IPoolContext);
8 changes: 8 additions & 0 deletions src/interfaces/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,10 @@ export interface ITokenApproval {
blockchainEvent: string;
}

export interface ITokenApprovalWithPoolName extends ITokenApproval {
poolName: string;
}

export interface ITokenBalance {
pool: string;
uri: string;
Expand All @@ -515,6 +519,10 @@ export interface ITokenBalance {
updated: string;
}

export interface ITokenBalanceWithPoolName extends ITokenBalance {
poolName: string;
}

export interface ITokenConnector {
[key: string]: string;
}
Expand Down
52 changes: 42 additions & 10 deletions src/pages/Tokens/views/Approvals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ import {
IDataTableRecord,
IPagedTokenApprovalResponse,
ITokenApproval,
ITokenApprovalWithPoolName,
} from '../../../interfaces';
import { DEFAULT_PADDING, DEFAULT_PAGE_LIMITS } from '../../../theme';
import { fetchCatcher, getFFTime } from '../../../utils';
import { fetchCatcher, fetchPool, getFFTime } from '../../../utils';
import { hasApprovalEvent } from '../../../utils/wsEvents';
import { PoolContext } from '../../../contexts/PoolContext';

export const TokensApprovals: () => JSX.Element = () => {
const { newEvents, lastRefreshTime, clearNewEvents, selectedNamespace } =
Expand All @@ -49,13 +51,17 @@ export const TokensApprovals: () => JSX.Element = () => {
useContext(FilterContext);
const { slideID, setSlideSearchParam } = useContext(SlideContext);
const { reportFetchError } = useContext(SnackbarContext);
const { poolCache, setPoolCache } = useContext(PoolContext);
const { t } = useTranslation();
const [isMounted, setIsMounted] = useState(false);
// Token approvals
const [tokenApprovals, setTokenApprovals] = useState<ITokenApproval[]>();
const [tokenApprovals, setTokenApprovals] = useState<
ITokenApprovalWithPoolName[]
>([]);
// Token approvals totals
const [tokenApprovalsTotal, setTokenApprovalsTotal] = useState(0);
const [viewApproval, setViewApproval] = useState<ITokenApproval>();
const [viewApproval, setViewApproval] =
useState<ITokenApprovalWithPoolName>();
const [currentPage, setCurrentPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(DEFAULT_PAGE_LIMITS[1]);

Expand All @@ -72,10 +78,21 @@ export const TokensApprovals: () => JSX.Element = () => {
fetchCatcher(
`${FF_Paths.nsPrefix}/${selectedNamespace}${FF_Paths.tokenApprovals}?localid=${slideID}`
)
.then((approvalRes: ITokenApproval[]) => {
isMounted &&
approvalRes.length === 1 &&
setViewApproval(approvalRes[0]);
.then(async (approvalRes: ITokenApproval[]) => {
if (isMounted && approvalRes.length === 1) {
const item = approvalRes[0];
const pool = await fetchPool(
selectedNamespace,
item.pool,
poolCache,
setPoolCache
);
const approvalWithPoolName: ITokenApprovalWithPoolName = {
...item,
poolName: pool ? pool.name : item.pool,
};
setViewApproval(approvalWithPoolName);
}
})
.catch((err) => {
reportFetchError(err);
Expand All @@ -93,8 +110,23 @@ export const TokensApprovals: () => JSX.Element = () => {
dateFilter.filterString
}${filterString ?? ''}`
)
.then((tokenApprovalRes: IPagedTokenApprovalResponse) => {
setTokenApprovals(tokenApprovalRes.items);
.then(async (tokenApprovalRes: IPagedTokenApprovalResponse) => {
for (const item of tokenApprovalRes.items) {
const pool = await fetchPool(
selectedNamespace,
item.pool,
poolCache,
setPoolCache
);
const approval: ITokenApprovalWithPoolName = {
...item,
poolName: pool ? pool.name : item.pool,
};
setTokenApprovals((tokenApprovals) => [
...tokenApprovals,
approval,
]);
}
setTokenApprovalsTotal(tokenApprovalRes.total);
})
.catch((err) => {
Expand Down Expand Up @@ -133,7 +165,7 @@ export const TokensApprovals: () => JSX.Element = () => {
value: <HashPopover address={approval.operator} />,
},
{
value: <HashPopover address={approval.pool} />,
value: <HashPopover address={approval.poolName} />,
},
{
value: <HashPopover address={approval.protocolId} />,
Expand Down
28 changes: 23 additions & 5 deletions src/pages/Tokens/views/Balances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ import {
IDataTableRecord,
IPagedTokenBalanceResponse,
ITokenBalance,
ITokenBalanceWithPoolName,
} from '../../../interfaces';
import { DEFAULT_PADDING, DEFAULT_PAGE_LIMITS } from '../../../theme';
import { fetchCatcher, getFFTime } from '../../../utils';
import { fetchCatcher, fetchPool, getFFTime } from '../../../utils';
import { hasTransferEvent } from '../../../utils/wsEvents';
import { PoolContext } from '../../../contexts/PoolContext';

export const KEY_POOL_DELIM = '||';

Expand All @@ -51,10 +53,13 @@ export const TokensBalances: () => JSX.Element = () => {
useContext(FilterContext);
const { slideID, setSlideSearchParam } = useContext(SlideContext);
const { reportFetchError } = useContext(SnackbarContext);
const { poolCache, setPoolCache } = useContext(PoolContext);
const { t } = useTranslation();
const [isMounted, setIsMounted] = useState(false);
// Token balances
const [tokenBalances, setTokenBalances] = useState<ITokenBalance[]>();
const [tokenBalances, setTokenBalances] = useState<
ITokenBalanceWithPoolName[]
>([]);
// Token balances totals
const [tokenBalancesTotal, setTokenBalancesTotal] = useState(0);
const [viewBalance, setViewBalance] = useState<ITokenBalance>();
Expand Down Expand Up @@ -104,9 +109,21 @@ export const TokensBalances: () => JSX.Element = () => {
dateFilter.filterString
}${filterString ?? ''}`
)
.then((tokenBalancesRes: IPagedTokenBalanceResponse) => {
setTokenBalances(tokenBalancesRes.items);
.then(async (tokenBalancesRes: IPagedTokenBalanceResponse) => {
setTokenBalancesTotal(tokenBalancesRes.total);
for (const item of tokenBalancesRes.items) {
const pool = await fetchPool(
selectedNamespace,
item.pool,
poolCache,
setPoolCache
);
const balance = {
...item,
poolName: pool ? pool.name : item.pool,
};
setTokenBalances((tokenBalances) => [...tokenBalances, balance]);
}
})
.catch((err) => {
reportFetchError(err);
Expand All @@ -129,6 +146,7 @@ export const TokensBalances: () => JSX.Element = () => {
t('connector'),
t('updated'),
];

const tokenBalanceRecords: IDataTableRecord[] | undefined =
tokenBalances?.map((balance, idx) => ({
key: idx.toString(),
Expand All @@ -140,7 +158,7 @@ export const TokensBalances: () => JSX.Element = () => {
value: <FFTableText color="primary" text={balance.balance} />,
},
{
value: <HashPopover address={balance.pool} />,
value: <HashPopover address={balance.poolName} />,
},
{
value: <HashPopover address={balance.uri} />,
Expand Down
Loading