From a4b26525c9ff29335f0a0d76c42bbf805a487ac0 Mon Sep 17 00:00:00 2001 From: Onno Visser <23527729+onnovisser@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:16:57 +0200 Subject: [PATCH] banner --- .../src/components/PoolChangesBanner.tsx | 43 +++++++++++++++++++ .../Configuration/EpochAndTranches.tsx | 7 +-- .../Configuration/WriteOffGroups.tsx | 3 +- .../pages/IssuerPool/Configuration/index.tsx | 6 ++- centrifuge-app/src/pages/IssuerPool/index.tsx | 31 +++++++------ centrifuge-js/src/modules/pools.ts | 14 +++--- .../src/hooks/useCentrifugeTransaction.ts | 3 ++ 7 files changed, 82 insertions(+), 25 deletions(-) create mode 100644 centrifuge-app/src/components/PoolChangesBanner.tsx diff --git a/centrifuge-app/src/components/PoolChangesBanner.tsx b/centrifuge-app/src/components/PoolChangesBanner.tsx new file mode 100644 index 0000000000..316986714a --- /dev/null +++ b/centrifuge-app/src/components/PoolChangesBanner.tsx @@ -0,0 +1,43 @@ +import { Banner, Text } from '@centrifuge/fabric' +import * as React from 'react' +import { useLoanChanges, usePoolChanges } from '../utils/usePools' +import { RouterTextLink } from './TextLink' + +export type PoolChangesBannerProps = { + poolId: string +} +const STORAGE_KEY = 'poolChangesBannerDismissedAt' + +export function PoolChangesBanner({ poolId }: PoolChangesBannerProps) { + const changes = usePoolChanges(poolId) + const loanChanges = useLoanChanges(poolId) + const [isOpen, setIsOpen] = React.useState(false) + + React.useEffect(() => { + const dismissedAt = new Date(localStorage.getItem(STORAGE_KEY) ?? 0) + if ( + (changes && new Date(changes.submittedAt) > dismissedAt) || + (loanChanges?.length && new Date(loanChanges.at(-1)!.submittedAt) > dismissedAt) + ) { + setIsOpen(true) + } + }, [changes, loanChanges]) + + function onClose() { + localStorage.setItem(STORAGE_KEY, new Date(Date.now()).toISOString()) + setIsOpen(false) + } + + return ( + + There are pending pool changes that can now be enabled{' '} + here + + } + /> + ) +} diff --git a/centrifuge-app/src/pages/IssuerPool/Configuration/EpochAndTranches.tsx b/centrifuge-app/src/pages/IssuerPool/Configuration/EpochAndTranches.tsx index 8cf75fc5aa..b2067df591 100644 --- a/centrifuge-app/src/pages/IssuerPool/Configuration/EpochAndTranches.tsx +++ b/centrifuge-app/src/pages/IssuerPool/Configuration/EpochAndTranches.tsx @@ -12,7 +12,7 @@ import { LabelValueStack } from '../../../components/LabelValueStack' import { PageSection } from '../../../components/PageSection' import { formatBalance, formatPercentage } from '../../../utils/formatting' import { useSuitableAccounts } from '../../../utils/usePermissions' -import { useConstants, usePool, usePoolMetadata } from '../../../utils/usePools' +import { useConstants, usePool, usePoolChanges, usePoolMetadata } from '../../../utils/usePools' import { TrancheInput } from '../../IssuerCreatePool/TrancheInput' import { validate } from '../../IssuerCreatePool/validate' @@ -25,7 +25,8 @@ export function EpochAndTranches() { const [isEditing, setIsEditing] = React.useState(false) const pool = usePool(poolId) const { data: metadata } = usePoolMetadata(pool) - const [account] = useSuitableAccounts({ poolId, poolRole: ['PoolAdmin'] }) + const [account] = useSuitableAccounts({ poolId, poolRole: ['PoolAdmin'], proxyType: ['Borrow'] }) + const changes = usePoolChanges(poolId) const columns: Column[] = [ { @@ -177,7 +178,7 @@ export function EpochAndTranches() { ] execute( [poolId, newPoolMetadata, { minEpochTime: epochSeconds, tranches: hasTrancheChanges ? tranches : undefined }], - { account } + { account, forceProxyType: 'Borrow' } ) actions.setSubmitting(false) }, diff --git a/centrifuge-app/src/pages/IssuerPool/Configuration/WriteOffGroups.tsx b/centrifuge-app/src/pages/IssuerPool/Configuration/WriteOffGroups.tsx index 70692053b6..210f5d91ce 100644 --- a/centrifuge-app/src/pages/IssuerPool/Configuration/WriteOffGroups.tsx +++ b/centrifuge-app/src/pages/IssuerPool/Configuration/WriteOffGroups.tsx @@ -54,7 +54,7 @@ export function WriteOffGroups() { const { pid: poolId } = useParams<{ pid: string }>() const [isEditing, setIsEditing] = React.useState(false) const consts = useConstants() - const [account] = useSuitableAccounts({ poolId, poolRole: ['LoanAdmin'] }) + const [account] = useSuitableAccounts({ poolId, poolRole: ['PoolAdmin'] }) const savedGroups = useWriteOffGroups(poolId) const sortedSavedGroups = [...(savedGroups ?? [])].sort((a, b) => a.overdueDays - b.overdueDays) @@ -186,6 +186,7 @@ export function WriteOffGroups() { small loading={isLoading || form.isSubmitting} loadingMessage={isLoading || form.isSubmitting ? 'Pending...' : undefined} + disabled={!account} key="done" > Done diff --git a/centrifuge-app/src/pages/IssuerPool/Configuration/index.tsx b/centrifuge-app/src/pages/IssuerPool/Configuration/index.tsx index baad4393f9..79985e7cf4 100644 --- a/centrifuge-app/src/pages/IssuerPool/Configuration/index.tsx +++ b/centrifuge-app/src/pages/IssuerPool/Configuration/index.tsx @@ -4,7 +4,7 @@ import { useDebugFlags } from '../../../components/DebugFlags' import { LoadBoundary } from '../../../components/LoadBoundary' import { PageWithSideBar } from '../../../components/PageWithSideBar' import { PendingMultisigs } from '../../../components/PendingMultisigs' -import { usePoolAdmin } from '../../../utils/usePermissions' +import { useCanBorrow, usePoolAdmin } from '../../../utils/usePermissions' import { IssuerPoolHeader } from '../Header' import { Details } from './Details' import { EpochAndTranches } from './EpochAndTranches' @@ -28,10 +28,12 @@ export function IssuerPoolConfigurationPage() { function IssuerPoolConfiguration() { const { pid: poolId } = useParams<{ pid: string }>() const { editPoolConfig } = useDebugFlags() + const isPoolAdmin = !!usePoolAdmin(poolId) + const isBorrower = useCanBorrow(poolId) return ( - {!!usePoolAdmin(poolId) && ( + {(isPoolAdmin || isBorrower) && ( <>
diff --git a/centrifuge-app/src/pages/IssuerPool/index.tsx b/centrifuge-app/src/pages/IssuerPool/index.tsx index 19db03f840..9678d3f3b6 100644 --- a/centrifuge-app/src/pages/IssuerPool/index.tsx +++ b/centrifuge-app/src/pages/IssuerPool/index.tsx @@ -1,5 +1,6 @@ import * as React from 'react' -import { Route, Switch, useRouteMatch } from 'react-router' +import { Route, Switch, useParams, useRouteMatch } from 'react-router' +import { PoolChangesBanner } from '../../components/PoolChangesBanner' import { IssuerPoolAccessPage } from './Access' import { IssuerPoolAssetPage } from './Assets' import { IssuerPoolConfigurationPage } from './Configuration' @@ -10,20 +11,24 @@ import { IssuerPoolLiquidityPage } from './Liquidity' import { IssuerPoolOverviewPage } from './Overview' import { IssuerPoolReportingPage } from './Reporting' -export const IssuerPoolPage: React.FC = () => { +export function IssuerPoolPage() { const { path } = useRouteMatch() + const { pid: poolId } = useParams<{ pid: string }>() return ( - - - - - - - - - - - + <> + + + + + + + + + + + + + ) } diff --git a/centrifuge-js/src/modules/pools.ts b/centrifuge-js/src/modules/pools.ts index 85e290bbe0..1c0a67357f 100644 --- a/centrifuge-js/src/modules/pools.ts +++ b/centrifuge-js/src/modules/pools.ts @@ -2899,15 +2899,17 @@ export function getPoolsModule(inst: Centrifuge) { switchMap((api) => api.query.poolSystem.scheduledUpdate(poolId)), map((updateData) => { const update = updateData.toPrimitive() as any - if (!update) return null + if (!update?.changes) return null + const { changes, submittedAt } = update + console.log('update', update) return { changes: { - tranches: update.tranches.noChange === null ? null : update.tranches.newValue, - trancheMetadata: update.trancheMetadata.noChange === null ? null : update.trancheMetadata.newValue, - minEpochTime: update.minEpochTime.noChange === null ? null : update.minEpochTime.newValue, - maxNavAge: update.maxNavAge.noChange === null ? null : update.maxNavAge.newValue, + tranches: changes.tranches.noChange === null ? null : changes.tranches.newValue, + trancheMetadata: changes.trancheMetadata.noChange === null ? null : changes.trancheMetadata.newValue, + minEpochTime: changes.minEpochTime.noChange === null ? null : changes.minEpochTime.newValue, + maxNavAge: changes.maxNavAge.noChange === null ? null : changes.maxNavAge.newValue, }, - submittedAt: new Date(update.submittedAt * 1000).toISOString(), + submittedAt: new Date(submittedAt * 1000).toISOString(), } }) ) diff --git a/centrifuge-react/src/hooks/useCentrifugeTransaction.ts b/centrifuge-react/src/hooks/useCentrifugeTransaction.ts index 7db9c1739f..30f4924898 100644 --- a/centrifuge-react/src/hooks/useCentrifugeTransaction.ts +++ b/centrifuge-react/src/hooks/useCentrifugeTransaction.ts @@ -9,6 +9,9 @@ import { PalletError } from '../utils/errors' export type CentrifugeTransactionOptions = Pick & { account?: CombinedSubstrateAccount + // If a transaction can be done via a proxy other than Any, pass the allowed types here, + // to make sure the transaction selects the right one. + // Otherwise by default it will try the transaction with the Any proxy type forceProxyType?: string | string[] }