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/memeber list expiration #225

Merged
merged 16 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/dcellar-web-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"apollo-node-client": "1.4.3",
"antd": "5.6.3",
"ahooks": "3.7.7",
"hash-wasm": "4.9.0",
"hash-wasm": "4.10.0",
"@babel/core": "^7.20.12",
"@bnb-chain/greenfield-js-sdk": "0.2.7-alpha.2",
"@bnb-chain/greenfield-cosmos-types": "0.4.0-alpha.23",
Expand Down
1 change: 0 additions & 1 deletion apps/dcellar-web-ui/public/js/iconfont_v0.1.min.js

This file was deleted.

50 changes: 50 additions & 0 deletions apps/dcellar-web-ui/public/js/iconfont_v0.2.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/dcellar-web-ui/src/base/theme/var.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
--ui-colors-bg-codebox: #262D37;
--ui-colors-bg-top-normal: #2B2F36;
--ui-colors-bg-top-active: #2E323A;
--ui-colors-scene-primary-active: #CD7CFF;
--ui-colors-scene-primary-active: #3ec659;
--ui-colors-scene-success-normal: #02C076;
--ui-colors-scene-success-active: #48FFB8;
--ui-colors-scene-danger-normal: #D9304E;
Expand Down
86 changes: 82 additions & 4 deletions apps/dcellar-web-ui/src/components/common/DCComboBox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
import { memo, ReactNode, useRef } from 'react';
import { memo, ReactNode, useEffect, useRef, useState } from 'react';
import { ConfigProvider, Select, SelectProps } from 'antd';
import { Flex } from '@totejs/uikit';
import { Flex, Text } from '@totejs/uikit';
import styled from '@emotion/styled';
import { antdTheme } from '@/base/theme/antd';
import { IconFont } from '@/components/IconFont';
import { DCDatePicker } from '@/components/common/DCDatePicker';
import dayjs, { Dayjs } from 'dayjs';

interface DCComboBoxProps extends SelectProps {
addon?: ReactNode;
dateChange?: (date: Dayjs) => void;
}

