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
#380)

* feat(dcellar-web-ui): introduce activities feature for bucket, object and group

* fix(dcellar-web-ui): text case error

* refactor(dcellar-web-ui): the transfer in style & toolbox style

* feat(dcellar-web-ui): add discord and release note link

* feat(dcellar-web-ui): introduce the stop upload feature (#385)

* feat(dcellar-web-ui): introduce the stop upload feature

* fix(dcellar-web-ui): the uploading name text ellispsis

* fix(dcellar-web-ui): change the stop status icon

* feat(dcellar-web-ui): introduce activities feature for bucket, object and group

* fix(dcellar-web-ui): text case error

* refactor(dcellar-web-ui): the transfer in style & toolbox style

* feat(dcellar-web-ui): add discord and release note link

* feat(dcellar-web-ui): introduce the stop upload feature

* refactor(dcellar-web-ui): remove rerandunt codes

* docs(dcellar-web-ui): update changelog
  • Loading branch information
devinxl committed May 22, 2024
1 parent c82efa3 commit 002b26b
Show file tree
Hide file tree
Showing 30 changed files with 750 additions and 243 deletions.
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 @@ -473,4 +473,13 @@ export const cancelMigrateBucket = async (
if (!tx) return [null, error1];

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

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 @@ -59,7 +59,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 @@ -654,6 +654,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

0 comments on commit 002b26b

Please sign in to comment.