Skip to content

Commit

Permalink
feat: enable address copy from selector.
Browse files Browse the repository at this point in the history
  • Loading branch information
gdethier committed Mar 26, 2024
1 parent b944b3c commit cd876e3
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 38 deletions.
48 changes: 26 additions & 22 deletions src/common/AccountAddress.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,30 @@ import { shallowRender } from '../tests';

import AccountAddress from './AccountAddress';

test("renders", () => {
const result = shallowRender(
<AccountAddress
balance={{
available: new Numbers.PrefixedNumber("2", Numbers.NONE),
total: new Numbers.PrefixedNumber("2", Numbers.NONE),
reserved: new Numbers.PrefixedNumber("0", Numbers.NONE),
coin: {
id: "lgnt",
symbol: "LGNT"
},
level: 1
}}
account={{
name: "Name 1",
accountId: mockValidPolkadotAccountId("address1"),
isLegalOfficer: false,
}}
disabled={ false }
/>
);
expect(result).toMatchSnapshot();
describe("AccountAddress", () => {

it("renders", () => {
const result = shallowRender(
<AccountAddress
balance={{
available: new Numbers.PrefixedNumber("2", Numbers.NONE),
total: new Numbers.PrefixedNumber("2", Numbers.NONE),
reserved: new Numbers.PrefixedNumber("0", Numbers.NONE),
coin: {
id: "lgnt",
symbol: "LGNT"
},
level: 1
}}
account={{
name: "Name 1",
accountId: mockValidPolkadotAccountId("address1"),
isLegalOfficer: false,
}}
disabled={ false }
/>
);
expect(result).toMatchSnapshot();
});

});
16 changes: 13 additions & 3 deletions src/common/AccountAddress.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { CoinBalance } from "@logion/node-api";
import { CSSProperties } from 'react';
import { CSSProperties, useCallback } from 'react';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import Tooltip from 'react-bootstrap/Tooltip';

import { Account } from './types/Accounts';
import { useCommonContext } from './CommonContext';
import Icon from './Icon';
import { copyToClipBoard } from "./Tools";

import './AccountAddress.css';
import { Spinner } from "react-bootstrap";
Expand All @@ -19,9 +20,17 @@ export interface Props {
}

export default function AccountAddress(props: Props) {
const { colorTheme } = useCommonContext();
const { colorTheme, setNotification } = useCommonContext();

let style: CSSProperties = {};
const copyAddress = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
e.stopPropagation();
copyToClipBoard(props.account.accountId.address);
setNotification("The address was copied to your clip board");
}, [ props.account.accountId.address, setNotification ]);

let style: CSSProperties = {
cursor: "copy"
};
const backgroundIcon = colorTheme.accounts.legalOfficerIcon;
let foregroundIcon;
if(props.account.isLegalOfficer) {
Expand All @@ -41,6 +50,7 @@ export default function AccountAddress(props: Props) {
<div
className="icon"
style={ style }
onClick={ copyAddress }
>
<Icon icon={{ id: foregroundIcon }} width="40px" />
</div>
Expand Down
35 changes: 35 additions & 0 deletions src/common/CommonContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export interface CommonContext {
expectNewTransactionState: ExpectNewTransactionState;
expectNewTransaction: () => void;
stopExpectNewTransaction: () => void;
notificationText?: string;
setNotification: (text?: string) => void;
}

interface FullCommonContext extends CommonContext {
Expand Down Expand Up @@ -83,6 +85,7 @@ function initialContextValue(): FullCommonContext {
},
expectNewTransaction: () => {},
stopExpectNewTransaction: () => {},
setNotification: () => {},
}
}

Expand All @@ -106,6 +109,8 @@ type ActionType = 'FETCH_IN_PROGRESS'
| 'SET_EXPECT_NEW_TRANSACTION'
| 'STOP_EXPECT_NEW_TRANSACTION'
| 'SET_STOP_EXPECT_NEW_TRANSACTION'
| 'SET_NOTIFICATION'
| 'SET_SET_NOTIFICATION'
;

interface Action {
Expand All @@ -128,6 +133,8 @@ interface Action {
backendConfig?: ((legalOfficerAddress: string | undefined) => BackendConfig);
expectNewTransaction?: () => void;
stopExpectNewTransaction?: () => void;
notificationText?: string;
setNotification?: (text?: string) => void;
}

const MAX_REFRESH_COUNT = 12;
Expand Down Expand Up @@ -239,6 +246,18 @@ const reducer: Reducer<FullCommonContext, Action> = (state: FullCommonContext, a
refreshCount: 0,
},
};
case "SET_NOTIFICATION": {
return {
...state,
notificationText: action.notificationText,
};
}
case "SET_SET_NOTIFICATION": {
return {
...state,
setNotification: action.setNotification!,
};
}
default:
/* istanbul ignore next */
throw new Error(`Unknown type: ${action.type}`);
Expand Down Expand Up @@ -422,6 +441,22 @@ export function CommonContextProvider(props: Props) {
}
}, [ contextValue.stopExpectNewTransaction, stopExpectNewTransaction ]);

