From 09087a8a544a4a8fbfd5387f2948b78ee2ae7c45 Mon Sep 17 00:00:00 2001 From: Daniel Rocha Date: Thu, 14 Sep 2023 14:14:08 +0200 Subject: [PATCH] ui: remove account name and improve some UI components (#65) * chore: update MetaMask provider * chore: remove dead code * fix: remove account name * chore: fix linting errors * chore: remove unused file * feat: multiple small UI improvements * feat: update accounts list on account deletion * ui: fix work-break of `CopyableItemValue` * ui: fix paddings and margins --- packages/site/package.json | 2 +- packages/site/src/components/Accordion.tsx | 3 +- packages/site/src/components/Buttons.tsx | 4 +- packages/site/src/components/EditAccount.tsx | 88 ---------- packages/site/src/components/Method.tsx | 62 ++++--- packages/site/src/components/Toggle.tsx | 6 +- .../site/src/components/styledComponents.ts | 8 +- packages/site/src/pages/index.tsx | 161 ++++++------------ yarn.lock | 2 +- 9 files changed, 95 insertions(+), 241 deletions(-) delete mode 100644 packages/site/src/components/EditAccount.tsx diff --git a/packages/site/package.json b/packages/site/package.json index cf8b3200..a5ea8134 100644 --- a/packages/site/package.json +++ b/packages/site/package.json @@ -28,7 +28,7 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@metamask/keyring-api": "^0.2.3", - "@metamask/providers": "^11.0.0", + "@metamask/providers": "^12.0.0", "@mui/icons-material": "^5.14.0", "@mui/material": "^5.14.0", "@types/uuid": "^9.0.1", diff --git a/packages/site/src/components/Accordion.tsx b/packages/site/src/components/Accordion.tsx index 8793dacb..68ae0dc6 100644 --- a/packages/site/src/components/Accordion.tsx +++ b/packages/site/src/components/Accordion.tsx @@ -14,11 +14,12 @@ const AccordionItem = styled.div` border: 1px solid #eaeaea; border-radius: 4px; margin-bottom: 20px; + padding: 8px; width: 100%; `; const AccordionHeader = styled.div` - margin: 16px; + margin: 8px; font-weight: bold; cursor: pointer; display: flex; diff --git a/packages/site/src/components/Buttons.tsx b/packages/site/src/components/Buttons.tsx index 844d32f1..8c13ecd3 100644 --- a/packages/site/src/components/Buttons.tsx +++ b/packages/site/src/components/Buttons.tsx @@ -75,9 +75,7 @@ const ActionButton = styled.button` background-color: #0376c9; border-radius: 999px; padding: 5px 20px; - margin-left: 16px; - margin-right: 2.5%; - margin-top: 16px; + margin: 8px 2.5% 8px 16px; &:hover { background-color: #0376ff; diff --git a/packages/site/src/components/EditAccount.tsx b/packages/site/src/components/EditAccount.tsx deleted file mode 100644 index f129d7ac..00000000 --- a/packages/site/src/components/EditAccount.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { KeyringAccount } from '@metamask/keyring-api'; -import { - FormControl, - FormGroup, - FormLabel, - MenuItem, - Select, - TextField, -} from '@mui/material'; -import React, { useState } from 'react'; - -export const EditAccountForm = ({ - accounts, - onChange, -}: { - accounts: KeyringAccount[]; - onChange: (account: KeyringAccount) => void; -}) => { - if (accounts.length === 0) { - return null; - } - const [account, setAccount] = useState(accounts[0]); - const [updateAccountPayload, setUpdateAccountPayload] = useState< - Pick - >({ - name: '', - options: {}, - }); - - const handleEditAccountChange = (payload: any) => { - setUpdateAccountPayload({ ...updateAccountPayload, ...payload }); - onChange({ ...account, ...payload }); - }; - - return ( - - - - - - Account Name - - handleEditAccountChange({ name: event.target.value }) - } - /> - - - Account Options - - handleEditAccountChange({ options: event.target.value }) - } - /> - - - ); -}; diff --git a/packages/site/src/components/Method.tsx b/packages/site/src/components/Method.tsx index abc28a5b..36d39e84 100644 --- a/packages/site/src/components/Method.tsx +++ b/packages/site/src/components/Method.tsx @@ -9,8 +9,8 @@ import { InputType } from '../types'; const StyledDescription = styled.p` font-size: 14px; - padding-top: 16px; - padding-left: 16px; + margin: 8px; + padding-top: 24px; `; const InputTitle = styled.p` @@ -21,9 +21,9 @@ const InputTitle = styled.p` const StyledSelect = styled.select` width: 95%; - padding: 10px; - margin-top: 8px; - margin-left: 16px; + padding-top: 8px; + padding-bottom: 10px; + margin: 8px 2.5% 8px 16px; border-radius: 5px; `; @@ -47,9 +47,7 @@ const TextField = styled.input` const CopyableContainer = styled.div` width: 95%; - margin-left: 2.5%; - margin-right: 2.5%; - margin-top: 20px; + margin: 0px 2.5% 8px 16px; `; export type MethodProps = { @@ -137,11 +135,12 @@ export const Method = ({ {action && ( { - setResponse(null); - setError(null); + setResponse(undefined); + setError(undefined); try { - const res = await action.callback(); - setResponse(res); + // eslint-disable-next-line id-length + const r = await action.callback(); + setResponse(r === undefined ? null : r); // eslint-disable-next-line id-length } catch (e: any) { setError(e); @@ -152,26 +151,25 @@ export const Method = ({ /> )} - - {response && ( - <> - - - - )} - {error && ( - <> - - - - )} - + {response !== undefined && ( + + + + + )} + + {error !== undefined && ( + + + + + )} ); }; diff --git a/packages/site/src/components/Toggle.tsx b/packages/site/src/components/Toggle.tsx index 1f46593c..ecceb3a5 100644 --- a/packages/site/src/components/Toggle.tsx +++ b/packages/site/src/components/Toggle.tsx @@ -104,7 +104,7 @@ export const Toggle = ({ checkedIcon = '🌞', uncheckedIcon = '🌜', }: { - onToggle(): void; + onToggle(): Promise; defaultChecked?: boolean; title?: string; checkedIcon?: string; @@ -116,8 +116,8 @@ export const Toggle = ({ setChecked(defaultChecked); }, [defaultChecked]); - const handleChange = () => { - onToggle(); + const handleChange = async () => { + await onToggle(); setChecked(!checked); }; diff --git a/packages/site/src/components/styledComponents.ts b/packages/site/src/components/styledComponents.ts index f0ed6b4b..ebf07f37 100644 --- a/packages/site/src/components/styledComponents.ts +++ b/packages/site/src/components/styledComponents.ts @@ -153,13 +153,15 @@ export const CopyableContainer = styled.div<{ active: boolean }>` export const CopyableItemValue = styled.div` color: #0376c9; - text-align: center; + text-align: left; max-width: 80%; - word-wrap: break-word; + word-break: break-all; + white-space: pre-wrap; margin: 0px; /* Body-SM-Medium */ - font-family: Euclid Circular B; + font-family: SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, + Inconsolata, monospace; font-size: 12px; font-style: normal; font-weight: 500; diff --git a/packages/site/src/pages/index.tsx b/packages/site/src/pages/index.tsx index d0dc2001..b0222796 100644 --- a/packages/site/src/pages/index.tsx +++ b/packages/site/src/pages/index.tsx @@ -46,7 +46,6 @@ const initialState: { const Index = () => { const [state, dispatch] = useContext(MetaMaskContext); const [snapState, setSnapState] = useState(initialState); - const [accountName, setAccountName] = useState(); // Is not a good practice to store sensitive data in the state of // a component but for this case it should be ok since this is an // internal development and testing tool. @@ -79,14 +78,7 @@ const Index = () => { [requestId], ); - // const handleAccountPayloadChange = useCallback( - // (newAccountPayload: KeyringAccount) => { - // setAccountPayload(newAccountPayload); - // }, - // [accountPayload], - // ); - - const sendCreateAccount = async () => { + const createAccount = async () => { const newAccount = await client.createAccount(); const accounts = await client.listAccounts(); setSnapState({ @@ -108,6 +100,15 @@ const Index = () => { return newAccount; }; + const deleteAccount = async () => { + await client.deleteAccount(accountId as string); + const accounts = await client.listAccounts(); + setSnapState({ + ...snapState, + accounts, + }); + }; + const handleConnectClick = async () => { try { await connectSnap(); @@ -134,66 +135,44 @@ const Index = () => { const accountManagementMethods = [ { - name: 'Create Account', - description: 'Method to create a new account', - inputs: [ - { - title: 'Account Name', - type: InputType.TextField, - placeholder: 'E.g. My new account', - onChange: (event: any) => { - setAccountName(event.currentTarget.value); - }, - }, - ], + name: 'Create account', + description: 'Create a new account', + inputs: [], action: { - disabled: Boolean(accountName), - callback: async () => { - return await sendCreateAccount(); - }, + callback: async () => await createAccount(), label: 'Create Account', }, - successMessage: 'Account Created', + successMessage: 'Account created', }, { - name: 'Import Account (Private Key)', - description: 'Method to import an account', + name: 'Import account', + description: 'Import an account using a private key', inputs: [ { - title: 'Account Name', - type: InputType.TextField, - placeholder: 'E.g. My new account', - onChange: (event: any) => { - setAccountName(event.currentTarget.value); - }, - }, - { - title: 'Private Key', + title: 'Private key', value: privateKey, type: InputType.TextField, - placeholder: 'Private key', + placeholder: + '0x0000000000000000000000000000000000000000000000000000000000000000', onChange: (event: any) => { setPrivateKey(event.currentTarget.value); }, }, ], action: { - disabled: Boolean(accountName), - callback: async () => { - return await importAccount(); - }, + callback: async () => await importAccount(), label: 'Import Account', }, - successMessage: 'Account Imported', + successMessage: 'Account imported', }, { - name: 'Get Account', - description: 'Get the data about a select account', + name: 'Get account', + description: 'Get data of the selected account', inputs: [ { title: 'Account ID', type: InputType.Dropdown, - placeholder: 'Select Account ID', + placeholder: 'Select account ID', options: snapState.accounts.map((account) => { return { value: account.address }; }), @@ -208,44 +187,35 @@ const Index = () => { ], action: { disabled: Boolean(accountId), - callback: async () => { - try { - const account = await client.getAccount(accountId as string); - return account; - } catch (error) { - dispatch({ type: MetamaskActions.SetError, payload: error }); - } - }, - label: 'Get data', + callback: async () => await client.getAccount(accountId as string), + label: 'Get Account', }, - successMessage: 'Data Fetched', + successMessage: 'Account fetched', }, { - name: 'List Accounts', - description: 'Method to list all account that the SSK manages', + name: 'List accounts', + description: 'List all account managed by the SSK', action: { disabled: false, callback: async () => { const accounts = await client.listAccounts(); - const addresses = accounts.map((a: { address: string }) => a.address); - console.log(addresses); setSnapState({ ...snapState, accounts, }); - return { accounts }; + return accounts; }, label: 'List Accounts', }, }, { - name: 'Remove Account', - description: 'Remove a select account', + name: 'Remove account', + description: 'Remove an account', inputs: [ { title: 'Account ID', type: InputType.Dropdown, - placeholder: 'Select Account ID', + placeholder: 'Select account ID', options: snapState.accounts.map((account) => { return { value: account.address }; }), @@ -260,10 +230,8 @@ const Index = () => { ], action: { disabled: Boolean(accountId), - callback: async () => { - await client.deleteAccount(accountId as string); - }, - label: 'Remove account', + callback: async () => await deleteAccount(), + label: 'Remove Account', }, successMessage: 'Account Removed', }, @@ -271,13 +239,13 @@ const Index = () => { const requestMethods = [ { - name: 'Get Request by Id', - description: 'Get a request made by id', + name: 'Get request', + description: 'Get a pending request by ID', inputs: [ { title: 'Request ID', type: InputType.TextField, - placeholder: 'E.g. Request ID', + placeholder: '6fcbe1b5-f250-452c-8114-683dfa5ea74d', onChange: (event: any) => { handleRequestIdChange(event.currentTarget.value); }, @@ -285,22 +253,13 @@ const Index = () => { ], action: { enabled: Boolean(requestId), - callback: async () => { - try { - const request = await client.getRequest(requestId as string); - console.log(request); - return request; - } catch (error) { - console.error(error); - return error; - } - }, + callback: async () => await client.getRequest(requestId as string), label: 'Get Request', }, }, { - name: 'Get all Requests', - description: 'Get all requests', + name: 'List requests', + description: 'List pending requests', action: { disabled: false, callback: async () => { @@ -309,19 +268,19 @@ const Index = () => { ...snapState, pendingRequests: requests, }); - return { requests }; + return requests; }, - label: 'List Pending Requests', + label: 'List Requests', }, }, { - name: 'Approve a request', - description: 'Approve a request by their id', + name: 'Approve request', + description: 'Approve a pending request by ID', inputs: [ { title: 'Request ID', type: InputType.TextField, - placeholder: 'E.g. Request ID', + placeholder: '6fcbe1b5-f250-452c-8114-683dfa5ea74d', onChange: (event: any) => { handleRequestIdChange(event.currentTarget.value); }, @@ -329,22 +288,14 @@ const Index = () => { ], action: { disabled: !requestId, - callback: async () => { - try { - await client.approveRequest(requestId as string); - return 'Approved'; - } catch (error) { - console.error(error); - throw error; - } - }, + callback: async () => await client.approveRequest(requestId as string), label: 'Approve Request', }, - successMessage: 'Request Approved', + successMessage: 'Request approved', }, { - name: 'Reject a request', - description: 'Reject a request by id', + name: 'Reject request', + description: 'Reject a pending request by ID', inputs: [ { title: 'Request ID', @@ -357,15 +308,7 @@ const Index = () => { ], action: { disabled: !requestId, - callback: async () => { - try { - await client.rejectRequest(requestId as string); - return 'Rejected'; - } catch (error) { - console.error(error); - throw error; - } - }, + callback: async () => await client.rejectRequest(requestId as string), label: 'Reject Request', }, successMessage: 'Request Rejected', diff --git a/yarn.lock b/yarn.lock index 2018520d..02d5814b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2915,7 +2915,7 @@ __metadata: "@metamask/eslint-config-nodejs": ^11.1.0 "@metamask/eslint-config-typescript": ^11.1.0 "@metamask/keyring-api": ^0.2.3 - "@metamask/providers": ^11.0.0 + "@metamask/providers": ^12.0.0 "@mui/icons-material": ^5.14.0 "@mui/material": ^5.14.0 "@svgr/webpack": ^6.5.1