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
15 changes: 15 additions & 0 deletions apps/dcellar-web-ui/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
{
"name": "dcellar-web-ui",
"entries": [
{
"version": "1.4.0",
"tag": "dcellar-web-ui_v1.4.0",
"date": "Thu, 16 May 2024 09:14:19 GMT",
"comments": {
"minor": [
{
"comment": "Introduce the activities feature for bucket, object and group"
},
{
"comment": "Introduce the stop upload feature"
}
]
}
},
{
"version": "1.3.2",
"tag": "dcellar-web-ui_v1.3.2",
Expand Down
10 changes: 9 additions & 1 deletion apps/dcellar-web-ui/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Change Log - dcellar-web-ui

This log was last generated on Sat, 11 May 2024 05:44:13 GMT and should not be manually modified.
This log was last generated on Thu, 16 May 2024 09:14:19 GMT and should not be manually modified.

## 1.4.0
Thu, 16 May 2024 09:14:19 GMT

### Minor changes

- Introduce the activities feature for bucket, object and group
- Introduce the stop upload feature

## 1.3.2
Sat, 11 May 2024 05:44:13 GMT
Expand Down
2 changes: 1 addition & 1 deletion apps/dcellar-web-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dcellar-web-ui",
"version": "1.3.2",
"version": "1.4.0",
"private": false,
"scripts": {
"dev": "node ./scripts/dev.js -p 3200",
Expand Down

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>
)}
</>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ export const GlobalObjectUploadManager = memo<GlobalTasksProps>(
} else {
axios
.put(url, task.waitObject.file, {
signal: task.abortController?.signal,
async onUploadProgress(progressEvent) {
const progress = progressEvent.total
? Math.floor((progressEvent.loaded / progressEvent.total) * 100)
Expand Down Expand Up @@ -265,6 +266,7 @@ export const GlobalObjectUploadManager = memo<GlobalTasksProps>(
setupUploadTaskErrorMsg({
account: loginAccount,
task,
status: e?.code === 'ERR_CANCELED' ? 'CANCEL' : 'ERROR',
errorMsg: authExpired
? 'Authentication expired.'
: message || e?.message || 'upload error',
Expand Down Expand Up @@ -461,8 +463,28 @@ export const GlobalObjectUploadManager = memo<GlobalTasksProps>(
// 3. upload
useAsyncEffect(async () => {
if (!uploadTasks.length) return;
dispatch(updateUploadStatus({ ids: uploadTasks, status: 'UPLOAD', account: loginAccount }));
const tasks = queue.filter((t) => uploadTasks.includes(t.id));
// Add abortController to each task
const extraFields: Record<string, Partial<UploadObject>> = uploadTasks.reduce(
(acc, id) => {
acc[id] = {
abortController: new AbortController(),
};
return acc;
},
{} as Record<string, Partial<UploadObject>>,
);
dispatch(
updateUploadStatus({
ids: uploadTasks,
status: 'UPLOAD',
account: loginAccount,
extraFields,
}),
);

const tasks = queue
.filter((t) => uploadTasks.includes(t.id))
.map((t) => ({ ...t, ...extraFields[t.id] }));
tasks.forEach(runUploadTask);
}, [uploadTasks.join('')]);

Expand Down
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
Loading
Loading