From db559bec94f241b191626e42fb19a2f7bee868d2 Mon Sep 17 00:00:00 2001 From: aidencao Date: Tue, 9 Apr 2024 10:56:40 +0800 Subject: [PATCH] feat(dcellar-web-ui): remove some duplicate code --- .../src/components/common/DCTable/index.tsx | 27 +++++--------- .../src/hooks/useUploadProcessObjects.ts | 30 ++++++++++++++++ .../components/BatchDeleteObjectOperation.tsx | 20 +++-------- .../modules/object/components/ObjectList.tsx | 35 +++++++------------ 4 files changed, 56 insertions(+), 56 deletions(-) create mode 100644 apps/dcellar-web-ui/src/hooks/useUploadProcessObjects.ts diff --git a/apps/dcellar-web-ui/src/components/common/DCTable/index.tsx b/apps/dcellar-web-ui/src/components/common/DCTable/index.tsx index 203837f3..f9619af9 100644 --- a/apps/dcellar-web-ui/src/components/common/DCTable/index.tsx +++ b/apps/dcellar-web-ui/src/components/common/DCTable/index.tsx @@ -5,14 +5,13 @@ import { SimplePaginationProps, } from '@/components/common/DCTable/SimplePagination'; import { useAppSelector } from '@/store'; -import { UploadObject, selectUploadQueue } from '@/store/slices/global'; import { formatBytes } from '@/utils/formatter'; import styled from '@emotion/styled'; -import { Badge, Box, Flex, Pagination, PaginationProps, Text, keyframes } from '@node-real/uikit'; +import { Badge, Box, Flex, keyframes, Pagination, PaginationProps, Text } from '@node-real/uikit'; import { ConfigProvider, Table, TableProps } from 'antd'; import { ConfigProviderProps } from 'antd/es/config-provider'; -import { find } from 'lodash-es'; import { memo } from 'react'; +import { useUploadProcessObjects } from '@/hooks/useUploadProcessObjects'; export type AlignType = 'left' | 'right' | 'center'; @@ -165,21 +164,13 @@ export const UploadProgress = (props: { progress: number }) => { export const UploadStatus = ({ object, size }: { object: string; size: number }) => { const loginAccount = useAppSelector((root) => root.persist.loginAccount); - const queue = useAppSelector(selectUploadQueue(loginAccount)); - - const file = find(queue, (q) => { - const objectInList = [ - q.bucketName, - ...q.prefixFolders, - q.waitObject.relativePath || '', - q.waitObject.name, - ] - .filter((item) => !!item) - .join('/'); - return objectInList === object && q.status !== 'ERROR'; - }); - - if (!file) return Created on Chain; + const { processUploadObjects, processUploadObjectRecord } = useUploadProcessObjects(loginAccount); + + const processing = processUploadObjects.includes(object); + + if (!processing) return Created on Chain; + + const file = processUploadObjectRecord[object]; if (file.status === 'UPLOAD') return ; diff --git a/apps/dcellar-web-ui/src/hooks/useUploadProcessObjects.ts b/apps/dcellar-web-ui/src/hooks/useUploadProcessObjects.ts new file mode 100644 index 00000000..9367cb08 --- /dev/null +++ b/apps/dcellar-web-ui/src/hooks/useUploadProcessObjects.ts @@ -0,0 +1,30 @@ +import { useAppSelector } from '@/store'; +import { selectUploadQueue, UploadObject } from '@/store/slices/global'; +import { useMemo } from 'react'; + +export const useUploadProcessObjects = (loginAccount: string) => { + const queue = useAppSelector(selectUploadQueue(loginAccount)); + + return useMemo(() => { + const processUploadObjectRecord: Record = {}; + const processUploadObjects = queue + .filter((q) => q.status !== 'ERROR') + .map((q) => { + const key = [ + q.bucketName, + ...q.prefixFolders, + q.waitObject.relativePath || '', + q.waitObject.name, + ] + .filter((item) => !!item) + .join('/'); + processUploadObjectRecord[key] = q; + return key; + }); + + return { + processUploadObjects, + processUploadObjectRecord, + }; + }, [queue]); +}; diff --git a/apps/dcellar-web-ui/src/modules/object/components/BatchDeleteObjectOperation.tsx b/apps/dcellar-web-ui/src/modules/object/components/BatchDeleteObjectOperation.tsx index bcacc3c1..b34cbb97 100644 --- a/apps/dcellar-web-ui/src/modules/object/components/BatchDeleteObjectOperation.tsx +++ b/apps/dcellar-web-ui/src/modules/object/components/BatchDeleteObjectOperation.tsx @@ -23,7 +23,6 @@ import { selectGnfdGasFeesConfig, selectUploadQueue, setSignatureAction, - UploadObject, } from '@/store/slices/global'; import { setDeletedObject, setObjectSelectedKeys } from '@/store/slices/object'; import { BN } from '@/utils/math'; @@ -39,9 +38,10 @@ import { ColoredWaitingIcon } from '@node-real/icons'; import { Flex, ModalBody, ModalFooter, ModalHeader, Text, toast } from '@node-real/uikit'; import { useAsyncEffect } from 'ahooks'; import { parseEther } from 'ethers/lib/utils.js'; -import { find, round } from 'lodash-es'; +import { round } from 'lodash-es'; import { memo, useMemo, useState } from 'react'; import { useAccount } from 'wagmi'; +import { useUploadProcessObjects } from '@/hooks/useUploadProcessObjects'; interface BatchDeleteObjectOperationProps { selectBucket: TBucket; @@ -65,7 +65,6 @@ export const BatchDeleteObjectOperation = memo( const bankBalance = useAppSelector((root) => root.accounts.bankOrWalletBalance); const gnfdGasFeesConfig = useAppSelector(selectGnfdGasFeesConfig); - const uploadQueue = useAppSelector(selectUploadQueue(loginAccount)); const { crudTimestamp } = useAppSelector(selectAccount(bucket?.PaymentAddress)); const availableBalance = useAppSelector(selectAvailableBalance(bucket?.PaymentAddress)); const [loading, setLoading] = useState(false); @@ -76,6 +75,7 @@ export const BatchDeleteObjectOperation = memo( const { loading: loadingSettlementFee, settlementFee } = useSettlementFee( bucket?.PaymentAddress, ); + const { processUploadObjects } = useUploadProcessObjects(loginAccount); const deleteObjects = objectSelectedKeys.map((key) => { return objectRecords[currentBucketName + '/' + key]; @@ -158,19 +158,9 @@ export const BatchDeleteObjectOperation = memo( privateKey, }; - const file = find(uploadQueue, (q) => { - const objectInList = [ - ...q.prefixFolders, - q.waitObject.relativePath || '', - q.waitObject.name, - ] - .filter((item) => !!item) - .join('/'); + const processing = processUploadObjects.includes(`${currentBucketName}/${objectName}`); - return objectInList === objectName && q.status !== 'ERROR'; - }); - - const [txRes, error] = await (ObjectStatus === 1 || (ObjectStatus !== 1 && !file) + const [txRes, error] = await (ObjectStatus === 1 || (ObjectStatus !== 1 && !processing) ? deleteObject(payload) : cancelCreateObject(payload)); if (error && error !== E_OBJECT_NOT_EXISTS) { diff --git a/apps/dcellar-web-ui/src/modules/object/components/ObjectList.tsx b/apps/dcellar-web-ui/src/modules/object/components/ObjectList.tsx index 1becbc93..1d6747ae 100644 --- a/apps/dcellar-web-ui/src/modules/object/components/ObjectList.tsx +++ b/apps/dcellar-web-ui/src/modules/object/components/ObjectList.tsx @@ -54,10 +54,11 @@ import { Box, Flex } from '@node-real/uikit'; import { useAsyncEffect, useUpdateEffect } from 'ahooks'; import { ColumnProps } from 'antd/es/table'; import dayjs from 'dayjs'; -import { find, uniq, without, xor } from 'lodash-es'; +import { uniq, without, xor } from 'lodash-es'; import { memo, useCallback } from 'react'; import { OBJECT_ERROR_TYPES, ObjectErrorType } from '../ObjectError'; import Link from 'next/link'; +import { useUploadProcessObjects } from '@/hooks/useUploadProcessObjects'; export type ObjectActionValueType = | 'marketplace' @@ -122,6 +123,7 @@ export const ObjectList = memo(function ObjectList({ shareMode const loading = useAppSelector(selectPathLoading); const objectList = useAppSelector(selectObjectList); const uploadQueue = useAppSelector(selectUploadQueue(loginAccount)); + const { processUploadObjects, processUploadObjectRecord } = useUploadProcessObjects(loginAccount); const { setOpenAuthModal } = useOffChainAuth(); const bucket = bucketRecords[currentBucketName]; @@ -344,17 +346,13 @@ export const ObjectList = memo(function ObjectList({ shareMode pruneActions = removeAction(pruneActions, ['cancel']); } else { // It is not allowed to cancel when the chain is sealed, but the SP is not synchronized. - const file = find( - uploadQueue, - (q) => - [...q.prefixFolders, q.waitObject.relativePath || '', q.waitObject.name] - .filter((item) => !!item) - .join('/') === record.objectName && q.status !== 'ERROR', - ); + const object = `${record.bucketName}/${record.objectName}`; + const processing = processUploadObjects.includes(object); + const file = processUploadObjectRecord[object]; // if is uploading, can not cancel; - if (file && ['SIGN', 'SIGNED', 'UPLOAD'].includes(file.status)) { + if (processing && ['SIGN', 'SIGNED', 'UPLOAD'].includes(file.status)) { pruneActions = pickAction(pruneActions, ['detail']); - } else if (file && ['SEAL', 'SEALING'].includes(file.status)) { + } else if (processing && ['SEAL', 'SEALING'].includes(file.status)) { pruneActions = removeAction(pruneActions, ['cancel', 'share', 'delete']); } else { // if not sealed, only support 'cancel' 'detail' @@ -403,21 +401,12 @@ export const ObjectList = memo(function ObjectList({ shareMode onSelect: onSelectChange, onSelectAll: onSelectAllChange, getCheckboxProps: (record: ObjectEntity) => { - const file = find(uploadQueue, (q) => { - const objectInList = [ - ...q.prefixFolders, - q.waitObject.relativePath || '', - q.waitObject.name, - ] - .filter((item) => !!item) - .join('/'); - - return objectInList === record.objectName && q.status !== 'ERROR'; - }); + const object = `${record.bucketName}/${record.objectName}`; + const processing = processUploadObjects.includes(object); return { - // folder or upload failed - disabled: record.folder || (record.objectStatus !== 1 && !!file), // Column configuration not to be checked + // folder or processing + disabled: record.folder || (record.objectStatus !== 1 && processing), // Column configuration not to be checked name: record.name, }; },