Skip to content

Commit

Permalink
feat(dcellar-web-ui): introduce activities feature for bucket, object…
Browse files Browse the repository at this point in the history
… and group
  • Loading branch information
devinxl committed May 9, 2024
1 parent 9726cfe commit d99b6c4
Show file tree
Hide file tree
Showing 13 changed files with 419 additions and 107 deletions.
80 changes: 80 additions & 0 deletions apps/dcellar-web-ui/src/components/Activities/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { GREENFIELD_CHAIN_EXPLORER_URL } from '@/base/env';
import { IconFont } from '@/components/IconFont';
import { CopyText } from '@/components/common/CopyText';
import { ListEmpty } from '@/components/common/DCTable/ListEmpty';
import { Activity } from '@/store/slices/object';
import { formatMsgType } from '@/utils/object';
import { trimAddress } from '@/utils/string';
import { formatFullTime } from '@/utils/time';
import { Box, Center, Flex, Link, Loading, Text } from '@node-real/uikit';
import { memo } from 'react';

interface ActivitiesProps {
loading: boolean;
activities: Activity[];
}

export const Activities = memo<ActivitiesProps>(function Activities({ loading, activities }) {
if (loading) return <Loading w={'100%'} my={24} size={24} />;
if (!activities.length)
return (
<ListEmpty
empty
h={240}
type="empty-object"
title="No Records"
desc="There are no records at the moment."
/>
);

return (
<>
{activities.map((item, index) => (
<Flex key={index} gap={8}>
<Flex flexDirection={'column'} alignItems={'center'}>
<Center w={24} h={24} borderRadius={12} bgColor={'bg.bottom'} alignItems={'center'}>
<IconFont type="object" w={16} h={16} />
</Center>
{index < activities.length - 1 && (
<Box flex={1} width={1} bgColor={'readable.border'} />
)}
</Flex>
<Flex fontWeight={500} flexDirection={'column'} gap={8}>
<Flex alignItems={'center'}>
<Text as="span" color={'readable.tertiary'}>
{formatMsgType(item.tx_result.type)}&nbsp;
</Text>
<Text as="span" color={'readable.normal'}>
Transaction Hash
</Text>
&nbsp; (
<Link
color={'#1184EE'}
_hover={{ color: '#3C9AF1' }}
href={`${GREENFIELD_CHAIN_EXPLORER_URL}/tx/0x${item.hash}`}
target="_blank"
fontSize={12}
textDecoration={'underline'}
>
0x{trimAddress(item.hash, 28, 6, 5)}
</Link>
)
<CopyText value={`0x${item.hash}`} />
</Flex>
<Flex gap={2} alignItems={'center'} mb={16} fontSize={12}>
<IconFont type="calendar" w={16} h={16} />
<Text as="span" color={'readable.tertiary'}>
{formatFullTime(item.time)}
</Text>
</Flex>
</Flex>
</Flex>
))}
{activities.length >= 100 && (
<Text textAlign={'center'} fontSize={12} color={'readable.tertiary'}>
Only showing the latest 100 activities ~
</Text>
)}
</>
);
});
11 changes: 10 additions & 1 deletion apps/dcellar-web-ui/src/facade/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import { getClient } from '@/facade/index';
import { BroadcastResponse } from '@/facade/object';
import { signTypedDataCallback } from '@/facade/wallet';
import { ObjectResource } from '@/store/slices/object';
import { Activity, ObjectResource } from '@/store/slices/object';
import { parseError } from '@/utils/string';
import { getTimestampInSeconds } from '@/utils/time';
import {
Expand Down Expand Up @@ -447,3 +447,12 @@ export const updateBucketTags = async (params: UpdateBucketTagsParams, connector

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

export const getBucketActivities = async (id: string): Promise<Activity[]> => {
const url = `/api/tx/list/by_bucket/${id}`;

const [result] = await axios.get<{ result: Activity[] }>(url).then(resolve, commonFault);
if (!result) return [];

return result.data.result || [];
};
10 changes: 10 additions & 0 deletions apps/dcellar-web-ui/src/facade/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getClient } from '@/facade/index';
import { BroadcastResponse, DeliverResponse, xmlParser } from '@/facade/object';
import { signTypedDataCallback } from '@/facade/wallet';
import { GroupMember } from '@/store/slices/group';
import { Activity } from '@/store/slices/object';
import {
MsgCreateGroup,
MsgDeleteGroup,
Expand Down Expand Up @@ -252,3 +253,12 @@ export const updateGroupTags = async (

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

export const getGroupActivities = async (id: string): Promise<Activity[]> => {
const url = `/api/tx/list/by_group/${id}`;

const [result] = await axios.get<{ result: Activity[] }>(url).then(resolve, commonFault);
if (!result) return [];

return result.data.result || [];
};
11 changes: 10 additions & 1 deletion apps/dcellar-web-ui/src/facade/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import { ObjectMeta } from '@bnb-chain/greenfield-js-sdk/dist/esm/types/sp/Commo
import axios from 'axios';
import { XMLParser } from 'fast-xml-parser';
import { Connector } from 'wagmi';
import { ObjectVersion } from '@/store/slices/object';
import { Activity, ObjectVersion } from '@/store/slices/object';

export type DeliverResponse = Awaited<ReturnType<TxResponse['broadcast']>>;

Expand Down Expand Up @@ -647,6 +647,15 @@ export const getObjectVersions = async (id: string): Promise<ObjectVersion[]> =>
return result.data.result || [];
};

export const getObjectActivities = async (id: string): Promise<Activity[]> => {
const url = `/api/tx/list/by_object/${id}`;

const [result] = await axios.get<{ result: Activity[] }>(url).then(resolve, commonFault);
if (!result) return [];

return result.data.result || [];
};

export type UpdateObjectTagsParams = {
address: string;
bucketName: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
setBucketEditQuota,
setupBucketQuota,
TBucket,
setupBucketActivity,
} from '@/store/slices/bucket';
import { selectBucketSp } from '@/store/slices/sp';
import { convertObjectKey } from '@/utils/common';
Expand All @@ -27,20 +28,28 @@ import {
QDrawerBody,
QDrawerFooter,
QDrawerHeader,
Tab,
TabList,
TabPanel,
TabPanels,
Tabs,
Text,
Tooltip,
} from '@node-real/uikit';
import dayjs from 'dayjs';
import { memo, PropsWithChildren, useEffect, useState } from 'react';
import { useUnmount } from 'ahooks';
import { useMount, useUnmount } from 'ahooks';
import { DEFAULT_TAG } from '@/components/common/ManageTags';
import { Activities } from '@/components/Activities';

export const Label = ({ children }: PropsWithChildren) => (
<Text as={'div'} fontSize={'14px'} fontWeight={500} color="readable.tertiary">
{children}
</Text>
);

const VERSION_TABS = ['General Info', 'Activities'];

interface DetailBucketOperationProps {
selectedBucketInfo: TBucket;
}
Expand Down Expand Up @@ -68,6 +77,7 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
}) {
const dispatch = useAppDispatch();
const bucketQuotaRecords = useAppSelector((root) => root.bucket.bucketQuotaRecords);
const bucketActivityRecords = useAppSelector((root) => root.bucket.bucketActivityRecords);
const accountInfos = useAppSelector((root) => root.accounts.accountInfos);
const primarySp = useAppSelector(selectBucketSp(selectedBucketInfo))!;

Expand All @@ -76,6 +86,10 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
const endDate = dayjs().utc?.().endOf('month').format('D MMM, YYYY');
const formattedQuota = formatQuota(bucketQuota);

const activityKey = selectedBucketInfo.BucketName;
const loading = !(activityKey in bucketActivityRecords);
const bucketActivities = bucketActivityRecords[activityKey];

const nullObjectMeta: ObjectMeta = {
...defaultNullObject,
ObjectInfo: {
Expand Down Expand Up @@ -367,6 +381,10 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
dispatch(setupBucketQuota(selectedBucketInfo.BucketName));
}, [selectedBucketInfo.BucketName, dispatch]);

useMount(() => {
dispatch(setupBucketActivity(selectedBucketInfo.BucketName, selectedBucketInfo.Id));
});

useUnmount(() => dispatch(setBucketTagsEditData([DEFAULT_TAG])));

return (
Expand Down Expand Up @@ -432,10 +450,25 @@ export const DetailBucketOperation = memo<DetailBucketOperationProps>(function D
</Text>
</Box>
</Flex>
<Divider mb={24} />
{getContent()}
<Divider mb={24} mt={8} />
<SharePermission selectObjectInfo={nullObjectMeta} />
<Tabs>
<TabList mb={24}>
{VERSION_TABS.map((tab) => (
<Tab h={24} key={tab} fontSize={14} fontWeight={500} pb={8}>
{tab}
</Tab>
))}
</TabList>
<TabPanels>
<TabPanel>
{getContent()}
<Divider mb={24} mt={8} />
<SharePermission selectObjectInfo={nullObjectMeta} />
</TabPanel>
<TabPanel>
<Activities loading={loading} activities={bucketActivities} />
</TabPanel>
</TabPanels>
</Tabs>
</QDrawerBody>
<QDrawerFooter>
<DCButton size="lg" w={'100%'} onClick={onManageQuota}>
Expand Down
Loading

0 comments on commit d99b6c4

Please sign in to comment.