export const DCComboBox = memo<DCComboBoxProps>(function DCComboBox({ addon, ...props }) {
export const DCComboBox = memo<DCComboBoxProps>(function DCComboBox({
addon,
dateChange = () => {},
...props
}) {
const ref = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);
const now = new Date();
now.setMonth(now.getMonth() + 6);
const [date, setDate] = useState<Dayjs>(dayjs(now));
const dateChangeRef = useRef(dateChange);

useEffect(() => {
dateChangeRef.current(date);
}, [date]);

return (
<Container ref={ref}>
Expand All @@ -23,18 +40,79 @@ export const DCComboBox = memo<DCComboBoxProps>(function DCComboBox({ addon, ...
}}
dropdownRender={() => <></>}
open={false}
dropdownAlign={{ offset: [0, 32] }}
{...props}
/>
</ConfigProvider>
{addon}
<ExpireSelector>
<IconFont type={'calendar'} w={20} mr={4} />
Access expires {dayjs(date).format('D MMM, YYYY')}{' '}
<Text as={'span'} ml={16} onClick={() => setOpen(!open)}>
Edit
</Text>
<DCDatePicker
value={date}
dropdownAlign={{ offset: [-80] }}
open={open}
style={{ visibility: 'hidden', width: 0 }}
onOpenChange={(open) => setOpen(open)}
showToday={false}
getPopupContainer={() => ref.current!}
onChange={(e) => e && setDate(e)}
disabledDate={(e) => e && e < dayjs().endOf('day')}
/>
</ExpireSelector>
</Container>
);
});

const ExpireSelector = styled(Flex)`
position: absolute;
bottom: 1px;
left: 1px;
width: calc(100% - 2px);
border-top: 1px solid var(--ui-colors-readable-border);
background: var(--ui-colors-bg-middle);
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
display: flex;
align-items: center;
height: 28px;
padding: 7px 8px 8px 8px;
:before {
content: '';
position: absolute;
box-shadow: 0 -4px 12px 1px rgba(0, 0, 0, 0.08);
width: 100%;
left: 0;
top: 0;
}

font-size: 12px;
font-weight: 500;

> span {
transition: all 0.15s;
cursor: pointer;
color: var(--ui-colors-brand-brand6);
:hover {
color: var(--ui-colors-brand-brand5);
}
}
`;

// todo refactor
const Container = styled(Flex)`
position: relative;
flex: 1;
min-width: 0;
.ant-select-selector {
margin-bottom: 28px;
}
.ant-select-arrow > * {
margin-bottom: 28px;
}

.ant-select-dropdown .ant-select-item-option-selected:not(.ant-select-item-option-disabled) {
font-weight: normal;
Expand Down Expand Up @@ -86,7 +164,7 @@ const Container = styled(Flex)`

.ant-select-dropdown {
box-shadow: none;
border: 1px solid var(--system-readable-border, #e6e8ea);
border: 1px solid #e6e8ea;

.ant-select-item {
border-radius: 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ConfigProvider, DatePicker, DatePickerProps } from 'antd';
import { memo } from 'react';
import { antdTheme } from '@/base/theme/antd';

type DCDatePickerProps = DatePickerProps;

export const DCDatePicker = memo<DCDatePickerProps>(function DCDatePicker(props) {
return (
<ConfigProvider theme={antdTheme}>
<DatePicker {...props} />
</ConfigProvider>
);
});
6 changes: 3 additions & 3 deletions apps/dcellar-web-ui/src/components/layout/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const Header = memo<HeaderProps>(function Header({ taskManagement = true
<Link href="/" target="_blank" data-track-id="dc.main.nav.logo.click">
<IconFont type="logo" w={122} h={24} />
</Link>
<Badge>{networkTag(runtimeEnv)}</Badge>
{runtimeEnv === 'testnet' && <Badge>{networkTag(runtimeEnv)}</Badge>}
</LogoContainer>
<Content>
{taskManagement && (
Expand Down Expand Up @@ -61,8 +61,8 @@ const Content = styled(Flex)`
export const Badge = styled.span`
display: inline-flex;
border-radius: 2px;
color: var(--ui-colors-brand-normal-hight);
background-color: var(--ui-colors-scene-success-opacity-normal);
color: var(--ui-colors-brand-brand7);
background-color: var(--ui-colors-opacity1);
padding: 3px 4px;
font-size: 12px;
transform: scale(0.83333);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ErrorMsgMap } from '@/context/WalletConnectContext/error/error';
import { toast } from '@totejs/uikit';
import { ConnectorNotFoundError } from 'wagmi';
import * as Sentry from '@sentry/nextjs';

export function handleWalletError(err: any, args: any, context: unknown) {
let text = '';
Expand All @@ -22,6 +23,10 @@ export function handleWalletError(err: any, args: any, context: unknown) {
const message = err.cause?.message ?? err.message;
const description = text || ErrorMsgMap[code] || message;

Sentry.withScope((scope) => {
scope.setTag('Component', 'handleWalletError');
Sentry.captureMessage(JSON.stringify(err));
});
toast.error({
description,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { setAuthModalOpen } from '@/store/slices/global';
import { getDomain } from '@/utils/bom';
import { getClient } from '@/facade';
import { IconFont } from '@/components/IconFont';
import * as Sentry from '@sentry/nextjs';

const EXPIRATION_MS = 5 * 24 * 60 * 60 * 1000;
export const OffChainAuthContext = createContext<any>({});
Expand Down Expand Up @@ -54,8 +55,8 @@ export const OffChainAuthProvider: React.FC<any> = ({ children }) => {
const onOffChainAuth = useCallback(
async (address: string) => {
setIsAuthPending(true);
const provider = await connector?.getProvider();
try {
const provider = await connector?.getProvider();
const domain = getDomain();

// If no sps selected, use all sps for welcome auth
Expand Down Expand Up @@ -96,6 +97,11 @@ export const OffChainAuthProvider: React.FC<any> = ({ children }) => {
} catch (e: any) {
console.log('gen offChain data error', e);
const { message } = e;
console.error(provider);
Sentry.withScope((scope) => {
scope.setTag('Component', 'OffChainAuthContext');
Sentry.captureMessage(JSON.stringify(e));
});
message && toast.error({ description: `${message}`, duration: 3000 });
setIsAuthPending(false);
onClose();
Expand Down
29 changes: 7 additions & 22 deletions apps/dcellar-web-ui/src/facade/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,28 +138,13 @@ export const removeMemberFromGroup = async (
}
if (!members.length) return [{ code: 0 } as DeliverResponse, null];

const payloads = members.map((member) => ({
...msg,
membersToDelete: [member],
}));

const tasks = await Promise.all(
payloads.map((payload) => client.group.updateGroupMember(payload).then(resolve, createTxFault)),
);

for (const [opt, error] of tasks) {
if (!!error) return [null, error];
}

const _tasks = tasks.map((task) => task[0] as TxResponse);

const txs = await client.txClient.multiTx(_tasks);

const [simulate, simulateError] = await txs
.simulate({ denom: 'BNB' })
.then(resolve, simulateFault);
const [tx, error1] = await client.group
.updateGroupMember({ ...msg, membersToDelete: members })
.then(resolve, createTxFault);
if (!tx) return [null, error1];

if (!simulate) return [null, simulateError];
const [simulate, error2] = await tx.simulate({ denom: 'BNB' }).then(resolve, simulateFault);
if (!simulate) return [null, error2];

const payload = {
denom: 'BNB',
Expand All @@ -170,7 +155,7 @@ export const removeMemberFromGroup = async (
signTypedDataCallback: signTypedDataCallback(connector),
};

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

export const deleteGroup = async (msg: MsgDeleteGroup, connector: Connector): BroadcastResponse => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const DeleteGroup = memo<DeleteGroupProps>(function DeleteGroup() {
groupName: removeGroup.groupName,
};
dispatch(
setStatusDetail({ icon: Animates.group, title: 'GROUP_DELETE', desc: WALLET_CONFIRM }),
setStatusDetail({ icon: Animates.group, title: 'Deleting Group', desc: WALLET_CONFIRM }),
);
const [txRes, txError] = await deleteGroup(payload, connector!);
if (!txRes || txRes.code !== 0) return errorHandler(txError || UNKNOWN_ERROR);
Expand Down
Loading