const setNotification = useCallback((text?: string) => {
dispatch({
type: "SET_NOTIFICATION",
notificationText: text,
});
}, [ ]);

useEffect(() => {
if(contextValue.setNotification !== setNotification) {
dispatch({
type: "SET_SET_NOTIFICATION",
setNotification,
})
}
}, [ contextValue.setNotification, setNotification ]);

return (
<CommonContextObject.Provider value={contextValue}>
{props.children}
Expand Down
29 changes: 18 additions & 11 deletions src/common/CopyPasteButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { useCallback } from "react";
import Button from "./Button";
import Icon from "./Icon";
import { copyToClipBoard } from "./Tools";

import './CopyPasteButton.css';
import { customClassName } from "./types/Helpers";
import { OverlayTrigger, Tooltip } from "react-bootstrap";
import { useCommonContext } from "./CommonContext";

export interface Props {
value?: string | null;
Expand All @@ -13,7 +15,15 @@ export interface Props {
}

export default function CopyPasteButton(props: Props) {
const { setNotification } = useCommonContext();

const copy = useCallback(() => {
copyToClipBoard(props.value || "");
setNotification("Value was copied to the clip board");
}, [ props.value, setNotification ]);

const value = props.value;
const className = customClassName("CopyPasteButton", props.className ? props.className : "big");
if(value) {
if(props.tooltip) {
return (
Expand All @@ -27,23 +37,20 @@ export default function CopyPasteButton(props: Props) {
}
>
<span className="Button-container">
{ renderButton(props) }
<Button onClick={ copy } className={ className }>
<Icon icon={{id: "copy_paste"}} />
</Button>
</span>
</OverlayTrigger>
);
} else {
return renderButton(props);
return (
<Button onClick={ copy } className={ className }>
<Icon icon={{id: "copy_paste"}} />
</Button>
);
}
} else {
return null;
}
}

function renderButton(props: Props) {
const className = customClassName("CopyPasteButton", props.className ? props.className : "big");
return (
<Button onClick={ () => copyToClipBoard(props.value || "") } className={ className }>
<Icon icon={{id: "copy_paste"}} />
</Button>
);
}
7 changes: 7 additions & 0 deletions src/common/Dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@
padding-bottom: 30px;
}

.Dashboard .Notifications {
position: absolute;
top: 130px;
right: 35px;
width: 280px;
}

@media (max-width: 1350px) {
.Dashboard .Sidebar {
width: 260px;
Expand Down
14 changes: 13 additions & 1 deletion src/common/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Toast from 'react-bootstrap/Toast';

import { Children } from './types/Helpers';
import Logo from './Logo';
Expand Down Expand Up @@ -159,7 +160,7 @@ export interface Props {
}

export default function Dashboard(props: Props) {
const { colorTheme } = useCommonContext();
const { colorTheme, notificationText, setNotification } = useCommonContext();

const inlineCss = `
.Dashboard .PrimaryArea .table {
Expand Down Expand Up @@ -215,6 +216,17 @@ export default function Dashboard(props: Props) {
</div>
</div>
{ props.children }
<div className="Notifications">
<Toast
show={ notificationText !== undefined }
onClose={ () => setNotification(undefined) }
bg={ colorTheme.type }
autohide
delay={ 3000 }
>
<Toast.Body>{ notificationText }</Toast.Body>
</Toast>
</div>
</div>
);
}
4 changes: 3 additions & 1 deletion src/common/__snapshots__/AccountAddress.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders 1`] = `
exports[`AccountAddress renders 1`] = `
<div
className="AccountAddress"
>
<div
className="icon"
onClick={[Function]}
style={
Object {
"backgroundColor": "#3b6cf4",
"cursor": "copy",
}
}
>
Expand Down
13 changes: 13 additions & 0 deletions src/common/__snapshots__/Dashboard.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ exports[`renders Dashboard 1`] = `
/>
</div>
</div>
<div
className="Notifications"
>
<Toast
autohide={true}
bg="dark"
delay={3000}
onClose={[Function]}
show={false}
>
<ToastBody />
</Toast>
</div>
</div>
`;

Expand Down

0 comments on commit cd876e3

Please sign in to comment.