Skip to content

Commit

Permalink
feat(dcellar-web-ui): introduce migrate bucket feature
Browse files Browse the repository at this point in the history
  • Loading branch information
devinxl committed May 9, 2024
1 parent 9726cfe commit a19c2a1
Show file tree
Hide file tree
Showing 24 changed files with 679 additions and 103 deletions.
2 changes: 1 addition & 1 deletion apps/dcellar-web-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"antd": "5.11.0",
"ahooks": "3.7.7",
"hash-wasm": "4.10.0",
"@bnb-chain/greenfield-js-sdk": "2.0.0-alpha.7",
"@bnb-chain/greenfield-js-sdk": "2.1.0-alpha.0",
"@bnb-chain/greenfield-cosmos-types": "0.4.0-alpha.32",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ import { Flex, Text } from '@node-real/uikit';
import NextLink from 'next/link';
import { useEffect, useState } from 'react';

export type InsufficientBalanceProps = {
export type InsufficientBalancesProps = {
loginAccount: string;
accounts: { address: string }[];
accounts: string[];
};

export const InsufficientBalance = ({ loginAccount, accounts }: InsufficientBalanceProps) => {
export const InsufficientBalances = ({ loginAccount, accounts }: InsufficientBalancesProps) => {
const [activeWays, setActiveWays] = useState<{ link: string; text: string }[]>([]);

useEffect(() => {
const ways = accounts.map((account) => {
const isOwnerAccount = account.address === loginAccount;
const isOwnerAccount = account === loginAccount;
return isOwnerAccount
? {
link: InternalRoutePaths.transfer_in,
text: 'Transfer in',
}
: {
link: `${InternalRoutePaths.send}&from=${loginAccount}&to=${account.address}`,
link: `${InternalRoutePaths.send}&from=${loginAccount}&to=${account}`,
text: 'Send',
};
});
Expand Down
9 changes: 8 additions & 1 deletion apps/dcellar-web-ui/src/components/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface LayoutProps extends PropsWithChildren {}
export const Layout = memo<LayoutProps>(function Layout({ children }) {
const dispatch = useAppDispatch();
const isBucketDiscontinue = useAppSelector((root) => root.bucket.isBucketDiscontinue);
const isBucketMigrating = useAppSelector((root) => root.bucket.isBucketMigrating);
const isBucketOwner = useAppSelector((root) => root.bucket.isBucketOwner);
const bucketRecords = useAppSelector((root) => root.bucket.bucketRecords);
const currentBucketName = useAppSelector((root) => root.object.currentBucketName);
Expand Down Expand Up @@ -49,7 +50,13 @@ export const Layout = memo<LayoutProps>(function Layout({ children }) {
},
hover() {
if (pathname !== '/buckets/[...path]') return;
if (isBucketDiscontinue || !isBucketOwner || accountDetail.clientFrozen || !folderExist)
if (
isBucketDiscontinue ||
isBucketMigrating ||
!isBucketOwner ||
accountDetail.clientFrozen ||
!folderExist
)
return;
dispatch(setObjectOperation({ operation: ['', 'upload'] }));
},
Expand Down
29 changes: 28 additions & 1 deletion apps/dcellar-web-ui/src/facade/bucket.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { resolve } from '@/facade/common';
import { DeliverTxResponse, broadcastTx, resolve } from '@/facade/common';
import {
ErrorResponse,
broadcastFault,
Expand All @@ -18,6 +18,7 @@ import {
QueryQuoteUpdateTimeResponse,
} from '@bnb-chain/greenfield-cosmos-types/greenfield/storage/query';
import {
MsgCancelMigrateBucket,
MsgCreateBucket,
MsgUpdateBucketInfo,
} from '@bnb-chain/greenfield-cosmos-types/greenfield/storage/tx';
Expand All @@ -30,6 +31,7 @@ import {
IQuotaProps,
ISimulateGasFee,
Long,
MigrateBucketApprovalRequest,
ReadQuotaRequest,
SpResponse,
TxResponse,
Expand Down Expand Up @@ -447,3 +449,28 @@ export const updateBucketTags = async (params: UpdateBucketTagsParams, connector

return tx.broadcast(payload).then(resolve, broadcastFault);
};

export const migrateBucket = async (
params: MigrateBucketApprovalRequest,
authType: AuthType,
connector: Connector,
): Promise<ErrorResponse | [DeliverTxResponse, null]> => {
const client = await getClient();
const [tx, error1] = await client.bucket
.migrateBucket(params, authType)
.then(resolve, createTxFault);
if (!tx) return [null, error1];

return broadcastTx({ tx: tx, address: params.operator, connector });
};

export const cancelMigrateBucket = async (
params: MsgCancelMigrateBucket,
connector: Connector,
): Promise<ErrorResponse | [DeliverTxResponse, null]> => {
const client = await getClient();
const [tx, error1] = await client.bucket.cancelMigrateBucket(params).then(resolve, createTxFault);
if (!tx) return [null, error1];

return broadcastTx({ tx: tx, address: params.operator, connector });
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { setObjectListPage } from '@/store/slices/object';
import { formatFullTime } from '@/utils/time';
import styled from '@emotion/styled';
import Link from 'next/link';
import { memo } from 'react';
import { DiscontinueNotice } from './DiscontinueNotice';
import { memo, useMemo } from 'react';
import { BucketStatus as BucketStatusEnum } from '@bnb-chain/greenfield-js-sdk';
import { BucketStatusNotice } from './BucketStatusNotice';

interface BucketNameColumnProps {
item: BucketEntity;
Expand All @@ -15,13 +16,31 @@ interface BucketNameColumnProps {
export const BucketNameColumn = memo<BucketNameColumnProps>(function BucketNameColumn({ item }) {
const dispatch = useAppDispatch();
const { DeleteAt, BucketStatus, BucketName } = item;
const discontinue = BucketStatus === 1;
const estimateTime = formatFullTime(
+DeleteAt * 1000 + 7 * 24 * 60 * 60 * 1000,
'YYYY-MM-DD HH:mm:ss',
);
const more = 'https://docs.nodereal.io/docs/dcellar-faq#question-what-is-discontinue';
const content = `This item will be deleted by SP with an estimated time of ${estimateTime}. Please backup your data in time.`;
const bucketStatusNotice = useMemo(() => {
switch (BucketStatus) {
case BucketStatusEnum.BUCKET_STATUS_DISCONTINUED: {
const estimateTime = formatFullTime(
+DeleteAt * 1000 + 7 * 24 * 60 * 60 * 1000,
'YYYY-MM-DD HH:mm:ss',
);
return {
icon: 'colored-error2',
title: 'Discontinue Notice',
learnMore: 'https://docs.nodereal.io/docs/dcellar-faq#question-what-is-discontinue',
content: `This item will be deleted by SP with an estimated time of ${estimateTime}. Please backup your data in time.`,
};
}
case BucketStatusEnum.BUCKET_STATUS_MIGRATING:
return {
icon: 'migrate',
title: 'Data Migrating',
content:
'This bucket, in the process of data migration to another provider, supports only downloads, quota modifications, deletions, and sharing. It does not support uploads.',
};
default:
return null;
}
}, [BucketStatus, DeleteAt]);

return (
<Container>
Expand All @@ -35,7 +54,7 @@ export const BucketNameColumn = memo<BucketNameColumnProps>(function BucketNameC
<IconFont type="bucket-thumbnail" w={20} />
<span title={item.BucketName}>{item.BucketName}</span>
</Link>
{discontinue && <DiscontinueNotice content={content} learnMore={more} />}
{bucketStatusNotice && <BucketStatusNotice {...bucketStatusNotice} />}
</Container>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { memo, useCallback, useMemo } from 'react';
import { EditBucketTagsOperation } from './EditBucketTagsOperation';
import { PaymentAccountOperation } from './PaymentAccountOperation';
import { UpdateBucketTagsOperation } from './UpdateBucketTagsOperation';
import { MigrateBucketOperation } from './MigrateBucketOperation';

interface BucketOperationsProps {
level?: 0 | 1;
Expand All @@ -39,6 +40,7 @@ export const BucketOperations = memo<BucketOperationsProps>(function BucketOpera
'tags',
'edit_tags',
'update_tags',
'migrate',
].includes(operation);
const isModal = ['delete'].includes(operation);
const _operation = useModalValues<BucketOperationsType>(operation);
Expand Down Expand Up @@ -76,6 +78,8 @@ export const BucketOperations = memo<BucketOperationsProps>(function BucketOpera
return <EditBucketTagsOperation onClose={onClose} />;
case 'update_tags':
return <UpdateBucketTagsOperation bucket={_selectBucketInfo} onClose={onClose} />;
case 'migrate':
return <MigrateBucketOperation bucket={_selectBucketInfo} onClose={onClose} />;
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,38 @@ import { IconFont } from '@/components/IconFont';
import { DCLink } from '@/components/common/DCLink';
import { Box, Flex, Menu, MenuButton, MenuList, Text } from '@node-real/uikit';

export const DiscontinueNotice = ({
export const BucketStatusNotice = ({
icon,
title,
content,
learnMore,
}: {
icon: string;
title: string;
content: string;
learnMore: string;
learnMore?: string;
}) => {
return (
<Menu strategy="fixed" trigger="hover" placement="right-start">
<>
<MenuButton onClick={(e) => e.stopPropagation()}>
<IconFont type="colored-error2" w={16} />
<IconFont type={icon} w={16} />
</MenuButton>
<MenuList>
<Box width={'280px'} padding="8px 12px" onClick={(e) => e.stopPropagation()}>
<Text fontSize={'14px'} fontWeight={'600'} marginBottom={'4px'}>
Discontinue Notice
{title}
</Text>
<Text>{content}</Text>
<Flex justifyContent={'right'}>
<DCLink href={learnMore} target="_blank" onClick={(e) => e.stopPropagation()}>
Learn More
</DCLink>
</Flex>
<Text fontWeight={400} color={'readable.secondary'}>
{content}
</Text>
{learnMore && (
<Flex justifyContent={'right'}>
<DCLink href={learnMore} target="_blank" onClick={(e) => e.stopPropagation()}>
Learn More
</DCLink>
</Flex>
)}
</Box>
</MenuList>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
setBucketEditQuota,
setupBucketQuota,
TBucket,
BucketOperationsType,
} from '@/store/slices/bucket';
import { selectBucketSp } from '@/store/slices/sp';
import { convertObjectKey } from '@/utils/common';
Expand All @@ -29,11 +30,13 @@ import {
QDrawerHeader,
Text,
Tooltip,
toast,
} from '@node-real/uikit';
import dayjs from 'dayjs';
import { memo, PropsWithChildren, useEffect, useState } from 'react';
import { useUnmount } from 'ahooks';
import { DEFAULT_TAG } from '@/components/common/ManageTags';
import { BucketStatus } from '@bnb-chain/greenfield-js-sdk';

export const Label = ({ children }: PropsWithChildren) => (
<Text as={'div'} fontSize={'14px'} fontWeight={500} color="readable.tertiary">
Expand Down Expand Up @@ -127,23 +130,13 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
dispatch(setBucketEditQuota([selectedBucketInfo.BucketName, 'drawer']));
};

const onManagePaymentAccount = () => {
dispatch(
setBucketOperation({
level: 1,
operation: [selectedBucketInfo.BucketName, 'payment_account'],
}),
);
};

const getContent = () => {
const CreateAt = getMillisecond(selectedBucketInfo.CreateAt);
const spName = primarySp.moniker;
const payAccountName = accountInfos[selectedBucketInfo.PaymentAddress]?.name;
const infos = [
{
canCopy: false,
edit: false,
label: 'Date created',
value: formatFullTime(CreateAt),
display: formatFullTime(CreateAt),
Expand All @@ -152,7 +145,9 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
{
canCopy: true,
label: 'Primary SP address',
edit: 'migrate',
name: spName,
operation: 'payment_account',
value: primarySp.operatorAddress || '--',
display: primarySp.operatorAddress ? trimAddress(primarySp.operatorAddress) : '--',
copyGaClickName: 'dc.bucket.b_detail_pop.copy_spadd.click',
Expand All @@ -161,7 +156,7 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
},
{
canCopy: true,
edit: true,
edit: 'payment_account',
label: 'Payment address',
name: payAccountName,
value: selectedBucketInfo.PaymentAddress,
Expand All @@ -172,7 +167,6 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
},
{
canCopy: true,
edit: false,
label: 'Bucket ID',
value: formatId(Number(selectedBucketInfo.Id)),
display: formatAddress(formatId(Number(selectedBucketInfo.Id))),
Expand All @@ -182,7 +176,6 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
},
{
canCopy: true,
edit: false,
label: 'Create transaction hash',
value: selectedBucketInfo.CreateTxHash,
display: formatAddress(selectedBucketInfo.CreateTxHash),
Expand Down Expand Up @@ -221,7 +214,7 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
gap={4}
color={'brand.brand6'}
cursor={'pointer'}
onClick={onManagePaymentAccount}
onClick={() => onEditClick(item.edit as BucketOperationsType)}
w={16}
h={16}
>
Expand Down Expand Up @@ -363,6 +356,30 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
);
};

const onEditClick = (operation?: BucketOperationsType) => {
switch (operation) {
case 'payment_account':
dispatch(
setBucketOperation({
level: 1,
operation: [selectedBucketInfo.BucketName, 'payment_account'],
}),
);
break;
case 'migrate':
if (selectedBucketInfo.BucketStatus === BucketStatus.BUCKET_STATUS_MIGRATING) {
toast.error({ description: 'The bucket is migrating, please wait.' });
} else {
dispatch(
setBucketOperation({
level: 1,
operation: [selectedBucketInfo.BucketName, 'migrate'],
}),
);
}
break;
}
};
useEffect(() => {
dispatch(setupBucketQuota(selectedBucketInfo.BucketName));
}, [selectedBucketInfo.BucketName, dispatch]);
Expand Down
Loading

0 comments on commit a19c2a1

Please sign in to comment.