From 18e46a9161a8e6ce3e4e2d3869e6d889b76d6d17 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Mon, 7 Oct 2024 16:15:26 +0800 Subject: [PATCH 01/22] exposing coretime wss endpoint to use on relay chain, adjusted hooks to accept api endpoint as a parameter --- .../src/endpoints/testingRelayPaseo.ts | 4 +-- packages/apps-routing/src/coretime.ts | 22 +++++++++++++ packages/apps-routing/src/index.ts | 3 ++ packages/apps-routing/tsconfig.build.json | 3 +- packages/page-broker/src/Overview/Summary.tsx | 9 +++--- packages/react-api/src/Api.tsx | 32 ++++++++++++------- packages/react-api/src/types.ts | 1 + packages/react-hooks/src/ctx/types.ts | 1 + packages/react-hooks/src/index.ts | 2 ++ packages/react-hooks/src/useBrokerConfig.ts | 6 ++-- packages/react-hooks/src/useBrokerLeases.ts | 2 +- .../react-hooks/src/useBrokerSalesInfo.ts | 7 ++-- packages/react-hooks/src/useBrokerStatus.ts | 13 +++++--- .../react-hooks/src/useCoretimeEndpoint.ts | 23 +++++++++++++ 14 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 packages/apps-routing/src/coretime.ts create mode 100644 packages/react-hooks/src/useCoretimeEndpoint.ts diff --git a/packages/apps-config/src/endpoints/testingRelayPaseo.ts b/packages/apps-config/src/endpoints/testingRelayPaseo.ts index e19b350e30fc..4e8834fea3da 100644 --- a/packages/apps-config/src/endpoints/testingRelayPaseo.ts +++ b/packages/apps-config/src/endpoints/testingRelayPaseo.ts @@ -326,7 +326,7 @@ export const testParasPaseoCommon: EndpointOption[] = [ } }, { - info: 'BridgeHub', + info: 'PaseoBridgeHub', isPeopleForIdentity: true, paraId: 1002, providers: { @@ -342,7 +342,7 @@ export const testParasPaseoCommon: EndpointOption[] = [ } }, { - info: 'Coretime', + info: 'PaseoCoretime', isPeopleForIdentity: true, paraId: 1005, providers: { diff --git a/packages/apps-routing/src/coretime.ts b/packages/apps-routing/src/coretime.ts new file mode 100644 index 000000000000..2015c6000e67 --- /dev/null +++ b/packages/apps-routing/src/coretime.ts @@ -0,0 +1,22 @@ +// Copyright 2017-2024 @polkadot/apps-routing authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { Route, TFunction } from './types.js'; + +import Component from '@polkadot/app-coretime'; + +export default function create (t: TFunction): Route { + return { + Component, + display: { + needsApi: [ + 'query.coretimeAssignmentProvider.coreDescriptors', + ], + needsApiInstances: true + }, + group: 'network', + icon: 'flask', + name: 'coretime', + text: t('nav.coretime', 'Coretime (Experimental)', { ns: 'app-coretime' }) + }; +} \ No newline at end of file diff --git a/packages/apps-routing/src/index.ts b/packages/apps-routing/src/index.ts index 60d3a739c24b..713b0b9bcc02 100644 --- a/packages/apps-routing/src/index.ts +++ b/packages/apps-routing/src/index.ts @@ -14,6 +14,7 @@ import calendar from './calendar.js'; import claims from './claims.js'; import collator from './collator.js'; import contracts from './contracts.js'; +import coretime from './coretime.js'; import council from './council.js'; import democracy from './democracy.js'; import explorer from './explorer.js'; @@ -62,7 +63,9 @@ export default function create (t: TFunction): Routes { // Legacy staking Pre v14 pallet version. stakingLegacy(t), collator(t), + // Coretime broker(t), + coretime(t), // governance v2 referenda(t), membership(t), diff --git a/packages/apps-routing/tsconfig.build.json b/packages/apps-routing/tsconfig.build.json index 32327a5d919a..b1f8b42f3575 100644 --- a/packages/apps-routing/tsconfig.build.json +++ b/packages/apps-routing/tsconfig.build.json @@ -11,12 +11,13 @@ { "path": "../page-alliance/tsconfig.build.json" }, { "path": "../page-ambassador/tsconfig.build.json" }, { "path": "../page-assets/tsconfig.build.json" }, + { "path": "../page-broker/tsconfig.build.json" }, { "path": "../page-bounties/tsconfig.build.json" }, { "path": "../page-calendar/tsconfig.build.json" }, { "path": "../page-claims/tsconfig.build.json" }, - { "path": "../page-broker/tsconfig.build.json" }, { "path": "../page-collator/tsconfig.build.json" }, { "path": "../page-contracts/tsconfig.build.json" }, + { "path": "../page-coretime/tsconfig.build.json" }, { "path": "../page-council/tsconfig.build.json" }, { "path": "../page-democracy/tsconfig.build.json" }, { "path": "../page-explorer/tsconfig.build.json" }, diff --git a/packages/page-broker/src/Overview/Summary.tsx b/packages/page-broker/src/Overview/Summary.tsx index b3067c0e0a73..affa4b2e4f61 100644 --- a/packages/page-broker/src/Overview/Summary.tsx +++ b/packages/page-broker/src/Overview/Summary.tsx @@ -39,14 +39,13 @@ interface Props { workloadInfos?: CoreWorkload[] } -function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { +function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { const { t } = useTranslation(); - const { api, apiEndpoint } = useApi(); - const totalCores = useBrokerStatus('coreCount'); + const { api, apiEndpoint, isApiReady } = useApi(); const uiHighlight = apiEndpoint?.ui.color || defaultHighlight; - const { idles, pools, tasks }: statsType = React.useMemo(() => getStats(totalCores, workloadInfos), [totalCores, workloadInfos]); + const { idles, pools, tasks }: statsType = React.useMemo(() => getStats(coreCount, workloadInfos), [coreCount, workloadInfos]); - const salesInfo = useBrokerSalesInfo(); + const salesInfo = useBrokerSalesInfo(api, isApiReady); return ( diff --git a/packages/react-api/src/Api.tsx b/packages/react-api/src/Api.tsx index a5c644731d86..81446f8ad8b1 100644 --- a/packages/react-api/src/Api.tsx +++ b/packages/react-api/src/Api.tsx @@ -18,7 +18,7 @@ import { deriveMapCache, setDeriveCache } from '@polkadot/api-derive/util'; import { ethereumChains, typesBundle } from '@polkadot/apps-config'; import { web3Accounts, web3Enable } from '@polkadot/extension-dapp'; import { TokenUnit } from '@polkadot/react-components/InputConsts/units'; -import { useApiUrl, useEndpoint, usePeopleEndpoint, useQueue } from '@polkadot/react-hooks'; +import { useApiUrl, useEndpoint, usePeopleEndpoint, useQueue, useCoretimeEndpoint } from '@polkadot/react-hooks'; import { ApiCtx } from '@polkadot/react-hooks/ctx/Api'; import { ApiSigner } from '@polkadot/react-signer/signers'; import { keyring } from '@polkadot/ui-keyring'; @@ -58,7 +58,7 @@ export const DEFAULT_AUX = ['Aux1', 'Aux2', 'Aux3', 'Aux4', 'Aux5', 'Aux6', 'Aux const DISALLOW_EXTENSIONS: string[] = []; const EMPTY_STATE = { hasInjectedAccounts: false, isApiReady: false } as unknown as ApiState; -function isKeyringLoaded () { +function isKeyringLoaded() { try { return !!keyring.keyring; } catch { @@ -66,7 +66,7 @@ function isKeyringLoaded () { } } -function getDevTypes (): Record> { +function getDevTypes(): Record> { const types = decodeUrlTypes() || store.get('types', {}) as Record>; const names = Object.keys(types); @@ -75,7 +75,7 @@ function getDevTypes (): Record> { return types; } -async function getInjectedAccounts (injectedPromise: Promise): Promise { +async function getInjectedAccounts(injectedPromise: Promise): Promise { try { await injectedPromise; @@ -95,7 +95,7 @@ async function getInjectedAccounts (injectedPromise: Promise string { +function makeCreateLink(baseApiUrl: string, isElectron: boolean): (path: string) => string { return (path: string, apiUrl?: string): string => `${isElectron ? 'https://polkadot.js.org/apps/' @@ -103,7 +103,7 @@ function makeCreateLink (baseApiUrl: string, isElectron: boolean): (path: string }?rpc=${encodeURIComponent(apiUrl || baseApiUrl)}#${path}`; } -async function retrieve (api: ApiPromise, injectedPromise: Promise): Promise { +async function retrieve(api: ApiPromise, injectedPromise: Promise): Promise { const [systemChain, systemChainType, systemName, systemVersion, injectedAccounts] = await Promise.all([ api.rpc.system.chain(), api.rpc.system.chainType @@ -131,7 +131,7 @@ async function retrieve (api: ApiPromise, injectedPromise: Promise, store: KeyringStore | undefined, types: Record>, urlIsEthereum = false): Promise { +async function loadOnReady(api: ApiPromise, endpoint: LinkOption | null, fork: Blockchain | null, injectedPromise: Promise, store: KeyringStore | undefined, types: Record>, urlIsEthereum = false): Promise { statics.registry.register(types); const { injectedAccounts, properties, systemChain, systemChainType, systemName, systemVersion } = await retrieve(api, injectedPromise); @@ -203,7 +203,7 @@ async function loadOnReady (api: ApiPromise, endpoint: LinkOption | null, fork: * @internal * Creates a ScProvider from a [/parachain] string */ -async function getLightProvider (chain: string): Promise { +async function getLightProvider(chain: string): Promise { const [sc, relayName, paraName] = chain.split('/'); if (sc !== 'substrate-connect') { @@ -228,7 +228,7 @@ async function getLightProvider (chain: string): Promise { /** * @internal */ -async function createApi (apiUrl: string, signer: ApiSigner, isLocalFork: boolean, onError: (error: unknown) => void): Promise { +async function createApi(apiUrl: string, signer: ApiSigner, isLocalFork: boolean, onError: (error: unknown) => void): Promise { const types = getDevTypes(); const isLight = apiUrl.startsWith('light://'); let provider; @@ -287,7 +287,7 @@ async function createApi (apiUrl: string, signer: ApiSigner, isLocalFork: boolea return { fork: chopsticksFork, types }; } -export function ApiCtxRoot ({ apiUrl, children, isElectron, store: keyringStore }: Props): React.ReactElement | null { +export function ApiCtxRoot({ apiUrl, children, isElectron, store: keyringStore }: Props): React.ReactElement | null { const { queuePayload, queueSetTxStatus } = useQueue(); const [state, setState] = useState(EMPTY_STATE); const [isApiConnected, setIsApiConnected] = useState(false); @@ -297,6 +297,7 @@ export function ApiCtxRoot ({ apiUrl, children, isElectron, store: keyringStore const [isLocalFork] = useState(store.get('localFork') === apiUrl); const apiEndpoint = useEndpoint(apiUrl); const peopleEndpoint = usePeopleEndpoint(apiEndpoint?.relayName || apiEndpoint?.info); + const coreTimeEndpoint = useCoretimeEndpoint(apiEndpoint?.relayName || apiEndpoint?.info) const relayUrls = useMemo( () => (apiEndpoint?.valueRelay && isNumber(apiEndpoint.paraId) && (apiEndpoint.paraId < 2000)) ? apiEndpoint.valueRelay @@ -309,7 +310,14 @@ export function ApiCtxRoot ({ apiUrl, children, isElectron, store: keyringStore : null, [apiEndpoint, peopleEndpoint] ); + const coretimeUrls = useMemo( + () => (coreTimeEndpoint && coreTimeEndpoint?.providers) + ? coreTimeEndpoint.providers + : null, + [apiEndpoint, peopleEndpoint] + ); const apiRelay = useApiUrl(relayUrls); + const apiCoretime = useApiUrl(coretimeUrls); const apiSystemPeople = useApiUrl(peopleUrls); const createLink = useMemo( () => makeCreateLink(apiUrl, isElectron), @@ -317,8 +325,8 @@ export function ApiCtxRoot ({ apiUrl, children, isElectron, store: keyringStore ); const enableIdentity = apiEndpoint?.isPeople || (isNumber(apiEndpoint?.paraId) && (apiEndpoint?.paraId >= 2000)) || (typeof apiEndpoint?.isPeopleForIdentity === 'boolean' && !apiEndpoint?.isPeopleForIdentity); const value = useMemo( - () => objectSpread({}, state, { api: statics.api, apiEndpoint, apiError, apiIdentity: ((apiEndpoint?.isPeopleForIdentity && apiSystemPeople) || statics.api), apiRelay, apiSystemPeople, apiUrl, createLink, enableIdentity, extensions, isApiConnected, isApiInitialized, isElectron, isLocalFork, isWaitingInjected: !extensions }), - [apiError, createLink, extensions, isApiConnected, isApiInitialized, isElectron, isLocalFork, state, apiEndpoint, apiRelay, apiUrl, apiSystemPeople, enableIdentity] + () => objectSpread({}, state, { api: statics.api, apiEndpoint, apiError, apiIdentity: ((apiEndpoint?.isPeopleForIdentity && apiSystemPeople) || statics.api), apiRelay, apiCoretime, apiSystemPeople, apiUrl, createLink, enableIdentity, extensions, isApiConnected, isApiInitialized, isElectron, isLocalFork, isWaitingInjected: !extensions }), + [apiError, createLink, extensions, isApiConnected, isApiInitialized, isElectron, isLocalFork, state, apiEndpoint, apiRelay, apiCoretime, apiUrl, apiSystemPeople, enableIdentity] ); // initial initialization diff --git a/packages/react-api/src/types.ts b/packages/react-api/src/types.ts index d7873857e511..e86868034e85 100644 --- a/packages/react-api/src/types.ts +++ b/packages/react-api/src/types.ts @@ -53,6 +53,7 @@ export interface ApiProps extends ApiState { * Used for checking if tx.idenitity.* should be used. Can be used for other scenarios as well. */ enableIdentity: boolean; + apiCoretime: ApiPromise; apiRelay: ApiPromise | null; apiSystemPeople: ApiPromise | null; apiUrl?: string; diff --git a/packages/react-hooks/src/ctx/types.ts b/packages/react-hooks/src/ctx/types.ts index c236701bec12..227fa46a6f59 100644 --- a/packages/react-hooks/src/ctx/types.ts +++ b/packages/react-hooks/src/ctx/types.ts @@ -31,6 +31,7 @@ export interface ApiProps extends ApiState { apiEndpoint: LinkOption | null; apiError: string | null; apiIdentity: ApiPromise; + apiCoretime: ApiPromise; enableIdentity: boolean; apiRelay: ApiPromise | null; apiSystemPeople: ApiPromise | null; diff --git a/packages/react-hooks/src/index.ts b/packages/react-hooks/src/index.ts index 25db1357818a..192e2a2cbd4b 100644 --- a/packages/react-hooks/src/index.ts +++ b/packages/react-hooks/src/index.ts @@ -68,6 +68,8 @@ export { useParaApi } from './useParaApi.js'; export { useIsParasLinked, useParaEndpoints } from './useParaEndpoints.js'; export { usePassword } from './usePassword.js'; export { usePeopleEndpoint } from './usePeopleEndpoint.js'; +export { useCoretimeEndpoint } from './useCoretimeEndpoint.js' +// export { useCoretimeInformation } from './useCoretimeInformation.js' export { usePopupWindow } from './usePopupWindow.js'; export { usePreimage } from './usePreimage.js'; export { useProxies } from './useProxies.js'; diff --git a/packages/react-hooks/src/useBrokerConfig.ts b/packages/react-hooks/src/useBrokerConfig.ts index 61423945bf7f..53358ba85423 100644 --- a/packages/react-hooks/src/useBrokerConfig.ts +++ b/packages/react-hooks/src/useBrokerConfig.ts @@ -5,6 +5,7 @@ import type { Option } from '@polkadot/types'; import type { PalletBrokerConfigRecord } from '@polkadot/types/lookup'; import type { PalletBrokerConfigRecord as SimplifiedPalletBrokerConfigRecord } from './types.js'; +import type { ApiPromise } from '@polkadot/api' import { useEffect, useState } from 'react'; import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks'; @@ -24,10 +25,9 @@ function extractInfo (config: Option): SimplifiedPalle }; } -function useBrokerConfigImpl () { - const { api, isApiReady } = useApi(); +function useBrokerConfigImpl (api: ApiPromise, ready: boolean) { - const config = useCall>(isApiReady && api.query.broker.configuration); + const config = useCall>(ready && api.query.broker.configuration); const [state, setState] = useState(); diff --git a/packages/react-hooks/src/useBrokerLeases.ts b/packages/react-hooks/src/useBrokerLeases.ts index 441bbd066f1d..bf61d9c37ba5 100644 --- a/packages/react-hooks/src/useBrokerLeases.ts +++ b/packages/react-hooks/src/useBrokerLeases.ts @@ -11,7 +11,7 @@ import { useEffect, useState } from 'react'; import { createNamedHook, useCall } from '@polkadot/react-hooks'; function useBrokerLeasesImpl (api: ApiPromise, ready: boolean): LegacyLease[] | undefined { - const leases = useCall>(ready && api.query.broker.leases); + const leases = useCall>(ready && api.query?.broker?.leases); const [state, setState] = useState(); useEffect((): void => { diff --git a/packages/react-hooks/src/useBrokerSalesInfo.ts b/packages/react-hooks/src/useBrokerSalesInfo.ts index fcc67e517e23..92968a2c890a 100644 --- a/packages/react-hooks/src/useBrokerSalesInfo.ts +++ b/packages/react-hooks/src/useBrokerSalesInfo.ts @@ -1,6 +1,7 @@ // Copyright 2017-2024 @polkadot/react-hooks authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { ApiPromise } from '@polkadot/api' import type { Option } from '@polkadot/types'; import type { PalletBrokerSaleInfoRecord } from '@polkadot/types/lookup'; import type { PalletBrokerSaleInfoRecord as SimplifiedPalletBrokerSaleInfoRecord } from './types.js'; @@ -27,10 +28,8 @@ function extractInfo (record: Option): SimplifiedPal }; } -function useBrokerSalesInfoImpl () { - const { api, isApiReady } = useApi(); - - const record = useCall>(isApiReady && api.query.broker.saleInfo); +function useBrokerSalesInfoImpl (api: ApiPromise, ready: boolean) { + const record = useCall>(ready && api.query.broker.saleInfo); const [state, setState] = useState(); diff --git a/packages/react-hooks/src/useBrokerStatus.ts b/packages/react-hooks/src/useBrokerStatus.ts index 708dece93f5a..7b49c1c15dfe 100644 --- a/packages/react-hooks/src/useBrokerStatus.ts +++ b/packages/react-hooks/src/useBrokerStatus.ts @@ -3,13 +3,13 @@ import type { PalletBrokerStatusRecord } from '@polkadot/types/lookup'; +import type { ApiPromise } from '@polkadot/api' import { useEffect, useState } from 'react'; -import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks'; +import { createNamedHook, useCall } from '@polkadot/react-hooks'; -function useBrokerStatusImpl (query: string): string | undefined { - const { api } = useApi(); - const status = useCall(api.query.broker?.status); +function useBrokerStatusImpl (api: ApiPromise, ready: boolean, query?: string): any | undefined { + const status = useCall(ready && api.query.broker?.status); const [state, setState] = useState(); useEffect((): void => { @@ -19,7 +19,10 @@ function useBrokerStatusImpl (query: string): string | undefined { ); }, [status]); - return state?.toJSON()?.[query]?.toString(); + if (query) { + return state?.toJSON()?.[query]?.toString(); + } + return state?.toJSON(); } export const useBrokerStatus = createNamedHook('useBrokerStatus', useBrokerStatusImpl); diff --git a/packages/react-hooks/src/useCoretimeEndpoint.ts b/packages/react-hooks/src/useCoretimeEndpoint.ts new file mode 100644 index 000000000000..c7d8879544a8 --- /dev/null +++ b/packages/react-hooks/src/useCoretimeEndpoint.ts @@ -0,0 +1,23 @@ +// Copyright 2017-2024 @polkadot/react-hooks authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { LinkOption } from '@polkadot/apps-config/endpoints/types'; + +import { useMemo } from 'react'; + +import { createWsEndpoints } from '@polkadot/apps-config'; +import { isString } from '@polkadot/util'; + +import { createNamedHook } from './createNamedHook.js'; + +const endpoints = createWsEndpoints((k, v) => v?.toString() || k); + +export function getCoretimeEndpoint (curApiInfo?: string): LinkOption | null { + return endpoints.find(({ info }) => isString(info) && isString(curApiInfo) && info.toLowerCase().includes('coretime') && info.toLowerCase().includes(curApiInfo.toLowerCase())) || null; +} + +function getCoretimeEndpointImpl (relayInfo?: string): LinkOption | null { + return useMemo(() => getCoretimeEndpoint(relayInfo), [relayInfo]); +} + +export const useCoretimeEndpoint = createNamedHook('useCoretimeEndpoint', getCoretimeEndpointImpl); From 94a432917e07ace8ad0f5553f8a935f275640514 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Mon, 7 Oct 2024 16:17:33 +0800 Subject: [PATCH 02/22] adjusting hook calls to new parameters --- packages/page-broker/src/Overview/Summary/RenewalPrice.tsx | 7 ++++--- packages/page-broker/src/Overview/Workload.tsx | 6 +++--- packages/page-broker/src/Overview/index.tsx | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/page-broker/src/Overview/Summary/RenewalPrice.tsx b/packages/page-broker/src/Overview/Summary/RenewalPrice.tsx index a355ad030b3a..cabdb88b243c 100644 --- a/packages/page-broker/src/Overview/Summary/RenewalPrice.tsx +++ b/packages/page-broker/src/Overview/Summary/RenewalPrice.tsx @@ -3,7 +3,7 @@ import React from 'react'; -import { useBrokerSalesInfo } from '@polkadot/react-hooks'; +import { useApi, useBrokerSalesInfo } from '@polkadot/react-hooks'; import { formatBalance } from '@polkadot/util'; interface Props { @@ -13,8 +13,9 @@ interface Props { currentPrice?: string; } -function RenewalPrice (): React.ReactElement | null { - const salesInfo = useBrokerSalesInfo(); +function RenewalPrice(): React.ReactElement | null { + const { api, isApiReady } = useApi(); + const salesInfo = useBrokerSalesInfo(api, isApiReady); return (
diff --git a/packages/page-broker/src/Overview/Workload.tsx b/packages/page-broker/src/Overview/Workload.tsx index 028c84ee29c6..deacc0d33640 100644 --- a/packages/page-broker/src/Overview/Workload.tsx +++ b/packages/page-broker/src/Overview/Workload.tsx @@ -23,9 +23,9 @@ interface Props { workplan?: CoreWorkplanType[] | undefined } -function Workload ({ api, core, workload, workplan }: Props): React.ReactElement { +function Workload({ api, core, workload, workplan }: Props): React.ReactElement { const { isApiReady } = useApi(); - const salesInfo = useBrokerSalesInfo(); + const salesInfo = useBrokerSalesInfo(api, isApiReady); const status = useCall>(isApiReady && api.query.broker?.status); const [isExpanded, toggleIsExpanded] = useToggle(false); @@ -56,7 +56,7 @@ function Workload ({ api, core, workload, workplan }: Props): React.ReactElement setWorkplanData(formatRowInfo(workplan, core, region, currentTimeSlice, salesInfo)); } } - , [workplan, region, currentTimeSlice, core, salesInfo]); + , [workplan, region, currentTimeSlice, core, salesInfo]); const hasWorkplan = workplan?.length; diff --git a/packages/page-broker/src/Overview/index.tsx b/packages/page-broker/src/Overview/index.tsx index 9506e2080e3d..18ed3e1482c6 100644 --- a/packages/page-broker/src/Overview/index.tsx +++ b/packages/page-broker/src/Overview/index.tsx @@ -25,7 +25,7 @@ const formatDataObject = (one: CoreWorkplan | CoreWorkload, leaseMap: LeaseMapTy lastBlock: leaseMap[one?.info.task as number]?.until || 0, maskBits: one.info.maskBits, task: one.info.task, - type: getOccupancyType(leaseMap[one.info.task as number], reservationMap[one.info.task as number]) + type: getOccupancyType(leaseMap[one.info.task as number], reservationMap[one.info.task as number], one.info.isPool) }); const formatData = (coreCount: number, workplan: CoreWorkplan[], workload: CoreWorkload[], leaseMap: LeaseMapType, reservationMap: ReservationMapType): CoreInfo[] => { @@ -51,12 +51,12 @@ const formatData = (coreCount: number, workplan: CoreWorkplan[], workload: CoreW }); }; -function Overview ({ className }: Props): React.ReactElement { +function Overview({ className }: Props): React.ReactElement { const { api, apiEndpoint, isApiReady } = useApi(); const [data, setData] = useState([]); const [filtered, setFiltered] = useState(); - const coreCount = useBrokerStatus('coreCount') || '-'; + const coreCount = useBrokerStatus(api, isApiReady, 'coreCount') || '-'; const workloadInfos: CoreWorkload[] | undefined = useWorkloadInfos(api, isApiReady); const workplanInfos: CoreWorkplan[] | undefined = useWorkplanInfos(api, isApiReady); From ec64d753fda58bb449d50038feaca21c488bf52b Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Mon, 7 Oct 2024 16:19:02 +0800 Subject: [PATCH 03/22] added Tag for coretime types, renamed occupancyType to coretimeType --- .../page-broker/src/Overview/WorkInfoRow.tsx | 81 +++++++++++-------- packages/page-broker/src/types.ts | 11 +-- packages/page-broker/src/utils.ts | 32 +++++--- 3 files changed, 77 insertions(+), 47 deletions(-) diff --git a/packages/page-broker/src/Overview/WorkInfoRow.tsx b/packages/page-broker/src/Overview/WorkInfoRow.tsx index 09f55ba88283..321a99ec346f 100644 --- a/packages/page-broker/src/Overview/WorkInfoRow.tsx +++ b/packages/page-broker/src/Overview/WorkInfoRow.tsx @@ -3,9 +3,17 @@ import React from 'react'; -import { AddressMini, styled } from '@polkadot/react-components'; +import { AddressMini, Tag, styled } from '@polkadot/react-components'; -import { type InfoRow, Occupancy } from '../types.js'; +import { type InfoRow, CoreTimeTypes } from '../types.js'; +import { FlagColor } from '@polkadot/react-components/types'; + +const colours: Record = { + [CoreTimeTypes.Reservation]: 'orange', + [CoreTimeTypes.Lease]: 'blue', + [CoreTimeTypes['Bulk Coretime']]: 'pink', + [CoreTimeTypes['On Demand']]: 'green', +} const StyledTableCol = styled.td<{ hide?: 'mobile' | 'tablet' | 'both' }>` width: 150px; @@ -25,17 +33,17 @@ const StyledTableCol = styled.td<{ hide?: 'mobile' | 'tablet' | 'both' }>` const TableCol = ({ header, hide, value }: { - header: string; - value: string | number | null | undefined; - hide?: 'mobile' | 'tablet' | 'both'; -}) => ( + header: string; + value: string | number | null | undefined; + hide?: 'mobile' | 'tablet' | 'both'; + }) => (
{header}

{value || <> }

); -function WorkInfoRow ({ data }: { data: InfoRow }): React.ReactElement { +function WorkInfoRow({ data }: { data: InfoRow }): React.ReactElement { if (!data.task) { return ( <> @@ -45,7 +53,7 @@ function WorkInfoRow ({ data }: { data: InfoRow }): React.ReactElement { } switch (data.type) { - case (Occupancy.Reservation): { + case (CoreTimeTypes.Reservation): { return ( <> - + + + ); } - case (Occupancy.Lease): { + case (CoreTimeTypes.Lease): + case (CoreTimeTypes['On Demand']): { return ( <> - + +
type
+ +
); } @@ -123,23 +137,24 @@ function WorkInfoRow ({ data }: { data: InfoRow }): React.ReactElement { header='Last block' value={data.endBlock} /> - - -
{'Owner'}
- {data.owner - ? ( - - ) - - :

 

} + +
type
+
+ {data.owner ? +
{'Owner'}
+ + + + +
: } ); } } diff --git a/packages/page-broker/src/types.ts b/packages/page-broker/src/types.ts index 69d25e21c6ef..28547c792ed1 100644 --- a/packages/page-broker/src/types.ts +++ b/packages/page-broker/src/types.ts @@ -13,7 +13,7 @@ export interface InfoRow { owner?: string leaseLength?: number endBlock?: number - type?: Occupancy + type?: CoreTimeTypes } export interface CoreInfo { @@ -28,18 +28,19 @@ export interface statsType { tasks: number } -export enum Occupancy { +export enum CoreTimeTypes { 'Reservation', 'Lease', - 'Bulk Coretime' + 'Bulk Coretime', + 'On Demand' } export interface CoreWorkplanType extends CoreWorkplan { lastBlock: number, - type: Occupancy + type: CoreTimeTypes } export interface CoreWorkloadType extends CoreWorkload { lastBlock: number, - type: Occupancy + type: CoreTimeTypes } diff --git a/packages/page-broker/src/utils.ts b/packages/page-broker/src/utils.ts index 90104c4afaf3..0debf8d9a9ea 100644 --- a/packages/page-broker/src/utils.ts +++ b/packages/page-broker/src/utils.ts @@ -6,7 +6,7 @@ import type { CoreWorkloadType, CoreWorkplanType, InfoRow } from './types.js'; import { BN } from '@polkadot/util'; -import { Occupancy } from './types.js'; +import { CoreTimeTypes } from './types.js'; export const CoreTimeConsts = { BlockTime: 6000, @@ -61,15 +61,26 @@ export const estimateTime = (targetTimeslice: string | number, latestBlock: numb } }; -export function formatRowInfo (data: CoreWorkloadType[] | CoreWorkplanType[], core: number, currentRegion: RegionInfo | undefined, timeslice: number, { regionBegin, regionEnd }: { regionBegin: number, regionEnd: number }, regionLength = CoreTimeConsts.DefaultRegion): InfoRow[] { +/** + * + * @param data: CoreWorkloadType[] + * @param core: core number + * @param currentRegion + * @param timeslice + * @param param4 + * @param regionLength + * @returns + */ + +export function formatRowInfo (data: CoreWorkloadType[] | CoreWorkplanType[], core: number, currentRegion: RegionInfo | undefined, currentTimeSlice: number, { regionBegin, regionEnd }: { regionBegin: number, regionEnd: number }, regionLength = CoreTimeConsts.DefaultRegion): InfoRow[] { return data.map((one: CoreWorkloadType | CoreWorkplanType) => { const item: InfoRow = { core, maskBits: one?.info?.maskBits, task: one?.info?.task, type: one?.type }; - const blockNumber = timeslice * 80; + const blockNumberNow = currentTimeSlice * 80; item.type = one.type; let end; let start = null; - if (one.type === Occupancy.Lease) { + if (one.type === CoreTimeTypes.Lease) { const period = Math.floor(one.lastBlock / regionLength); end = period * regionLength; @@ -79,12 +90,12 @@ export function formatRowInfo (data: CoreWorkloadType[] | CoreWorkplanType[], co } item.owner = currentRegion?.owner.toString(); - item.start = start ? estimateTime(start, blockNumber) : null; - item.end = end ? estimateTime(end, blockNumber) : null; + item.start = start ? estimateTime(start, blockNumberNow) : null; + item.end = end ? estimateTime(end, blockNumberNow) : null; item.endBlock = end ? Number(end) * 80 : 0; if ('timeslice' in one && !start) { - start = estimateTime(one.timeslice, blockNumber) ?? null; + start = estimateTime(one.timeslice, blockNumberNow) ?? null; } return item; @@ -121,6 +132,9 @@ export const createTaskMap = (items: T[]): Record); }; -export const getOccupancyType = (lease: LegacyLease | undefined, reservation: Reservation | undefined): Occupancy => { - return reservation ? Occupancy.Reservation : lease ? Occupancy.Lease : Occupancy['Bulk Coretime']; +export const getOccupancyType = (lease: LegacyLease | undefined, reservation: Reservation | undefined, isPool: boolean): CoreTimeTypes => { + if (isPool) { + return CoreTimeTypes['On Demand']; + } + return reservation ? CoreTimeTypes.Reservation : lease ? CoreTimeTypes.Lease : CoreTimeTypes['Bulk Coretime']; }; From 250020512f62abd912e636ec23ad819fb012f5bf Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Tue, 8 Oct 2024 15:42:35 +0800 Subject: [PATCH 04/22] added cycle progress and cycle end date to summary, fixed the estimation dates --- packages/page-broker/src/Overview/Summary.tsx | 34 +++++++++++++++---- .../src/Overview/Summary/Timeslice.tsx | 16 ++++----- .../page-broker/src/Overview/Workload.tsx | 5 +-- packages/page-broker/src/Overview/index.tsx | 10 +++--- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/packages/page-broker/src/Overview/Summary.tsx b/packages/page-broker/src/Overview/Summary.tsx index affa4b2e4f61..1c7199cd3806 100644 --- a/packages/page-broker/src/Overview/Summary.tsx +++ b/packages/page-broker/src/Overview/Summary.tsx @@ -3,17 +3,18 @@ import type { LinkOption } from '@polkadot/apps-config/endpoints/types'; import type { statsType } from '../types.js'; +import { BN } from '@polkadot/util'; -import React from 'react'; +import React, { useMemo } from 'react'; import { CardSummary, styled, SummaryBox, UsageBar } from '@polkadot/react-components'; import { defaultHighlight } from '@polkadot/react-components/styles'; -import { useApi, useBrokerSalesInfo, useBrokerStatus } from '@polkadot/react-hooks'; -import { type CoreWorkload } from '@polkadot/react-hooks/types'; +import { useApi, useBrokerConfig, useBrokerSalesInfo, useBrokerStatus } from '@polkadot/react-hooks'; +import { PalletBrokerConfigRecord, type CoreWorkload } from '@polkadot/react-hooks/types'; import { formatBalance } from '@polkadot/util'; import { useTranslation } from '../translate.js'; -import { getStats } from '../utils.js'; +import { estimateTime, getStats } from '../utils.js'; import RegionLength from './Summary/RegionLength.js'; import Timeslice from './Summary/Timeslice.js'; import TimeslicePeriod from './Summary/TimeslicePeriod.js'; @@ -45,7 +46,10 @@ function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { const uiHighlight = apiEndpoint?.ui.color || defaultHighlight; const { idles, pools, tasks }: statsType = React.useMemo(() => getStats(coreCount, workloadInfos), [coreCount, workloadInfos]); - const salesInfo = useBrokerSalesInfo(api, isApiReady); + const saleInfo = useBrokerSalesInfo(api, isApiReady); + const config = useBrokerConfig(api, isApiReady) + const status = useBrokerStatus(api, isApiReady) + const currentRegionEnd = useMemo(() => saleInfo?.regionEnd - config?.regionLength, [saleInfo, config]) return ( @@ -64,7 +68,7 @@ function Summary({ coreCount, workloadInfos }: Props): React.ReactElement {
- {formatBalance(salesInfo?.endPrice) || '-'} + {formatBalance(saleInfo?.endPrice) || '-'}
@@ -72,13 +76,29 @@ function Summary({ coreCount, workloadInfos }: Props): React.ReactElement {
- {salesInfo?.coresSold} / {salesInfo?.coresOffered} + {saleInfo?.coresSold} / {saleInfo?.coresOffered}
+ {status && +
+ {estimateTime(currentRegionEnd, status?.lastTimeslice * 80)} +
+
} + )} +
| null { +function Timeslice({ children, className }: Props): React.ReactElement | null { + const { api, isApiReady } = useApi() + const info = useBrokerStatus(api, isApiReady); + return ( - +
+ {info?.lastTimeslice || '-'} {children} - - ); +
) } export default React.memo(Timeslice); diff --git a/packages/page-broker/src/Overview/Workload.tsx b/packages/page-broker/src/Overview/Workload.tsx index deacc0d33640..053c76fcf936 100644 --- a/packages/page-broker/src/Overview/Workload.tsx +++ b/packages/page-broker/src/Overview/Workload.tsx @@ -12,7 +12,7 @@ import React, { useEffect, useMemo, useState } from 'react'; import { ExpandButton } from '@polkadot/react-components'; import { useApi, useBrokerSalesInfo, useCall, useRegions, useToggle } from '@polkadot/react-hooks'; -import { formatRowInfo } from '../utils.js'; +import { CoreTimeConsts, formatRowInfo } from '../utils.js'; import WorkInfoRow from './WorkInfoRow.js'; import Workplan from './Workplan.js'; @@ -45,7 +45,8 @@ function Workload({ api, core, workload, workplan }: Props): React.ReactElement< useEffect(() => { if (!!workload?.length && !!salesInfo) { - setWorkloadData(formatRowInfo(workload, core, region, currentTimeSlice, salesInfo)); + // saleInfo points to a regionEnd and regionBeing in the next cycle, but we want the start and end of the current cycle + setWorkloadData(formatRowInfo(workload, core, region, currentTimeSlice, { regionBegin: salesInfo.regionBegin - CoreTimeConsts.DefaultRegion, regionEnd: salesInfo.regionEnd - CoreTimeConsts.DefaultRegion })); } else { return setWorkloadData([{ core }]); } diff --git a/packages/page-broker/src/Overview/index.tsx b/packages/page-broker/src/Overview/index.tsx index 18ed3e1482c6..0dd785f79a5e 100644 --- a/packages/page-broker/src/Overview/index.tsx +++ b/packages/page-broker/src/Overview/index.tsx @@ -56,7 +56,7 @@ function Overview({ className }: Props): React.ReactElement { const [data, setData] = useState([]); const [filtered, setFiltered] = useState(); - const coreCount = useBrokerStatus(api, isApiReady, 'coreCount') || '-'; + const status = useBrokerStatus(api, isApiReady); const workloadInfos: CoreWorkload[] | undefined = useWorkloadInfos(api, isApiReady); const workplanInfos: CoreWorkplan[] | undefined = useWorkplanInfos(api, isApiReady); @@ -67,15 +67,15 @@ function Overview({ className }: Props): React.ReactElement { const reservationMap: ReservationMapType = useMemo(() => reservations ? createTaskMap(reservations) : [], [reservations]); useEffect(() => { - !!workplanInfos && !!workloadInfos && !!coreCount && - setData(formatData(Number(coreCount), workplanInfos, workloadInfos, leaseMap, reservationMap)); - }, [workplanInfos, workloadInfos, leaseMap, reservationMap, coreCount]); + !!workplanInfos && !!workloadInfos && !!status?.coreCount && + setData(formatData(Number(status?.coreCount), workplanInfos, workloadInfos, leaseMap, reservationMap)); + }, [workplanInfos, workloadInfos, leaseMap, reservationMap, status]); return (
{!!data?.length && From 1913d17e7520b3d7d978b235ec7a098e02138fc8 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Tue, 8 Oct 2024 22:01:12 +0800 Subject: [PATCH 05/22] coretime page draft, added hook for gathering all the coretime information in order to show it on relay chain --- packages/page-broker/src/Overview/Summary.tsx | 3 +- .../src/Overview/Summary/RenewalPrice.tsx | 27 ------ packages/page-coretime/README.md | 1 + packages/page-coretime/package.json | 27 ++++++ .../page-coretime/src/Overview/BrokerId.tsx | 27 ++++++ .../src/Overview/CoreDescriptor.tsx | 66 +++++++++++++ .../src/Overview/CoreDescriptors.tsx | 67 ++++++++++++++ .../page-coretime/src/Overview/CoreQueue.tsx | 41 +++++++++ .../src/Overview/CurrentWork.tsx | 62 +++++++++++++ .../src/Overview/QueueStatus.tsx | 35 +++++++ .../page-coretime/src/Overview/Summary.tsx | 66 +++++++++++++ packages/page-coretime/src/Overview/index.tsx | 31 +++++++ .../page-coretime/src/ParachainsTable.tsx | 92 +++++++++++++++++++ packages/page-coretime/src/index.tsx | 73 +++++++++++++++ packages/page-coretime/src/translate.ts | 8 ++ packages/page-coretime/src/utils.ts | 54 +++++++++++ packages/page-coretime/tsconfig.build.json | 13 +++ packages/react-hooks/src/index.ts | 2 +- packages/react-hooks/src/types.ts | 56 +++++++++++ packages/react-hooks/src/useBrokerConfig.ts | 2 +- .../src/useBrokerPotentialRenewals.ts | 64 +++++++++++++ .../react-hooks/src/useBrokerSalesInfo.ts | 2 +- packages/react-hooks/src/useBrokerStatus.ts | 31 ++++--- .../react-hooks/src/useCoretimeInformation.ts | 73 +++++++++++++++ packages/react-hooks/src/useWorkloadInfos.ts | 2 +- packages/react-hooks/src/useWorkplanInfos.ts | 2 +- yarn.lock | 13 +++ 27 files changed, 893 insertions(+), 47 deletions(-) delete mode 100644 packages/page-broker/src/Overview/Summary/RenewalPrice.tsx create mode 100644 packages/page-coretime/README.md create mode 100644 packages/page-coretime/package.json create mode 100644 packages/page-coretime/src/Overview/BrokerId.tsx create mode 100644 packages/page-coretime/src/Overview/CoreDescriptor.tsx create mode 100644 packages/page-coretime/src/Overview/CoreDescriptors.tsx create mode 100644 packages/page-coretime/src/Overview/CoreQueue.tsx create mode 100644 packages/page-coretime/src/Overview/CurrentWork.tsx create mode 100644 packages/page-coretime/src/Overview/QueueStatus.tsx create mode 100644 packages/page-coretime/src/Overview/Summary.tsx create mode 100644 packages/page-coretime/src/Overview/index.tsx create mode 100644 packages/page-coretime/src/ParachainsTable.tsx create mode 100644 packages/page-coretime/src/index.tsx create mode 100644 packages/page-coretime/src/translate.ts create mode 100644 packages/page-coretime/src/utils.ts create mode 100644 packages/page-coretime/tsconfig.build.json create mode 100644 packages/react-hooks/src/useBrokerPotentialRenewals.ts create mode 100644 packages/react-hooks/src/useCoretimeInformation.ts diff --git a/packages/page-broker/src/Overview/Summary.tsx b/packages/page-broker/src/Overview/Summary.tsx index 1c7199cd3806..a4514a1c1771 100644 --- a/packages/page-broker/src/Overview/Summary.tsx +++ b/packages/page-broker/src/Overview/Summary.tsx @@ -49,8 +49,7 @@ function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { const saleInfo = useBrokerSalesInfo(api, isApiReady); const config = useBrokerConfig(api, isApiReady) const status = useBrokerStatus(api, isApiReady) - const currentRegionEnd = useMemo(() => saleInfo?.regionEnd - config?.regionLength, [saleInfo, config]) - + const currentRegionEnd = useMemo(() => saleInfo && config && saleInfo?.regionEnd - config?.regionLength, [saleInfo, config]) return ( diff --git a/packages/page-broker/src/Overview/Summary/RenewalPrice.tsx b/packages/page-broker/src/Overview/Summary/RenewalPrice.tsx deleted file mode 100644 index cabdb88b243c..000000000000 --- a/packages/page-broker/src/Overview/Summary/RenewalPrice.tsx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-broker authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; - -import { useApi, useBrokerSalesInfo } from '@polkadot/react-hooks'; -import { formatBalance } from '@polkadot/util'; - -interface Props { - className?: string; - children?: React.ReactNode; - renewalBump?: string; - currentPrice?: string; -} - -function RenewalPrice(): React.ReactElement | null { - const { api, isApiReady } = useApi(); - const salesInfo = useBrokerSalesInfo(api, isApiReady); - - return ( -
- {formatBalance(salesInfo?.endPrice) || '-'} -
- ); -} - -export default React.memo(RenewalPrice); diff --git a/packages/page-coretime/README.md b/packages/page-coretime/README.md new file mode 100644 index 000000000000..d9c23d4732fd --- /dev/null +++ b/packages/page-coretime/README.md @@ -0,0 +1 @@ +# @polkadot/app-coretime diff --git a/packages/page-coretime/package.json b/packages/page-coretime/package.json new file mode 100644 index 000000000000..c5d8d7392c04 --- /dev/null +++ b/packages/page-coretime/package.json @@ -0,0 +1,27 @@ +{ + "bugs": "https://github.com/polkadot-js/apps/issues", + "engines": { + "node": ">=18" + }, + "homepage": "https://github.com/polkadot-js/apps/tree/master/packages/page-coretime#readme", + "license": "Apache-2.0", + "name": "@polkadot/app-coretime", + "private": true, + "repository": { + "directory": "packages/page-coretime", + "type": "git", + "url": "https://github.com/polkadot-js/apps.git" + }, + "sideEffects": false, + "type": "module", + "version": "0.144.2-2-x", + "dependencies": { + "@polkadot/react-components": "0.144.2-2-x", + "@polkadot/react-query": "0.144.2-2-x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*", + "react-is": "*" + } +} diff --git a/packages/page-coretime/src/Overview/BrokerId.tsx b/packages/page-coretime/src/Overview/BrokerId.tsx new file mode 100644 index 000000000000..622a0e3471d1 --- /dev/null +++ b/packages/page-coretime/src/Overview/BrokerId.tsx @@ -0,0 +1,27 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { u32 } from '@polkadot/types'; + +import React from 'react'; + +import { useApi } from '@polkadot/react-hooks'; + +interface Props { + className?: string; + children?: React.ReactNode; +} + +function BrokerId ({ children, className }: Props): React.ReactElement | null { + const { api } = useApi(); + const id = api.consts.coretime?.brokerId as u32; + + return ( +
+ {id?.toString()} + {children} +
+ ); +} + +export default React.memo(BrokerId); diff --git a/packages/page-coretime/src/Overview/CoreDescriptor.tsx b/packages/page-coretime/src/Overview/CoreDescriptor.tsx new file mode 100644 index 000000000000..3704e938ea88 --- /dev/null +++ b/packages/page-coretime/src/Overview/CoreDescriptor.tsx @@ -0,0 +1,66 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { CoreDescription } from '@polkadot/react-hooks/types'; +import type { PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor } from '@polkadot/types/lookup'; + +import React from 'react'; + +import { styled } from '@polkadot/react-components'; + +import CoreQueue from './CoreQueue.js'; +import CurrentWork from './CurrentWork.js'; + +interface Props { + className?: string; + value: CoreDescription; +} + +function CoreDescriptor ({ className, value: { core, info } }: Props): React.ReactElement { + let sanitized: PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor[] = []; + + if (Array.isArray(info)) { + sanitized = info; + } else if (info) { + sanitized.push(info); + } + + return ( + <> + + {sanitized?.map((i) => ( + + + + )) + } + {sanitized?.map((i) => ( + + + + ))} + + + ); +} + +const StyledTr = styled.tr` + .shortHash { + max-width: var(--width-shorthash); + min-width: 3em; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: var(--width-shorthash); + } +`; + +export default React.memo(CoreDescriptor); diff --git a/packages/page-coretime/src/Overview/CoreDescriptors.tsx b/packages/page-coretime/src/Overview/CoreDescriptors.tsx new file mode 100644 index 000000000000..2e63e28186cd --- /dev/null +++ b/packages/page-coretime/src/Overview/CoreDescriptors.tsx @@ -0,0 +1,67 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { CoreDescription } from '@polkadot/react-hooks/types'; + +import React, { useMemo } from 'react'; + +import { ExpandButton, Table } from '@polkadot/react-components'; +import { useToggle } from '@polkadot/react-hooks'; + +import { useTranslation } from '../translate.js'; +import CoreDescriptor from './CoreDescriptor.js'; + +interface Props { + className?: string; + coreInfos?: CoreDescription; +} + +function CoreDescriptors ({ className, coreInfos }: Props): React.ReactElement { + const { t } = useTranslation(); + const [isExpanded, toggleExpanded] = useToggle(); + + const [headerButton, headerChildren] = useMemo( + () => [ + false && coreInfos && ( + + ), + isExpanded && coreInfos && ( + + + + ) + ], + [isExpanded, toggleExpanded, coreInfos] + ); + + const [header, key] = useMemo( + (): [([React.ReactNode?, string?, number?] | null)[], string] => [ + [ + [<>{t('core')}
{coreInfos?.core}
, 'start', 8], + null && [headerButton] + ], + 'core' + ], + [headerButton, t, coreInfos] + ); + + return ( + + {coreInfos && } +
+ ); +} + +export default React.memo(CoreDescriptors); diff --git a/packages/page-coretime/src/Overview/CoreQueue.tsx b/packages/page-coretime/src/Overview/CoreQueue.tsx new file mode 100644 index 000000000000..f2f4567a9b2e --- /dev/null +++ b/packages/page-coretime/src/Overview/CoreQueue.tsx @@ -0,0 +1,41 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor } from '@polkadot/types/lookup'; + +import React, { useRef } from 'react'; + +import { Table } from '@polkadot/react-components'; + +interface Props { + value?: PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor; +} + +function CoreQueue ({ value }: Props): React.ReactElement { + const headerRef = useRef<([React.ReactNode?, string?] | false)[]>([ + ['work queue'] + ]); + + return ( + + {value + ? + + + + : + + } +
+
{'first'}
+ {value?.first.toString()} +
+
{'last'}
+ {value?.last.toString()} +
+
{'No work queue found'}
+
+ ); +} + +export default React.memo(CoreQueue); diff --git a/packages/page-coretime/src/Overview/CurrentWork.tsx b/packages/page-coretime/src/Overview/CurrentWork.tsx new file mode 100644 index 000000000000..6465a6dc7d82 --- /dev/null +++ b/packages/page-coretime/src/Overview/CurrentWork.tsx @@ -0,0 +1,62 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { PolkadotRuntimeParachainsAssignerCoretimeWorkState } from '@polkadot/types/lookup'; + +import React, { useEffect, useRef, useState } from 'react'; + +import { Table } from '@polkadot/react-components'; + +interface Props { + value?: PolkadotRuntimeParachainsAssignerCoretimeWorkState; +} + +function createAssignments (value?: PolkadotRuntimeParachainsAssignerCoretimeWorkState): string { + if (value) { + if (value.assignments.length > 1) { + return value.assignments.map((_, index) => { + const ratio = value.assignments[index][1].ratio.toNumber() / 57600 * 100; + + if (value.assignments[index][0].isIdle) { + return `${ratio}% Idle`; + } else if (value.assignments[index][0].isPool) { + return `${ratio}% Pool`; + } else { + return `${ratio}% Task: ${value.assignments[index][0].asTask.toString()}`; + } + }).join(', '); + } else { + if (value.assignments[0][0].isIdle) { + return '100% Idle'; + } else if (value.assignments[0][0].isPool) { + return '100% Pool'; + } else { + return `100% Task: ${value.assignments[0][0].asTask.toString()}`; + } + } + } else { + return 'Queue empty'; + } +} + +function CurrentWork ({ value }: Props): React.ReactElement { + const [assignments, setAssignments] = useState(''); + + useEffect(() => { + setAssignments(createAssignments(value)); + }, [value]); + + const headerRef = useRef<([React.ReactNode?, string?] | false)[]>([ + ['current work'] + ]); + + return ( + + + + +
{assignments}
+ ); +} + +export default React.memo(CurrentWork); diff --git a/packages/page-coretime/src/Overview/QueueStatus.tsx b/packages/page-coretime/src/Overview/QueueStatus.tsx new file mode 100644 index 000000000000..16dad860c2fc --- /dev/null +++ b/packages/page-coretime/src/Overview/QueueStatus.tsx @@ -0,0 +1,35 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { OnDemandQueueStatus } from '@polkadot/react-hooks/types'; + +import React from 'react'; + +import { FormatBalance } from '@polkadot/react-query'; + +interface Props { + className?: string; + value?: OnDemandQueueStatus; + query: string; +} + +function QueueStatus ({ className, query, value }: Props): React.ReactElement { + return ( + <> + {value && query === 'traffic' + ?
+ +
+ : value && +
+ {value?.nextIndex.toString()} +
} + + ); +} + +export default React.memo(QueueStatus); diff --git a/packages/page-coretime/src/Overview/Summary.tsx b/packages/page-coretime/src/Overview/Summary.tsx new file mode 100644 index 000000000000..de1274dd9539 --- /dev/null +++ b/packages/page-coretime/src/Overview/Summary.tsx @@ -0,0 +1,66 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { BrokerStatus, CoreDescription, PalletBrokerConfigRecord, PalletBrokerSaleInfoRecord, RegionInfo } from '@polkadot/react-hooks/types'; + +import React from 'react'; +import { BN } from '@polkadot/util'; + +import { CardSummary, SummaryBox } from '@polkadot/react-components'; + +import { useTranslation } from '../translate.js'; +import { estimateTime } from '../utils.js'; + +interface Props { + coreDscriptors?: CoreDescription[]; + saleInfo: any + config: PalletBrokerConfigRecord, + region: RegionInfo, + status: BrokerStatus, + parachainCount: number +} + +function Summary({ status, region, saleInfo, config, parachainCount }: Props): React.ReactElement { + const { t } = useTranslation(); + console.log('saleInfo ', saleInfo) + const currentRegionEnd = saleInfo.regionEnd - config.regionLength + return ( + +
+ <> + + {status?.lastTimeslice} + + + {`${saleInfo?.coresSold} / ${saleInfo?.coresOffered}`} + + + {/* + {leasePeriod + ? formatNumber(leasePeriod.currentPeriod) + : 99} + */} + + {parachainCount && parachainCount} + + {status && +
+ {estimateTime(currentRegionEnd, status?.lastTimeslice * 80)} +
+
} + {config && status && } +
+
+ ); +} + +export default React.memo(Summary); diff --git a/packages/page-coretime/src/Overview/index.tsx b/packages/page-coretime/src/Overview/index.tsx new file mode 100644 index 000000000000..e88106b0414a --- /dev/null +++ b/packages/page-coretime/src/Overview/index.tsx @@ -0,0 +1,31 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { CoreDescription } from '@polkadot/react-hooks/types'; + +import React from 'react'; + +import CoreDescriptors from './CoreDescriptors.js'; +import Summary from './Summary.js'; + +interface Props { + className?: string; + coreInfos?: CoreDescription[]; +} + +function Overview({ className, coreInfos }: Props): React.ReactElement { + + return ( +
+ + + +
+ ); +} + +export default React.memo(Overview); diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx new file mode 100644 index 000000000000..87b56dede766 --- /dev/null +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -0,0 +1,92 @@ +// Copyright 2017-2024 @polkadot/app-broker authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import React, { useRef } from 'react'; + +import { ParaLink, Table, Tag } from '@polkadot/react-components'; +import { useTranslation } from './translate.js'; +import { BN } from '@polkadot/util'; +import { useApi, useCoreDescriptor } from '@polkadot/react-hooks'; +import { estimateTime } from './utils.js'; +import { CoretimeInformation } from '@polkadot/react-hooks/types'; +import { FlagColor } from '@polkadot/react-components/types'; +import { formatBalance } from '@polkadot/util'; +import { formatNumber } from 'chart.js/helpers'; + + +export enum CoreTimeTypes { + 'Reservation', + 'Lease', + 'Bulk Coretime', + 'On Demand' +} + +interface Props { + ids: number[] + coretimeInfo: CoretimeInformation +} + +const colours: Record = { + [CoreTimeTypes.Reservation]: 'orange', + [CoreTimeTypes.Lease]: 'blue', + [CoreTimeTypes['Bulk Coretime']]: 'pink', +} + + +function ParachainsTable({ ids, coretimeInfo }: Props): React.ReactElement { + const { api, isApiReady } = useApi(); + const coreInfos = useCoreDescriptor(api, isApiReady); + const { t } = useTranslation(); + const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([ + [t('parachains'), 'start'], + [t('name'), 'start'], + // ['', 'media--1400'], + [t('core number'), 'start'], + [t('type'), 'start'], + [t('last block'), 'start'], + [t('end'), 'start'], + [t('renewal'), 'start'], + [t('renewal price'), 'start'], + // [t('chain'), 'no-pad-left'], + // [t('in/out'), 'media--1700', 2], + // [t('leases'), 'media--1100'] + ]); + return ( + + {ids && coretimeInfo && ids.map((id: number) => { + const chain = coretimeInfo.chainInfo[id] + const onCore = coreInfos?.some(one => one.info?.currentWork.assignments.some(value => value.task === id.toString())) ? 'yes' : 'no'; + const type = !!chain?.lease ? CoreTimeTypes.Lease : !!chain?.reservation ? CoreTimeTypes.Reservation : CoreTimeTypes['Bulk Coretime'] + const targetTimeslice = chain?.lease?.until || coretimeInfo.salesInfo.regionEnd + const showEsimates = !!targetTimeslice && type !== CoreTimeTypes.Reservation + // const renewBefore = + + return ( + + + + + + + + + + + ) + } + )} + +
{id}{chain?.workload?.core || onCore} + + {showEsimates && formatNumber(targetTimeslice * 80).toString()}{showEsimates && estimateTime(targetTimeslice, coretimeInfo.status.lastCommittedTimeslice * 80)}{!!chain.renewal ? "renewed" : ""}{!!chain.renewal ? formatBalance(chain.renewal?.price.toString()) : ""}
+ ); +} + +export default React.memo(ParachainsTable); diff --git a/packages/page-coretime/src/index.tsx b/packages/page-coretime/src/index.tsx new file mode 100644 index 000000000000..472a4f38734f --- /dev/null +++ b/packages/page-coretime/src/index.tsx @@ -0,0 +1,73 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { TabItem } from '@polkadot/react-components/types'; + +import React, { useEffect, useRef, useState } from 'react'; + +import { Tabs } from '@polkadot/react-components'; +import { useApi, useCall, useCoretimeInformation } from '@polkadot/react-hooks'; + +import type { ParaId } from '@polkadot/types/interfaces'; + +import { useTranslation } from './translate.js'; +import ParachainsTable from './ParachainsTable.js'; +import Summary from './Overview/Summary.js'; + +interface Props { + basePath: string; + className?: string; +} + +function createItemsRef(t: (key: string, options?: { replace: Record }) => string): TabItem[] { + return [ + { + isRoot: true, + name: 'overview', + text: t('Overview') + } + ]; +} + +function CoretimeApp({ basePath, className }: Props): React.ReactElement { + const { t } = useTranslation(); + const { api, isApiReady } = useApi(); + const itemsRef = useRef(createItemsRef(t)); + const [parachainIds, setParachainIds] = useState([]) + const coretimeInfo = useCoretimeInformation(api, isApiReady) + + const paraIds = useCall(api.query.paras.parachains); + useEffect(() => { + if (!!paraIds) { + setParachainIds(paraIds.map(a => a.toNumber())) + } + }, [paraIds]) + + return ( +
+ + {coretimeInfo?.salesInfo && ( + + )} + + {!!parachainIds && + + } + +
+ ); +} + +export default React.memo(CoretimeApp); diff --git a/packages/page-coretime/src/translate.ts b/packages/page-coretime/src/translate.ts new file mode 100644 index 000000000000..125dda4ab07d --- /dev/null +++ b/packages/page-coretime/src/translate.ts @@ -0,0 +1,8 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import { useTranslation as useTranslationBase } from 'react-i18next'; + +export function useTranslation (): { t: (key: string, options?: { replace: Record }) => string } { + return useTranslationBase('app-coretime'); +} diff --git a/packages/page-coretime/src/utils.ts b/packages/page-coretime/src/utils.ts new file mode 100644 index 000000000000..9b60af4ddd83 --- /dev/null +++ b/packages/page-coretime/src/utils.ts @@ -0,0 +1,54 @@ +import { BN } from '@polkadot/util'; + +export const CoreTimeConsts = { + BlockTime: 6000, + BlocksPerTimeslice: 80, + DefaultRegion: 5040, + }; + +function formatDate (date: Date) { + const day = date.getDate(); + const month = date.toLocaleString('default', { month: 'short' }); + const year = date.getFullYear(); + + return `${day} ${month} ${year}`; +} + +/** + * blockTime = 6000 ms + * BlocksPerTimeslice = 80 + * Default Regoin = 5040 timeslices + * TargetBlock = TargetTimeslice * BlocksPerTimeslice + * Block Time Difference = |TargetBlock - latest Block| * blockTime + * + * Estimate timestamp = + * if targetBlock is before the latestBlock + * now minus block time difference + * else + * now plus block time difference + */ +export const estimateTime = (targetTimeslice: string | number, latestBlock: number): string | null => { + if (!latestBlock || !targetTimeslice) { + console.error('Invalid input: one or more inputs are missing'); + + return null; + } + + const now = new Date().getTime(); + + try { + const blockTime = new BN(CoreTimeConsts.BlockTime); // Average block time in milliseconds (6 seconds) + const timeSlice = new BN(CoreTimeConsts.BlocksPerTimeslice); + const latestBlockBN = new BN(latestBlock); + const timestampBN = new BN(now); + const targetBlockBN = new BN(targetTimeslice).mul(timeSlice); + const blockTimeDifference = targetBlockBN.sub(latestBlockBN).mul(blockTime); + const estTimestamp = timestampBN.add(blockTimeDifference); + + return formatDate(new Date(estTimestamp.toNumber())); + } catch (error) { + console.error('Error in calculation:', error); + + return null; + } + }; \ No newline at end of file diff --git a/packages/page-coretime/tsconfig.build.json b/packages/page-coretime/tsconfig.build.json new file mode 100644 index 000000000000..0292e5e4c9fe --- /dev/null +++ b/packages/page-coretime/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": "..", + "outDir": "./build", + "rootDir": "./src" + }, + "references": [ + { "path": "../react-api/tsconfig.xref.json" }, + { "path": "../react-hooks/tsconfig.build.json" }, + { "path": "../react-components/tsconfig.build.json" } + ] +} diff --git a/packages/react-hooks/src/index.ts b/packages/react-hooks/src/index.ts index 192e2a2cbd4b..7002cdc0a452 100644 --- a/packages/react-hooks/src/index.ts +++ b/packages/react-hooks/src/index.ts @@ -69,7 +69,7 @@ export { useIsParasLinked, useParaEndpoints } from './useParaEndpoints.js'; export { usePassword } from './usePassword.js'; export { usePeopleEndpoint } from './usePeopleEndpoint.js'; export { useCoretimeEndpoint } from './useCoretimeEndpoint.js' -// export { useCoretimeInformation } from './useCoretimeInformation.js' +export { useCoretimeInformation } from './useCoretimeInformation.js' export { usePopupWindow } from './usePopupWindow.js'; export { usePreimage } from './usePreimage.js'; export { useProxies } from './useProxies.js'; diff --git a/packages/react-hooks/src/types.ts b/packages/react-hooks/src/types.ts index ad387f2fa9ef..b5ee50d6a8b2 100644 --- a/packages/react-hooks/src/types.ts +++ b/packages/react-hooks/src/types.ts @@ -13,6 +13,7 @@ import type { ICompact, IExtrinsic, INumber } from '@polkadot/types/types'; import type { KeyringJson$Meta } from '@polkadot/ui-keyring/types'; import type { BN } from '@polkadot/util'; import type { HexString } from '@polkadot/util/types'; +import type { ParaId } from '@polkadot/types/interfaces'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type CallParam = any; @@ -220,6 +221,28 @@ export interface CoreDescription { info: PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor[]; } +export interface CoreDescriptorAssignment { + task: string, + ratio: number, + remaining: number +} + +export interface CoreDescriptor { + core: number, + info: { + currentWork: { + assignments: Array, + endHint: BN | null, + pos: number, + step: number + }, + queue: { + first: BN, + last: BN + } + } +} + export interface OnDemandQueueStatus { traffic: u128; nextIndex: u32; @@ -297,3 +320,36 @@ export interface PalletBrokerConfigRecord { renewalBump: BN; contributionTimeout: number; } + +export interface CoretimeInformation { + chainInfo: Record, + salesInfo: PalletBrokerSaleInfoRecord, + status: BrokerStatus, + region: RegionInfo[], + config: PalletBrokerConfigRecord +} + +export interface BrokerStatus { + coreCount: number; + privatePoolSize: number; + systemPoolSize: number; + lastCommittedTimeslice: number; + lastTimeslice: number; +} + +export interface PotentialRenewal { + core: number, + when: number, + price: BN, + completion: 'Complete' | 'Partial', + mask: string[] + maskBits: number, + task: string +} \ No newline at end of file diff --git a/packages/react-hooks/src/useBrokerConfig.ts b/packages/react-hooks/src/useBrokerConfig.ts index 53358ba85423..98e73129166d 100644 --- a/packages/react-hooks/src/useBrokerConfig.ts +++ b/packages/react-hooks/src/useBrokerConfig.ts @@ -8,7 +8,7 @@ import type { PalletBrokerConfigRecord as SimplifiedPalletBrokerConfigRecord } f import type { ApiPromise } from '@polkadot/api' import { useEffect, useState } from 'react'; -import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks'; +import { createNamedHook, useCall } from '@polkadot/react-hooks'; function extractInfo (config: Option): SimplifiedPalletBrokerConfigRecord { const c = config.unwrap(); diff --git a/packages/react-hooks/src/useBrokerPotentialRenewals.ts b/packages/react-hooks/src/useBrokerPotentialRenewals.ts new file mode 100644 index 000000000000..846406c2745e --- /dev/null +++ b/packages/react-hooks/src/useBrokerPotentialRenewals.ts @@ -0,0 +1,64 @@ +// Copyright 2017-2024 @polkadot/react-hooks authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { ApiPromise } from '@polkadot/api'; +import type { StorageKey, u32, Option} from '@polkadot/types'; +import type { PalletBrokerPotentialRenewalRecord, PalletBrokerPotentialRenewalId } from '@polkadot/types/lookup'; +import { useEffect, useState } from 'react'; + +import { createNamedHook, useCall, useMapKeys } from '@polkadot/react-hooks'; +import { processHexMask } from './utils/dataProcessing.js'; +import { PotentialRenewal } from './types.js'; + +function extractInfo(info: Option, item: PalletBrokerPotentialRenewalId ): PotentialRenewal { + + const unwrapped: PalletBrokerPotentialRenewalRecord | null = info.isSome ? info.unwrap() : null + let mask = [] + let task = null + const completion = unwrapped?.completion + if (completion?.isComplete ) { + const complete = completion?.asComplete[0] + task = complete.assignment.isTask ? complete?.assignment.asTask.toString() : complete?.assignment.isPool ? 'Pool' : 'Idle' + mask = processHexMask(complete.mask); + } else if (completion?.isPartial) { + task = null + mask = completion.asPartial[0] + } else { + mask = [] + } + + return { + core: item?.core.toNumber(), + when: item?.when.toNumber(), + price: unwrapped?.price.toBn(), + // How much of a core has been assigned or, if completely assigned, the workload itself. + completion: completion?.type, + mask, + maskBits: mask?.length, + task + }; +} + +const OPT_KEY = { + transform: (keys: StorageKey<[u32]>[]): u32[] => + keys.map(({ args: [id] }) => id) +}; + +function useBrokerPotentialRenewalsImpl(api: ApiPromise, ready: boolean): any | undefined { + const keys = useMapKeys(ready && api.query.broker.potentialRenewals, [], OPT_KEY); + const potentialRenewals = useCall<[[PalletBrokerPotentialRenewalId[]], Option[]]>(ready && api.query.broker.potentialRenewals.multi, [keys], { withParams: true }); + + const [state, setState] = useState(); + console.log('potentialRenewals ', potentialRenewals) + + useEffect((): void => { + potentialRenewals && + setState(potentialRenewals[0][0].map((info, index) => extractInfo(potentialRenewals[1][index], info)) + ); + }, [potentialRenewals]); + + console.log(state) + return state; +} + +export const useBrokerPotentialRenewals = createNamedHook('useBrokerPotentialRenewals', useBrokerPotentialRenewalsImpl); diff --git a/packages/react-hooks/src/useBrokerSalesInfo.ts b/packages/react-hooks/src/useBrokerSalesInfo.ts index 92968a2c890a..5dde3b0f2fe5 100644 --- a/packages/react-hooks/src/useBrokerSalesInfo.ts +++ b/packages/react-hooks/src/useBrokerSalesInfo.ts @@ -8,7 +8,7 @@ import type { PalletBrokerSaleInfoRecord as SimplifiedPalletBrokerSaleInfoRecord import { useEffect, useState } from 'react'; -import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks'; +import { createNamedHook, useCall } from '@polkadot/react-hooks'; import { BN } from '@polkadot/util'; function extractInfo (record: Option): SimplifiedPalletBrokerSaleInfoRecord { diff --git a/packages/react-hooks/src/useBrokerStatus.ts b/packages/react-hooks/src/useBrokerStatus.ts index 7b49c1c15dfe..0225a8d1e785 100644 --- a/packages/react-hooks/src/useBrokerStatus.ts +++ b/packages/react-hooks/src/useBrokerStatus.ts @@ -6,23 +6,28 @@ import type { PalletBrokerStatusRecord } from '@polkadot/types/lookup'; import type { ApiPromise } from '@polkadot/api' import { useEffect, useState } from 'react'; -import { createNamedHook, useCall } from '@polkadot/react-hooks'; +import type { Option } from '@polkadot/types'; -function useBrokerStatusImpl (api: ApiPromise, ready: boolean, query?: string): any | undefined { - const status = useCall(ready && api.query.broker?.status); - const [state, setState] = useState(); +import { createNamedHook, useCall } from '@polkadot/react-hooks'; +import { BrokerStatus } from './types.js'; +function useBrokerStatusImpl(api: ApiPromise, ready: boolean): BrokerStatus | undefined { + const status = useCall>(ready && api.query.broker?.status); + const [state, setState] = useState(); useEffect((): void => { - status && - setState( - status - ); - }, [status]); + if (!!status && status.isSome) { + const s = status.unwrap() + setState({ + coreCount: s.coreCount?.toNumber(), + privatePoolSize: s.privatePoolSize?.toNumber(), + systemPoolSize: s.systemPoolSize?.toNumber(), + lastCommittedTimeslice: s.lastCommittedTimeslice?.toNumber(), + lastTimeslice: s.lastTimeslice?.toNumber() + }); + } - if (query) { - return state?.toJSON()?.[query]?.toString(); - } - return state?.toJSON(); + }, [status]); + return state; } export const useBrokerStatus = createNamedHook('useBrokerStatus', useBrokerStatusImpl); diff --git a/packages/react-hooks/src/useCoretimeInformation.ts b/packages/react-hooks/src/useCoretimeInformation.ts new file mode 100644 index 000000000000..3ba775a8c35a --- /dev/null +++ b/packages/react-hooks/src/useCoretimeInformation.ts @@ -0,0 +1,73 @@ +// Copyright 2017-2024 @polkadot/react-hooks authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { ApiPromise } from '@polkadot/api'; +import type { ParaId } from '@polkadot/types/interfaces'; + +import { useEffect, useMemo, useState } from 'react'; + +import { createNamedHook, useApi, useBrokerConfig, useBrokerLeases, useBrokerReservations, useBrokerSalesInfo, useBrokerStatus, useCall, useRegions, useWorkloadInfos, useWorkplanInfos } from '@polkadot/react-hooks'; +import { CoretimeInformation } from './types.js'; +import { useBrokerPotentialRenewals } from './useBrokerPotentialRenewals.js'; + + +function useCoretimeInformationImpl(api: ApiPromise, ready: boolean): CoretimeInformation | undefined { + + const { apiCoretime, isApiReady } = useApi(); + if (!apiCoretime || !apiCoretime?.query) { + return + } + const status = useBrokerStatus(apiCoretime, isApiReady) + const leases = useBrokerLeases(apiCoretime, ready) + const reservations = useBrokerReservations(apiCoretime, ready) + const salesInfo = useBrokerSalesInfo(apiCoretime, ready) + const paraIds = useCall(api.query.paras.parachains); + const workloads = useWorkloadInfos(apiCoretime, ready) + const workplans = useWorkplanInfos(apiCoretime, ready) + const config = useBrokerConfig(apiCoretime, ready) + const region = useRegions(apiCoretime) + const potentialRenewals = useBrokerPotentialRenewals(apiCoretime, ready) + + const potentialRenewalsCurrentRegion = useMemo(() => potentialRenewals?.filter(renewal => renewal.when === salesInfo?.regionEnd), [potentialRenewals]) + + console.log('potent ', potentialRenewals) + + const [state, setState] = useState(); + + console.log(potentialRenewals) + + useEffect((): void => { + if(!workloads?.length || !leases?.length || !reservations?.length) { + return + } + let chainInfo: Record = {}; + paraIds?.forEach((id: ParaId) => { + const lease = leases?.find( lease => lease.task === id.toString()) + const reservation = reservations?.find( reservation => reservation.task === id.toString()) + const workload = workloads?.find(one => one.info.task === id.toString()) + chainInfo[id.toString()] = { + id: id.toNumber(), + lease, + reservation, + workload, + renewal: potentialRenewalsCurrentRegion?.find(renewal => renewal.task.toString() === id.toString()), + renewed: workplans?.find(workplan => workplan.core === workload?.core && workplan.info.task.toString() === id.toString()) + } + + }) + + if (chainInfo) { + setState({ + chainInfo, + salesInfo, + status, + region, + config, + }) + } + }, [paraIds, workloads, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status]); + + return state; +} + +export const useCoretimeInformation = createNamedHook('useCoretimeInformation', useCoretimeInformationImpl); diff --git a/packages/react-hooks/src/useWorkloadInfos.ts b/packages/react-hooks/src/useWorkloadInfos.ts index 32dd71389e32..8473c1e695a8 100644 --- a/packages/react-hooks/src/useWorkloadInfos.ts +++ b/packages/react-hooks/src/useWorkloadInfos.ts @@ -34,7 +34,7 @@ function extractInfo (info: PalletBrokerScheduleItem[], core: number): CoreWorkl isTask: assignment.isTask, mask, maskBits: mask.length, - task: assignment.isTask ? assignment.asTask.toString() : assignment.isPool ? 'Pool' : '' + task: assignment.isTask ? assignment.asTask.toString() : assignment.isPool ? 'Pool' : 'Idle' } }; } diff --git a/packages/react-hooks/src/useWorkplanInfos.ts b/packages/react-hooks/src/useWorkplanInfos.ts index 13bd487facb6..f0084097fb03 100644 --- a/packages/react-hooks/src/useWorkplanInfos.ts +++ b/packages/react-hooks/src/useWorkplanInfos.ts @@ -34,7 +34,7 @@ function extractInfo (info: Vec, core: number, timesli isTask: assignment.isTask, mask, maskBits: mask.length, - task: assignment.isTask ? assignment.asTask.toString() : assignment.isPool ? 'Pool' : '' + task: assignment.isTask ? assignment.asTask.toString() : assignment.isPool ? 'Pool' : 'Idle' }, timeslice }; diff --git a/yarn.lock b/yarn.lock index 443aa7b31c5a..7b36267d0423 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1427,6 +1427,19 @@ __metadata: languageName: unknown linkType: soft +"@polkadot/app-coretime@workspace:packages/page-coretime": + version: 0.0.0-use.local + resolution: "@polkadot/app-coretime@workspace:packages/page-coretime" + dependencies: + "@polkadot/react-components": "npm:0.144.2-2-x" + "@polkadot/react-query": "npm:0.144.2-2-x" + peerDependencies: + react: "*" + react-dom: "*" + react-is: "*" + languageName: unknown + linkType: soft + "@polkadot/app-council@workspace:packages/page-council": version: 0.0.0-use.local resolution: "@polkadot/app-council@workspace:packages/page-council" From 92b52166eef4ec510bfcf2f3a7ca0b0258702629 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Wed, 9 Oct 2024 11:58:41 +0800 Subject: [PATCH 06/22] lint --- packages/apps-routing/src/coretime.ts | 4 +- packages/page-broker/src/Overview/Summary.tsx | 15 ++- .../src/Overview/Summary/Timeslice.tsx | 6 +- .../page-broker/src/Overview/WorkInfoRow.tsx | 44 +++++---- .../page-broker/src/Overview/Workload.tsx | 4 +- packages/page-broker/src/Overview/index.tsx | 2 +- packages/page-broker/src/utils.ts | 15 +-- packages/page-coretime/package.json | 6 +- .../page-coretime/src/Overview/Summary.tsx | 8 +- packages/page-coretime/src/Overview/index.tsx | 6 +- .../page-coretime/src/ParachainsTable.tsx | 47 ++++----- packages/page-coretime/src/index.tsx | 31 +++--- packages/page-coretime/src/utils.ts | 69 ++++++------- packages/react-api/src/Api.tsx | 24 ++--- packages/react-hooks/src/index.ts | 4 +- packages/react-hooks/src/types.ts | 7 +- packages/react-hooks/src/useBrokerConfig.ts | 3 +- .../src/useBrokerPotentialRenewals.ts | 37 +++---- .../react-hooks/src/useBrokerSalesInfo.ts | 2 +- packages/react-hooks/src/useBrokerStatus.ts | 15 +-- packages/react-hooks/src/useCoreDescriptor.ts | 48 +++++++--- .../react-hooks/src/useCoretimeEndpoint.ts | 2 +- .../react-hooks/src/useCoretimeInformation.ts | 96 +++++++++---------- packages/react-hooks/src/useQueueStatus.ts | 2 +- yarn.lock | 4 +- 25 files changed, 259 insertions(+), 242 deletions(-) diff --git a/packages/apps-routing/src/coretime.ts b/packages/apps-routing/src/coretime.ts index 2015c6000e67..a9c594fd5b59 100644 --- a/packages/apps-routing/src/coretime.ts +++ b/packages/apps-routing/src/coretime.ts @@ -10,7 +10,7 @@ export default function create (t: TFunction): Route { Component, display: { needsApi: [ - 'query.coretimeAssignmentProvider.coreDescriptors', + 'query.coretimeAssignmentProvider.coreDescriptors' ], needsApiInstances: true }, @@ -19,4 +19,4 @@ export default function create (t: TFunction): Route { name: 'coretime', text: t('nav.coretime', 'Coretime (Experimental)', { ns: 'app-coretime' }) }; -} \ No newline at end of file +} diff --git a/packages/page-broker/src/Overview/Summary.tsx b/packages/page-broker/src/Overview/Summary.tsx index a4514a1c1771..9ad87de73b00 100644 --- a/packages/page-broker/src/Overview/Summary.tsx +++ b/packages/page-broker/src/Overview/Summary.tsx @@ -3,15 +3,14 @@ import type { LinkOption } from '@polkadot/apps-config/endpoints/types'; import type { statsType } from '../types.js'; -import { BN } from '@polkadot/util'; import React, { useMemo } from 'react'; import { CardSummary, styled, SummaryBox, UsageBar } from '@polkadot/react-components'; import { defaultHighlight } from '@polkadot/react-components/styles'; import { useApi, useBrokerConfig, useBrokerSalesInfo, useBrokerStatus } from '@polkadot/react-hooks'; -import { PalletBrokerConfigRecord, type CoreWorkload } from '@polkadot/react-hooks/types'; -import { formatBalance } from '@polkadot/util'; +import { type CoreWorkload, PalletBrokerConfigRecord } from '@polkadot/react-hooks/types'; +import { BN, formatBalance } from '@polkadot/util'; import { useTranslation } from '../translate.js'; import { estimateTime, getStats } from '../utils.js'; @@ -40,16 +39,17 @@ interface Props { workloadInfos?: CoreWorkload[] } -function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { +function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { const { t } = useTranslation(); const { api, apiEndpoint, isApiReady } = useApi(); const uiHighlight = apiEndpoint?.ui.color || defaultHighlight; const { idles, pools, tasks }: statsType = React.useMemo(() => getStats(coreCount, workloadInfos), [coreCount, workloadInfos]); const saleInfo = useBrokerSalesInfo(api, isApiReady); - const config = useBrokerConfig(api, isApiReady) - const status = useBrokerStatus(api, isApiReady) - const currentRegionEnd = useMemo(() => saleInfo && config && saleInfo?.regionEnd - config?.regionLength, [saleInfo, config]) + const config = useBrokerConfig(api, isApiReady); + const status = useBrokerStatus(api, isApiReady); + const currentRegionEnd = useMemo(() => saleInfo && config && saleInfo?.regionEnd - config?.regionLength, [saleInfo, config]); + return ( @@ -97,7 +97,6 @@ function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { )} -
| null { - const { api, isApiReady } = useApi() +function Timeslice ({ children, className }: Props): React.ReactElement | null { + const { api, isApiReady } = useApi(); const info = useBrokerStatus(api, isApiReady); return (
{info?.lastTimeslice || '-'} {children} -
) +
); } export default React.memo(Timeslice); diff --git a/packages/page-broker/src/Overview/WorkInfoRow.tsx b/packages/page-broker/src/Overview/WorkInfoRow.tsx index 321a99ec346f..8f5a8786cc28 100644 --- a/packages/page-broker/src/Overview/WorkInfoRow.tsx +++ b/packages/page-broker/src/Overview/WorkInfoRow.tsx @@ -1,19 +1,20 @@ // Copyright 2017-2024 @polkadot/app-broker authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { FlagColor } from '@polkadot/react-components/types'; + import React from 'react'; -import { AddressMini, Tag, styled } from '@polkadot/react-components'; +import { AddressMini, styled, Tag } from '@polkadot/react-components'; -import { type InfoRow, CoreTimeTypes } from '../types.js'; -import { FlagColor } from '@polkadot/react-components/types'; +import { CoreTimeTypes, type InfoRow } from '../types.js'; const colours: Record = { [CoreTimeTypes.Reservation]: 'orange', [CoreTimeTypes.Lease]: 'blue', [CoreTimeTypes['Bulk Coretime']]: 'pink', - [CoreTimeTypes['On Demand']]: 'green', -} + [CoreTimeTypes['On Demand']]: 'green' +}; const StyledTableCol = styled.td<{ hide?: 'mobile' | 'tablet' | 'both' }>` width: 150px; @@ -33,17 +34,17 @@ const StyledTableCol = styled.td<{ hide?: 'mobile' | 'tablet' | 'both' }>` const TableCol = ({ header, hide, value }: { - header: string; - value: string | number | null | undefined; - hide?: 'mobile' | 'tablet' | 'both'; - }) => ( + header: string; + value: string | number | null | undefined; + hide?: 'mobile' | 'tablet' | 'both'; +}) => (
{header}

{value || <> }

); -function WorkInfoRow({ data }: { data: InfoRow }): React.ReactElement { +function WorkInfoRow ({ data }: { data: InfoRow }): React.ReactElement { if (!data.task) { return ( <> @@ -76,6 +77,7 @@ function WorkInfoRow({ data }: { data: InfoRow }): React.ReactElement { } case (CoreTimeTypes.Lease): + case (CoreTimeTypes['On Demand']): { return ( <> @@ -144,17 +146,17 @@ function WorkInfoRow({ data }: { data: InfoRow }): React.ReactElement { label={'Bulk Coretime'} /> - {data.owner ? -
{'Owner'}
- - - - -
: } + {data.owner + ? +
{'Owner'}
+ + +
+ : } ); } } diff --git a/packages/page-broker/src/Overview/Workload.tsx b/packages/page-broker/src/Overview/Workload.tsx index 053c76fcf936..cb1f8ecca41e 100644 --- a/packages/page-broker/src/Overview/Workload.tsx +++ b/packages/page-broker/src/Overview/Workload.tsx @@ -23,7 +23,7 @@ interface Props { workplan?: CoreWorkplanType[] | undefined } -function Workload({ api, core, workload, workplan }: Props): React.ReactElement { +function Workload ({ api, core, workload, workplan }: Props): React.ReactElement { const { isApiReady } = useApi(); const salesInfo = useBrokerSalesInfo(api, isApiReady); @@ -57,7 +57,7 @@ function Workload({ api, core, workload, workplan }: Props): React.ReactElement< setWorkplanData(formatRowInfo(workplan, core, region, currentTimeSlice, salesInfo)); } } - , [workplan, region, currentTimeSlice, core, salesInfo]); + , [workplan, region, currentTimeSlice, core, salesInfo]); const hasWorkplan = workplan?.length; diff --git a/packages/page-broker/src/Overview/index.tsx b/packages/page-broker/src/Overview/index.tsx index 0dd785f79a5e..a10d10db2998 100644 --- a/packages/page-broker/src/Overview/index.tsx +++ b/packages/page-broker/src/Overview/index.tsx @@ -51,7 +51,7 @@ const formatData = (coreCount: number, workplan: CoreWorkplan[], workload: CoreW }); }; -function Overview({ className }: Props): React.ReactElement { +function Overview ({ className }: Props): React.ReactElement { const { api, apiEndpoint, isApiReady } = useApi(); const [data, setData] = useState([]); diff --git a/packages/page-broker/src/utils.ts b/packages/page-broker/src/utils.ts index 0debf8d9a9ea..c2682ae8360f 100644 --- a/packages/page-broker/src/utils.ts +++ b/packages/page-broker/src/utils.ts @@ -62,14 +62,14 @@ export const estimateTime = (targetTimeslice: string | number, latestBlock: numb }; /** - * + * * @param data: CoreWorkloadType[] - * @param core: core number - * @param currentRegion - * @param timeslice - * @param param4 - * @param regionLength - * @returns + * @param core: core number + * @param currentRegion + * @param timeslice + * @param param4 + * @param regionLength + * @returns */ export function formatRowInfo (data: CoreWorkloadType[] | CoreWorkplanType[], core: number, currentRegion: RegionInfo | undefined, currentTimeSlice: number, { regionBegin, regionEnd }: { regionBegin: number, regionEnd: number }, regionLength = CoreTimeConsts.DefaultRegion): InfoRow[] { @@ -136,5 +136,6 @@ export const getOccupancyType = (lease: LegacyLease | undefined, reservation: Re if (isPool) { return CoreTimeTypes['On Demand']; } + return reservation ? CoreTimeTypes.Reservation : lease ? CoreTimeTypes.Lease : CoreTimeTypes['Bulk Coretime']; }; diff --git a/packages/page-coretime/package.json b/packages/page-coretime/package.json index c5d8d7392c04..7e253d4ddc34 100644 --- a/packages/page-coretime/package.json +++ b/packages/page-coretime/package.json @@ -14,10 +14,10 @@ }, "sideEffects": false, "type": "module", - "version": "0.144.2-2-x", + "version": "0.144.2-11-x", "dependencies": { - "@polkadot/react-components": "0.144.2-2-x", - "@polkadot/react-query": "0.144.2-2-x" + "@polkadot/react-components": "0.144.2-11-x", + "@polkadot/react-query": "0.144.2-11-x" }, "peerDependencies": { "react": "*", diff --git a/packages/page-coretime/src/Overview/Summary.tsx b/packages/page-coretime/src/Overview/Summary.tsx index de1274dd9539..7d606e72708c 100644 --- a/packages/page-coretime/src/Overview/Summary.tsx +++ b/packages/page-coretime/src/Overview/Summary.tsx @@ -4,9 +4,9 @@ import type { BrokerStatus, CoreDescription, PalletBrokerConfigRecord, PalletBrokerSaleInfoRecord, RegionInfo } from '@polkadot/react-hooks/types'; import React from 'react'; -import { BN } from '@polkadot/util'; import { CardSummary, SummaryBox } from '@polkadot/react-components'; +import { BN } from '@polkadot/util'; import { useTranslation } from '../translate.js'; import { estimateTime } from '../utils.js'; @@ -20,10 +20,10 @@ interface Props { parachainCount: number } -function Summary({ status, region, saleInfo, config, parachainCount }: Props): React.ReactElement { +function Summary({ config, parachainCount, region, saleInfo, status }: Props): React.ReactElement { const { t } = useTranslation(); - console.log('saleInfo ', saleInfo) - const currentRegionEnd = saleInfo.regionEnd - config.regionLength + const currentRegionEnd = saleInfo.regionEnd - config.regionLength; + return (
diff --git a/packages/page-coretime/src/Overview/index.tsx b/packages/page-coretime/src/Overview/index.tsx index e88106b0414a..01427c96555b 100644 --- a/packages/page-coretime/src/Overview/index.tsx +++ b/packages/page-coretime/src/Overview/index.tsx @@ -13,17 +13,15 @@ interface Props { coreInfos?: CoreDescription[]; } -function Overview({ className, coreInfos }: Props): React.ReactElement { - +function Overview ({ className, coreInfos }: Props): React.ReactElement { return (
-
); } diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx index 87b56dede766..809baf1cf3c9 100644 --- a/packages/page-coretime/src/ParachainsTable.tsx +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -1,18 +1,18 @@ // Copyright 2017-2024 @polkadot/app-broker authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { FlagColor } from '@polkadot/react-components/types'; +import type { CoretimeInformation } from '@polkadot/react-hooks/types'; + +import { formatNumber } from 'chart.js/helpers'; import React, { useRef } from 'react'; import { ParaLink, Table, Tag } from '@polkadot/react-components'; -import { useTranslation } from './translate.js'; -import { BN } from '@polkadot/util'; import { useApi, useCoreDescriptor } from '@polkadot/react-hooks'; -import { estimateTime } from './utils.js'; -import { CoretimeInformation } from '@polkadot/react-hooks/types'; -import { FlagColor } from '@polkadot/react-components/types'; -import { formatBalance } from '@polkadot/util'; -import { formatNumber } from 'chart.js/helpers'; +import { BN, formatBalance } from '@polkadot/util'; +import { useTranslation } from './translate.js'; +import { estimateTime } from './utils.js'; export enum CoreTimeTypes { 'Reservation', @@ -29,11 +29,10 @@ interface Props { const colours: Record = { [CoreTimeTypes.Reservation]: 'orange', [CoreTimeTypes.Lease]: 'blue', - [CoreTimeTypes['Bulk Coretime']]: 'pink', -} + [CoreTimeTypes['Bulk Coretime']]: 'pink' +}; - -function ParachainsTable({ ids, coretimeInfo }: Props): React.ReactElement { +function ParachainsTable ({ coretimeInfo, ids }: Props): React.ReactElement { const { api, isApiReady } = useApi(); const coreInfos = useCoreDescriptor(api, isApiReady); const { t } = useTranslation(); @@ -46,11 +45,12 @@ function ParachainsTable({ ids, coretimeInfo }: Props): React.ReactElement {ids && coretimeInfo && ids.map((id: number) => { - const chain = coretimeInfo.chainInfo[id] - const onCore = coreInfos?.some(one => one.info?.currentWork.assignments.some(value => value.task === id.toString())) ? 'yes' : 'no'; - const type = !!chain?.lease ? CoreTimeTypes.Lease : !!chain?.reservation ? CoreTimeTypes.Reservation : CoreTimeTypes['Bulk Coretime'] - const targetTimeslice = chain?.lease?.until || coretimeInfo.salesInfo.regionEnd - const showEsimates = !!targetTimeslice && type !== CoreTimeTypes.Reservation - // const renewBefore = + const chain = coretimeInfo.chainInfo[id]; + const onCore = coreInfos?.some((one) => one.info?.currentWork.assignments.some((value) => value.task === id.toString())) ? 'yes' : 'no'; + const type = chain?.lease ? CoreTimeTypes.Lease : chain?.reservation ? CoreTimeTypes.Reservation : CoreTimeTypes['Bulk Coretime']; + const targetTimeslice = chain?.lease?.until || coretimeInfo.salesInfo.regionEnd; + const showEsimates = !!targetTimeslice && type !== CoreTimeTypes.Reservation; + // const renewBefore = return ( {id} - + {chain?.workload?.core || onCore} {showEsimates && formatNumber(targetTimeslice * 80).toString()} {showEsimates && estimateTime(targetTimeslice, coretimeInfo.status.lastCommittedTimeslice * 80)} - {!!chain.renewal ? "renewed" : ""} - {!!chain.renewal ? formatBalance(chain.renewal?.price.toString()) : ""} + {chain.renewal ? 'renewed' : ''} + {chain.renewal ? formatBalance(chain.renewal?.price.toString()) : ''} - ) + ); } )} diff --git a/packages/page-coretime/src/index.tsx b/packages/page-coretime/src/index.tsx index 472a4f38734f..89afa520aa24 100644 --- a/packages/page-coretime/src/index.tsx +++ b/packages/page-coretime/src/index.tsx @@ -2,24 +2,23 @@ // SPDX-License-Identifier: Apache-2.0 import type { TabItem } from '@polkadot/react-components/types'; +import type { ParaId } from '@polkadot/types/interfaces'; import React, { useEffect, useRef, useState } from 'react'; import { Tabs } from '@polkadot/react-components'; import { useApi, useCall, useCoretimeInformation } from '@polkadot/react-hooks'; -import type { ParaId } from '@polkadot/types/interfaces'; - -import { useTranslation } from './translate.js'; -import ParachainsTable from './ParachainsTable.js'; import Summary from './Overview/Summary.js'; +import ParachainsTable from './ParachainsTable.js'; +import { useTranslation } from './translate.js'; interface Props { basePath: string; className?: string; } -function createItemsRef(t: (key: string, options?: { replace: Record }) => string): TabItem[] { +function createItemsRef (t: (key: string, options?: { replace: Record }) => string): TabItem[] { return [ { isRoot: true, @@ -29,19 +28,20 @@ function createItemsRef(t: (key: string, options?: { replace: Record { +function CoretimeApp ({ basePath, className }: Props): React.ReactElement { const { t } = useTranslation(); const { api, isApiReady } = useApi(); const itemsRef = useRef(createItemsRef(t)); - const [parachainIds, setParachainIds] = useState([]) - const coretimeInfo = useCoretimeInformation(api, isApiReady) + const [parachainIds, setParachainIds] = useState([]); + const coretimeInfo = useCoretimeInformation(api, isApiReady); const paraIds = useCall(api.query.paras.parachains); + useEffect(() => { - if (!!paraIds) { - setParachainIds(paraIds.map(a => a.toNumber())) + if (paraIds) { + setParachainIds(paraIds.map((a) => a.toNumber())); } - }, [paraIds]) + }, [paraIds]); return (
@@ -51,18 +51,17 @@ function CoretimeApp({ basePath, className }: Props): React.ReactElement /> {coretimeInfo?.salesInfo && ( )} - {!!parachainIds && } diff --git a/packages/page-coretime/src/utils.ts b/packages/page-coretime/src/utils.ts index 9b60af4ddd83..9326c12a3770 100644 --- a/packages/page-coretime/src/utils.ts +++ b/packages/page-coretime/src/utils.ts @@ -1,17 +1,20 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + import { BN } from '@polkadot/util'; export const CoreTimeConsts = { - BlockTime: 6000, - BlocksPerTimeslice: 80, - DefaultRegion: 5040, - }; - + BlockTime: 6000, + BlocksPerTimeslice: 80, + DefaultRegion: 5040 +}; + function formatDate (date: Date) { - const day = date.getDate(); - const month = date.toLocaleString('default', { month: 'short' }); - const year = date.getFullYear(); + const day = date.getDate(); + const month = date.toLocaleString('default', { month: 'short' }); + const year = date.getFullYear(); - return `${day} ${month} ${year}`; + return `${day} ${month} ${year}`; } /** @@ -28,27 +31,27 @@ function formatDate (date: Date) { * now plus block time difference */ export const estimateTime = (targetTimeslice: string | number, latestBlock: number): string | null => { - if (!latestBlock || !targetTimeslice) { - console.error('Invalid input: one or more inputs are missing'); - - return null; - } - - const now = new Date().getTime(); - - try { - const blockTime = new BN(CoreTimeConsts.BlockTime); // Average block time in milliseconds (6 seconds) - const timeSlice = new BN(CoreTimeConsts.BlocksPerTimeslice); - const latestBlockBN = new BN(latestBlock); - const timestampBN = new BN(now); - const targetBlockBN = new BN(targetTimeslice).mul(timeSlice); - const blockTimeDifference = targetBlockBN.sub(latestBlockBN).mul(blockTime); - const estTimestamp = timestampBN.add(blockTimeDifference); - - return formatDate(new Date(estTimestamp.toNumber())); - } catch (error) { - console.error('Error in calculation:', error); - - return null; - } - }; \ No newline at end of file + if (!latestBlock || !targetTimeslice) { + console.error('Invalid input: one or more inputs are missing'); + + return null; + } + + const now = new Date().getTime(); + + try { + const blockTime = new BN(CoreTimeConsts.BlockTime); // Average block time in milliseconds (6 seconds) + const timeSlice = new BN(CoreTimeConsts.BlocksPerTimeslice); + const latestBlockBN = new BN(latestBlock); + const timestampBN = new BN(now); + const targetBlockBN = new BN(targetTimeslice).mul(timeSlice); + const blockTimeDifference = targetBlockBN.sub(latestBlockBN).mul(blockTime); + const estTimestamp = timestampBN.add(blockTimeDifference); + + return formatDate(new Date(estTimestamp.toNumber())); + } catch (error) { + console.error('Error in calculation:', error); + + return null; + } +}; diff --git a/packages/react-api/src/Api.tsx b/packages/react-api/src/Api.tsx index 81446f8ad8b1..8b1009d77783 100644 --- a/packages/react-api/src/Api.tsx +++ b/packages/react-api/src/Api.tsx @@ -18,7 +18,7 @@ import { deriveMapCache, setDeriveCache } from '@polkadot/api-derive/util'; import { ethereumChains, typesBundle } from '@polkadot/apps-config'; import { web3Accounts, web3Enable } from '@polkadot/extension-dapp'; import { TokenUnit } from '@polkadot/react-components/InputConsts/units'; -import { useApiUrl, useEndpoint, usePeopleEndpoint, useQueue, useCoretimeEndpoint } from '@polkadot/react-hooks'; +import { useApiUrl, useCoretimeEndpoint, useEndpoint, usePeopleEndpoint, useQueue } from '@polkadot/react-hooks'; import { ApiCtx } from '@polkadot/react-hooks/ctx/Api'; import { ApiSigner } from '@polkadot/react-signer/signers'; import { keyring } from '@polkadot/ui-keyring'; @@ -58,7 +58,7 @@ export const DEFAULT_AUX = ['Aux1', 'Aux2', 'Aux3', 'Aux4', 'Aux5', 'Aux6', 'Aux const DISALLOW_EXTENSIONS: string[] = []; const EMPTY_STATE = { hasInjectedAccounts: false, isApiReady: false } as unknown as ApiState; -function isKeyringLoaded() { +function isKeyringLoaded () { try { return !!keyring.keyring; } catch { @@ -66,7 +66,7 @@ function isKeyringLoaded() { } } -function getDevTypes(): Record> { +function getDevTypes (): Record> { const types = decodeUrlTypes() || store.get('types', {}) as Record>; const names = Object.keys(types); @@ -75,7 +75,7 @@ function getDevTypes(): Record> { return types; } -async function getInjectedAccounts(injectedPromise: Promise): Promise { +async function getInjectedAccounts (injectedPromise: Promise): Promise { try { await injectedPromise; @@ -95,7 +95,7 @@ async function getInjectedAccounts(injectedPromise: Promise } } -function makeCreateLink(baseApiUrl: string, isElectron: boolean): (path: string) => string { +function makeCreateLink (baseApiUrl: string, isElectron: boolean): (path: string) => string { return (path: string, apiUrl?: string): string => `${isElectron ? 'https://polkadot.js.org/apps/' @@ -103,7 +103,7 @@ function makeCreateLink(baseApiUrl: string, isElectron: boolean): (path: string) }?rpc=${encodeURIComponent(apiUrl || baseApiUrl)}#${path}`; } -async function retrieve(api: ApiPromise, injectedPromise: Promise): Promise { +async function retrieve (api: ApiPromise, injectedPromise: Promise): Promise { const [systemChain, systemChainType, systemName, systemVersion, injectedAccounts] = await Promise.all([ api.rpc.system.chain(), api.rpc.system.chainType @@ -131,7 +131,7 @@ async function retrieve(api: ApiPromise, injectedPromise: Promise, store: KeyringStore | undefined, types: Record>, urlIsEthereum = false): Promise { +async function loadOnReady (api: ApiPromise, endpoint: LinkOption | null, fork: Blockchain | null, injectedPromise: Promise, store: KeyringStore | undefined, types: Record>, urlIsEthereum = false): Promise { statics.registry.register(types); const { injectedAccounts, properties, systemChain, systemChainType, systemName, systemVersion } = await retrieve(api, injectedPromise); @@ -203,7 +203,7 @@ async function loadOnReady(api: ApiPromise, endpoint: LinkOption | null, fork: B * @internal * Creates a ScProvider from a [/parachain] string */ -async function getLightProvider(chain: string): Promise { +async function getLightProvider (chain: string): Promise { const [sc, relayName, paraName] = chain.split('/'); if (sc !== 'substrate-connect') { @@ -228,7 +228,7 @@ async function getLightProvider(chain: string): Promise { /** * @internal */ -async function createApi(apiUrl: string, signer: ApiSigner, isLocalFork: boolean, onError: (error: unknown) => void): Promise { +async function createApi (apiUrl: string, signer: ApiSigner, isLocalFork: boolean, onError: (error: unknown) => void): Promise { const types = getDevTypes(); const isLight = apiUrl.startsWith('light://'); let provider; @@ -287,7 +287,7 @@ async function createApi(apiUrl: string, signer: ApiSigner, isLocalFork: boolean return { fork: chopsticksFork, types }; } -export function ApiCtxRoot({ apiUrl, children, isElectron, store: keyringStore }: Props): React.ReactElement | null { +export function ApiCtxRoot ({ apiUrl, children, isElectron, store: keyringStore }: Props): React.ReactElement | null { const { queuePayload, queueSetTxStatus } = useQueue(); const [state, setState] = useState(EMPTY_STATE); const [isApiConnected, setIsApiConnected] = useState(false); @@ -297,7 +297,7 @@ export function ApiCtxRoot({ apiUrl, children, isElectron, store: keyringStore } const [isLocalFork] = useState(store.get('localFork') === apiUrl); const apiEndpoint = useEndpoint(apiUrl); const peopleEndpoint = usePeopleEndpoint(apiEndpoint?.relayName || apiEndpoint?.info); - const coreTimeEndpoint = useCoretimeEndpoint(apiEndpoint?.relayName || apiEndpoint?.info) + const coreTimeEndpoint = useCoretimeEndpoint(apiEndpoint?.relayName || apiEndpoint?.info); const relayUrls = useMemo( () => (apiEndpoint?.valueRelay && isNumber(apiEndpoint.paraId) && (apiEndpoint.paraId < 2000)) ? apiEndpoint.valueRelay @@ -311,7 +311,7 @@ export function ApiCtxRoot({ apiUrl, children, isElectron, store: keyringStore } [apiEndpoint, peopleEndpoint] ); const coretimeUrls = useMemo( - () => (coreTimeEndpoint && coreTimeEndpoint?.providers) + () => (coreTimeEndpoint?.providers) ? coreTimeEndpoint.providers : null, [apiEndpoint, peopleEndpoint] diff --git a/packages/react-hooks/src/index.ts b/packages/react-hooks/src/index.ts index 7002cdc0a452..83f3695e1b5a 100644 --- a/packages/react-hooks/src/index.ts +++ b/packages/react-hooks/src/index.ts @@ -33,6 +33,8 @@ export { useCallMulti } from './useCallMulti.js'; export { useCollectiveInstance } from './useCollectiveInstance.js'; export { useCollectiveMembers } from './useCollectiveMembers.js'; export { useCoreDescriptor } from './useCoreDescriptor.js'; +export { useCoretimeEndpoint } from './useCoretimeEndpoint.js'; +export { useCoretimeInformation } from './useCoretimeInformation.js'; export { useDebounce } from './useDebounce.js'; export { useDelegations } from './useDelegations.js'; export { useDeriveAccountFlags } from './useDeriveAccountFlags.js'; @@ -68,8 +70,6 @@ export { useParaApi } from './useParaApi.js'; export { useIsParasLinked, useParaEndpoints } from './useParaEndpoints.js'; export { usePassword } from './usePassword.js'; export { usePeopleEndpoint } from './usePeopleEndpoint.js'; -export { useCoretimeEndpoint } from './useCoretimeEndpoint.js' -export { useCoretimeInformation } from './useCoretimeInformation.js' export { usePopupWindow } from './usePopupWindow.js'; export { usePreimage } from './usePreimage.js'; export { useProxies } from './useProxies.js'; diff --git a/packages/react-hooks/src/types.ts b/packages/react-hooks/src/types.ts index b5ee50d6a8b2..b5c7ed2257e5 100644 --- a/packages/react-hooks/src/types.ts +++ b/packages/react-hooks/src/types.ts @@ -7,13 +7,12 @@ import type { SubmittableExtrinsic } from '@polkadot/api/types'; import type { DeriveAccountFlags, DeriveAccountRegistration } from '@polkadot/api-derive/types'; import type { DisplayedJudgement } from '@polkadot/react-components/types'; import type { Option, u32, u128, Vec } from '@polkadot/types'; -import type { AccountId, BlockNumber, Call, Hash, SessionIndex, ValidatorPrefs } from '@polkadot/types/interfaces'; +import type { AccountId, BlockNumber, Call, Hash, ParaId, SessionIndex, ValidatorPrefs } from '@polkadot/types/interfaces'; import type { PalletPreimageRequestStatus, PalletStakingRewardDestination, PalletStakingStakingLedger, PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, SpStakingExposurePage, SpStakingPagedExposureMetadata } from '@polkadot/types/lookup'; import type { ICompact, IExtrinsic, INumber } from '@polkadot/types/types'; import type { KeyringJson$Meta } from '@polkadot/ui-keyring/types'; import type { BN } from '@polkadot/util'; import type { HexString } from '@polkadot/util/types'; -import type { ParaId } from '@polkadot/types/interfaces'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type CallParam = any; @@ -231,7 +230,7 @@ export interface CoreDescriptor { core: number, info: { currentWork: { - assignments: Array, + assignments: CoreDescriptorAssignment[], endHint: BN | null, pos: number, step: number @@ -352,4 +351,4 @@ export interface PotentialRenewal { mask: string[] maskBits: number, task: string -} \ No newline at end of file +} diff --git a/packages/react-hooks/src/useBrokerConfig.ts b/packages/react-hooks/src/useBrokerConfig.ts index 98e73129166d..46b7a75d2ccc 100644 --- a/packages/react-hooks/src/useBrokerConfig.ts +++ b/packages/react-hooks/src/useBrokerConfig.ts @@ -1,11 +1,11 @@ // Copyright 2017-2024 @polkadot/react-hooks authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { ApiPromise } from '@polkadot/api'; import type { Option } from '@polkadot/types'; import type { PalletBrokerConfigRecord } from '@polkadot/types/lookup'; import type { PalletBrokerConfigRecord as SimplifiedPalletBrokerConfigRecord } from './types.js'; -import type { ApiPromise } from '@polkadot/api' import { useEffect, useState } from 'react'; import { createNamedHook, useCall } from '@polkadot/react-hooks'; @@ -26,7 +26,6 @@ function extractInfo (config: Option): SimplifiedPalle } function useBrokerConfigImpl (api: ApiPromise, ready: boolean) { - const config = useCall>(ready && api.query.broker.configuration); const [state, setState] = useState(); diff --git a/packages/react-hooks/src/useBrokerPotentialRenewals.ts b/packages/react-hooks/src/useBrokerPotentialRenewals.ts index 846406c2745e..d78cbe6c6860 100644 --- a/packages/react-hooks/src/useBrokerPotentialRenewals.ts +++ b/packages/react-hooks/src/useBrokerPotentialRenewals.ts @@ -2,31 +2,34 @@ // SPDX-License-Identifier: Apache-2.0 import type { ApiPromise } from '@polkadot/api'; -import type { StorageKey, u32, Option} from '@polkadot/types'; -import type { PalletBrokerPotentialRenewalRecord, PalletBrokerPotentialRenewalId } from '@polkadot/types/lookup'; +import type { Option, StorageKey, u32 } from '@polkadot/types'; +import type { PalletBrokerPotentialRenewalId, PalletBrokerPotentialRenewalRecord } from '@polkadot/types/lookup'; +import type { PotentialRenewal } from './types.js'; + import { useEffect, useState } from 'react'; import { createNamedHook, useCall, useMapKeys } from '@polkadot/react-hooks'; + import { processHexMask } from './utils/dataProcessing.js'; -import { PotentialRenewal } from './types.js'; -function extractInfo(info: Option, item: PalletBrokerPotentialRenewalId ): PotentialRenewal { +function extractInfo (info: Option, item: PalletBrokerPotentialRenewalId): PotentialRenewal { + const unwrapped: PalletBrokerPotentialRenewalRecord | null = info.isSome ? info.unwrap() : null; + let mask = []; + let task = null; + const completion = unwrapped?.completion; - const unwrapped: PalletBrokerPotentialRenewalRecord | null = info.isSome ? info.unwrap() : null - let mask = [] - let task = null - const completion = unwrapped?.completion - if (completion?.isComplete ) { - const complete = completion?.asComplete[0] - task = complete.assignment.isTask ? complete?.assignment.asTask.toString() : complete?.assignment.isPool ? 'Pool' : 'Idle' + if (completion?.isComplete) { + const complete = completion?.asComplete[0]; + + task = complete.assignment.isTask ? complete?.assignment.asTask.toString() : complete?.assignment.isPool ? 'Pool' : 'Idle'; mask = processHexMask(complete.mask); } else if (completion?.isPartial) { - task = null - mask = completion.asPartial[0] + task = null; + mask = completion.asPartial[0]; } else { - mask = [] + mask = []; } - + return { core: item?.core.toNumber(), when: item?.when.toNumber(), @@ -44,12 +47,11 @@ const OPT_KEY = { keys.map(({ args: [id] }) => id) }; -function useBrokerPotentialRenewalsImpl(api: ApiPromise, ready: boolean): any | undefined { +function useBrokerPotentialRenewalsImpl (api: ApiPromise, ready: boolean): any | undefined { const keys = useMapKeys(ready && api.query.broker.potentialRenewals, [], OPT_KEY); const potentialRenewals = useCall<[[PalletBrokerPotentialRenewalId[]], Option[]]>(ready && api.query.broker.potentialRenewals.multi, [keys], { withParams: true }); const [state, setState] = useState(); - console.log('potentialRenewals ', potentialRenewals) useEffect((): void => { potentialRenewals && @@ -57,7 +59,6 @@ function useBrokerPotentialRenewalsImpl(api: ApiPromise, ready: boolean): any | ); }, [potentialRenewals]); - console.log(state) return state; } diff --git a/packages/react-hooks/src/useBrokerSalesInfo.ts b/packages/react-hooks/src/useBrokerSalesInfo.ts index 5dde3b0f2fe5..71f6aa7dd1ac 100644 --- a/packages/react-hooks/src/useBrokerSalesInfo.ts +++ b/packages/react-hooks/src/useBrokerSalesInfo.ts @@ -1,7 +1,7 @@ // Copyright 2017-2024 @polkadot/react-hooks authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { ApiPromise } from '@polkadot/api' +import type { ApiPromise } from '@polkadot/api'; import type { Option } from '@polkadot/types'; import type { PalletBrokerSaleInfoRecord } from '@polkadot/types/lookup'; import type { PalletBrokerSaleInfoRecord as SimplifiedPalletBrokerSaleInfoRecord } from './types.js'; diff --git a/packages/react-hooks/src/useBrokerStatus.ts b/packages/react-hooks/src/useBrokerStatus.ts index 0225a8d1e785..a0f5bd553491 100644 --- a/packages/react-hooks/src/useBrokerStatus.ts +++ b/packages/react-hooks/src/useBrokerStatus.ts @@ -1,22 +1,23 @@ // Copyright 2017-2024 @polkadot/react-query authors & contributors // SPDX-License-Identifier: Apache-2.0 +import type { ApiPromise } from '@polkadot/api'; +import type { Option } from '@polkadot/types'; import type { PalletBrokerStatusRecord } from '@polkadot/types/lookup'; +import type { BrokerStatus } from './types.js'; -import type { ApiPromise } from '@polkadot/api' import { useEffect, useState } from 'react'; -import type { Option } from '@polkadot/types'; - import { createNamedHook, useCall } from '@polkadot/react-hooks'; -import { BrokerStatus } from './types.js'; -function useBrokerStatusImpl(api: ApiPromise, ready: boolean): BrokerStatus | undefined { +function useBrokerStatusImpl (api: ApiPromise, ready: boolean): BrokerStatus | undefined { const status = useCall>(ready && api.query.broker?.status); const [state, setState] = useState(); + useEffect((): void => { if (!!status && status.isSome) { - const s = status.unwrap() + const s = status.unwrap(); + setState({ coreCount: s.coreCount?.toNumber(), privatePoolSize: s.privatePoolSize?.toNumber(), @@ -25,8 +26,8 @@ function useBrokerStatusImpl(api: ApiPromise, ready: boolean): BrokerStatus | un lastTimeslice: s.lastTimeslice?.toNumber() }); } - }, [status]); + return state; } diff --git a/packages/react-hooks/src/useCoreDescriptor.ts b/packages/react-hooks/src/useCoreDescriptor.ts index c7eca803969f..2cd5842d9ddc 100644 --- a/packages/react-hooks/src/useCoreDescriptor.ts +++ b/packages/react-hooks/src/useCoreDescriptor.ts @@ -2,18 +2,41 @@ // SPDX-License-Identifier: Apache-2.0 import type { ApiPromise } from '@polkadot/api'; -import type { StorageKey, u32, Vec } from '@polkadot/types'; -import type { PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor } from '@polkadot/types/lookup'; -import type { CoreDescription } from './types.js'; - +import type { StorageKey, u32 } from '@polkadot/types'; +import type { PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, PalletBrokerCoretimeInterfaceCoreAssignment, PolkadotRuntimeParachainsAssignerCoretimeAssignmentState, PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor, PolkadotRuntimeParachainsAssignerCoretimeWorkState } from '@polkadot/types/lookup'; +import type { CoreDescriptor } from './types.js'; +import { BN } from '@polkadot/util'; import { useEffect, useState } from 'react'; import { createNamedHook, useCall, useMapKeys } from '@polkadot/react-hooks'; -function extractInfo (info: PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor[], core: number) { +function extractInfo(info: PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, core: number): CoreDescriptor { + const currentWork: PolkadotRuntimeParachainsAssignerCoretimeWorkState | null = info?.currentWork.isSome ? info.currentWork.unwrap() : null + const queue: PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor | null = info?.queue.isSome ? info.queue.unwrap() : null + const assignments = currentWork?.assignments || [] return { core, - info + info: { + currentWork: { + assignments: assignments?.map((one: [PalletBrokerCoretimeInterfaceCoreAssignment, PolkadotRuntimeParachainsAssignerCoretimeAssignmentState]) => { + return ({ + task: one[0]?.isTask ? one[0]?.asTask.toString() : one[0]?.isPool ? 'Pool' : 'Idle', + ratio: one[1]?.ratio.toNumber(), + remaining: one[1]?.remaining.toNumber(), + isPool: one[0]?.isPool, + isTask: one[0]?.isTask, + + }) + }), + endHint: currentWork?.endHint.isSome ? currentWork?.endHint?.unwrap().toBn() : null, + pos: currentWork?.pos.toNumber() || 0, + step: currentWork?.step.toNumber() || 0 + }, + queue: { + first: queue?.first.toBn() || new BN(0), + last: queue?.last.toBn() || new BN(0) + } + } }; } @@ -22,7 +45,7 @@ const OPT_KEY = { keys.map(({ args: [id] }) => id) }; -function useCoreDescriptorImpl (api: ApiPromise, ready: boolean): CoreDescription[] | undefined { +function useCoreDescriptorImpl(api: ApiPromise, ready: boolean): CoreDescriptor[] | undefined { const keys = useMapKeys(ready && api.query.coretimeAssignmentProvider.coreDescriptors, [], OPT_KEY); const sanitizedKeys = keys?.map((_, index) => { @@ -31,17 +54,12 @@ function useCoreDescriptorImpl (api: ApiPromise, ready: boolean): CoreDescriptio sanitizedKeys?.pop(); - const coreDescriptors = useCall<[[number[]], Vec[]]>(ready && api.query.coretimeAssignmentProvider.coreDescriptors.multi, [sanitizedKeys], { withParams: true }); - - const [state, setState] = useState(); + const coreDescriptors = useCall<[[number[]], PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor[]]>(ready && api.query.coretimeAssignmentProvider.coreDescriptors.multi, [sanitizedKeys], { withParams: true }); + const [state, setState] = useState(); useEffect((): void => { coreDescriptors && - setState( - coreDescriptors[0][0].map((info, index) => { - return extractInfo(coreDescriptors[1][index], info); - } - ) + setState(coreDescriptors[0][0].map((info, index) => extractInfo(coreDescriptors[1][index], info)) ); }, [coreDescriptors]); diff --git a/packages/react-hooks/src/useCoretimeEndpoint.ts b/packages/react-hooks/src/useCoretimeEndpoint.ts index c7d8879544a8..192b134bf2f8 100644 --- a/packages/react-hooks/src/useCoretimeEndpoint.ts +++ b/packages/react-hooks/src/useCoretimeEndpoint.ts @@ -13,7 +13,7 @@ import { createNamedHook } from './createNamedHook.js'; const endpoints = createWsEndpoints((k, v) => v?.toString() || k); export function getCoretimeEndpoint (curApiInfo?: string): LinkOption | null { - return endpoints.find(({ info }) => isString(info) && isString(curApiInfo) && info.toLowerCase().includes('coretime') && info.toLowerCase().includes(curApiInfo.toLowerCase())) || null; + return endpoints.find(({ info }) => isString(info) && isString(curApiInfo) && info.toLowerCase().includes('coretime') && info.toLowerCase().includes(curApiInfo.toLowerCase())) || null; } function getCoretimeEndpointImpl (relayInfo?: string): LinkOption | null { diff --git a/packages/react-hooks/src/useCoretimeInformation.ts b/packages/react-hooks/src/useCoretimeInformation.ts index 3ba775a8c35a..d875aa20724f 100644 --- a/packages/react-hooks/src/useCoretimeInformation.ts +++ b/packages/react-hooks/src/useCoretimeInformation.ts @@ -3,71 +3,65 @@ import type { ApiPromise } from '@polkadot/api'; import type { ParaId } from '@polkadot/types/interfaces'; +import type { CoretimeInformation } from './types.js'; import { useEffect, useMemo, useState } from 'react'; import { createNamedHook, useApi, useBrokerConfig, useBrokerLeases, useBrokerReservations, useBrokerSalesInfo, useBrokerStatus, useCall, useRegions, useWorkloadInfos, useWorkplanInfos } from '@polkadot/react-hooks'; -import { CoretimeInformation } from './types.js'; -import { useBrokerPotentialRenewals } from './useBrokerPotentialRenewals.js'; +import { useBrokerPotentialRenewals } from './useBrokerPotentialRenewals.js'; -function useCoretimeInformationImpl(api: ApiPromise, ready: boolean): CoretimeInformation | undefined { +function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeInformation | undefined { + const { apiCoretime, isApiReady } = useApi(); - const { apiCoretime, isApiReady } = useApi(); - if (!apiCoretime || !apiCoretime?.query) { - return - } - const status = useBrokerStatus(apiCoretime, isApiReady) - const leases = useBrokerLeases(apiCoretime, ready) - const reservations = useBrokerReservations(apiCoretime, ready) - const salesInfo = useBrokerSalesInfo(apiCoretime, ready) - const paraIds = useCall(api.query.paras.parachains); - const workloads = useWorkloadInfos(apiCoretime, ready) - const workplans = useWorkplanInfos(apiCoretime, ready) - const config = useBrokerConfig(apiCoretime, ready) - const region = useRegions(apiCoretime) - const potentialRenewals = useBrokerPotentialRenewals(apiCoretime, ready) + const status = useBrokerStatus(apiCoretime, isApiReady); + const leases = useBrokerLeases(apiCoretime, ready); + const reservations = useBrokerReservations(apiCoretime, ready); + const salesInfo = useBrokerSalesInfo(apiCoretime, ready); + const paraIds = useCall(api.query.paras.parachains); + const workloads = useWorkloadInfos(apiCoretime, ready); + const workplans = useWorkplanInfos(apiCoretime, ready); + const config = useBrokerConfig(apiCoretime, ready); + const region = useRegions(apiCoretime); + const potentialRenewals = useBrokerPotentialRenewals(apiCoretime, ready); - const potentialRenewalsCurrentRegion = useMemo(() => potentialRenewals?.filter(renewal => renewal.when === salesInfo?.regionEnd), [potentialRenewals]) + const potentialRenewalsCurrentRegion = useMemo(() => potentialRenewals?.filter((renewal) => renewal.when === salesInfo?.regionEnd), [potentialRenewals]); + const [state, setState] = useState(); - console.log('potent ', potentialRenewals) + useEffect((): void => { + if (!workloads?.length || !leases?.length || !reservations?.length) { + return; + } - const [state, setState] = useState(); + const chainInfo: Record = {}; - console.log(potentialRenewals) + paraIds?.forEach((id: ParaId) => { + const lease = leases?.find((lease) => lease.task === id.toString()); + const reservation = reservations?.find((reservation) => reservation.task === id.toString()); + const workload = workloads?.find((one) => one.info.task === id.toString()); - useEffect((): void => { - if(!workloads?.length || !leases?.length || !reservations?.length) { - return - } - let chainInfo: Record = {}; - paraIds?.forEach((id: ParaId) => { - const lease = leases?.find( lease => lease.task === id.toString()) - const reservation = reservations?.find( reservation => reservation.task === id.toString()) - const workload = workloads?.find(one => one.info.task === id.toString()) - chainInfo[id.toString()] = { - id: id.toNumber(), - lease, - reservation, - workload, - renewal: potentialRenewalsCurrentRegion?.find(renewal => renewal.task.toString() === id.toString()), - renewed: workplans?.find(workplan => workplan.core === workload?.core && workplan.info.task.toString() === id.toString()) - } - - }) + chainInfo[id.toString()] = { + id: id.toNumber(), + lease, + reservation, + workload, + renewal: potentialRenewalsCurrentRegion?.find((renewal) => renewal.task.toString() === id.toString()), + renewed: workplans?.find((workplan) => workplan.core === workload?.core && workplan.info.task.toString() === id.toString()) + }; + }); - if (chainInfo) { - setState({ - chainInfo, - salesInfo, - status, - region, - config, - }) - } - }, [paraIds, workloads, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status]); + if (chainInfo) { + setState({ + chainInfo, + salesInfo, + status, + region, + config + }); + } + }, [paraIds, workloads, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status]); - return state; + return state; } export const useCoretimeInformation = createNamedHook('useCoretimeInformation', useCoretimeInformationImpl); diff --git a/packages/react-hooks/src/useQueueStatus.ts b/packages/react-hooks/src/useQueueStatus.ts index fa4271f6b63c..e132fcf6ad3e 100644 --- a/packages/react-hooks/src/useQueueStatus.ts +++ b/packages/react-hooks/src/useQueueStatus.ts @@ -19,7 +19,7 @@ function extractInfo (value: OnDemandQueueStatus) { function useQueueStatusImpl (): OnDemandQueueStatus | undefined { const { api } = useApi(); - const queue = useCall(api.query.onDemandAssignmentProvider.queueStatus); + const queue = useCall(api.query.onDemandAssignmentProvider?.queueStatus); const [state, setState] = useState(); diff --git a/yarn.lock b/yarn.lock index ecffbe2f278e..83d77b011ec2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1431,8 +1431,8 @@ __metadata: version: 0.0.0-use.local resolution: "@polkadot/app-coretime@workspace:packages/page-coretime" dependencies: - "@polkadot/react-components": "npm:0.144.2-2-x" - "@polkadot/react-query": "npm:0.144.2-2-x" + "@polkadot/react-components": "npm:0.144.2-11-x" + "@polkadot/react-query": "npm:0.144.2-11-x" peerDependencies: react: "*" react-dom: "*" From 7eec0b7d84a8c09319fe4191c93267bf2dda5b0a Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Wed, 16 Oct 2024 16:43:11 +0800 Subject: [PATCH 07/22] bumped version --- packages/page-coretime/package.json | 6 +++--- yarn.lock | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/page-coretime/package.json b/packages/page-coretime/package.json index 7e253d4ddc34..53a31bb9bea5 100644 --- a/packages/page-coretime/package.json +++ b/packages/page-coretime/package.json @@ -14,10 +14,10 @@ }, "sideEffects": false, "type": "module", - "version": "0.144.2-11-x", + "version": "0.145.2-0-x", "dependencies": { - "@polkadot/react-components": "0.144.2-11-x", - "@polkadot/react-query": "0.144.2-11-x" + "@polkadot/react-components": "^0.145.2-0-x", + "@polkadot/react-query": "^0.145.2-0-x" }, "peerDependencies": { "react": "*", diff --git a/yarn.lock b/yarn.lock index bafc15945a13..7113d01d2e74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1431,8 +1431,8 @@ __metadata: version: 0.0.0-use.local resolution: "@polkadot/app-coretime@workspace:packages/page-coretime" dependencies: - "@polkadot/react-components": "npm:0.144.2-11-x" - "@polkadot/react-query": "npm:0.144.2-11-x" + "@polkadot/react-components": "npm:^0.145.2-0-x" + "@polkadot/react-query": "npm:^0.145.2-0-x" peerDependencies: react: "*" react-dom: "*" From 19ee4e0838e0f650a9e98ea5052cf2d5abac433b Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Wed, 16 Oct 2024 18:44:11 +0800 Subject: [PATCH 08/22] updated coretime chain summary --- packages/page-broker/src/Overview/Summary.tsx | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/page-broker/src/Overview/Summary.tsx b/packages/page-broker/src/Overview/Summary.tsx index 9ad87de73b00..57c0f874191e 100644 --- a/packages/page-broker/src/Overview/Summary.tsx +++ b/packages/page-broker/src/Overview/Summary.tsx @@ -39,7 +39,7 @@ interface Props { workloadInfos?: CoreWorkload[] } -function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { +function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { const { t } = useTranslation(); const { api, apiEndpoint, isApiReady } = useApi(); const uiHighlight = apiEndpoint?.ui.color || defaultHighlight; @@ -49,6 +49,7 @@ function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { const config = useBrokerConfig(api, isApiReady); const status = useBrokerStatus(api, isApiReady); const currentRegionEnd = useMemo(() => saleInfo && config && saleInfo?.regionEnd - config?.regionLength, [saleInfo, config]); + const currentRegionStart = useMemo(() => currentRegionEnd && config && currentRegionEnd - config?.regionLength, [currentRegionEnd, config]); return ( @@ -65,11 +66,6 @@ function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { - -
- {formatBalance(saleInfo?.endPrice) || '-'} -
-
{coreCount} @@ -78,13 +74,7 @@ function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { {saleInfo?.coresSold} / {saleInfo?.coresOffered}
- {status && -
- {estimateTime(currentRegionEnd, status?.lastTimeslice * 80)} -
-
} )} -
+
+
+ {status && + ( +
+
{estimateTime(currentRegionStart, status?.lastTimeslice * 80)}
+
{estimateTime(currentRegionEnd, status?.lastTimeslice * 80)}
+
+
) + } + + {status && + +
+
{currentRegionStart}
+
{currentRegionEnd}
+
+
+ } +
); } From 7bb556ff569cd92e8e151aeabf53f3705f62a7f6 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Wed, 16 Oct 2024 18:44:56 +0800 Subject: [PATCH 09/22] updated summary, added timeslice for the first sale start, --- .../page-coretime/src/Overview/Summary.tsx | 67 ++++++++++++------- .../page-coretime/src/ParachainsTable.tsx | 8 +-- packages/page-coretime/src/index.tsx | 5 +- packages/page-coretime/src/utils.ts | 6 +- 4 files changed, 55 insertions(+), 31 deletions(-) diff --git a/packages/page-coretime/src/Overview/Summary.tsx b/packages/page-coretime/src/Overview/Summary.tsx index 7d606e72708c..c062c1f6f001 100644 --- a/packages/page-coretime/src/Overview/Summary.tsx +++ b/packages/page-coretime/src/Overview/Summary.tsx @@ -1,15 +1,16 @@ // Copyright 2017-2024 @polkadot/app-coretime authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { BrokerStatus, CoreDescription, PalletBrokerConfigRecord, PalletBrokerSaleInfoRecord, RegionInfo } from '@polkadot/react-hooks/types'; +import type { BrokerStatus, CoreDescription, PalletBrokerConfigRecord, RegionInfo } from '@polkadot/react-hooks/types'; -import React from 'react'; +import React, { useMemo } from 'react'; import { CardSummary, SummaryBox } from '@polkadot/react-components'; import { BN } from '@polkadot/util'; +import { useCall } from '@polkadot/react-hooks'; import { useTranslation } from '../translate.js'; -import { estimateTime } from '../utils.js'; +import { CoreTimeConsts, estimateTime } from '../utils.js'; interface Props { coreDscriptors?: CoreDescription[]; @@ -20,36 +21,37 @@ interface Props { parachainCount: number } -function Summary({ config, parachainCount, region, saleInfo, status }: Props): React.ReactElement { +function Summary({ api, config, parachainCount, saleInfo, status }: Props): React.ReactElement { const { t } = useTranslation(); const currentRegionEnd = saleInfo.regionEnd - config.regionLength; + const currentRegionStart = saleInfo.regionEnd - config.regionLength * 2; + const chainName = useCall(api?.rpc.system.chain)?.toString().toLowerCase(); + + const cycleNumber = useMemo(() => + chainName && currentRegionEnd && Math.floor((currentRegionEnd - CoreTimeConsts.FirstCycleStart[chainName]) / config.regionLength) + , [currentRegionEnd, chainName]); return (
- <> - - {status?.lastTimeslice} - - - {`${saleInfo?.coresSold} / ${saleInfo?.coresOffered}`} - - - {/* - {leasePeriod - ? formatNumber(leasePeriod.currentPeriod) - : 99} - */} + + {status?.lastTimeslice} + + + {`${saleInfo?.coresSold} / ${saleInfo?.coresOffered}`} + {parachainCount && parachainCount} - {status && -
- {estimateTime(currentRegionEnd, status?.lastTimeslice * 80)} -
-
} + {status && + +
+ {cycleNumber} +
+
+ } {config && status && }
+
+ {status && + ( +
+
{estimateTime(currentRegionStart, status?.lastTimeslice * 80)}
+
{estimateTime(currentRegionEnd, status?.lastTimeslice * 80)}
+
+
) + } + + {status && + +
+
{currentRegionStart}
+
{currentRegionEnd}
+
+
+ } +
); } diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx index 809baf1cf3c9..60787cce0387 100644 --- a/packages/page-coretime/src/ParachainsTable.tsx +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -32,9 +32,8 @@ const colours: Record = { [CoreTimeTypes['Bulk Coretime']]: 'pink' }; -function ParachainsTable ({ coretimeInfo, ids }: Props): React.ReactElement { +function ParachainsTable({ coretimeInfo, ids }: Props): React.ReactElement { const { api, isApiReady } = useApi(); - const coreInfos = useCoreDescriptor(api, isApiReady); const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([ [t('parachains'), 'start'], @@ -59,7 +58,6 @@ function ParachainsTable ({ coretimeInfo, ids }: Props): React.ReactElement {ids && coretimeInfo && ids.map((id: number) => { const chain = coretimeInfo.chainInfo[id]; - const onCore = coreInfos?.some((one) => one.info?.currentWork.assignments.some((value) => value.task === id.toString())) ? 'yes' : 'no'; const type = chain?.lease ? CoreTimeTypes.Lease : chain?.reservation ? CoreTimeTypes.Reservation : CoreTimeTypes['Bulk Coretime']; const targetTimeslice = chain?.lease?.until || coretimeInfo.salesInfo.regionEnd; const showEsimates = !!targetTimeslice && type !== CoreTimeTypes.Reservation; @@ -71,8 +69,8 @@ function ParachainsTable ({ coretimeInfo, ids }: Props): React.ReactElement - {chain?.workload?.core || onCore} + /> + {chain?.workload?.core} }) => string): TabItem[] { +function createItemsRef(t: (key: string, options?: { replace: Record }) => string): TabItem[] { return [ { isRoot: true, @@ -28,7 +28,7 @@ function createItemsRef (t: (key: string, options?: { replace: Record { +function CoretimeApp({ basePath, className }: Props): React.ReactElement { const { t } = useTranslation(); const { api, isApiReady } = useApi(); const itemsRef = useRef(createItemsRef(t)); @@ -51,6 +51,7 @@ function CoretimeApp ({ basePath, className }: Props): React.ReactElement /> {coretimeInfo?.salesInfo && ( Date: Wed, 16 Oct 2024 18:45:41 +0800 Subject: [PATCH 10/22] hook updates to make sure the coretime data is displayed even if workloads are empty, fallback on coreAssignments --- packages/react-hooks/src/types.ts | 4 +- packages/react-hooks/src/useBrokerConfig.ts | 2 +- packages/react-hooks/src/useBrokerLeases.ts | 2 +- .../src/useBrokerPotentialRenewals.ts | 4 +- .../react-hooks/src/useBrokerReservations.ts | 2 +- .../react-hooks/src/useBrokerSalesInfo.ts | 2 +- packages/react-hooks/src/useBrokerStatus.ts | 2 +- .../react-hooks/src/useCoretimeInformation.ts | 56 ++++++++++++++----- packages/react-hooks/src/useWorkloadInfos.ts | 4 +- packages/react-hooks/src/useWorkplanInfos.ts | 4 +- 10 files changed, 56 insertions(+), 26 deletions(-) diff --git a/packages/react-hooks/src/types.ts b/packages/react-hooks/src/types.ts index b5c7ed2257e5..e6ff5f88f411 100644 --- a/packages/react-hooks/src/types.ts +++ b/packages/react-hooks/src/types.ts @@ -223,7 +223,9 @@ export interface CoreDescription { export interface CoreDescriptorAssignment { task: string, ratio: number, - remaining: number + remaining: number, + isTask: boolean, + isPool: boolean } export interface CoreDescriptor { diff --git a/packages/react-hooks/src/useBrokerConfig.ts b/packages/react-hooks/src/useBrokerConfig.ts index 46b7a75d2ccc..da46006905c3 100644 --- a/packages/react-hooks/src/useBrokerConfig.ts +++ b/packages/react-hooks/src/useBrokerConfig.ts @@ -26,7 +26,7 @@ function extractInfo (config: Option): SimplifiedPalle } function useBrokerConfigImpl (api: ApiPromise, ready: boolean) { - const config = useCall>(ready && api.query.broker.configuration); + const config = useCall>(ready && api?.query.broker.configuration); const [state, setState] = useState(); diff --git a/packages/react-hooks/src/useBrokerLeases.ts b/packages/react-hooks/src/useBrokerLeases.ts index bf61d9c37ba5..075dbfff1519 100644 --- a/packages/react-hooks/src/useBrokerLeases.ts +++ b/packages/react-hooks/src/useBrokerLeases.ts @@ -11,7 +11,7 @@ import { useEffect, useState } from 'react'; import { createNamedHook, useCall } from '@polkadot/react-hooks'; function useBrokerLeasesImpl (api: ApiPromise, ready: boolean): LegacyLease[] | undefined { - const leases = useCall>(ready && api.query?.broker?.leases); + const leases = useCall>(ready && api?.query?.broker?.leases); const [state, setState] = useState(); useEffect((): void => { diff --git a/packages/react-hooks/src/useBrokerPotentialRenewals.ts b/packages/react-hooks/src/useBrokerPotentialRenewals.ts index d78cbe6c6860..a295bda11ded 100644 --- a/packages/react-hooks/src/useBrokerPotentialRenewals.ts +++ b/packages/react-hooks/src/useBrokerPotentialRenewals.ts @@ -48,8 +48,8 @@ const OPT_KEY = { }; function useBrokerPotentialRenewalsImpl (api: ApiPromise, ready: boolean): any | undefined { - const keys = useMapKeys(ready && api.query.broker.potentialRenewals, [], OPT_KEY); - const potentialRenewals = useCall<[[PalletBrokerPotentialRenewalId[]], Option[]]>(ready && api.query.broker.potentialRenewals.multi, [keys], { withParams: true }); + const keys = useMapKeys(ready && api?.query.broker.potentialRenewals, [], OPT_KEY); + const potentialRenewals = useCall<[[PalletBrokerPotentialRenewalId[]], Option[]]>(ready && api?.query.broker.potentialRenewals.multi, [keys], { withParams: true }); const [state, setState] = useState(); diff --git a/packages/react-hooks/src/useBrokerReservations.ts b/packages/react-hooks/src/useBrokerReservations.ts index cd5e37e085a1..6d3d16faa01a 100644 --- a/packages/react-hooks/src/useBrokerReservations.ts +++ b/packages/react-hooks/src/useBrokerReservations.ts @@ -13,7 +13,7 @@ import { createNamedHook, useCall } from '@polkadot/react-hooks'; import { processHexMask } from './utils/dataProcessing.js'; function useBrokerReservationsImpl (api: ApiPromise, ready: boolean): Reservation[] | undefined { - const reservations = useCall<[any, Vec>[]]>(ready && api.query.broker.reservations); + const reservations = useCall<[any, Vec>[]]>(ready && api?.query.broker.reservations); const [state, setState] = useState(); useEffect((): void => { diff --git a/packages/react-hooks/src/useBrokerSalesInfo.ts b/packages/react-hooks/src/useBrokerSalesInfo.ts index 71f6aa7dd1ac..7d28a07e2cf0 100644 --- a/packages/react-hooks/src/useBrokerSalesInfo.ts +++ b/packages/react-hooks/src/useBrokerSalesInfo.ts @@ -29,7 +29,7 @@ function extractInfo (record: Option): SimplifiedPal } function useBrokerSalesInfoImpl (api: ApiPromise, ready: boolean) { - const record = useCall>(ready && api.query.broker.saleInfo); + const record = useCall>(ready && api?.query.broker.saleInfo); const [state, setState] = useState(); diff --git a/packages/react-hooks/src/useBrokerStatus.ts b/packages/react-hooks/src/useBrokerStatus.ts index a0f5bd553491..082249f62e98 100644 --- a/packages/react-hooks/src/useBrokerStatus.ts +++ b/packages/react-hooks/src/useBrokerStatus.ts @@ -11,7 +11,7 @@ import { useEffect, useState } from 'react'; import { createNamedHook, useCall } from '@polkadot/react-hooks'; function useBrokerStatusImpl (api: ApiPromise, ready: boolean): BrokerStatus | undefined { - const status = useCall>(ready && api.query.broker?.status); + const status = useCall>(ready && api?.query.broker?.status); const [state, setState] = useState(); useEffect((): void => { diff --git a/packages/react-hooks/src/useCoretimeInformation.ts b/packages/react-hooks/src/useCoretimeInformation.ts index d875aa20724f..ae1adb1a352d 100644 --- a/packages/react-hooks/src/useCoretimeInformation.ts +++ b/packages/react-hooks/src/useCoretimeInformation.ts @@ -3,33 +3,61 @@ import type { ApiPromise } from '@polkadot/api'; import type { ParaId } from '@polkadot/types/interfaces'; -import type { CoretimeInformation } from './types.js'; +import { CoreWorkload, CoreWorkloadInfo, type CoretimeInformation } from './types.js'; import { useEffect, useMemo, useState } from 'react'; -import { createNamedHook, useApi, useBrokerConfig, useBrokerLeases, useBrokerReservations, useBrokerSalesInfo, useBrokerStatus, useCall, useRegions, useWorkloadInfos, useWorkplanInfos } from '@polkadot/react-hooks'; +import { createNamedHook, useApi, useBrokerConfig, useBrokerLeases, useBrokerReservations, useBrokerSalesInfo, useBrokerStatus, useCall, useCoreDescriptor, useRegions, useWorkloadInfos, useWorkplanInfos } from '@polkadot/react-hooks'; import { useBrokerPotentialRenewals } from './useBrokerPotentialRenewals.js'; function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeInformation | undefined { const { apiCoretime, isApiReady } = useApi(); + const [workloadData, setWorkloadData] = useState([]) + + /** coretime API calls */ const status = useBrokerStatus(apiCoretime, isApiReady); - const leases = useBrokerLeases(apiCoretime, ready); - const reservations = useBrokerReservations(apiCoretime, ready); - const salesInfo = useBrokerSalesInfo(apiCoretime, ready); - const paraIds = useCall(api.query.paras.parachains); - const workloads = useWorkloadInfos(apiCoretime, ready); - const workplans = useWorkplanInfos(apiCoretime, ready); - const config = useBrokerConfig(apiCoretime, ready); + const leases = useBrokerLeases(apiCoretime, isApiReady); + const reservations = useBrokerReservations(apiCoretime, isApiReady); + const salesInfo = useBrokerSalesInfo(apiCoretime, isApiReady); + let workloads = useWorkloadInfos(apiCoretime, isApiReady); + const workplans = useWorkplanInfos(apiCoretime, isApiReady); + const config = useBrokerConfig(apiCoretime, isApiReady); + const potentialRenewals = useBrokerPotentialRenewals(apiCoretime, isApiReady); const region = useRegions(apiCoretime); - const potentialRenewals = useBrokerPotentialRenewals(apiCoretime, ready); + + /** Other APIs */ + const paraIds = useCall(api.query.paras.parachains); + const coreInfos = useCoreDescriptor(api, ready); const potentialRenewalsCurrentRegion = useMemo(() => potentialRenewals?.filter((renewal) => renewal.when === salesInfo?.regionEnd), [potentialRenewals]); const [state, setState] = useState(); + useEffect(() => { + if(workloads?.length) { + setWorkloadData(workloads) + } + if (!!coreInfos?.length && !workloads?.length) { + const parsedCoreInfos = coreInfos?.map(coreInfo => ({ + core: -1, + info: coreInfo.info.currentWork.assignments.map(assignment => ( + { + isPool: assignment.isPool, + isTask: assignment.isTask, + task: assignment.task, + mask: [], + maskBits: 0 + } + ) as CoreWorkloadInfo) + })) + setWorkloadData(parsedCoreInfos) + } + + }, [workloads, coreInfos]) + useEffect((): void => { - if (!workloads?.length || !leases?.length || !reservations?.length) { + if (!workloadData?.length || !leases?.length || !reservations?.length) { return; } @@ -38,13 +66,13 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI paraIds?.forEach((id: ParaId) => { const lease = leases?.find((lease) => lease.task === id.toString()); const reservation = reservations?.find((reservation) => reservation.task === id.toString()); - const workload = workloads?.find((one) => one.info.task === id.toString()); + const workload = workloadData?.find((one) => one.info.task === id.toString()); chainInfo[id.toString()] = { id: id.toNumber(), lease, reservation, - workload, + workload: workloadData, renewal: potentialRenewalsCurrentRegion?.find((renewal) => renewal.task.toString() === id.toString()), renewed: workplans?.find((workplan) => workplan.core === workload?.core && workplan.info.task.toString() === id.toString()) }; @@ -59,7 +87,7 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI config }); } - }, [paraIds, workloads, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status]); + }, [paraIds, workloadData, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status]); return state; } diff --git a/packages/react-hooks/src/useWorkloadInfos.ts b/packages/react-hooks/src/useWorkloadInfos.ts index 8473c1e695a8..4a66a63f70ea 100644 --- a/packages/react-hooks/src/useWorkloadInfos.ts +++ b/packages/react-hooks/src/useWorkloadInfos.ts @@ -45,8 +45,8 @@ const OPT_KEY = { }; function useWorkloadInfosImpl (api: ApiPromise, ready: boolean): CoreWorkload[] | undefined { - const cores = useMapKeys(ready && api.query.broker.workload, [], OPT_KEY); - const workloadInfo = useCall<[[BN[]], Vec[]]>(ready && api.query.broker.workload.multi, [cores], { withParams: true }); + const cores = useMapKeys(ready && api?.query.broker.workload, [], OPT_KEY); + const workloadInfo = useCall<[[BN[]], Vec[]]>(ready && api?.query.broker.workload.multi, [cores], { withParams: true }); const [state, setState] = useState(); useEffect((): void => { diff --git a/packages/react-hooks/src/useWorkplanInfos.ts b/packages/react-hooks/src/useWorkplanInfos.ts index f0084097fb03..f804700f155c 100644 --- a/packages/react-hooks/src/useWorkplanInfos.ts +++ b/packages/react-hooks/src/useWorkplanInfos.ts @@ -46,13 +46,13 @@ const OPT_KEY = { }; function useWorkplanInfosImpl (api: ApiPromise, ready: boolean): CoreWorkplan[] | undefined { - const workplanKeys = useMapKeys(ready && api.query.broker.workplan, [], OPT_KEY); + const workplanKeys = useMapKeys(ready && api?.query.broker.workplan, [], OPT_KEY); const sanitizedKeys = workplanKeys?.map((value) => { return value[0]; }); - const workplanInfo = useCall<[[[u32, u16][]], Option>[]]>(ready && api.query.broker.workplan.multi, [sanitizedKeys], { withParams: true }); + const workplanInfo = useCall<[[[u32, u16][]], Option>[]]>(ready && api?.query.broker.workplan.multi, [sanitizedKeys], { withParams: true }); const [state, setState] = useState(); From 56bbcfaeff4a95fe02f3fbfef7238810ce492288 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Wed, 16 Oct 2024 18:50:33 +0800 Subject: [PATCH 11/22] removed unused files --- .../page-coretime/src/Overview/BrokerId.tsx | 27 -------- .../src/Overview/CoreDescriptor.tsx | 66 ------------------ .../src/Overview/CoreDescriptors.tsx | 67 ------------------- .../page-coretime/src/Overview/CoreQueue.tsx | 41 ------------ .../src/Overview/CurrentWork.tsx | 62 ----------------- .../src/Overview/QueueStatus.tsx | 35 ---------- packages/page-coretime/src/Overview/index.tsx | 29 -------- 7 files changed, 327 deletions(-) delete mode 100644 packages/page-coretime/src/Overview/BrokerId.tsx delete mode 100644 packages/page-coretime/src/Overview/CoreDescriptor.tsx delete mode 100644 packages/page-coretime/src/Overview/CoreDescriptors.tsx delete mode 100644 packages/page-coretime/src/Overview/CoreQueue.tsx delete mode 100644 packages/page-coretime/src/Overview/CurrentWork.tsx delete mode 100644 packages/page-coretime/src/Overview/QueueStatus.tsx delete mode 100644 packages/page-coretime/src/Overview/index.tsx diff --git a/packages/page-coretime/src/Overview/BrokerId.tsx b/packages/page-coretime/src/Overview/BrokerId.tsx deleted file mode 100644 index 622a0e3471d1..000000000000 --- a/packages/page-coretime/src/Overview/BrokerId.tsx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-coretime authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import type { u32 } from '@polkadot/types'; - -import React from 'react'; - -import { useApi } from '@polkadot/react-hooks'; - -interface Props { - className?: string; - children?: React.ReactNode; -} - -function BrokerId ({ children, className }: Props): React.ReactElement | null { - const { api } = useApi(); - const id = api.consts.coretime?.brokerId as u32; - - return ( -
- {id?.toString()} - {children} -
- ); -} - -export default React.memo(BrokerId); diff --git a/packages/page-coretime/src/Overview/CoreDescriptor.tsx b/packages/page-coretime/src/Overview/CoreDescriptor.tsx deleted file mode 100644 index 3704e938ea88..000000000000 --- a/packages/page-coretime/src/Overview/CoreDescriptor.tsx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-coretime authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import type { CoreDescription } from '@polkadot/react-hooks/types'; -import type { PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor } from '@polkadot/types/lookup'; - -import React from 'react'; - -import { styled } from '@polkadot/react-components'; - -import CoreQueue from './CoreQueue.js'; -import CurrentWork from './CurrentWork.js'; - -interface Props { - className?: string; - value: CoreDescription; -} - -function CoreDescriptor ({ className, value: { core, info } }: Props): React.ReactElement { - let sanitized: PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor[] = []; - - if (Array.isArray(info)) { - sanitized = info; - } else if (info) { - sanitized.push(info); - } - - return ( - <> - - {sanitized?.map((i) => ( - - - - )) - } - {sanitized?.map((i) => ( - - - - ))} - - - ); -} - -const StyledTr = styled.tr` - .shortHash { - max-width: var(--width-shorthash); - min-width: 3em; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: var(--width-shorthash); - } -`; - -export default React.memo(CoreDescriptor); diff --git a/packages/page-coretime/src/Overview/CoreDescriptors.tsx b/packages/page-coretime/src/Overview/CoreDescriptors.tsx deleted file mode 100644 index 2e63e28186cd..000000000000 --- a/packages/page-coretime/src/Overview/CoreDescriptors.tsx +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-coretime authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import type { CoreDescription } from '@polkadot/react-hooks/types'; - -import React, { useMemo } from 'react'; - -import { ExpandButton, Table } from '@polkadot/react-components'; -import { useToggle } from '@polkadot/react-hooks'; - -import { useTranslation } from '../translate.js'; -import CoreDescriptor from './CoreDescriptor.js'; - -interface Props { - className?: string; - coreInfos?: CoreDescription; -} - -function CoreDescriptors ({ className, coreInfos }: Props): React.ReactElement { - const { t } = useTranslation(); - const [isExpanded, toggleExpanded] = useToggle(); - - const [headerButton, headerChildren] = useMemo( - () => [ - false && coreInfos && ( - - ), - isExpanded && coreInfos && ( - - - - ) - ], - [isExpanded, toggleExpanded, coreInfos] - ); - - const [header, key] = useMemo( - (): [([React.ReactNode?, string?, number?] | null)[], string] => [ - [ - [<>{t('core')}
{coreInfos?.core}
, 'start', 8], - null && [headerButton] - ], - 'core' - ], - [headerButton, t, coreInfos] - ); - - return ( - - {coreInfos && } -
- ); -} - -export default React.memo(CoreDescriptors); diff --git a/packages/page-coretime/src/Overview/CoreQueue.tsx b/packages/page-coretime/src/Overview/CoreQueue.tsx deleted file mode 100644 index f2f4567a9b2e..000000000000 --- a/packages/page-coretime/src/Overview/CoreQueue.tsx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-coretime authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import type { PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor } from '@polkadot/types/lookup'; - -import React, { useRef } from 'react'; - -import { Table } from '@polkadot/react-components'; - -interface Props { - value?: PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor; -} - -function CoreQueue ({ value }: Props): React.ReactElement { - const headerRef = useRef<([React.ReactNode?, string?] | false)[]>([ - ['work queue'] - ]); - - return ( - - {value - ? - - - - : - - } -
-
{'first'}
- {value?.first.toString()} -
-
{'last'}
- {value?.last.toString()} -
-
{'No work queue found'}
-
- ); -} - -export default React.memo(CoreQueue); diff --git a/packages/page-coretime/src/Overview/CurrentWork.tsx b/packages/page-coretime/src/Overview/CurrentWork.tsx deleted file mode 100644 index 6465a6dc7d82..000000000000 --- a/packages/page-coretime/src/Overview/CurrentWork.tsx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-coretime authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import type { PolkadotRuntimeParachainsAssignerCoretimeWorkState } from '@polkadot/types/lookup'; - -import React, { useEffect, useRef, useState } from 'react'; - -import { Table } from '@polkadot/react-components'; - -interface Props { - value?: PolkadotRuntimeParachainsAssignerCoretimeWorkState; -} - -function createAssignments (value?: PolkadotRuntimeParachainsAssignerCoretimeWorkState): string { - if (value) { - if (value.assignments.length > 1) { - return value.assignments.map((_, index) => { - const ratio = value.assignments[index][1].ratio.toNumber() / 57600 * 100; - - if (value.assignments[index][0].isIdle) { - return `${ratio}% Idle`; - } else if (value.assignments[index][0].isPool) { - return `${ratio}% Pool`; - } else { - return `${ratio}% Task: ${value.assignments[index][0].asTask.toString()}`; - } - }).join(', '); - } else { - if (value.assignments[0][0].isIdle) { - return '100% Idle'; - } else if (value.assignments[0][0].isPool) { - return '100% Pool'; - } else { - return `100% Task: ${value.assignments[0][0].asTask.toString()}`; - } - } - } else { - return 'Queue empty'; - } -} - -function CurrentWork ({ value }: Props): React.ReactElement { - const [assignments, setAssignments] = useState(''); - - useEffect(() => { - setAssignments(createAssignments(value)); - }, [value]); - - const headerRef = useRef<([React.ReactNode?, string?] | false)[]>([ - ['current work'] - ]); - - return ( - - - - -
{assignments}
- ); -} - -export default React.memo(CurrentWork); diff --git a/packages/page-coretime/src/Overview/QueueStatus.tsx b/packages/page-coretime/src/Overview/QueueStatus.tsx deleted file mode 100644 index 16dad860c2fc..000000000000 --- a/packages/page-coretime/src/Overview/QueueStatus.tsx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-coretime authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import type { OnDemandQueueStatus } from '@polkadot/react-hooks/types'; - -import React from 'react'; - -import { FormatBalance } from '@polkadot/react-query'; - -interface Props { - className?: string; - value?: OnDemandQueueStatus; - query: string; -} - -function QueueStatus ({ className, query, value }: Props): React.ReactElement { - return ( - <> - {value && query === 'traffic' - ?
- -
- : value && -
- {value?.nextIndex.toString()} -
} - - ); -} - -export default React.memo(QueueStatus); diff --git a/packages/page-coretime/src/Overview/index.tsx b/packages/page-coretime/src/Overview/index.tsx deleted file mode 100644 index 01427c96555b..000000000000 --- a/packages/page-coretime/src/Overview/index.tsx +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-coretime authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import type { CoreDescription } from '@polkadot/react-hooks/types'; - -import React from 'react'; - -import CoreDescriptors from './CoreDescriptors.js'; -import Summary from './Summary.js'; - -interface Props { - className?: string; - coreInfos?: CoreDescription[]; -} - -function Overview ({ className, coreInfos }: Props): React.ReactElement { - return ( -
- - -
- ); -} - -export default React.memo(Overview); From da7be71cf821646d0f59e57a87bbe8c268ad92c1 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Wed, 16 Oct 2024 19:50:08 +0800 Subject: [PATCH 12/22] lint --- packages/apps-routing/src/coretime.ts | 2 +- packages/page-broker/src/Overview/Summary.tsx | 34 +++++++---- .../page-broker/src/Overview/WorkInfoRow.tsx | 33 +++++++++++ packages/page-coretime/.skip-build | 0 packages/page-coretime/.skip-npm | 0 .../page-coretime/src/Overview/Summary.tsx | 35 ++++++------ .../page-coretime/src/ParachainsTable.tsx | 19 +++---- packages/page-coretime/src/index.tsx | 4 +- packages/page-coretime/src/utils.ts | 4 +- packages/react-api/src/Api.tsx | 6 +- packages/react-hooks/src/types.ts | 17 +++--- .../src/useBrokerPotentialRenewals.ts | 10 ++-- packages/react-hooks/src/useBrokerStatus.ts | 6 +- packages/react-hooks/src/useCoreDescriptor.ts | 25 ++++---- .../react-hooks/src/useCoretimeEndpoint.ts | 4 +- .../react-hooks/src/useCoretimeInformation.ts | 57 ++++++++++--------- packages/react-hooks/src/useRegions.ts | 2 +- 17 files changed, 153 insertions(+), 105 deletions(-) create mode 100644 packages/page-coretime/.skip-build create mode 100644 packages/page-coretime/.skip-npm diff --git a/packages/apps-routing/src/coretime.ts b/packages/apps-routing/src/coretime.ts index a9c594fd5b59..37b45a48d8ea 100644 --- a/packages/apps-routing/src/coretime.ts +++ b/packages/apps-routing/src/coretime.ts @@ -17,6 +17,6 @@ export default function create (t: TFunction): Route { group: 'network', icon: 'flask', name: 'coretime', - text: t('nav.coretime', 'Coretime (Experimental)', { ns: 'app-coretime' }) + text: t('nav.coretime', 'Coretime (Experimental)', { ns: 'apps-routing' }) }; } diff --git a/packages/page-broker/src/Overview/Summary.tsx b/packages/page-broker/src/Overview/Summary.tsx index 57c0f874191e..e85e71af4d42 100644 --- a/packages/page-broker/src/Overview/Summary.tsx +++ b/packages/page-broker/src/Overview/Summary.tsx @@ -9,8 +9,8 @@ import React, { useMemo } from 'react'; import { CardSummary, styled, SummaryBox, UsageBar } from '@polkadot/react-components'; import { defaultHighlight } from '@polkadot/react-components/styles'; import { useApi, useBrokerConfig, useBrokerSalesInfo, useBrokerStatus } from '@polkadot/react-hooks'; -import { type CoreWorkload, PalletBrokerConfigRecord } from '@polkadot/react-hooks/types'; -import { BN, formatBalance } from '@polkadot/util'; +import { type CoreWorkload } from '@polkadot/react-hooks/types'; +import { BN } from '@polkadot/util'; import { useTranslation } from '../translate.js'; import { estimateTime, getStats } from '../utils.js'; @@ -39,7 +39,7 @@ interface Props { workloadInfos?: CoreWorkload[] } -function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { +function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { const { t } = useTranslation(); const { api, apiEndpoint, isApiReady } = useApi(); const uiHighlight = apiEndpoint?.ui.color || defaultHighlight; @@ -87,7 +87,10 @@ function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { )} -
+
{status && - ( -
-
{estimateTime(currentRegionStart, status?.lastTimeslice * 80)}
-
{estimateTime(currentRegionEnd, status?.lastTimeslice * 80)}
-
-
) + ( + +
+
{estimateTime(currentRegionStart, status?.lastTimeslice * 80)}
+
{estimateTime(currentRegionEnd, status?.lastTimeslice * 80)}
+
+
+ ) } - {status && - +
{currentRegionStart}
{currentRegionEnd}
diff --git a/packages/page-broker/src/Overview/WorkInfoRow.tsx b/packages/page-broker/src/Overview/WorkInfoRow.tsx index 8f5a8786cc28..a56f22deffe5 100644 --- a/packages/page-broker/src/Overview/WorkInfoRow.tsx +++ b/packages/page-broker/src/Overview/WorkInfoRow.tsx @@ -77,6 +77,39 @@ function WorkInfoRow ({ data }: { data: InfoRow }): React.ReactElement { } case (CoreTimeTypes.Lease): + return ( + <> + + + + + + +
type
+ +
+ + ); case (CoreTimeTypes['On Demand']): { return ( diff --git a/packages/page-coretime/.skip-build b/packages/page-coretime/.skip-build new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/page-coretime/.skip-npm b/packages/page-coretime/.skip-npm new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/page-coretime/src/Overview/Summary.tsx b/packages/page-coretime/src/Overview/Summary.tsx index c062c1f6f001..7bfbd41b8cd4 100644 --- a/packages/page-coretime/src/Overview/Summary.tsx +++ b/packages/page-coretime/src/Overview/Summary.tsx @@ -1,27 +1,29 @@ // Copyright 2017-2024 @polkadot/app-coretime authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { BrokerStatus, CoreDescription, PalletBrokerConfigRecord, RegionInfo } from '@polkadot/react-hooks/types'; +import type { ApiPromise } from '@polkadot/api'; +import type { BrokerStatus, CoreDescription, PalletBrokerConfigRecord, PalletBrokerSaleInfoRecord, RegionInfo } from '@polkadot/react-hooks/types'; import React, { useMemo } from 'react'; import { CardSummary, SummaryBox } from '@polkadot/react-components'; -import { BN } from '@polkadot/util'; import { useCall } from '@polkadot/react-hooks'; +import { BN } from '@polkadot/util'; import { useTranslation } from '../translate.js'; import { CoreTimeConsts, estimateTime } from '../utils.js'; interface Props { + api: ApiPromise, coreDscriptors?: CoreDescription[]; - saleInfo: any + saleInfo: PalletBrokerSaleInfoRecord config: PalletBrokerConfigRecord, region: RegionInfo, status: BrokerStatus, parachainCount: number } -function Summary({ api, config, parachainCount, saleInfo, status }: Props): React.ReactElement { +function Summary ({ api, config, parachainCount, saleInfo, status }: Props): React.ReactElement { const { t } = useTranslation(); const currentRegionEnd = saleInfo.regionEnd - config.regionLength; const currentRegionStart = saleInfo.regionEnd - config.regionLength * 2; @@ -29,7 +31,7 @@ function Summary({ api, config, parachainCount, saleInfo, status }: Props): Reac const cycleNumber = useMemo(() => chainName && currentRegionEnd && Math.floor((currentRegionEnd - CoreTimeConsts.FirstCycleStart[chainName]) / config.regionLength) - , [currentRegionEnd, chainName]); + , [currentRegionEnd, chainName, config]); return ( @@ -50,16 +52,18 @@ function Summary({ api, config, parachainCount, saleInfo, status }: Props): Reac
} - {config && status && } + {config && status && + + }
{status && @@ -70,7 +74,6 @@ function Summary({ api, config, parachainCount, saleInfo, status }: Props): Reac
) } - {status &&
diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx index 60787cce0387..53f844bfbf51 100644 --- a/packages/page-coretime/src/ParachainsTable.tsx +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -1,15 +1,13 @@ -// Copyright 2017-2024 @polkadot/app-broker authors & contributors +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors // SPDX-License-Identifier: Apache-2.0 import type { FlagColor } from '@polkadot/react-components/types'; import type { CoretimeInformation } from '@polkadot/react-hooks/types'; -import { formatNumber } from 'chart.js/helpers'; import React, { useRef } from 'react'; import { ParaLink, Table, Tag } from '@polkadot/react-components'; -import { useApi, useCoreDescriptor } from '@polkadot/react-hooks'; -import { BN, formatBalance } from '@polkadot/util'; +import { BN, formatBalance, formatNumber } from '@polkadot/util'; import { useTranslation } from './translate.js'; import { estimateTime } from './utils.js'; @@ -32,8 +30,7 @@ const colours: Record = { [CoreTimeTypes['Bulk Coretime']]: 'pink' }; -function ParachainsTable({ coretimeInfo, ids }: Props): React.ReactElement { - const { api, isApiReady } = useApi(); +function ParachainsTable ({ coretimeInfo, ids }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([ [t('parachains'), 'start'], @@ -66,10 +63,12 @@ function ParachainsTable({ coretimeInfo, ids }: Props): React.ReactElement {id} - + + + {chain?.workload?.core} }) => string): TabItem[] { +function createItemsRef (t: (key: string, options?: { replace: Record }) => string): TabItem[] { return [ { isRoot: true, @@ -28,7 +28,7 @@ function createItemsRef(t: (key: string, options?: { replace: Record { +function CoretimeApp ({ basePath, className }: Props): React.ReactElement { const { t } = useTranslation(); const { api, isApiReady } = useApi(); const itemsRef = useRef(createItemsRef(t)); diff --git a/packages/page-coretime/src/utils.ts b/packages/page-coretime/src/utils.ts index 76466300972f..d05d6028c5a7 100644 --- a/packages/page-coretime/src/utils.ts +++ b/packages/page-coretime/src/utils.ts @@ -8,8 +8,8 @@ export const CoreTimeConsts = { BlocksPerTimeslice: 80, DefaultRegion: 5040, FirstCycleStart: { - 'polkadot': 282525, - 'kusama': 285768 + kusama: 285768, + polkadot: 282525 } }; diff --git a/packages/react-api/src/Api.tsx b/packages/react-api/src/Api.tsx index 8b1009d77783..011fbf5cff87 100644 --- a/packages/react-api/src/Api.tsx +++ b/packages/react-api/src/Api.tsx @@ -314,7 +314,7 @@ export function ApiCtxRoot ({ apiUrl, children, isElectron, store: keyringStore () => (coreTimeEndpoint?.providers) ? coreTimeEndpoint.providers : null, - [apiEndpoint, peopleEndpoint] + [coreTimeEndpoint] ); const apiRelay = useApiUrl(relayUrls); const apiCoretime = useApiUrl(coretimeUrls); @@ -325,8 +325,8 @@ export function ApiCtxRoot ({ apiUrl, children, isElectron, store: keyringStore ); const enableIdentity = apiEndpoint?.isPeople || (isNumber(apiEndpoint?.paraId) && (apiEndpoint?.paraId >= 2000)) || (typeof apiEndpoint?.isPeopleForIdentity === 'boolean' && !apiEndpoint?.isPeopleForIdentity); const value = useMemo( - () => objectSpread({}, state, { api: statics.api, apiEndpoint, apiError, apiIdentity: ((apiEndpoint?.isPeopleForIdentity && apiSystemPeople) || statics.api), apiRelay, apiCoretime, apiSystemPeople, apiUrl, createLink, enableIdentity, extensions, isApiConnected, isApiInitialized, isElectron, isLocalFork, isWaitingInjected: !extensions }), - [apiError, createLink, extensions, isApiConnected, isApiInitialized, isElectron, isLocalFork, state, apiEndpoint, apiRelay, apiCoretime, apiUrl, apiSystemPeople, enableIdentity] + () => objectSpread({}, state, { api: statics.api, apiCoretime, apiEndpoint, apiError, apiIdentity: ((apiEndpoint?.isPeopleForIdentity && apiSystemPeople) || statics.api), apiRelay, apiSystemPeople, apiUrl, createLink, enableIdentity, extensions, isApiConnected, isApiInitialized, isElectron, isLocalFork, isWaitingInjected: !extensions }), + [apiError, createLink, extensions, isApiConnected, isApiInitialized, isElectron, isLocalFork, state, apiEndpoint, apiCoretime, apiRelay, apiUrl, apiSystemPeople, enableIdentity] ); // initial initialization diff --git a/packages/react-hooks/src/types.ts b/packages/react-hooks/src/types.ts index e6ff5f88f411..9ff9991cccd4 100644 --- a/packages/react-hooks/src/types.ts +++ b/packages/react-hooks/src/types.ts @@ -322,15 +322,16 @@ export interface PalletBrokerConfigRecord { contributionTimeout: number; } +export interface ChainInformation { + id: ParaId, + workload: CoreWorkload[] | undefined, + renewal: PotentialRenewal | undefined, + worklplan: CoreWorkplan[] | undefined, + lease: LegacyLease | undefined, + reservation: Reservation| undefined +} export interface CoretimeInformation { - chainInfo: Record, + chainInfo: Record, salesInfo: PalletBrokerSaleInfoRecord, status: BrokerStatus, region: RegionInfo[], diff --git a/packages/react-hooks/src/useBrokerPotentialRenewals.ts b/packages/react-hooks/src/useBrokerPotentialRenewals.ts index a295bda11ded..5b611aea5402 100644 --- a/packages/react-hooks/src/useBrokerPotentialRenewals.ts +++ b/packages/react-hooks/src/useBrokerPotentialRenewals.ts @@ -31,14 +31,14 @@ function extractInfo (info: Option, item: Pa } return { - core: item?.core.toNumber(), - when: item?.when.toNumber(), - price: unwrapped?.price.toBn(), // How much of a core has been assigned or, if completely assigned, the workload itself. completion: completion?.type, + core: item?.core.toNumber(), mask, maskBits: mask?.length, - task + price: unwrapped?.price.toBn(), + task, + when: item?.when.toNumber() }; } @@ -47,7 +47,7 @@ const OPT_KEY = { keys.map(({ args: [id] }) => id) }; -function useBrokerPotentialRenewalsImpl (api: ApiPromise, ready: boolean): any | undefined { +function useBrokerPotentialRenewalsImpl (api: ApiPromise, ready: boolean): PotentialRenewal[] | undefined { const keys = useMapKeys(ready && api?.query.broker.potentialRenewals, [], OPT_KEY); const potentialRenewals = useCall<[[PalletBrokerPotentialRenewalId[]], Option[]]>(ready && api?.query.broker.potentialRenewals.multi, [keys], { withParams: true }); diff --git a/packages/react-hooks/src/useBrokerStatus.ts b/packages/react-hooks/src/useBrokerStatus.ts index 082249f62e98..d1f757a024f7 100644 --- a/packages/react-hooks/src/useBrokerStatus.ts +++ b/packages/react-hooks/src/useBrokerStatus.ts @@ -20,10 +20,10 @@ function useBrokerStatusImpl (api: ApiPromise, ready: boolean): BrokerStatus | u setState({ coreCount: s.coreCount?.toNumber(), - privatePoolSize: s.privatePoolSize?.toNumber(), - systemPoolSize: s.systemPoolSize?.toNumber(), lastCommittedTimeslice: s.lastCommittedTimeslice?.toNumber(), - lastTimeslice: s.lastTimeslice?.toNumber() + lastTimeslice: s.lastTimeslice?.toNumber(), + privatePoolSize: s.privatePoolSize?.toNumber(), + systemPoolSize: s.systemPoolSize?.toNumber() }); } }, [status]); diff --git a/packages/react-hooks/src/useCoreDescriptor.ts b/packages/react-hooks/src/useCoreDescriptor.ts index 2cd5842d9ddc..7fca588d812f 100644 --- a/packages/react-hooks/src/useCoreDescriptor.ts +++ b/packages/react-hooks/src/useCoreDescriptor.ts @@ -3,30 +3,31 @@ import type { ApiPromise } from '@polkadot/api'; import type { StorageKey, u32 } from '@polkadot/types'; -import type { PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, PalletBrokerCoretimeInterfaceCoreAssignment, PolkadotRuntimeParachainsAssignerCoretimeAssignmentState, PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor, PolkadotRuntimeParachainsAssignerCoretimeWorkState } from '@polkadot/types/lookup'; +import type { PalletBrokerCoretimeInterfaceCoreAssignment, PolkadotRuntimeParachainsAssignerCoretimeAssignmentState, PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor, PolkadotRuntimeParachainsAssignerCoretimeWorkState } from '@polkadot/types/lookup'; import type { CoreDescriptor } from './types.js'; -import { BN } from '@polkadot/util'; + import { useEffect, useState } from 'react'; import { createNamedHook, useCall, useMapKeys } from '@polkadot/react-hooks'; +import { BN } from '@polkadot/util'; + +function extractInfo (info: PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, core: number): CoreDescriptor { + const currentWork: PolkadotRuntimeParachainsAssignerCoretimeWorkState | null = info?.currentWork.isSome ? info.currentWork.unwrap() : null; + const queue: PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor | null = info?.queue.isSome ? info.queue.unwrap() : null; + const assignments = currentWork?.assignments || []; -function extractInfo(info: PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, core: number): CoreDescriptor { - const currentWork: PolkadotRuntimeParachainsAssignerCoretimeWorkState | null = info?.currentWork.isSome ? info.currentWork.unwrap() : null - const queue: PolkadotRuntimeParachainsAssignerCoretimeQueueDescriptor | null = info?.queue.isSome ? info.queue.unwrap() : null - const assignments = currentWork?.assignments || [] return { core, info: { currentWork: { assignments: assignments?.map((one: [PalletBrokerCoretimeInterfaceCoreAssignment, PolkadotRuntimeParachainsAssignerCoretimeAssignmentState]) => { return ({ - task: one[0]?.isTask ? one[0]?.asTask.toString() : one[0]?.isPool ? 'Pool' : 'Idle', - ratio: one[1]?.ratio.toNumber(), - remaining: one[1]?.remaining.toNumber(), isPool: one[0]?.isPool, isTask: one[0]?.isTask, - - }) + ratio: one[1]?.ratio.toNumber(), + remaining: one[1]?.remaining.toNumber(), + task: one[0]?.isTask ? one[0]?.asTask.toString() : one[0]?.isPool ? 'Pool' : 'Idle' + }); }), endHint: currentWork?.endHint.isSome ? currentWork?.endHint?.unwrap().toBn() : null, pos: currentWork?.pos.toNumber() || 0, @@ -45,7 +46,7 @@ const OPT_KEY = { keys.map(({ args: [id] }) => id) }; -function useCoreDescriptorImpl(api: ApiPromise, ready: boolean): CoreDescriptor[] | undefined { +function useCoreDescriptorImpl (api: ApiPromise, ready: boolean): CoreDescriptor[] | undefined { const keys = useMapKeys(ready && api.query.coretimeAssignmentProvider.coreDescriptors, [], OPT_KEY); const sanitizedKeys = keys?.map((_, index) => { diff --git a/packages/react-hooks/src/useCoretimeEndpoint.ts b/packages/react-hooks/src/useCoretimeEndpoint.ts index 192b134bf2f8..2e63072aaf2d 100644 --- a/packages/react-hooks/src/useCoretimeEndpoint.ts +++ b/packages/react-hooks/src/useCoretimeEndpoint.ts @@ -16,8 +16,8 @@ export function getCoretimeEndpoint (curApiInfo?: string): LinkOption | null { return endpoints.find(({ info }) => isString(info) && isString(curApiInfo) && info.toLowerCase().includes('coretime') && info.toLowerCase().includes(curApiInfo.toLowerCase())) || null; } -function getCoretimeEndpointImpl (relayInfo?: string): LinkOption | null { +function useCoretimeEndpointImpl (relayInfo?: string): LinkOption | null { return useMemo(() => getCoretimeEndpoint(relayInfo), [relayInfo]); } -export const useCoretimeEndpoint = createNamedHook('useCoretimeEndpoint', getCoretimeEndpointImpl); +export const useCoretimeEndpoint = createNamedHook('useCoretimeEndpoint', useCoretimeEndpointImpl); diff --git a/packages/react-hooks/src/useCoretimeInformation.ts b/packages/react-hooks/src/useCoretimeInformation.ts index ae1adb1a352d..bca05612ee38 100644 --- a/packages/react-hooks/src/useCoretimeInformation.ts +++ b/packages/react-hooks/src/useCoretimeInformation.ts @@ -3,7 +3,7 @@ import type { ApiPromise } from '@polkadot/api'; import type { ParaId } from '@polkadot/types/interfaces'; -import { CoreWorkload, CoreWorkloadInfo, type CoretimeInformation } from './types.js'; +import type { ChainInformation, CoretimeInformation, CoreWorkload, CoreWorkloadInfo, PotentialRenewal } from './types.js'; import { useEffect, useMemo, useState } from 'react'; @@ -14,14 +14,14 @@ import { useBrokerPotentialRenewals } from './useBrokerPotentialRenewals.js'; function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeInformation | undefined { const { apiCoretime, isApiReady } = useApi(); - const [workloadData, setWorkloadData] = useState([]) + const [workloadData, setWorkloadData] = useState([]); /** coretime API calls */ const status = useBrokerStatus(apiCoretime, isApiReady); const leases = useBrokerLeases(apiCoretime, isApiReady); const reservations = useBrokerReservations(apiCoretime, isApiReady); const salesInfo = useBrokerSalesInfo(apiCoretime, isApiReady); - let workloads = useWorkloadInfos(apiCoretime, isApiReady); + const workloads = useWorkloadInfos(apiCoretime, isApiReady); const workplans = useWorkplanInfos(apiCoretime, isApiReady); const config = useBrokerConfig(apiCoretime, isApiReady); const potentialRenewals = useBrokerPotentialRenewals(apiCoretime, isApiReady); @@ -31,37 +31,38 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI const paraIds = useCall(api.query.paras.parachains); const coreInfos = useCoreDescriptor(api, ready); - const potentialRenewalsCurrentRegion = useMemo(() => potentialRenewals?.filter((renewal) => renewal.when === salesInfo?.regionEnd), [potentialRenewals]); - const [state, setState] = useState(); + const potentialRenewalsCurrentRegion = useMemo(() => potentialRenewals?.filter((renewal: PotentialRenewal) => renewal.when === salesInfo?.regionEnd), [potentialRenewals, salesInfo]); + const [state, setState] = useState(); useEffect(() => { - if(workloads?.length) { - setWorkloadData(workloads) + if (workloads?.length) { + setWorkloadData(workloads); } + if (!!coreInfos?.length && !workloads?.length) { - const parsedCoreInfos = coreInfos?.map(coreInfo => ({ + const parsedCoreInfos = coreInfos?.map((coreInfo) => ({ core: -1, - info: coreInfo.info.currentWork.assignments.map(assignment => ( - { - isPool: assignment.isPool, - isTask: assignment.isTask, - task: assignment.task, - mask: [], - maskBits: 0 - } - ) as CoreWorkloadInfo) - })) - setWorkloadData(parsedCoreInfos) + info: coreInfo.info.currentWork.assignments.map((assignment) => ( + { + isPool: assignment.isPool, + isTask: assignment.isTask, + mask: [], + maskBits: 0, + task: assignment.task + } + ) as CoreWorkloadInfo) + })); + + setWorkloadData(parsedCoreInfos); } - - }, [workloads, coreInfos]) + }, [workloads, coreInfos]); useEffect((): void => { if (!workloadData?.length || !leases?.length || !reservations?.length) { return; } - const chainInfo: Record = {}; + const chainInfo: Record = {}; paraIds?.forEach((id: ParaId) => { const lease = leases?.find((lease) => lease.task === id.toString()); @@ -69,25 +70,25 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI const workload = workloadData?.find((one) => one.info.task === id.toString()); chainInfo[id.toString()] = { - id: id.toNumber(), + id: id.toNumber() as unknown as ParaId, lease, + renewal: potentialRenewalsCurrentRegion?.find((renewal) => renewal.task.toString() === id.toString()), reservation, workload: workloadData, - renewal: potentialRenewalsCurrentRegion?.find((renewal) => renewal.task.toString() === id.toString()), - renewed: workplans?.find((workplan) => workplan.core === workload?.core && workplan.info.task.toString() === id.toString()) + worklplan: workplans?.filter((workplan) => workplan.core === workload?.core && workplan.info.task.toString() === id.toString()) }; }); if (chainInfo) { setState({ chainInfo, + config, + region, salesInfo, status, - region, - config }); } - }, [paraIds, workloadData, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status]); + }, [paraIds, workloadData, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status, config, workplans]); return state; } diff --git a/packages/react-hooks/src/useRegions.ts b/packages/react-hooks/src/useRegions.ts index 4570c3c39c91..ad6eb98d51b6 100644 --- a/packages/react-hooks/src/useRegions.ts +++ b/packages/react-hooks/src/useRegions.ts @@ -29,7 +29,7 @@ const OPT_KEY = { function useRegionsImpl (api: ApiPromise): RegionInfo[] | undefined { const regionKeys = useMapKeys(api.query.broker.regions, [], OPT_KEY); - const regionInfo = useCall<[[PalletBrokerRegionId[]], Option[]]>(api.query.broker.regions.multi, [regionKeys], { withParams: true }); + const regionInfo = useCall<[[PalletBrokerRegionId[]], Option[]]>(api?.query?.broker.regions.multi, [regionKeys], { withParams: true }); const [state, setState] = useState(); From a5de399bdade3c6845d6a79a797877e0f426aa6e Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Thu, 17 Oct 2024 15:44:47 +0800 Subject: [PATCH 13/22] tsc --- packages/page-broker/src/Overview/Summary.tsx | 51 ++++++++++--------- .../src/Overview/Summary/Cores.tsx | 24 --------- .../src/useBrokerPotentialRenewals.ts | 28 ++++++---- .../react-hooks/src/useCoretimeInformation.ts | 6 +-- packages/react-hooks/src/useRegions.ts | 2 +- .../react-hooks/src/utils/dataProcessing.ts | 4 +- packages/react-query/src/BrokerStatus.tsx | 25 --------- packages/react-query/src/index.ts | 1 - 8 files changed, 50 insertions(+), 91 deletions(-) delete mode 100644 packages/page-broker/src/Overview/Summary/Cores.tsx delete mode 100644 packages/react-query/src/BrokerStatus.tsx diff --git a/packages/page-broker/src/Overview/Summary.tsx b/packages/page-broker/src/Overview/Summary.tsx index e85e71af4d42..9a4840e54828 100644 --- a/packages/page-broker/src/Overview/Summary.tsx +++ b/packages/page-broker/src/Overview/Summary.tsx @@ -10,7 +10,7 @@ import { CardSummary, styled, SummaryBox, UsageBar } from '@polkadot/react-compo import { defaultHighlight } from '@polkadot/react-components/styles'; import { useApi, useBrokerConfig, useBrokerSalesInfo, useBrokerStatus } from '@polkadot/react-hooks'; import { type CoreWorkload } from '@polkadot/react-hooks/types'; -import { BN } from '@polkadot/util'; +import { BN, BN_ZERO } from '@polkadot/util'; import { useTranslation } from '../translate.js'; import { estimateTime, getStats } from '../utils.js'; @@ -39,7 +39,7 @@ interface Props { workloadInfos?: CoreWorkload[] } -function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { +function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { const { t } = useTranslation(); const { api, apiEndpoint, isApiReady } = useApi(); const uiHighlight = apiEndpoint?.ui.color || defaultHighlight; @@ -79,7 +79,7 @@ function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { progress={{ isBlurred: false, total: new BN(config?.regionLength || 0), - value: config?.regionLength && new BN(config?.regionLength - (currentRegionEnd - status?.lastTimeslice)), + value: config?.regionLength && currentRegionEnd && status && new BN(config?.regionLength - (currentRegionEnd - status?.lastTimeslice)) || BN_ZERO, withTime: false }} /> @@ -88,7 +88,7 @@ function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { )}
- {status && + {status && currentRegionStart && currentRegionEnd && ( - -
-
{estimateTime(currentRegionStart, status?.lastTimeslice * 80)}
-
{estimateTime(currentRegionEnd, status?.lastTimeslice * 80)}
-
-
+ <> + +
+
{estimateTime(currentRegionStart, status?.lastTimeslice * 80)}
+
{estimateTime(currentRegionEnd, status?.lastTimeslice * 80)}
+
+
+ + +
+
{currentRegionStart}
+
{currentRegionEnd}
+
+
+ ) } - {status && - -
-
{currentRegionStart}
-
{currentRegionEnd}
-
-
- }
); diff --git a/packages/page-broker/src/Overview/Summary/Cores.tsx b/packages/page-broker/src/Overview/Summary/Cores.tsx deleted file mode 100644 index 2e15228a741d..000000000000 --- a/packages/page-broker/src/Overview/Summary/Cores.tsx +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017-2024 @polkadot/app-broker authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; - -import { BrokerStatus } from '@polkadot/react-query'; - -interface Props { - children?: React.ReactNode; - className?: string; -} - -function Cores ({ children, className }: Props): React.ReactElement | null { - return ( - - {children} - - ); -} - -export default React.memo(Cores); diff --git a/packages/react-hooks/src/useBrokerPotentialRenewals.ts b/packages/react-hooks/src/useBrokerPotentialRenewals.ts index 5b611aea5402..c51c383ac202 100644 --- a/packages/react-hooks/src/useBrokerPotentialRenewals.ts +++ b/packages/react-hooks/src/useBrokerPotentialRenewals.ts @@ -5,6 +5,7 @@ import type { ApiPromise } from '@polkadot/api'; import type { Option, StorageKey, u32 } from '@polkadot/types'; import type { PalletBrokerPotentialRenewalId, PalletBrokerPotentialRenewalRecord } from '@polkadot/types/lookup'; import type { PotentialRenewal } from './types.js'; +import { BN_ZERO, } from '@polkadot/util'; import { useEffect, useState } from 'react'; @@ -12,10 +13,14 @@ import { createNamedHook, useCall, useMapKeys } from '@polkadot/react-hooks'; import { processHexMask } from './utils/dataProcessing.js'; -function extractInfo (info: Option, item: PalletBrokerPotentialRenewalId): PotentialRenewal { +function extractInfo (info: Option, item: PalletBrokerPotentialRenewalId): PotentialRenewal | undefined { const unwrapped: PalletBrokerPotentialRenewalRecord | null = info.isSome ? info.unwrap() : null; - let mask = []; - let task = null; + let mask: string[] = []; + let task = ''; + + if (!unwrapped) { + return + } const completion = unwrapped?.completion; if (completion?.isComplete) { @@ -24,8 +29,8 @@ function extractInfo (info: Option, item: Pa task = complete.assignment.isTask ? complete?.assignment.asTask.toString() : complete?.assignment.isPool ? 'Pool' : 'Idle'; mask = processHexMask(complete.mask); } else if (completion?.isPartial) { - task = null; - mask = completion.asPartial[0]; + mask = processHexMask(completion?.asPartial); + task = ''; } else { mask = []; } @@ -36,10 +41,11 @@ function extractInfo (info: Option, item: Pa core: item?.core.toNumber(), mask, maskBits: mask?.length, - price: unwrapped?.price.toBn(), + price: unwrapped?.price.toBn() || BN_ZERO, task, when: item?.when.toNumber() }; + } const OPT_KEY = { @@ -51,12 +57,14 @@ function useBrokerPotentialRenewalsImpl (api: ApiPromise, ready: boolean): Poten const keys = useMapKeys(ready && api?.query.broker.potentialRenewals, [], OPT_KEY); const potentialRenewals = useCall<[[PalletBrokerPotentialRenewalId[]], Option[]]>(ready && api?.query.broker.potentialRenewals.multi, [keys], { withParams: true }); - const [state, setState] = useState(); + const [state, setState] = useState(); useEffect((): void => { - potentialRenewals && - setState(potentialRenewals[0][0].map((info, index) => extractInfo(potentialRenewals[1][index], info)) - ); + if (!potentialRenewals) { + return + } + const renewals = potentialRenewals[0][0].map((info, index) => extractInfo(potentialRenewals[1][index], info)) + setState(renewals.filter((renewal): renewal is PotentialRenewal => !!renewal)); }, [potentialRenewals]); return state; diff --git a/packages/react-hooks/src/useCoretimeInformation.ts b/packages/react-hooks/src/useCoretimeInformation.ts index bca05612ee38..0fca884c1e66 100644 --- a/packages/react-hooks/src/useCoretimeInformation.ts +++ b/packages/react-hooks/src/useCoretimeInformation.ts @@ -32,7 +32,7 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI const coreInfos = useCoreDescriptor(api, ready); const potentialRenewalsCurrentRegion = useMemo(() => potentialRenewals?.filter((renewal: PotentialRenewal) => renewal.when === salesInfo?.regionEnd), [potentialRenewals, salesInfo]); - const [state, setState] = useState(); + const [state, setState] = useState(); useEffect(() => { if (workloads?.length) { @@ -53,7 +53,7 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI ) as CoreWorkloadInfo) })); - setWorkloadData(parsedCoreInfos); + setWorkloadData(parsedCoreInfos as unknown as CoreWorkload[]); } }, [workloads, coreInfos]); @@ -79,7 +79,7 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI }; }); - if (chainInfo) { + if (chainInfo && config && region && salesInfo && status) { setState({ chainInfo, config, diff --git a/packages/react-hooks/src/useRegions.ts b/packages/react-hooks/src/useRegions.ts index ad6eb98d51b6..9e115ec0e726 100644 --- a/packages/react-hooks/src/useRegions.ts +++ b/packages/react-hooks/src/useRegions.ts @@ -27,7 +27,7 @@ const OPT_KEY = { }; function useRegionsImpl (api: ApiPromise): RegionInfo[] | undefined { - const regionKeys = useMapKeys(api.query.broker.regions, [], OPT_KEY); + const regionKeys = useMapKeys(api?.query?.broker.regions, [], OPT_KEY); const regionInfo = useCall<[[PalletBrokerRegionId[]], Option[]]>(api?.query?.broker.regions.multi, [regionKeys], { withParams: true }); diff --git a/packages/react-hooks/src/utils/dataProcessing.ts b/packages/react-hooks/src/utils/dataProcessing.ts index af03b48fc8d1..100d6b5fa179 100644 --- a/packages/react-hooks/src/utils/dataProcessing.ts +++ b/packages/react-hooks/src/utils/dataProcessing.ts @@ -1,7 +1,7 @@ // Copyright 2017-2024 @polkadot/react-hooks authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { PalletBrokerScheduleItem } from '@polkadot/types/lookup'; +import type { PalletBrokerScheduleItem, PalletBrokerCoreMask } from '@polkadot/types/lookup'; import { BN } from '@polkadot/util'; @@ -9,7 +9,7 @@ export function hexToBin (hex: string): string { return parseInt(hex, 16).toString(2); } -export function processHexMask (mask: PalletBrokerScheduleItem['mask'] | undefined): string[] { +export function processHexMask (mask: PalletBrokerScheduleItem['mask'] | PalletBrokerCoreMask | undefined): string[] { if (!mask) { return []; } diff --git a/packages/react-query/src/BrokerStatus.tsx b/packages/react-query/src/BrokerStatus.tsx deleted file mode 100644 index a85ed52d94cd..000000000000 --- a/packages/react-query/src/BrokerStatus.tsx +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017-2024 @polkadot/react-query authors & contributors -// SPDX-License-Identifier: Apache-2.0 - -import React from 'react'; - -import { useBrokerStatus } from '@polkadot/react-hooks'; - -interface Props { - children?: React.ReactNode; - className?: string; - query: string; -} - -function BrokerStatus ({ children, className = '', query }: Props): React.ReactElement { - const info = useBrokerStatus(query) || '-'; - - return ( -
- {info} - {children} -
- ); -} - -export default React.memo(BrokerStatus); diff --git a/packages/react-query/src/index.ts b/packages/react-query/src/index.ts index 53d94bf4566b..6d29a47722a7 100644 --- a/packages/react-query/src/index.ts +++ b/packages/react-query/src/index.ts @@ -8,7 +8,6 @@ export { default as BestFinalized } from './BestFinalized.js'; export { default as BestNumber } from './BestNumber.js'; export { default as BlockToTime } from './BlockToTime.js'; export { default as Bonded } from './Bonded.js'; -export { default as BrokerStatus } from './BrokerStatus.js'; export { default as Chain } from './Chain.js'; export { default as Elapsed } from './Elapsed.js'; export { default as FormatBalance } from './FormatBalance.js'; From ad8053bb048946e1e53f3150c30dd2be1edf64ee Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Thu, 17 Oct 2024 21:28:11 +0800 Subject: [PATCH 14/22] merging parachainIds with renewalIds --- packages/page-broker/src/Overview/Summary.tsx | 5 +-- .../page-coretime/src/Overview/Summary.tsx | 12 +++--- .../page-coretime/src/ParachainsTable.tsx | 23 ++++------- packages/page-coretime/src/index.tsx | 21 +++------- packages/page-coretime/src/utils.ts | 9 ++-- packages/react-hooks/src/types.ts | 7 ++-- .../src/useBrokerPotentialRenewals.ts | 12 +++--- .../react-hooks/src/useCoretimeInformation.ts | 41 ++++++++++++++----- .../react-hooks/src/utils/dataProcessing.ts | 4 +- 9 files changed, 69 insertions(+), 65 deletions(-) diff --git a/packages/page-broker/src/Overview/Summary.tsx b/packages/page-broker/src/Overview/Summary.tsx index 9a4840e54828..28e53cc90909 100644 --- a/packages/page-broker/src/Overview/Summary.tsx +++ b/packages/page-broker/src/Overview/Summary.tsx @@ -39,7 +39,7 @@ interface Props { workloadInfos?: CoreWorkload[] } -function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { +function Summary ({ coreCount, workloadInfos }: Props): React.ReactElement { const { t } = useTranslation(); const { api, apiEndpoint, isApiReady } = useApi(); const uiHighlight = apiEndpoint?.ui.color || defaultHighlight; @@ -79,7 +79,7 @@ function Summary({ coreCount, workloadInfos }: Props): React.ReactElement { progress={{ isBlurred: false, total: new BN(config?.regionLength || 0), - value: config?.regionLength && currentRegionEnd && status && new BN(config?.regionLength - (currentRegionEnd - status?.lastTimeslice)) || BN_ZERO, + value: (config?.regionLength && currentRegionEnd && status && new BN(config?.regionLength - (currentRegionEnd - status?.lastTimeslice))) || BN_ZERO, withTime: false }} /> @@ -114,7 +114,6 @@ function Summary({ coreCount, workloadInfos }: Props): React.ReactElement {
{estimateTime(currentRegionEnd, status?.lastTimeslice * 80)}
- { +function Summary({ api, config, parachainCount, saleInfo, status }: Props): React.ReactElement { const { t } = useTranslation(); const currentRegionEnd = saleInfo.regionEnd - config.regionLength; const currentRegionStart = saleInfo.regionEnd - config.regionLength * 2; const chainName = useCall(api?.rpc.system.chain)?.toString().toLowerCase(); const cycleNumber = useMemo(() => - chainName && currentRegionEnd && Math.floor((currentRegionEnd - CoreTimeConsts.FirstCycleStart[chainName]) / config.regionLength) - , [currentRegionEnd, chainName, config]); + chainName && currentRegionEnd && Math.floor((currentRegionEnd - FirstCycleStart[chainName]) / config.regionLength) + , [currentRegionEnd, chainName, config]); return ( diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx index 53f844bfbf51..cf45a0d91787 100644 --- a/packages/page-coretime/src/ParachainsTable.tsx +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -20,7 +20,6 @@ export enum CoreTimeTypes { } interface Props { - ids: number[] coretimeInfo: CoretimeInformation } @@ -30,21 +29,17 @@ const colours: Record = { [CoreTimeTypes['Bulk Coretime']]: 'pink' }; -function ParachainsTable ({ coretimeInfo, ids }: Props): React.ReactElement { +function ParachainsTable ({ coretimeInfo }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([ [t('parachains'), 'start'], [t('name'), 'start'], - // ['', 'media--1400'], [t('core number'), 'start'], [t('type'), 'start'], [t('last block'), 'start'], [t('end'), 'start'], [t('renewal'), 'start'], [t('renewal price'), 'start'] - // [t('chain'), 'no-pad-left'], - // [t('in/out'), 'media--1700', 2], - // [t('leases'), 'media--1100'] ]); return ( @@ -53,20 +48,18 @@ function ParachainsTable ({ coretimeInfo, ids }: Props): React.ReactElement - {ids && coretimeInfo && ids.map((id: number) => { - const chain = coretimeInfo.chainInfo[id]; + {coretimeInfo?.taskIds?.map((taskId: number) => { + const chain = coretimeInfo.chainInfo[taskId]; const type = chain?.lease ? CoreTimeTypes.Lease : chain?.reservation ? CoreTimeTypes.Reservation : CoreTimeTypes['Bulk Coretime']; const targetTimeslice = chain?.lease?.until || coretimeInfo.salesInfo.regionEnd; const showEsimates = !!targetTimeslice && type !== CoreTimeTypes.Reservation; - // const renewBefore = return ( - - {id} + + {taskId} {chain?.workload?.core} @@ -78,8 +71,8 @@ function ParachainsTable ({ coretimeInfo, ids }: Props): React.ReactElement {showEsimates && formatNumber(targetTimeslice * 80).toString()} {showEsimates && estimateTime(targetTimeslice, coretimeInfo.status.lastCommittedTimeslice * 80)} - {chain.renewal ? 'renewed' : ''} - {chain.renewal ? formatBalance(chain.renewal?.price.toString()) : ''} + {chain?.renewal ? 'renewed' : ''} + {chain?.renewal ? formatBalance(chain.renewal?.price.toString()) : ''} ); } diff --git a/packages/page-coretime/src/index.tsx b/packages/page-coretime/src/index.tsx index 7e24ba022520..3125e2b32760 100644 --- a/packages/page-coretime/src/index.tsx +++ b/packages/page-coretime/src/index.tsx @@ -2,12 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 import type { TabItem } from '@polkadot/react-components/types'; -import type { ParaId } from '@polkadot/types/interfaces'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useRef } from 'react'; import { Tabs } from '@polkadot/react-components'; -import { useApi, useCall, useCoretimeInformation } from '@polkadot/react-hooks'; +import { useApi, useCoretimeInformation } from '@polkadot/react-hooks'; import Summary from './Overview/Summary.js'; import ParachainsTable from './ParachainsTable.js'; @@ -32,37 +31,27 @@ function CoretimeApp ({ basePath, className }: Props): React.ReactElement const { t } = useTranslation(); const { api, isApiReady } = useApi(); const itemsRef = useRef(createItemsRef(t)); - const [parachainIds, setParachainIds] = useState([]); const coretimeInfo = useCoretimeInformation(api, isApiReady); - const paraIds = useCall(api.query.paras.parachains); - - useEffect(() => { - if (paraIds) { - setParachainIds(paraIds.map((a) => a.toNumber())); - } - }, [paraIds]); - return (
- {coretimeInfo?.salesInfo && ( + {coretimeInfo && ( )} - {!!parachainIds && + {!!coretimeInfo && } diff --git a/packages/page-coretime/src/utils.ts b/packages/page-coretime/src/utils.ts index d05d6028c5a7..bd8cf1e5aa5a 100644 --- a/packages/page-coretime/src/utils.ts +++ b/packages/page-coretime/src/utils.ts @@ -7,12 +7,13 @@ export const CoreTimeConsts = { BlockTime: 6000, BlocksPerTimeslice: 80, DefaultRegion: 5040, - FirstCycleStart: { - kusama: 285768, - polkadot: 282525 - } }; +export const FirstCycleStart: Record ={ + kusama: 285768, + polkadot: 282525 +} + function formatDate (date: Date) { const day = date.getDate(); const month = date.toLocaleString('default', { month: 'short' }); diff --git a/packages/react-hooks/src/types.ts b/packages/react-hooks/src/types.ts index 9ff9991cccd4..c4500712575e 100644 --- a/packages/react-hooks/src/types.ts +++ b/packages/react-hooks/src/types.ts @@ -7,7 +7,7 @@ import type { SubmittableExtrinsic } from '@polkadot/api/types'; import type { DeriveAccountFlags, DeriveAccountRegistration } from '@polkadot/api-derive/types'; import type { DisplayedJudgement } from '@polkadot/react-components/types'; import type { Option, u32, u128, Vec } from '@polkadot/types'; -import type { AccountId, BlockNumber, Call, Hash, ParaId, SessionIndex, ValidatorPrefs } from '@polkadot/types/interfaces'; +import type { AccountId, BlockNumber, Call, Hash, SessionIndex, ValidatorPrefs } from '@polkadot/types/interfaces'; import type { PalletPreimageRequestStatus, PalletStakingRewardDestination, PalletStakingStakingLedger, PolkadotRuntimeParachainsAssignerCoretimeCoreDescriptor, SpStakingExposurePage, SpStakingPagedExposureMetadata } from '@polkadot/types/lookup'; import type { ICompact, IExtrinsic, INumber } from '@polkadot/types/types'; import type { KeyringJson$Meta } from '@polkadot/ui-keyring/types'; @@ -323,8 +323,8 @@ export interface PalletBrokerConfigRecord { } export interface ChainInformation { - id: ParaId, - workload: CoreWorkload[] | undefined, + id: number, + workload: CoreWorkload | undefined, renewal: PotentialRenewal | undefined, worklplan: CoreWorkplan[] | undefined, lease: LegacyLease | undefined, @@ -336,6 +336,7 @@ export interface CoretimeInformation { status: BrokerStatus, region: RegionInfo[], config: PalletBrokerConfigRecord + taskIds: number[] } export interface BrokerStatus { diff --git a/packages/react-hooks/src/useBrokerPotentialRenewals.ts b/packages/react-hooks/src/useBrokerPotentialRenewals.ts index c51c383ac202..ed5cebbdfb8d 100644 --- a/packages/react-hooks/src/useBrokerPotentialRenewals.ts +++ b/packages/react-hooks/src/useBrokerPotentialRenewals.ts @@ -5,11 +5,11 @@ import type { ApiPromise } from '@polkadot/api'; import type { Option, StorageKey, u32 } from '@polkadot/types'; import type { PalletBrokerPotentialRenewalId, PalletBrokerPotentialRenewalRecord } from '@polkadot/types/lookup'; import type { PotentialRenewal } from './types.js'; -import { BN_ZERO, } from '@polkadot/util'; import { useEffect, useState } from 'react'; import { createNamedHook, useCall, useMapKeys } from '@polkadot/react-hooks'; +import { BN_ZERO } from '@polkadot/util'; import { processHexMask } from './utils/dataProcessing.js'; @@ -19,8 +19,9 @@ function extractInfo (info: Option, item: Pa let task = ''; if (!unwrapped) { - return + return; } + const completion = unwrapped?.completion; if (completion?.isComplete) { @@ -45,7 +46,6 @@ function extractInfo (info: Option, item: Pa task, when: item?.when.toNumber() }; - } const OPT_KEY = { @@ -61,9 +61,11 @@ function useBrokerPotentialRenewalsImpl (api: ApiPromise, ready: boolean): Poten useEffect((): void => { if (!potentialRenewals) { - return + return; } - const renewals = potentialRenewals[0][0].map((info, index) => extractInfo(potentialRenewals[1][index], info)) + + const renewals = potentialRenewals[0][0].map((info, index) => extractInfo(potentialRenewals[1][index], info)); + setState(renewals.filter((renewal): renewal is PotentialRenewal => !!renewal)); }, [potentialRenewals]); diff --git a/packages/react-hooks/src/useCoretimeInformation.ts b/packages/react-hooks/src/useCoretimeInformation.ts index 0fca884c1e66..5fa788f55b16 100644 --- a/packages/react-hooks/src/useCoretimeInformation.ts +++ b/packages/react-hooks/src/useCoretimeInformation.ts @@ -15,6 +15,7 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI const { apiCoretime, isApiReady } = useApi(); const [workloadData, setWorkloadData] = useState([]); + const [taskIds, setTaskIds] = useState([]); /** coretime API calls */ const status = useBrokerStatus(apiCoretime, isApiReady); @@ -30,10 +31,24 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI /** Other APIs */ const paraIds = useCall(api.query.paras.parachains); const coreInfos = useCoreDescriptor(api, ready); - - const potentialRenewalsCurrentRegion = useMemo(() => potentialRenewals?.filter((renewal: PotentialRenewal) => renewal.when === salesInfo?.regionEnd), [potentialRenewals, salesInfo]); + // when - The point in time that the renewable workload on core ends and a fresh renewal may begin. + const potentialRenewalsCurrentRegion = useMemo(() => config && salesInfo && potentialRenewals?.filter((renewal: PotentialRenewal) => renewal.when.toString() === salesInfo?.regionBegin.toString()), [potentialRenewals, salesInfo, config]); const [state, setState] = useState(); + useEffect(() => { + if (paraIds?.length && potentialRenewals?.length && !taskIds.length) { + const simpleIds = paraIds.map((p) => p.toNumber()); + const renewalIds = potentialRenewals?.map((r) => Number(r.task)); + const numbers = [...new Set(simpleIds.concat(renewalIds))]; + + if (numbers?.length > simpleIds.length) { + setTaskIds(numbers.sort((a, b) => a - b)); + } else { + setTaskIds(simpleIds); + } + } + }, [potentialRenewals, paraIds, taskIds]); + useEffect(() => { if (workloads?.length) { setWorkloadData(workloads); @@ -64,18 +79,21 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI const chainInfo: Record = {}; - paraIds?.forEach((id: ParaId) => { - const lease = leases?.find((lease) => lease.task === id.toString()); - const reservation = reservations?.find((reservation) => reservation.task === id.toString()); - const workload = workloadData?.find((one) => one.info.task === id.toString()); + taskIds?.forEach((id) => { + const taskId = id.toString(); + const lease = leases?.find((lease) => lease.task === taskId); + const reservation = reservations?.find((reservation) => reservation.task === taskId); + const workload = workloadData?.find((one) => one.info.task === taskId); + const renewal = potentialRenewalsCurrentRegion?.find((renewal) => renewal.task.toString() === taskId); + const worklplan = workplans?.filter((workplan) => workplan.core === workload?.core && workplan.info.task.toString() === taskId); chainInfo[id.toString()] = { - id: id.toNumber() as unknown as ParaId, + id, lease, - renewal: potentialRenewalsCurrentRegion?.find((renewal) => renewal.task.toString() === id.toString()), + renewal, reservation, - workload: workloadData, - worklplan: workplans?.filter((workplan) => workplan.core === workload?.core && workplan.info.task.toString() === id.toString()) + workload, + worklplan }; }); @@ -86,9 +104,10 @@ function useCoretimeInformationImpl (api: ApiPromise, ready: boolean): CoretimeI region, salesInfo, status, + taskIds }); } - }, [paraIds, workloadData, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status, config, workplans]); + }, [taskIds, workloadData, potentialRenewalsCurrentRegion, salesInfo, leases, reservations, region, status, config, workplans]); return state; } diff --git a/packages/react-hooks/src/utils/dataProcessing.ts b/packages/react-hooks/src/utils/dataProcessing.ts index 100d6b5fa179..af03b48fc8d1 100644 --- a/packages/react-hooks/src/utils/dataProcessing.ts +++ b/packages/react-hooks/src/utils/dataProcessing.ts @@ -1,7 +1,7 @@ // Copyright 2017-2024 @polkadot/react-hooks authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { PalletBrokerScheduleItem, PalletBrokerCoreMask } from '@polkadot/types/lookup'; +import type { PalletBrokerScheduleItem } from '@polkadot/types/lookup'; import { BN } from '@polkadot/util'; @@ -9,7 +9,7 @@ export function hexToBin (hex: string): string { return parseInt(hex, 16).toString(2); } -export function processHexMask (mask: PalletBrokerScheduleItem['mask'] | PalletBrokerCoreMask | undefined): string[] { +export function processHexMask (mask: PalletBrokerScheduleItem['mask'] | undefined): string[] { if (!mask) { return []; } From d807d4e8f1ee4c91b86c74b3eca7cfbccfe1e579 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Thu, 17 Oct 2024 21:35:53 +0800 Subject: [PATCH 15/22] if there is no record in potential renewals, then the chain has renewed already --- packages/page-coretime/src/ParachainsTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx index cf45a0d91787..6a2d3354480f 100644 --- a/packages/page-coretime/src/ParachainsTable.tsx +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -29,7 +29,7 @@ const colours: Record = { [CoreTimeTypes['Bulk Coretime']]: 'pink' }; -function ParachainsTable ({ coretimeInfo }: Props): React.ReactElement { +function ParachainsTable({ coretimeInfo }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([ [t('parachains'), 'start'], @@ -71,7 +71,7 @@ function ParachainsTable ({ coretimeInfo }: Props): React.ReactElement { {showEsimates && formatNumber(targetTimeslice * 80).toString()} {showEsimates && estimateTime(targetTimeslice, coretimeInfo.status.lastCommittedTimeslice * 80)} - {chain?.renewal ? 'renewed' : ''} + {chain?.renewal ? 'eligible' : type === CoreTimeTypes['Bulk Coretime'] ? 'renewed' : ''} {chain?.renewal ? formatBalance(chain.renewal?.price.toString()) : ''} ); From 316243a8b19a16b92f6d5bbcb934be4d5c6bcde5 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Thu, 17 Oct 2024 21:51:47 +0800 Subject: [PATCH 16/22] added config for page-coretime --- packages/page-coretime/src/Overview/Summary.tsx | 6 +++--- packages/page-coretime/src/ParachainsTable.tsx | 2 +- packages/page-coretime/src/utils.ts | 6 +++--- tsconfig.base.json | 1 + tsconfig.build.json | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/page-coretime/src/Overview/Summary.tsx b/packages/page-coretime/src/Overview/Summary.tsx index d07e00c0deb7..fa570454940f 100644 --- a/packages/page-coretime/src/Overview/Summary.tsx +++ b/packages/page-coretime/src/Overview/Summary.tsx @@ -11,7 +11,7 @@ import { useCall } from '@polkadot/react-hooks'; import { BN } from '@polkadot/util'; import { useTranslation } from '../translate.js'; -import { FirstCycleStart, estimateTime } from '../utils.js'; +import { estimateTime, FirstCycleStart } from '../utils.js'; interface Props { api: ApiPromise | null, @@ -23,7 +23,7 @@ interface Props { parachainCount: number } -function Summary({ api, config, parachainCount, saleInfo, status }: Props): React.ReactElement { +function Summary ({ api, config, parachainCount, saleInfo, status }: Props): React.ReactElement { const { t } = useTranslation(); const currentRegionEnd = saleInfo.regionEnd - config.regionLength; const currentRegionStart = saleInfo.regionEnd - config.regionLength * 2; @@ -31,7 +31,7 @@ function Summary({ api, config, parachainCount, saleInfo, status }: Props): Reac const cycleNumber = useMemo(() => chainName && currentRegionEnd && Math.floor((currentRegionEnd - FirstCycleStart[chainName]) / config.regionLength) - , [currentRegionEnd, chainName, config]); + , [currentRegionEnd, chainName, config]); return ( diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx index 6a2d3354480f..df48c0cbf836 100644 --- a/packages/page-coretime/src/ParachainsTable.tsx +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -29,7 +29,7 @@ const colours: Record = { [CoreTimeTypes['Bulk Coretime']]: 'pink' }; -function ParachainsTable({ coretimeInfo }: Props): React.ReactElement { +function ParachainsTable ({ coretimeInfo }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([ [t('parachains'), 'start'], diff --git a/packages/page-coretime/src/utils.ts b/packages/page-coretime/src/utils.ts index bd8cf1e5aa5a..51030072c13c 100644 --- a/packages/page-coretime/src/utils.ts +++ b/packages/page-coretime/src/utils.ts @@ -6,13 +6,13 @@ import { BN } from '@polkadot/util'; export const CoreTimeConsts = { BlockTime: 6000, BlocksPerTimeslice: 80, - DefaultRegion: 5040, + DefaultRegion: 5040 }; -export const FirstCycleStart: Record ={ +export const FirstCycleStart: Record = { kusama: 285768, polkadot: 282525 -} +}; function formatDate (date: Date) { const day = date.getDate(); diff --git a/tsconfig.base.json b/tsconfig.base.json index 662448d98d4f..158c1f661e9a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -33,6 +33,7 @@ "@polkadot/app-collator": ["page-collator/src/index.tsx"], "@polkadot/app-contracts": ["page-contracts/src/index.tsx"], "@polkadot/app-council": ["page-council/src/index.tsx"], + "@polkadot/app-coretime": ["page-coretime/src/index.tsx"], "@polkadot/app-democracy": ["page-democracy/src/index.tsx"], "@polkadot/app-democracy/*": ["page-democracy/src/*.tsx"], "@polkadot/app-extrinsics": ["page-extrinsics/src/index.tsx"], diff --git a/tsconfig.build.json b/tsconfig.build.json index bea32db31494..53428eb1a1a0 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -28,6 +28,7 @@ { "path": "./packages/page-collator/tsconfig.build.json" }, { "path": "./packages/page-contracts/tsconfig.build.json" }, { "path": "./packages/page-council/tsconfig.build.json" }, + { "path": "./packages/page-coretime/tsconfig.build.json" }, { "path": "./packages/page-democracy/tsconfig.build.json" }, { "path": "./packages/page-explorer/tsconfig.build.json" }, { "path": "./packages/page-extrinsics/tsconfig.build.json" }, From fc8c983d494a15b0894be47cb392e6d4e6877374 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Fri, 18 Oct 2024 16:45:33 +0800 Subject: [PATCH 17/22] removed hardcoded regionLength value --- packages/page-broker/src/Overview/CoreTable.tsx | 5 ++++- packages/page-broker/src/Overview/CoresTables.tsx | 6 +++++- packages/page-broker/src/Overview/Workload.tsx | 12 +++++++----- packages/page-broker/src/Overview/index.tsx | 3 ++- packages/page-broker/src/utils.ts | 3 +-- packages/page-coretime/src/utils.ts | 1 - 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/page-broker/src/Overview/CoreTable.tsx b/packages/page-broker/src/Overview/CoreTable.tsx index 1fb9bba2ea5c..84a0751b7f43 100644 --- a/packages/page-broker/src/Overview/CoreTable.tsx +++ b/packages/page-broker/src/Overview/CoreTable.tsx @@ -10,15 +10,17 @@ import { Table } from '@polkadot/react-components'; import { useTranslation } from '../translate.js'; import { type CoreWorkloadType, type CoreWorkplanType } from '../types.js'; import Workload from './Workload.js'; +import { PalletBrokerConfigRecord } from '@polkadot/react-hooks/types'; interface Props { api: ApiPromise; core: number; + config: PalletBrokerConfigRecord, workload?: CoreWorkloadType[], workplan?: CoreWorkplanType[], } -function CoreTable ({ api, core, workload, workplan }: Props): React.ReactElement { +function CoreTable({ api, core, workload, workplan, config }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?] | false)[]>([[t('core')]]); const header: [React.ReactNode?, string?, number?, (() => void)?][] = [ @@ -43,6 +45,7 @@ function CoreTable ({ api, core, workload, workplan }: Props): React.ReactElemen key={core} workload={workload} workplan={workplan} + config={config} /> diff --git a/packages/page-broker/src/Overview/CoresTables.tsx b/packages/page-broker/src/Overview/CoresTables.tsx index 41517a43fe06..4e4c836be6a8 100644 --- a/packages/page-broker/src/Overview/CoresTables.tsx +++ b/packages/page-broker/src/Overview/CoresTables.tsx @@ -7,13 +7,16 @@ import type { CoreInfo } from '../types.js'; import React from 'react'; import CoreTable from './CoreTable.js'; +import { useBrokerConfig } from '@polkadot/react-hooks'; interface Props { api: ApiPromise; + isApiReady: boolean; data: CoreInfo[]; } -function CoresTable ({ api, data }: Props): React.ReactElement { +function CoresTable({ api, isApiReady, data }: Props): React.ReactElement { + const config = useBrokerConfig(api, isApiReady); return ( <> {data?.map((coreData) => { @@ -24,6 +27,7 @@ function CoresTable ({ api, data }: Props): React.ReactElement { key={coreData?.core} workload={coreData?.workload} workplan={coreData?.workplan} + config={config} /> ); })} diff --git a/packages/page-broker/src/Overview/Workload.tsx b/packages/page-broker/src/Overview/Workload.tsx index cb1f8ecca41e..b3f47131ad7d 100644 --- a/packages/page-broker/src/Overview/Workload.tsx +++ b/packages/page-broker/src/Overview/Workload.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { ApiPromise } from '@polkadot/api'; -import type { RegionInfo } from '@polkadot/react-hooks/types'; +import type { PalletBrokerConfigRecord, RegionInfo } from '@polkadot/react-hooks/types'; import type { Option } from '@polkadot/types'; import type { PalletBrokerStatusRecord } from '@polkadot/types/lookup'; import type { CoreWorkloadType, CoreWorkplanType, InfoRow } from '../types.js'; @@ -15,15 +15,17 @@ import { useApi, useBrokerSalesInfo, useCall, useRegions, useToggle } from '@pol import { CoreTimeConsts, formatRowInfo } from '../utils.js'; import WorkInfoRow from './WorkInfoRow.js'; import Workplan from './Workplan.js'; +import RegionLength from './Summary/RegionLength.jsx'; interface Props { api: ApiPromise; core: number; workload: CoreWorkloadType[] | undefined workplan?: CoreWorkplanType[] | undefined + config: PalletBrokerConfigRecord } -function Workload ({ api, core, workload, workplan }: Props): React.ReactElement { +function Workload({ api, core, workload, workplan, config }: Props): React.ReactElement { const { isApiReady } = useApi(); const salesInfo = useBrokerSalesInfo(api, isApiReady); @@ -46,7 +48,7 @@ function Workload ({ api, core, workload, workplan }: Props): React.ReactElement useEffect(() => { if (!!workload?.length && !!salesInfo) { // saleInfo points to a regionEnd and regionBeing in the next cycle, but we want the start and end of the current cycle - setWorkloadData(formatRowInfo(workload, core, region, currentTimeSlice, { regionBegin: salesInfo.regionBegin - CoreTimeConsts.DefaultRegion, regionEnd: salesInfo.regionEnd - CoreTimeConsts.DefaultRegion })); + setWorkloadData(formatRowInfo(workload, core, region, currentTimeSlice, { regionBegin: salesInfo.regionBegin - config.regionLength, regionEnd: salesInfo.regionEnd - config.regionLength }, config.regionLength)); } else { return setWorkloadData([{ core }]); } @@ -54,10 +56,10 @@ function Workload ({ api, core, workload, workplan }: Props): React.ReactElement useEffect(() => { if (!!workplan?.length && !!salesInfo) { - setWorkplanData(formatRowInfo(workplan, core, region, currentTimeSlice, salesInfo)); + setWorkplanData(formatRowInfo(workplan, core, region, currentTimeSlice, salesInfo, config.regionLength)); } } - , [workplan, region, currentTimeSlice, core, salesInfo]); + , [workplan, region, currentTimeSlice, core, salesInfo]); const hasWorkplan = workplan?.length; diff --git a/packages/page-broker/src/Overview/index.tsx b/packages/page-broker/src/Overview/index.tsx index a10d10db2998..796a9fa6a958 100644 --- a/packages/page-broker/src/Overview/index.tsx +++ b/packages/page-broker/src/Overview/index.tsx @@ -51,7 +51,7 @@ const formatData = (coreCount: number, workplan: CoreWorkplan[], workload: CoreW }); }; -function Overview ({ className }: Props): React.ReactElement { +function Overview({ className }: Props): React.ReactElement { const { api, apiEndpoint, isApiReady } = useApi(); const [data, setData] = useState([]); @@ -87,6 +87,7 @@ function Overview ({ className }: Props): React.ReactElement { {!!filtered && ( )} diff --git a/packages/page-broker/src/utils.ts b/packages/page-broker/src/utils.ts index c2682ae8360f..971226fb5f96 100644 --- a/packages/page-broker/src/utils.ts +++ b/packages/page-broker/src/utils.ts @@ -11,7 +11,6 @@ import { CoreTimeTypes } from './types.js'; export const CoreTimeConsts = { BlockTime: 6000, BlocksPerTimeslice: 80, - DefaultRegion: 5040 }; function formatDate (date: Date) { @@ -72,7 +71,7 @@ export const estimateTime = (targetTimeslice: string | number, latestBlock: numb * @returns */ -export function formatRowInfo (data: CoreWorkloadType[] | CoreWorkplanType[], core: number, currentRegion: RegionInfo | undefined, currentTimeSlice: number, { regionBegin, regionEnd }: { regionBegin: number, regionEnd: number }, regionLength = CoreTimeConsts.DefaultRegion): InfoRow[] { +export function formatRowInfo (data: CoreWorkloadType[] | CoreWorkplanType[], core: number, currentRegion: RegionInfo | undefined, currentTimeSlice: number, { regionBegin, regionEnd }: { regionBegin: number, regionEnd: number }, regionLength: number): InfoRow[] { return data.map((one: CoreWorkloadType | CoreWorkplanType) => { const item: InfoRow = { core, maskBits: one?.info?.maskBits, task: one?.info?.task, type: one?.type }; const blockNumberNow = currentTimeSlice * 80; diff --git a/packages/page-coretime/src/utils.ts b/packages/page-coretime/src/utils.ts index 51030072c13c..cc07b3d3a9fd 100644 --- a/packages/page-coretime/src/utils.ts +++ b/packages/page-coretime/src/utils.ts @@ -6,7 +6,6 @@ import { BN } from '@polkadot/util'; export const CoreTimeConsts = { BlockTime: 6000, BlocksPerTimeslice: 80, - DefaultRegion: 5040 }; export const FirstCycleStart: Record = { From 90f06a51f296e262c502b8a52e24fd98b9321608 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Fri, 18 Oct 2024 16:51:46 +0800 Subject: [PATCH 18/22] improved function to find out type --- packages/page-coretime/src/ParachainsTable.tsx | 14 ++++---------- packages/page-coretime/src/types.ts | 7 +++++++ packages/page-coretime/src/utils.ts | 10 ++++++++++ 3 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 packages/page-coretime/src/types.ts diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx index df48c0cbf836..ba5b4c054f1b 100644 --- a/packages/page-coretime/src/ParachainsTable.tsx +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -10,14 +10,8 @@ import { ParaLink, Table, Tag } from '@polkadot/react-components'; import { BN, formatBalance, formatNumber } from '@polkadot/util'; import { useTranslation } from './translate.js'; -import { estimateTime } from './utils.js'; - -export enum CoreTimeTypes { - 'Reservation', - 'Lease', - 'Bulk Coretime', - 'On Demand' -} +import { estimateTime, getOccupancyType } from './utils.js'; +import { CoreTimeTypes } from './types.js'; interface Props { coretimeInfo: CoretimeInformation @@ -29,7 +23,7 @@ const colours: Record = { [CoreTimeTypes['Bulk Coretime']]: 'pink' }; -function ParachainsTable ({ coretimeInfo }: Props): React.ReactElement { +function ParachainsTable({ coretimeInfo }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([ [t('parachains'), 'start'], @@ -50,7 +44,7 @@ function ParachainsTable ({ coretimeInfo }: Props): React.ReactElement { > {coretimeInfo?.taskIds?.map((taskId: number) => { const chain = coretimeInfo.chainInfo[taskId]; - const type = chain?.lease ? CoreTimeTypes.Lease : chain?.reservation ? CoreTimeTypes.Reservation : CoreTimeTypes['Bulk Coretime']; + const type = getOccupancyType(chain?.lease, chain?.reservation, !!chain.worklplan?.find(a => a.info.isPool)) const targetTimeslice = chain?.lease?.until || coretimeInfo.salesInfo.regionEnd; const showEsimates = !!targetTimeslice && type !== CoreTimeTypes.Reservation; diff --git a/packages/page-coretime/src/types.ts b/packages/page-coretime/src/types.ts new file mode 100644 index 000000000000..3639fa6afcf9 --- /dev/null +++ b/packages/page-coretime/src/types.ts @@ -0,0 +1,7 @@ +export enum CoreTimeTypes { + 'Reservation', + 'Lease', + 'Bulk Coretime', + 'On Demand' + } + \ No newline at end of file diff --git a/packages/page-coretime/src/utils.ts b/packages/page-coretime/src/utils.ts index cc07b3d3a9fd..489402d1355b 100644 --- a/packages/page-coretime/src/utils.ts +++ b/packages/page-coretime/src/utils.ts @@ -1,7 +1,9 @@ // Copyright 2017-2024 @polkadot/app-coretime authors & contributors // SPDX-License-Identifier: Apache-2.0 +import { LegacyLease, Reservation } from '@polkadot/react-hooks/types'; import { BN } from '@polkadot/util'; +import { CoreTimeTypes } from './types.js'; export const CoreTimeConsts = { BlockTime: 6000, @@ -59,3 +61,11 @@ export const estimateTime = (targetTimeslice: string | number, latestBlock: numb return null; } }; + +export const getOccupancyType = (lease: LegacyLease | undefined, reservation: Reservation | undefined, isPool: boolean): CoreTimeTypes => { + if (isPool) { + return CoreTimeTypes['On Demand']; + } + + return reservation ? CoreTimeTypes.Reservation : lease ? CoreTimeTypes.Lease : CoreTimeTypes['Bulk Coretime']; +}; \ No newline at end of file From b15407c82f884c9f63be1c55966b6bb82edb6b9f Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Fri, 18 Oct 2024 17:06:14 +0800 Subject: [PATCH 19/22] lint --- packages/page-broker/src/Overview/CoreTable.tsx | 6 +++--- packages/page-broker/src/Overview/CoresTables.tsx | 8 +++++--- packages/page-broker/src/Overview/Workload.tsx | 9 ++++----- packages/page-broker/src/Overview/index.tsx | 4 ++-- packages/page-broker/src/utils.ts | 2 +- packages/page-coretime/src/ParachainsTable.tsx | 6 +++--- packages/page-coretime/src/types.ts | 14 ++++++++------ packages/page-coretime/src/utils.ts | 8 +++++--- 8 files changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/page-broker/src/Overview/CoreTable.tsx b/packages/page-broker/src/Overview/CoreTable.tsx index 84a0751b7f43..dd7d2fd7cae1 100644 --- a/packages/page-broker/src/Overview/CoreTable.tsx +++ b/packages/page-broker/src/Overview/CoreTable.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { ApiPromise } from '@polkadot/api'; +import type { PalletBrokerConfigRecord } from '@polkadot/react-hooks/types'; import React, { useRef } from 'react'; @@ -10,7 +11,6 @@ import { Table } from '@polkadot/react-components'; import { useTranslation } from '../translate.js'; import { type CoreWorkloadType, type CoreWorkplanType } from '../types.js'; import Workload from './Workload.js'; -import { PalletBrokerConfigRecord } from '@polkadot/react-hooks/types'; interface Props { api: ApiPromise; @@ -20,7 +20,7 @@ interface Props { workplan?: CoreWorkplanType[], } -function CoreTable({ api, core, workload, workplan, config }: Props): React.ReactElement { +function CoreTable ({ api, config, core, workload, workplan }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?] | false)[]>([[t('core')]]); const header: [React.ReactNode?, string?, number?, (() => void)?][] = [ @@ -41,11 +41,11 @@ function CoreTable({ api, core, workload, workplan, config }: Props): React.Reac > diff --git a/packages/page-broker/src/Overview/CoresTables.tsx b/packages/page-broker/src/Overview/CoresTables.tsx index 4e4c836be6a8..f3daa93fd2a3 100644 --- a/packages/page-broker/src/Overview/CoresTables.tsx +++ b/packages/page-broker/src/Overview/CoresTables.tsx @@ -6,28 +6,30 @@ import type { CoreInfo } from '../types.js'; import React from 'react'; -import CoreTable from './CoreTable.js'; import { useBrokerConfig } from '@polkadot/react-hooks'; +import CoreTable from './CoreTable.js'; + interface Props { api: ApiPromise; isApiReady: boolean; data: CoreInfo[]; } -function CoresTable({ api, isApiReady, data }: Props): React.ReactElement { +function CoresTable ({ api, data, isApiReady }: Props): React.ReactElement { const config = useBrokerConfig(api, isApiReady); + return ( <> {data?.map((coreData) => { return ( ); })} diff --git a/packages/page-broker/src/Overview/Workload.tsx b/packages/page-broker/src/Overview/Workload.tsx index b3f47131ad7d..ce9a8973400e 100644 --- a/packages/page-broker/src/Overview/Workload.tsx +++ b/packages/page-broker/src/Overview/Workload.tsx @@ -12,10 +12,9 @@ import React, { useEffect, useMemo, useState } from 'react'; import { ExpandButton } from '@polkadot/react-components'; import { useApi, useBrokerSalesInfo, useCall, useRegions, useToggle } from '@polkadot/react-hooks'; -import { CoreTimeConsts, formatRowInfo } from '../utils.js'; +import { formatRowInfo } from '../utils.js'; import WorkInfoRow from './WorkInfoRow.js'; import Workplan from './Workplan.js'; -import RegionLength from './Summary/RegionLength.jsx'; interface Props { api: ApiPromise; @@ -25,7 +24,7 @@ interface Props { config: PalletBrokerConfigRecord } -function Workload({ api, core, workload, workplan, config }: Props): React.ReactElement { +function Workload ({ api, config, core, workload, workplan }: Props): React.ReactElement { const { isApiReady } = useApi(); const salesInfo = useBrokerSalesInfo(api, isApiReady); @@ -52,14 +51,14 @@ function Workload({ api, core, workload, workplan, config }: Props): React.React } else { return setWorkloadData([{ core }]); } - }, [workload, region, currentTimeSlice, core, salesInfo]); + }, [workload, region, currentTimeSlice, core, salesInfo, config]); useEffect(() => { if (!!workplan?.length && !!salesInfo) { setWorkplanData(formatRowInfo(workplan, core, region, currentTimeSlice, salesInfo, config.regionLength)); } } - , [workplan, region, currentTimeSlice, core, salesInfo]); + , [workplan, region, currentTimeSlice, core, salesInfo, config]); const hasWorkplan = workplan?.length; diff --git a/packages/page-broker/src/Overview/index.tsx b/packages/page-broker/src/Overview/index.tsx index 796a9fa6a958..46b90b645692 100644 --- a/packages/page-broker/src/Overview/index.tsx +++ b/packages/page-broker/src/Overview/index.tsx @@ -51,7 +51,7 @@ const formatData = (coreCount: number, workplan: CoreWorkplan[], workload: CoreW }); }; -function Overview({ className }: Props): React.ReactElement { +function Overview ({ className }: Props): React.ReactElement { const { api, apiEndpoint, isApiReady } = useApi(); const [data, setData] = useState([]); @@ -87,8 +87,8 @@ function Overview({ className }: Props): React.ReactElement { {!!filtered && ( )} ) diff --git a/packages/page-broker/src/utils.ts b/packages/page-broker/src/utils.ts index 971226fb5f96..7d1ed455c082 100644 --- a/packages/page-broker/src/utils.ts +++ b/packages/page-broker/src/utils.ts @@ -10,7 +10,7 @@ import { CoreTimeTypes } from './types.js'; export const CoreTimeConsts = { BlockTime: 6000, - BlocksPerTimeslice: 80, + BlocksPerTimeslice: 80 }; function formatDate (date: Date) { diff --git a/packages/page-coretime/src/ParachainsTable.tsx b/packages/page-coretime/src/ParachainsTable.tsx index ba5b4c054f1b..950e2aba4a95 100644 --- a/packages/page-coretime/src/ParachainsTable.tsx +++ b/packages/page-coretime/src/ParachainsTable.tsx @@ -10,8 +10,8 @@ import { ParaLink, Table, Tag } from '@polkadot/react-components'; import { BN, formatBalance, formatNumber } from '@polkadot/util'; import { useTranslation } from './translate.js'; -import { estimateTime, getOccupancyType } from './utils.js'; import { CoreTimeTypes } from './types.js'; +import { estimateTime, getOccupancyType } from './utils.js'; interface Props { coretimeInfo: CoretimeInformation @@ -23,7 +23,7 @@ const colours: Record = { [CoreTimeTypes['Bulk Coretime']]: 'pink' }; -function ParachainsTable({ coretimeInfo }: Props): React.ReactElement { +function ParachainsTable ({ coretimeInfo }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([ [t('parachains'), 'start'], @@ -44,7 +44,7 @@ function ParachainsTable({ coretimeInfo }: Props): React.ReactElement { > {coretimeInfo?.taskIds?.map((taskId: number) => { const chain = coretimeInfo.chainInfo[taskId]; - const type = getOccupancyType(chain?.lease, chain?.reservation, !!chain.worklplan?.find(a => a.info.isPool)) + const type = getOccupancyType(chain?.lease, chain?.reservation, !!chain.worklplan?.find((a) => a.info.isPool)); const targetTimeslice = chain?.lease?.until || coretimeInfo.salesInfo.regionEnd; const showEsimates = !!targetTimeslice && type !== CoreTimeTypes.Reservation; diff --git a/packages/page-coretime/src/types.ts b/packages/page-coretime/src/types.ts index 3639fa6afcf9..b5afab7d6a10 100644 --- a/packages/page-coretime/src/types.ts +++ b/packages/page-coretime/src/types.ts @@ -1,7 +1,9 @@ +// Copyright 2017-2024 @polkadot/app-coretime authors & contributors +// SPDX-License-Identifier: Apache-2.0 + export enum CoreTimeTypes { - 'Reservation', - 'Lease', - 'Bulk Coretime', - 'On Demand' - } - \ No newline at end of file + 'Reservation', + 'Lease', + 'Bulk Coretime', + 'On Demand' +} diff --git a/packages/page-coretime/src/utils.ts b/packages/page-coretime/src/utils.ts index 489402d1355b..5b7800b7da96 100644 --- a/packages/page-coretime/src/utils.ts +++ b/packages/page-coretime/src/utils.ts @@ -1,13 +1,15 @@ // Copyright 2017-2024 @polkadot/app-coretime authors & contributors // SPDX-License-Identifier: Apache-2.0 -import { LegacyLease, Reservation } from '@polkadot/react-hooks/types'; +import type { LegacyLease, Reservation } from '@polkadot/react-hooks/types'; + import { BN } from '@polkadot/util'; + import { CoreTimeTypes } from './types.js'; export const CoreTimeConsts = { BlockTime: 6000, - BlocksPerTimeslice: 80, + BlocksPerTimeslice: 80 }; export const FirstCycleStart: Record = { @@ -68,4 +70,4 @@ export const getOccupancyType = (lease: LegacyLease | undefined, reservation: Re } return reservation ? CoreTimeTypes.Reservation : lease ? CoreTimeTypes.Lease : CoreTimeTypes['Bulk Coretime']; -}; \ No newline at end of file +}; From a425c9fa1fac936a11d613465a0de7f28f38bce6 Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Fri, 18 Oct 2024 17:21:15 +0800 Subject: [PATCH 20/22] tsc --- packages/page-broker/src/Overview/CoresTables.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/page-broker/src/Overview/CoresTables.tsx b/packages/page-broker/src/Overview/CoresTables.tsx index f3daa93fd2a3..01a0c224e281 100644 --- a/packages/page-broker/src/Overview/CoresTables.tsx +++ b/packages/page-broker/src/Overview/CoresTables.tsx @@ -21,7 +21,7 @@ function CoresTable ({ api, data, isApiReady }: Props): React.ReactElement - {data?.map((coreData) => { + {config && data?.map((coreData) => { return ( Date: Tue, 22 Oct 2024 09:16:05 -0400 Subject: [PATCH 21/22] Fix versioning --- packages/page-coretime/package.json | 6 +++--- yarn.lock | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/page-coretime/package.json b/packages/page-coretime/package.json index 53a31bb9bea5..221ac860267f 100644 --- a/packages/page-coretime/package.json +++ b/packages/page-coretime/package.json @@ -14,10 +14,10 @@ }, "sideEffects": false, "type": "module", - "version": "0.145.2-0-x", + "version": "0.145.2-1-x", "dependencies": { - "@polkadot/react-components": "^0.145.2-0-x", - "@polkadot/react-query": "^0.145.2-0-x" + "@polkadot/react-components": "^0.145.2-1-x", + "@polkadot/react-query": "^0.145.2-1-x" }, "peerDependencies": { "react": "*", diff --git a/yarn.lock b/yarn.lock index 6e47166626e3..49c4e6e6f74d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1431,8 +1431,8 @@ __metadata: version: 0.0.0-use.local resolution: "@polkadot/app-coretime@workspace:packages/page-coretime" dependencies: - "@polkadot/react-components": "npm:^0.145.2-0-x" - "@polkadot/react-query": "npm:^0.145.2-0-x" + "@polkadot/react-components": "npm:^0.145.2-1-x" + "@polkadot/react-query": "npm:^0.145.2-1-x" peerDependencies: react: "*" react-dom: "*" From bb764fd47972a7fbb6208c48ff5753e844833e2d Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 22 Oct 2024 09:25:08 -0400 Subject: [PATCH 22/22] fix comments --- packages/page-broker/src/utils.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/page-broker/src/utils.ts b/packages/page-broker/src/utils.ts index 7d1ed455c082..773e363af879 100644 --- a/packages/page-broker/src/utils.ts +++ b/packages/page-broker/src/utils.ts @@ -22,18 +22,18 @@ function formatDate (date: Date) { } /** - * blockTime = 6000 ms - * BlocksPerTimeslice = 80 - * Default Regoin = 5040 timeslices - * TargetBlock = TargetTimeslice * BlocksPerTimeslice - * Block Time Difference = |TargetBlock - latest Block| * blockTime - * - * Estimate timestamp = - * if targetBlock is before the latestBlock - * now minus block time difference - * else - * now plus block time difference - */ + * blockTime = 6000 ms + * BlocksPerTimeslice = 80 + * Default Regoin = 5040 timeslices + * TargetBlock = TargetTimeslice * BlocksPerTimeslice + * Block Time Difference = |TargetBlock - latest Block| * blockTime + * + * Estimate timestamp = + * if targetBlock is before the latestBlock + * now minus block time difference + * else + * now plus block time difference + */ export const estimateTime = (targetTimeslice: string | number, latestBlock: number): string | null => { if (!latestBlock || !targetTimeslice) { console.error('Invalid input: one or more inputs are missing'); @@ -68,9 +68,7 @@ export const estimateTime = (targetTimeslice: string | number, latestBlock: numb * @param timeslice * @param param4 * @param regionLength - * @returns */ - export function formatRowInfo (data: CoreWorkloadType[] | CoreWorkplanType[], core: number, currentRegion: RegionInfo | undefined, currentTimeSlice: number, { regionBegin, regionEnd }: { regionBegin: number, regionEnd: number }, regionLength: number): InfoRow[] { return data.map((one: CoreWorkloadType | CoreWorkplanType) => { const item: InfoRow = { core, maskBits: one?.info?.maskBits, task: one?.info?.task, type: one?.type };