From 9187f68bd27b22b4ab3d65c10299880edcc8a2bc Mon Sep 17 00:00:00 2001 From: Jaco Date: Wed, 30 Mar 2022 09:34:04 +0200 Subject: [PATCH] Rebag on upper limit breached (#7269) * Mrege prev/curr loadable bags * Rebag on upper limit breached --- packages/page-staking/src/Bags/Bag.tsx | 9 +-- packages/page-staking/src/Bags/Stash.tsx | 72 +++++++++++++------ packages/page-staking/src/Bags/Summary.tsx | 4 +- packages/page-staking/src/Bags/index.tsx | 2 +- packages/page-staking/src/Bags/useBagsIds.ts | 5 +- packages/page-staking/src/Bags/useBagsList.ts | 11 +-- 6 files changed, 67 insertions(+), 36 deletions(-) diff --git a/packages/page-staking/src/Bags/Bag.tsx b/packages/page-staking/src/Bags/Bag.tsx index 842ff601f8..426188a5dc 100644 --- a/packages/page-staking/src/Bags/Bag.tsx +++ b/packages/page-staking/src/Bags/Bag.tsx @@ -1,9 +1,9 @@ // Copyright 2017-2022 @polkadot/app-staking authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { u64 } from '@polkadot/types'; import type { AccountId32 } from '@polkadot/types/interfaces'; import type { PalletBagsListListBag } from '@polkadot/types/lookup'; +import type { BN } from '@polkadot/util'; import type { StashNode } from './types'; import React, { useEffect, useState } from 'react'; @@ -17,12 +17,12 @@ import useBagEntries from './useBagEntries'; import useBonded from './useBonded'; interface Props { - id: u64; info: PalletBagsListListBag; stashNodes?: StashNode[]; + upper: BN; } -function Bag ({ id, info, stashNodes }: Props): React.ReactElement { +function Bag ({ info, stashNodes, upper }: Props): React.ReactElement { const [[headId, trigger], setHeadId] = useState<[AccountId32 | null, number]>([null, 0]); const [isLoading, setLoading] = useState(true); const [isCompleted, list] = useBagEntries(headId, trigger); @@ -43,7 +43,7 @@ function Bag ({ id, info, stashNodes }: Props): React.ReactElement { return ( - + {info.head.isSome && } {info.tail.isSome && } @@ -53,6 +53,7 @@ function Bag ({ id, info, stashNodes }: Props): React.ReactElement { key={stashId} list={bonded} stashId={stashId} + upper={upper} /> ))} diff --git a/packages/page-staking/src/Bags/Stash.tsx b/packages/page-staking/src/Bags/Stash.tsx index 0dce3f6cc1..b5b2dd1081 100644 --- a/packages/page-staking/src/Bags/Stash.tsx +++ b/packages/page-staking/src/Bags/Stash.tsx @@ -1,6 +1,7 @@ // Copyright 2017-2022 @polkadot/app-staking authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { BN } from '@polkadot/util'; import type { ListNode } from './types'; import React, { useMemo } from 'react'; @@ -16,21 +17,36 @@ interface Props { isLoading: boolean; list?: ListNode[]; stashId: string; + upper: BN; } -function findEntry (stashId: string, list: ListNode[] = []): [ListNode | null, boolean, number] { - const entry = list.find((o) => o.stashId === stashId) || null; - const other = (entry && entry.jump && list.find((o) => o.stashId === entry.jump)) || null; - - return [entry, !!other, entry && other ? entry.index - other.index : 0]; +interface Entry { + canJump: boolean; + canRebag: boolean; + jumpCount: number; + stashInfo: ListNode | null; } -function Stash ({ className, isLoading, list, stashId }: Props): React.ReactElement { +function findEntry (upper: BN, stashId: string, list: ListNode[] = []): Entry { + const stashInfo = list.find((o) => o.stashId === stashId) || null; + const other = (stashInfo && stashInfo.jump && list.find((o) => o.stashId === stashInfo.jump)) || null; + + return { + canJump: !!other, + canRebag: !!stashInfo && stashInfo.bonded.gt(upper), + jumpCount: stashInfo && other + ? (stashInfo.index - other.index) + : 0, + stashInfo + }; +} + +function Stash ({ className, isLoading, list, stashId, upper }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); - const [stashInfo, canJump, jumpCount] = useMemo( - () => findEntry(stashId, list), - [list, stashId] + const { canJump, canRebag, jumpCount, stashInfo } = useMemo( + () => findEntry(upper, stashId, list), + [list, stashId, upper] ); return ( @@ -39,14 +55,31 @@ function Stash ({ className, isLoading, list, stashId }: Props): React.ReactElem value={stashId} withBonded /> - ('Move up {{jumpCount}}', { replace: { jumpCount } })} - params={[stashInfo?.jump]} - tx={api.tx.bagsList.putInFrontOf} - /> + {stashInfo && ( + canRebag + ? ( + ('Rebag')} + params={[stashInfo.stashId]} + tx={api.tx.bagsList.rebag} + /> + ) + : canJump + ? ( + ('Move up {{jumpCount}}', { replace: { jumpCount } })} + params={[stashInfo.jump]} + tx={api.tx.bagsList.putInFrontOf} + /> + ) + : null + )} ); } @@ -55,9 +88,4 @@ export default React.memo(styled(Stash)` .ui--AddressMini { vertical-align: middle; } - - .ui--Button.isDisabled { - cursor: default; - opacity: 0; - } `); diff --git a/packages/page-staking/src/Bags/Summary.tsx b/packages/page-staking/src/Bags/Summary.tsx index c1e9a6ede0..6e26969701 100644 --- a/packages/page-staking/src/Bags/Summary.tsx +++ b/packages/page-staking/src/Bags/Summary.tsx @@ -1,7 +1,7 @@ // Copyright 2017-2022 @polkadot/app-staking authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { u64 } from '@polkadot/types'; +import type { BN } from '@polkadot/util'; import React from 'react'; @@ -12,7 +12,7 @@ import { useTranslation } from '../translate'; interface Props { className?: string; - ids?: u64[]; + ids?: BN[]; } function Summary ({ className = '', ids }: Props): React.ReactElement { diff --git a/packages/page-staking/src/Bags/index.tsx b/packages/page-staking/src/Bags/index.tsx index 419319d769..b0c77f4f79 100644 --- a/packages/page-staking/src/Bags/index.tsx +++ b/packages/page-staking/src/Bags/index.tsx @@ -63,10 +63,10 @@ function Bags ({ ownStashes }: Props): React.ReactElement { > {sorted && sorted.map(({ id, info, key }) => ( ))} diff --git a/packages/page-staking/src/Bags/useBagsIds.ts b/packages/page-staking/src/Bags/useBagsIds.ts index f76d05e359..e7651a96ff 100644 --- a/packages/page-staking/src/Bags/useBagsIds.ts +++ b/packages/page-staking/src/Bags/useBagsIds.ts @@ -2,15 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 import type { StorageKey, u64 } from '@polkadot/types'; +import type { BN } from '@polkadot/util'; import { createNamedHook, useApi, useMapKeys } from '@polkadot/react-hooks'; const keyOptions = { - transform: (keys: StorageKey<[u64]>[]): u64[] => + transform: (keys: StorageKey<[u64]>[]): BN[] => keys.map(({ args: [id] }) => id) }; -function useBagsIdsImpl (): u64[] | undefined { +function useBagsIdsImpl (): BN[] | undefined { const { api } = useApi(); return useMapKeys(api.query.bagsList.listBags, keyOptions); diff --git a/packages/page-staking/src/Bags/useBagsList.ts b/packages/page-staking/src/Bags/useBagsList.ts index 85ca1fb744..5cc8594d10 100644 --- a/packages/page-staking/src/Bags/useBagsList.ts +++ b/packages/page-staking/src/Bags/useBagsList.ts @@ -1,23 +1,24 @@ // Copyright 2017-2022 @polkadot/app-staking authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Option, u64 } from '@polkadot/types'; +import type { Option } from '@polkadot/types'; import type { PalletBagsListListBag } from '@polkadot/types/lookup'; +import type { BN } from '@polkadot/util'; import { useEffect, useState } from 'react'; import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks'; interface Result { - id: u64; + id: BN; info: PalletBagsListListBag; key: string; } const multiOptions = { - transform: ([[ids], opts]: [[u64[]], Option[]]): Result[] => + transform: ([[ids], opts]: [[BN[]], Option[]]): Result[] => ids - .map((id, index): [u64, Option] => [id, opts[index]]) + .map((id, index): [BN, Option] => [id, opts[index]]) .filter(([, o]) => o.isSome) .map(([id, o]): Result => ({ id, info: o.unwrap(), key: id.toString() })), withParamsTransform: true @@ -33,7 +34,7 @@ function merge (prev: Result[] | undefined, curr: Result[]): Result[] { ); } -function useBagsListImpl (ids?: u64[]): Result[] | undefined { +function useBagsListImpl (ids?: BN[]): Result[] | undefined { const { api } = useApi(); const [result, setResult] = useState(); const query = useCall(ids && ids.length !== 0 && api.query.bagsList.listBags.multi, [ids], multiOptions);