diff --git a/packages/page-storage/src/Query.tsx b/packages/page-storage/src/Query.tsx index a05d07ffbb..5676e56a2a 100644 --- a/packages/page-storage/src/Query.tsx +++ b/packages/page-storage/src/Query.tsx @@ -82,7 +82,7 @@ function createComponent (type: string, Component: React.ComponentType, def } function getCachedComponent (registry: Registry, query: QueryTypes): CacheInstance { - const { id, isConst, key, params = [] } = query as StorageModuleQuery; + const { blockHash, id, isConst, key, params = [] } = query as StorageModuleQuery; if (!cache[id]) { let renderHelper; @@ -109,13 +109,16 @@ function getCachedComponent (registry: Registry, query: QueryTypes): CacheInstan const allCount = type.isPlain ? 0 : type.asMap.hashers.length; + const isEntries = values.length !== allCount; renderHelper = withCallDiv('subscribe', { paramName: 'params', paramValid: true, - params: values.length === allCount - ? [key, ...values] - : [key.entries, ...values], + params: isEntries + ? [key.entries, ...values] + : blockHash + ? [key.at, blockHash, ...values] + : [key, ...values], withIndicator: true }); } diff --git a/packages/page-storage/src/Selection/Modules.tsx b/packages/page-storage/src/Selection/Modules.tsx index 5da3176480..02b094ad27 100644 --- a/packages/page-storage/src/Selection/Modules.tsx +++ b/packages/page-storage/src/Selection/Modules.tsx @@ -7,16 +7,16 @@ import type { StorageEntryTypeLatest } from '@polkadot/types/interfaces'; import type { Registry, TypeDef } from '@polkadot/types/types'; import type { ComponentProps as Props } from '../types'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { ApiPromise } from '@polkadot/api'; -import { Button, InputStorage } from '@polkadot/react-components'; +import { Button, Input, InputStorage } from '@polkadot/react-components'; import { useApi } from '@polkadot/react-hooks'; import Params from '@polkadot/react-params'; import { getTypeDef } from '@polkadot/types'; import { getSiName } from '@polkadot/types/metadata/util'; import { TypeDefInfo } from '@polkadot/types/types'; -import { isNull, isUndefined } from '@polkadot/util'; +import { isHex, isNull, isUndefined } from '@polkadot/util'; import { useTranslation } from '../translate'; @@ -104,21 +104,38 @@ function expandKey (api: ApiPromise, key: QueryableStorageEntry<'promise'>): Key }; } +function extractParams (isIterable: boolean, values: RawParams): [RawParams, boolean] { + const params = values.filter(({ value }, index) => !isIterable || (index !== values.length - 1) || !isNull(value)); + + return [params, params.length === values.length]; +} + function Modules ({ onAdd }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); - const [{ defaultValues, isIterable, key, params }, setKey] = useState({ defaultValues: undefined, isIterable: false, key: api.query.timestamp?.now || api.query.system.events, params: [] }); - const [{ isValid, values }, setValues] = useState({ isValid: true, values: [] }); + const [{ defaultValues, isIterable, key, params }, setKey] = useState(() => ({ defaultValues: undefined, isIterable: false, key: api.query.timestamp?.now || api.query.system.events, params: [] })); + const [{ isValid, values }, setValues] = useState(() => ({ isValid: true, values: [] })); + const [blockHash, setBlockHash] = useState(null); const _onAdd = useCallback( (): void => { + const [params, isAtEnabled] = extractParams(isIterable, values); + isValid && onAdd({ + blockHash: isAtEnabled + ? blockHash + : null, isConst: false, key, - params: values.filter(({ value }, index) => !isIterable || (index !== values.length - 1) || !isNull(value)) + params }); }, - [isIterable, isValid, key, onAdd, values] + [blockHash, isIterable, isValid, key, onAdd, values] + ); + + const _onChangeAt = useCallback( + (value: string) => setBlockHash(isHex(value, 256) ? value : null), + [] ); const _onChangeValues = useCallback( @@ -137,6 +154,13 @@ function Modules ({ onAdd }: Props): React.ReactElement { [_onChangeValues, api] ); + const isAtAllowed = useMemo( + () => isValid + ? extractParams(isIterable, values)[1] + : false, + [isIterable, isValid, values] + ); + const { creator: { meta, method, section } } = key; return ( @@ -155,6 +179,13 @@ function Modules ({ onAdd }: Props): React.ReactElement { params={params} values={defaultValues} /> + ('blockhash to query at')} + onChange={_onChangeAt} + placeholder={t('0x...')} + />