Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dcellar-web-ui): introduce activities feature for bucket, object… #380

Merged
merged 9 commits into from
May 16, 2024

Large diffs are not rendered by default.

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>
)}
</>
);
});
57 changes: 45 additions & 12 deletions apps/dcellar-web-ui/src/components/layout/Nav/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IconFont } from '@/components/IconFont';
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { Box, Text } from '@node-real/uikit';
import { Box, Flex, Text, Tooltip } from '@node-real/uikit';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { memo } from 'react';
Expand Down Expand Up @@ -43,9 +43,21 @@ const ASIDE = [
{
link: 'https://docs.bnbchain.org/greenfield-docs/',
trackId: 'dc.main.nav.doc.click',
icon: 'doc',
icon: 'book',
text: 'BNB Greenfield Docs',
},
{
link: 'https://docs.bnbchain.org/greenfield-docs/docs/release-notes/releaseNotes/',
trackId: 'dc.main.nav.release_note.click',
icon: 'doc',
text: 'Release Notes',
},
{
link: 'https://discord.com/invite/bnbchain',
trackId: 'dc.main.nav.discord.click',
icon: 'discord',
text: 'Discord',
},
{
link: 'https://docs.nodereal.io/docs/dcellar-get-started',
trackId: 'dc.main.nav.faq.click',
Expand Down Expand Up @@ -78,18 +90,38 @@ export const Nav = memo<NavProps>(function Nav() {
);
})}
</MenuList>
<MenuList>
<Flex
justifyContent={'space-around'}
padding={'12px 30px'}
borderTop={'1px solid readable.border'}
>
{ASIDE.map((menu) => (
<MenuItem key={menu.text}>
<Link href={menu.link} data-track-id={menu.trackId} target="_blank">
<MenuIcon as="span">
<IconFont type={menu.icon} />
</MenuIcon>
<MenuText as="span">{menu.text}</MenuText>
</Link>
</MenuItem>
<Tooltip key={menu.text} content={menu.text}>
<Flex
key={menu.text}
width={32}
height={32}
borderRadius={16}
justifyContent={'center'}
alignItems={'center'}
border={'1px solid readable.border'}
_hover={{
borderColor: 'brand.brand6',
color: 'brand.brand6',
svg: {
color: 'brand.brand6',
},
}}
>
<Link href={menu.link} data-track-id={menu.trackId} target="_blank">
<MenuIcon as="span">
<IconFont type={menu.icon} />
</MenuIcon>
</Link>
</Flex>
</Tooltip>
))}
</MenuList>
</Flex>
</NavContainer>
);
});
Expand All @@ -114,6 +146,7 @@ const MenuItem = styled.li<{ $active?: boolean }>`
position: relative;
font-weight: 500;
transition: all 0.15s;
list-style-type: none;
a {
display: grid;
gap: 12px;
Expand Down
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 @@ -653,6 +653,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
Loading