From 5c910a78e2904c7371e8cff0e9791dc412354939 Mon Sep 17 00:00:00 2001 From: Gabo Esquivel Date: Mon, 4 Sep 2023 19:37:08 -0600 Subject: [PATCH] chore: new file naming convention --- src/lib/{blockTime.ts => block-time.ts} | 0 src/lib/{callOptions.ts => call-options.ts} | 0 .../{hasRevertFlag.ts => has-revert-flag.ts} | 0 src/lib/{initValue.ts => init-value.ts} | 0 .../{chainProps.ts => chain-props.service.ts} | 0 .../{contract.ts => contract.service.ts} | 2 +- src/services/chain/index.ts | 4 +- src/services/db/dexie-db.service.ts | 32 +++++ src/services/db/index.ts | 30 +---- src/ui/components/Transactions.tsx | 2 +- src/ui/components/account/Account.tsx | 2 +- src/ui/components/account/Select.tsx | 4 +- src/ui/components/account/account.tsx | 43 +++++++ src/ui/components/account/identicon.tsx | 69 ++++++++++ src/ui/components/account/index.ts | 6 +- src/ui/components/account/select.tsx | 92 ++++++++++++++ src/ui/components/app.tsx | 32 +++++ .../{AwaitApis.tsx => await-apis.tsx} | 2 +- src/ui/components/common/Loader.tsx | 2 +- .../{AccountsError.tsx => accounts-error.tsx} | 2 +- src/ui/components/common/button.tsx | 43 +++++++ ...nnectionError.tsx => connection-error.tsx} | 2 +- .../{CopyButton.tsx => copy-button.tsx} | 2 +- src/ui/components/common/dropdown.tsx | 119 ++++++++++++++++++ src/ui/components/common/error.tsx | 18 +++ .../{HeaderButtons.tsx => header-buttons.tsx} | 0 src/ui/components/common/index.ts | 22 ++-- src/ui/components/common/loader.tsx | 20 +++ src/ui/components/common/meter.tsx | 19 +++ .../{NoticeBanner.tsx => notice-banner.tsx} | 0 ...ficationIcon.tsx => notification-icon.tsx} | 2 +- .../{SearchResults.tsx => search-results.tsx} | 0 .../common/{SidePanel.tsx => side-panel.tsx} | 0 src/ui/components/common/spinner.tsx | 34 +++++ src/ui/components/common/switch.tsx | 38 ++++++ src/ui/components/common/tabs.tsx | 51 ++++++++ src/ui/components/contract/Interact.tsx | 6 +- .../{ContractRow.tsx => contract-row.tsx} | 2 +- .../{DryRunError.tsx => dry-run-error.tsx} | 2 +- .../{DryRunResult.tsx => dry-run-result.tsx} | 6 +- src/ui/components/contract/index.ts | 8 +- .../{MetadataTab.tsx => metadata-tab.tsx} | 2 +- .../{OutcomeItem.tsx => outcome-item.tsx} | 2 +- .../{ResultsOutput.tsx => results-output.tsx} | 6 +- ...ctionResult.tsx => transaction-result.tsx} | 0 src/ui/components/form/Bool.tsx | 2 +- src/ui/components/form/Enum.tsx | 8 +- .../{InputBalance.tsx => Input-balance.tsx} | 2 +- .../form/{InputBn.tsx => Input-bn.tsx} | 2 +- .../form/{InputBytes.tsx => Input-bytes.tsx} | 2 +- .../form/{InputFile.tsx => Input-file.tsx} | 0 src/ui/components/form/Option.tsx | 8 +- src/ui/components/form/Struct.tsx | 2 +- src/ui/components/form/Tuple.tsx | 2 +- src/ui/components/form/Vector.tsx | 10 +- .../{ArgumentForm.tsx => argument-form.tsx} | 6 +- src/ui/components/form/bool.tsx | 22 ++++ src/ui/components/form/enum.tsx | 69 ++++++++++ .../{findComponent.tsx => find-component.tsx} | 28 ++--- .../form/{FormField.tsx => form-field.tsx} | 0 src/ui/components/form/hooks/index.ts | 2 +- ...tadataField.tsx => use-metadata-field.tsx} | 2 +- src/ui/components/form/index.ts | 24 ++-- .../form/{InputHash.tsx => input-hash.tsx} | 2 +- .../form/{InputHex.tsx => input-hex.tsx} | 2 +- .../{InputNumber.tsx => input-number.tsx} | 0 .../form/{InputSalt.tsx => input-salt.tsx} | 4 +- ...it.tsx => input-storage-deposit-limit.tsx} | 4 +- .../{InputWeight.tsx => input-weight.tsx} | 4 +- src/ui/components/form/input.tsx | 50 ++++++++ src/ui/components/form/option.tsx | 76 +++++++++++ .../{OptionsForm.tsx => options-form.tsx} | 8 +- src/ui/components/form/struct.tsx | 47 +++++++ .../form/{SubForm.tsx => sub-form.tsx} | 0 src/ui/components/form/tuple.tsx | 53 ++++++++ .../{VectorFixed.tsx => vector-fixed.tsx} | 2 +- src/ui/components/form/vector.tsx | 87 +++++++++++++ src/ui/components/homepage/Contracts.tsx | 2 +- src/ui/components/homepage/contracts.tsx | 56 +++++++++ .../homepage/{HelpBox.tsx => help-box.tsx} | 2 +- src/ui/components/homepage/index.ts | 6 +- src/ui/components/homepage/statistics.tsx | 61 +++++++++ src/ui/components/index.ts | 2 +- src/ui/components/instantiate/Wizard.tsx | 8 +- ...Bundles.tsx => available-code-bundles.tsx} | 4 +- .../{CodeHash.tsx => code-hash.tsx} | 8 +- .../instantiate/{DryRun.tsx => dry-run.tsx} | 8 +- src/ui/components/instantiate/index.ts | 6 +- ...okUpCodeHash.tsx => look-up-code-hash.tsx} | 8 +- .../instantiate/{Step1.tsx => step-1.tsx} | 8 +- .../instantiate/{Step2.tsx => step-2.tsx} | 4 +- .../instantiate/{Step3.tsx => step-3.tsx} | 4 +- src/ui/components/instantiate/wizard.tsx | 30 +++++ .../{ArgSignature.tsx => arg-signature.tsx} | 0 src/ui/components/message/index.ts | 6 +- .../{MessageDocs.tsx => message-docs.tsx} | 2 +- ...ageSignature.tsx => message-signature.tsx} | 2 +- src/ui/components/metadata/index.ts | 2 +- src/ui/components/metadata/metadata.tsx | 44 +++++++ ...dal.tsx => forget-all-contracts-modal.tsx} | 4 +- ...actModal.tsx => forget-contract-modal.tsx} | 4 +- .../modal/{HelpModal.tsx => help-modal.tsx} | 32 ++--- src/ui/components/modal/index.ts | 6 +- src/ui/components/modal/logos.tsx | 33 +++++ .../modal/{ModalBase.tsx => modal-base.tsx} | 0 .../{SettingsModal.tsx => settings-modal.tsx} | 8 +- ...CustomEndpoint.tsx => custom-endpoint.tsx} | 6 +- src/ui/components/settings/index.ts | 4 +- .../{ThemeMode.tsx => theme-mode.tsx} | 2 +- src/ui/components/transactions.tsx | 63 ++++++++++ .../{ApiContext.tsx => api.context.tsx} | 6 +- ...tabaseContext.tsx => database.context.tsx} | 2 +- src/ui/contexts/index.tsx | 10 +- ...ateContext.tsx => instantiate.context.tsx} | 0 .../{ThemeContext.tsx => theme.context.tsx} | 2 +- ...nsContext.tsx => transactions.context.tsx} | 4 +- src/ui/hooks/index.ts | 20 +-- .../{useArgValues.ts => use-arg-values.ts} | 6 +- .../hooks/{useBalance.ts => use-balance.ts} | 4 +- .../hooks/{useDbQuery.ts => use-db-query.ts} | 0 .../{useFormField.ts => use-form-field.ts} | 0 .../{useIsMounted.ts => use-is-mounted.ts} | 0 ...seLocalStorage.ts => use-local-storage.ts} | 0 .../hooks/{useMetadata.ts => use-metadata.ts} | 2 +- ...{useNewContract.ts => use-new-contract.ts} | 0 ...EmptyString.ts => use-non-empty-string.ts} | 2 +- ...tLimit.ts => use-storage-deposit-limit.ts} | 6 +- ...oredContract.ts => use-stored-contract.ts} | 0 src/ui/hooks/{useToggle.ts => use-toggle.ts} | 2 +- src/ui/hooks/{useWeight.ts => use-weight.ts} | 0 src/ui/index.tsx | 2 +- src/ui/layout/index.ts | 2 +- .../{RootLayout.tsx => root.layout.tsx} | 0 src/ui/layout/sidebar/Footer.tsx | 10 +- src/ui/layout/sidebar/Navigation.tsx | 2 +- src/ui/layout/sidebar/footer.tsx | 53 ++++++++ src/ui/layout/sidebar/index.tsx | 10 +- .../{MobileMenu.tsx => mobile-menu.tsx} | 8 +- .../sidebar/{NavLink.tsx => nav-link.tsx} | 0 src/ui/layout/sidebar/navigation.tsx | 18 +++ ...etworkAndUser.tsx => network-and-user.tsx} | 0 .../{QuickLinks.tsx => quick-link.tsx} | 2 +- .../add-contract.page.tsx} | 0 src/ui/pages/add-contract/index.ts | 4 + .../address-lookup.page.tsx} | 2 +- src/ui/pages/address-lookup/index.ts | 4 + .../contract-header.page.tsx} | 2 +- src/ui/pages/contract-header/index.ts | 4 + .../contract.page.tsx} | 10 +- src/ui/pages/contract/index.ts | 4 + .../homepage.page.tsx} | 2 +- src/ui/pages/homepage/index.ts | 4 + src/ui/pages/index.ts | 14 +-- src/ui/pages/instantiate/index.ts | 4 + .../instantiate.page.tsx} | 0 src/ui/pages/not-found/index.ts | 4 + .../not-found.page.tsx} | 0 src/ui/pages/select-code-hash/index.ts | 4 + .../select-code-hash.tsx} | 0 src/ui/util/dropdown.tsx | 2 +- 160 files changed, 1653 insertions(+), 277 deletions(-) rename src/lib/{blockTime.ts => block-time.ts} (100%) rename src/lib/{callOptions.ts => call-options.ts} (100%) rename src/lib/{hasRevertFlag.ts => has-revert-flag.ts} (100%) rename src/lib/{initValue.ts => init-value.ts} (100%) rename src/services/chain/{chainProps.ts => chain-props.service.ts} (100%) rename src/services/chain/{contract.ts => contract.service.ts} (97%) create mode 100644 src/services/db/dexie-db.service.ts create mode 100644 src/ui/components/account/account.tsx create mode 100644 src/ui/components/account/identicon.tsx create mode 100644 src/ui/components/account/select.tsx create mode 100644 src/ui/components/app.tsx rename src/ui/components/{AwaitApis.tsx => await-apis.tsx} (95%) rename src/ui/components/common/{AccountsError.tsx => accounts-error.tsx} (98%) create mode 100644 src/ui/components/common/button.tsx rename src/ui/components/common/{ConnectionError.tsx => connection-error.tsx} (97%) rename src/ui/components/common/{CopyButton.tsx => copy-button.tsx} (97%) create mode 100644 src/ui/components/common/dropdown.tsx create mode 100644 src/ui/components/common/error.tsx rename src/ui/components/common/{HeaderButtons.tsx => header-buttons.tsx} (100%) create mode 100644 src/ui/components/common/loader.tsx create mode 100644 src/ui/components/common/meter.tsx rename src/ui/components/common/{NoticeBanner.tsx => notice-banner.tsx} (100%) rename src/ui/components/common/{NotificationIcon.tsx => notification-icon.tsx} (96%) rename src/ui/components/common/{SearchResults.tsx => search-results.tsx} (100%) rename src/ui/components/common/{SidePanel.tsx => side-panel.tsx} (100%) create mode 100644 src/ui/components/common/spinner.tsx create mode 100644 src/ui/components/common/switch.tsx create mode 100644 src/ui/components/common/tabs.tsx rename src/ui/components/contract/{ContractRow.tsx => contract-row.tsx} (96%) rename src/ui/components/contract/{DryRunError.tsx => dry-run-error.tsx} (91%) rename src/ui/components/contract/{DryRunResult.tsx => dry-run-result.tsx} (96%) rename src/ui/components/contract/{MetadataTab.tsx => metadata-tab.tsx} (97%) rename src/ui/components/contract/{OutcomeItem.tsx => outcome-item.tsx} (93%) rename src/ui/components/contract/{ResultsOutput.tsx => results-output.tsx} (87%) rename src/ui/components/contract/{TransactionResult.tsx => transaction-result.tsx} (100%) rename src/ui/components/form/{InputBalance.tsx => Input-balance.tsx} (97%) rename src/ui/components/form/{InputBn.tsx => Input-bn.tsx} (97%) rename src/ui/components/form/{InputBytes.tsx => Input-bytes.tsx} (98%) rename src/ui/components/form/{InputFile.tsx => Input-file.tsx} (100%) rename src/ui/components/form/{ArgumentForm.tsx => argument-form.tsx} (91%) create mode 100644 src/ui/components/form/bool.tsx create mode 100644 src/ui/components/form/enum.tsx rename src/ui/components/form/{findComponent.tsx => find-component.tsx} (88%) rename src/ui/components/form/{FormField.tsx => form-field.tsx} (100%) rename src/ui/components/form/hooks/{useMetadataField.tsx => use-metadata-field.tsx} (96%) rename src/ui/components/form/{InputHash.tsx => input-hash.tsx} (97%) rename src/ui/components/form/{InputHex.tsx => input-hex.tsx} (97%) rename src/ui/components/form/{InputNumber.tsx => input-number.tsx} (100%) rename src/ui/components/form/{InputSalt.tsx => input-salt.tsx} (91%) rename src/ui/components/form/{InputStorageDepositLimit.tsx => input-storage-deposit-limit.tsx} (94%) rename src/ui/components/form/{InputWeight.tsx => input-weight.tsx} (95%) create mode 100644 src/ui/components/form/input.tsx create mode 100644 src/ui/components/form/option.tsx rename src/ui/components/form/{OptionsForm.tsx => options-form.tsx} (89%) create mode 100644 src/ui/components/form/struct.tsx rename src/ui/components/form/{SubForm.tsx => sub-form.tsx} (100%) create mode 100644 src/ui/components/form/tuple.tsx rename src/ui/components/form/{VectorFixed.tsx => vector-fixed.tsx} (97%) create mode 100644 src/ui/components/form/vector.tsx create mode 100644 src/ui/components/homepage/contracts.tsx rename src/ui/components/homepage/{HelpBox.tsx => help-box.tsx} (95%) create mode 100644 src/ui/components/homepage/statistics.tsx rename src/ui/components/instantiate/{AvailableCodeBundles.tsx => available-code-bundles.tsx} (96%) rename src/ui/components/instantiate/{CodeHash.tsx => code-hash.tsx} (90%) rename src/ui/components/instantiate/{DryRun.tsx => dry-run.tsx} (95%) rename src/ui/components/instantiate/{LookUpCodeHash.tsx => look-up-code-hash.tsx} (93%) rename src/ui/components/instantiate/{Step1.tsx => step-1.tsx} (96%) rename src/ui/components/instantiate/{Step2.tsx => step-2.tsx} (98%) rename src/ui/components/instantiate/{Step3.tsx => step-3.tsx} (97%) create mode 100644 src/ui/components/instantiate/wizard.tsx rename src/ui/components/message/{ArgSignature.tsx => arg-signature.tsx} (100%) rename src/ui/components/message/{MessageDocs.tsx => message-docs.tsx} (96%) rename src/ui/components/message/{MessageSignature.tsx => message-signature.tsx} (97%) create mode 100644 src/ui/components/metadata/metadata.tsx rename src/ui/components/modal/{ForgetAllContractsModal.tsx => forget-all-contracts-modal.tsx} (94%) rename src/ui/components/modal/{ForgetContractModal.tsx => forget-contract-modal.tsx} (92%) rename src/ui/components/modal/{HelpModal.tsx => help-modal.tsx} (74%) create mode 100644 src/ui/components/modal/logos.tsx rename src/ui/components/modal/{ModalBase.tsx => modal-base.tsx} (100%) rename src/ui/components/modal/{SettingsModal.tsx => settings-modal.tsx} (77%) rename src/ui/components/settings/{CustomEndpoint.tsx => custom-endpoint.tsx} (90%) rename src/ui/components/settings/{ThemeMode.tsx => theme-mode.tsx} (93%) create mode 100644 src/ui/components/transactions.tsx rename src/ui/contexts/{ApiContext.tsx => api.context.tsx} (95%) rename src/ui/contexts/{DatabaseContext.tsx => database.context.tsx} (96%) rename src/ui/contexts/{InstantiateContext.tsx => instantiate.context.tsx} (100%) rename src/ui/contexts/{ThemeContext.tsx => theme.context.tsx} (94%) rename src/ui/contexts/{TransactionsContext.tsx => transactions.context.tsx} (97%) rename src/ui/hooks/{useArgValues.ts => use-arg-values.ts} (90%) rename src/ui/hooks/{useBalance.ts => use-balance.ts} (95%) rename src/ui/hooks/{useDbQuery.ts => use-db-query.ts} (100%) rename src/ui/hooks/{useFormField.ts => use-form-field.ts} (100%) rename src/ui/hooks/{useIsMounted.ts => use-is-mounted.ts} (100%) rename src/ui/hooks/{useLocalStorage.ts => use-local-storage.ts} (100%) rename src/ui/hooks/{useMetadata.ts => use-metadata.ts} (98%) rename src/ui/hooks/{useNewContract.ts => use-new-contract.ts} (100%) rename src/ui/hooks/{useNonEmptyString.ts => use-non-empty-string.ts} (92%) rename src/ui/hooks/{useStorageDepositLimit.ts => use-storage-deposit-limit.ts} (87%) rename src/ui/hooks/{useStoredContract.ts => use-stored-contract.ts} (100%) rename src/ui/hooks/{useToggle.ts => use-toggle.ts} (93%) rename src/ui/hooks/{useWeight.ts => use-weight.ts} (100%) rename src/ui/layout/{RootLayout.tsx => root.layout.tsx} (100%) create mode 100644 src/ui/layout/sidebar/footer.tsx rename src/ui/layout/sidebar/{MobileMenu.tsx => mobile-menu.tsx} (91%) rename src/ui/layout/sidebar/{NavLink.tsx => nav-link.tsx} (100%) create mode 100644 src/ui/layout/sidebar/navigation.tsx rename src/ui/layout/sidebar/{NetworkAndUser.tsx => network-and-user.tsx} (100%) rename src/ui/layout/sidebar/{QuickLinks.tsx => quick-link.tsx} (96%) rename src/ui/pages/{AddContract.tsx => add-contract/add-contract.page.tsx} (100%) create mode 100644 src/ui/pages/add-contract/index.ts rename src/ui/pages/{AddressLookup.tsx => address-lookup/address-lookup.page.tsx} (98%) create mode 100644 src/ui/pages/address-lookup/index.ts rename src/ui/pages/{ContractHeader.tsx => contract-header/contract-header.page.tsx} (96%) create mode 100644 src/ui/pages/contract-header/index.ts rename src/ui/pages/{Contract.tsx => contract/contract.page.tsx} (81%) create mode 100644 src/ui/pages/contract/index.ts rename src/ui/pages/{Homepage.tsx => homepage/homepage.page.tsx} (83%) create mode 100644 src/ui/pages/homepage/index.ts create mode 100644 src/ui/pages/instantiate/index.ts rename src/ui/pages/{Instantiate.tsx => instantiate/instantiate.page.tsx} (100%) create mode 100644 src/ui/pages/not-found/index.ts rename src/ui/pages/{NotFound.tsx => not-found/not-found.page.tsx} (100%) create mode 100644 src/ui/pages/select-code-hash/index.ts rename src/ui/pages/{SelectCodeHash.tsx => select-code-hash/select-code-hash.tsx} (100%) diff --git a/src/lib/blockTime.ts b/src/lib/block-time.ts similarity index 100% rename from src/lib/blockTime.ts rename to src/lib/block-time.ts diff --git a/src/lib/callOptions.ts b/src/lib/call-options.ts similarity index 100% rename from src/lib/callOptions.ts rename to src/lib/call-options.ts diff --git a/src/lib/hasRevertFlag.ts b/src/lib/has-revert-flag.ts similarity index 100% rename from src/lib/hasRevertFlag.ts rename to src/lib/has-revert-flag.ts diff --git a/src/lib/initValue.ts b/src/lib/init-value.ts similarity index 100% rename from src/lib/initValue.ts rename to src/lib/init-value.ts diff --git a/src/services/chain/chainProps.ts b/src/services/chain/chain-props.service.ts similarity index 100% rename from src/services/chain/chainProps.ts rename to src/services/chain/chain-props.service.ts diff --git a/src/services/chain/contract.ts b/src/services/chain/contract.service.ts similarity index 97% rename from src/services/chain/contract.ts rename to src/services/chain/contract.service.ts index 46b68978..a67a9b93 100644 --- a/src/services/chain/contract.ts +++ b/src/services/chain/contract.service.ts @@ -3,7 +3,7 @@ import { BlueprintPromise, CodePromise } from '@polkadot/api-contract'; import { isValidAddress, isValidCodeHash, isNumber } from 'lib/util'; -import { transformUserInput } from 'lib/callOptions'; +import { transformUserInput } from 'lib/call-options'; import { ApiPromise, CodeBundleDocument, diff --git a/src/services/chain/index.ts b/src/services/chain/index.ts index d2db2d55..0c330fde 100644 --- a/src/services/chain/index.ts +++ b/src/services/chain/index.ts @@ -1,5 +1,5 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './chainProps'; -export * from './contract'; +export * from './chain-props.service'; +export * from './contract.service'; diff --git a/src/services/db/dexie-db.service.ts b/src/services/db/dexie-db.service.ts new file mode 100644 index 00000000..b7ce8c4f --- /dev/null +++ b/src/services/db/dexie-db.service.ts @@ -0,0 +1,32 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import Dexie, { Table } from 'dexie'; + +export interface CodeBundleDocument { + abi: Record; + codeHash: string; + date: string; + id?: number; + name: string; +} + +export interface ContractDocument extends CodeBundleDocument { + abi: Record; + address: string; + external?: boolean; +} + +export class Database extends Dexie { + codeBundles!: Table; + contracts!: Table; + + constructor(genesisHash: string) { + super(`contracts-ui__${genesisHash}`); + + this.version(1).stores({ + codeBundles: '++id, codeHash, name, date', + contracts: '++id, address, codeHash, name, date', + }); + } +} diff --git a/src/services/db/index.ts b/src/services/db/index.ts index b7ce8c4f..33c6ae1d 100644 --- a/src/services/db/index.ts +++ b/src/services/db/index.ts @@ -1,32 +1,4 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import Dexie, { Table } from 'dexie'; - -export interface CodeBundleDocument { - abi: Record; - codeHash: string; - date: string; - id?: number; - name: string; -} - -export interface ContractDocument extends CodeBundleDocument { - abi: Record; - address: string; - external?: boolean; -} - -export class Database extends Dexie { - codeBundles!: Table; - contracts!: Table; - - constructor(genesisHash: string) { - super(`contracts-ui__${genesisHash}`); - - this.version(1).stores({ - codeBundles: '++id, codeHash, name, date', - contracts: '++id, address, codeHash, name, date', - }); - } -} +export * from './dexie-db.service'; diff --git a/src/ui/components/Transactions.tsx b/src/ui/components/Transactions.tsx index a8eeaa5e..22378a89 100644 --- a/src/ui/components/Transactions.tsx +++ b/src/ui/components/Transactions.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { BellIcon, XIcon } from '@heroicons/react/outline'; -import { NotificationIcon } from './common/NotificationIcon'; +import { NotificationIcon } from './common/notification-icon'; import { classes, isEmptyObj } from 'lib/util'; import type { QueuedTxOptions, TransactionsState } from 'types'; diff --git a/src/ui/components/account/Account.tsx b/src/ui/components/account/Account.tsx index 9b798050..dd4ab5e8 100644 --- a/src/ui/components/account/Account.tsx +++ b/src/ui/components/account/Account.tsx @@ -1,7 +1,7 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { Identicon } from './Identicon'; +import { Identicon } from './identicon'; import { classes, truncate } from 'lib/util'; import { OrFalsy } from 'types'; import { useApi } from 'ui/contexts'; diff --git a/src/ui/components/account/Select.tsx b/src/ui/components/account/Select.tsx index 6f76885c..dd649bed 100644 --- a/src/ui/components/account/Select.tsx +++ b/src/ui/components/account/Select.tsx @@ -3,8 +3,8 @@ import { useMemo, useState } from 'react'; import { GroupBase } from 'react-select'; -import { Dropdown } from '../common/Dropdown'; -import { Account } from './Account'; +import { Dropdown } from '../common/dropdown'; +import { Account } from './account'; import { createAccountOptions } from 'ui/util/dropdown'; import type { DropdownOption, DropdownProps, ValidFormField } from 'types'; import { useApi, useDatabase } from 'ui/contexts'; diff --git a/src/ui/components/account/account.tsx b/src/ui/components/account/account.tsx new file mode 100644 index 00000000..dd4ab5e8 --- /dev/null +++ b/src/ui/components/account/account.tsx @@ -0,0 +1,43 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { Identicon } from './identicon'; +import { classes, truncate } from 'lib/util'; +import { OrFalsy } from 'types'; +import { useApi } from 'ui/contexts'; + +interface Props extends React.HTMLAttributes { + name?: React.ReactNode; + value: OrFalsy; + size?: number; +} + +export function Account({ className, name: propsName, size = 42, value }: Props) { + const { accounts } = useApi(); + + const account = accounts?.find(a => a.address === value); + const name = propsName || account?.meta.name; + + if (!value) { + return null; + } + + return ( +
+ +
+ {name && ( + + {name} + + )} +

+ {truncate(value, 4)} +

+
+
+ ); +} diff --git a/src/ui/components/account/identicon.tsx b/src/ui/components/account/identicon.tsx new file mode 100644 index 00000000..05b64612 --- /dev/null +++ b/src/ui/components/account/identicon.tsx @@ -0,0 +1,69 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { polkadotIcon } from '@polkadot/ui-shared'; +import type { Circle } from '@polkadot/ui-shared/icons/types'; +import copy from 'copy-to-clipboard'; +import React, { useCallback } from 'react'; +import { Tooltip } from 'react-tooltip'; +import { Button } from '../common'; +import { classes } from 'lib/util'; + +export interface Props extends React.HTMLAttributes { + value?: string | null; + isAlternative?: boolean; + size: number; +} + +function renderCircle({ cx, cy, fill, r }: Circle, key: number): React.ReactNode { + return ; +} + +function IdenticonBase({ + value = '', + className = '', + isAlternative = false, + size, + style, +}: Props): React.ReactElement | null { + const onClick = useCallback(() => { + if (value) { + copy(value); + } + }, [value]); + + const tooltipId = `identicon-copied-${value}`; + + try { + return ( + <> + + + Copied to clipboard + + + ); + } catch (e) { + return null; + } +} + +export const Identicon = React.memo(IdenticonBase); diff --git a/src/ui/components/account/index.ts b/src/ui/components/account/index.ts index ca44994d..2cfcf63c 100644 --- a/src/ui/components/account/index.ts +++ b/src/ui/components/account/index.ts @@ -1,6 +1,6 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './Account'; -export * from './Select'; -export * from './Identicon'; +export * from './account'; +export * from './select'; +export * from './identicon'; diff --git a/src/ui/components/account/select.tsx b/src/ui/components/account/select.tsx new file mode 100644 index 00000000..dd649bed --- /dev/null +++ b/src/ui/components/account/select.tsx @@ -0,0 +1,92 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { useMemo, useState } from 'react'; +import { GroupBase } from 'react-select'; +import { Dropdown } from '../common/dropdown'; +import { Account } from './account'; +import { createAccountOptions } from 'ui/util/dropdown'; +import type { DropdownOption, DropdownProps, ValidFormField } from 'types'; +import { useApi, useDatabase } from 'ui/contexts'; +import { classes } from 'lib/util'; +import { useDbQuery } from 'ui/hooks'; + +type Props = ValidFormField & Omit, 'options'>; + +export function Option({ label, value }: DropdownOption) { + return ; +} + +function Select({ + isDisabled, + onChange, + options, + placeholder = 'Select account', + className, + value, + onCreate, +}: DropdownProps) { + return ( + + ); +} + +export function AccountSelect({ placeholder = 'Select account', ...props }: Props) { + const { accounts } = useApi(); + + return ( + + ); +} diff --git a/src/ui/components/app.tsx b/src/ui/components/app.tsx new file mode 100644 index 00000000..1e1b0938 --- /dev/null +++ b/src/ui/components/app.tsx @@ -0,0 +1,32 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { Outlet } from 'react-router'; +import { AwaitApis } from 'ui/components'; +import { + ApiContextProvider, + DatabaseContextProvider, + TransactionsContextProvider, + ThemeContextProvider, +} from 'ui/contexts'; +import { Sidebar } from 'ui/layout/sidebar'; + +export default function App() { + return ( + + + + + {/* we want the sidebar outside the outlet to prevent flickering in quicklinks */} +
+ + + + +
+
+
+
+
+ ); +} diff --git a/src/ui/components/AwaitApis.tsx b/src/ui/components/await-apis.tsx similarity index 95% rename from src/ui/components/AwaitApis.tsx rename to src/ui/components/await-apis.tsx index a778429f..62d57498 100644 --- a/src/ui/components/AwaitApis.tsx +++ b/src/ui/components/await-apis.tsx @@ -4,7 +4,7 @@ import { useEffect, useState } from 'react'; import type { HTMLAttributes } from 'react'; import { isWeb3Injected } from '@polkadot/extension-dapp'; -import { AccountsError, ExtensionError } from './common/AccountsError'; +import { AccountsError, ExtensionError } from './common/accounts-error'; import { useApi, useDatabase } from 'ui/contexts'; import { Loader, ConnectionError } from 'ui/components/common'; import { isKeyringLoaded } from 'lib/util'; diff --git a/src/ui/components/common/Loader.tsx b/src/ui/components/common/Loader.tsx index 665e8cf4..be1d9b4e 100644 --- a/src/ui/components/common/Loader.tsx +++ b/src/ui/components/common/Loader.tsx @@ -1,7 +1,7 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { Spinner } from './Spinner'; +import { Spinner } from './spinner'; interface Props extends React.HTMLAttributes { isLoading?: boolean; diff --git a/src/ui/components/common/AccountsError.tsx b/src/ui/components/common/accounts-error.tsx similarity index 98% rename from src/ui/components/common/AccountsError.tsx rename to src/ui/components/common/accounts-error.tsx index 2de89bd1..021af41b 100644 --- a/src/ui/components/common/AccountsError.tsx +++ b/src/ui/components/common/accounts-error.tsx @@ -1,7 +1,7 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { Error } from './Error'; +import { Error } from './error'; export function AccountsError() { return ( diff --git a/src/ui/components/common/button.tsx b/src/ui/components/common/button.tsx new file mode 100644 index 00000000..33c49148 --- /dev/null +++ b/src/ui/components/common/button.tsx @@ -0,0 +1,43 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import React from 'react'; +import { classes } from 'lib/util'; + +type Variant = 'default' | 'primary' | 'plain' | 'negative'; + +interface Props extends React.HTMLAttributes { + isDisabled?: boolean; + isLoading?: boolean; + ref?: React.MutableRefObject; + variant?: Variant; +} + +export function Buttons({ children, className }: React.HTMLAttributes) { + return
{children}
; +} + +export const Button = React.forwardRef((props, ref) => { + const { children, variant, className, isDisabled, isLoading, ...rest } = props; + + return ( + + ); +}); diff --git a/src/ui/components/common/ConnectionError.tsx b/src/ui/components/common/connection-error.tsx similarity index 97% rename from src/ui/components/common/ConnectionError.tsx rename to src/ui/components/common/connection-error.tsx index 1f6474a5..28809676 100644 --- a/src/ui/components/common/ConnectionError.tsx +++ b/src/ui/components/common/connection-error.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { useNavigate } from 'react-router-dom'; -import { Error } from './Error'; +import { Error } from './error'; import { useApi } from 'ui/contexts'; import { ROCOCO_CONTRACTS, LOCAL } from 'src/constants'; diff --git a/src/ui/components/common/CopyButton.tsx b/src/ui/components/common/copy-button.tsx similarity index 97% rename from src/ui/components/common/CopyButton.tsx rename to src/ui/components/common/copy-button.tsx index 3c9d1440..da8cf32b 100644 --- a/src/ui/components/common/CopyButton.tsx +++ b/src/ui/components/common/copy-button.tsx @@ -5,7 +5,7 @@ import copy from 'copy-to-clipboard'; import { MouseEventHandler, useCallback, useRef, useState } from 'react'; import { DocumentDuplicateIcon } from '@heroicons/react/outline'; import { Tooltip } from 'react-tooltip'; -import { Button } from './Button'; +import { Button } from './button'; import { classes } from 'lib/util'; interface Props extends React.HTMLAttributes { diff --git a/src/ui/components/common/dropdown.tsx b/src/ui/components/common/dropdown.tsx new file mode 100644 index 00000000..5aaf9355 --- /dev/null +++ b/src/ui/components/common/dropdown.tsx @@ -0,0 +1,119 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { useCallback, useMemo } from 'react'; +import { + components, + ControlProps, + DropdownIndicatorProps, + GroupBase, + InputProps, + OptionProps, + OptionsOrGroups, + Props as ReactSelectProps, +} from 'react-select'; +import CreatableSelect from 'react-select/creatable'; + +import { CheckIcon, ChevronDownIcon } from '@heroicons/react/solid'; +import { classes, isValidAddress } from 'lib/util'; +import type { DropdownOption, DropdownProps } from 'types'; + +function isGroupedOptions( + options: ReactSelectProps, false>['options'], +): options is GroupBase>[] { + try { + return !!options && (options as GroupBase>[])[0].options !== undefined; + } catch (e) { + return false; + } +} + +function Control(props: ControlProps, false>) { + return ; +} + +function Input(props: InputProps, false>) { + return ( + + ); +} + +function Option({ children, ...props }: OptionProps, false>) { + return ( + + {children} + {props.isSelected && } + + ); +} + +function DropdownIndicator(props: DropdownIndicatorProps, false>) { + return ( + + + + ); +} + +function getOption( + options: OptionsOrGroups, GroupBase>>, + val: T, +) { + if (isGroupedOptions(options)) { + return options + .reduce((result: DropdownOption[], { options }) => [...result, ...options], []) + .find(({ value }) => value === val); + } + + return (options as DropdownOption[]).find(({ value }) => value === val); +} + +export function Dropdown({ + className = '', + components = {}, + formatOptionLabel, + isDisabled = false, + isSearchable = false, + onChange: _onChange, + options = [], + placeholder, + value: _value, + onCreate, +}: DropdownProps) { + const onChange = useCallback( + (option: DropdownOption | null): void => { + option && _onChange(option.value); + }, + [_onChange], + ); + + const value = useMemo(() => getOption(options, _value), [options, _value]); + + return ( + undefined} + formatOptionLabel={formatOptionLabel} + isDisabled={isDisabled} + isSearchable={isSearchable} + isValidNewOption={inputValue => + isValidAddress(inputValue) && !getOption(options, inputValue as T) + } + onChange={onChange} + onCreateOption={onCreate} + options={options} + placeholder={placeholder} + styles={{ + dropdownIndicator: provided => ({ ...provided, padding: '0.25rem' }), + input: provided => ({ ...provided, color: 'unset' }), + option: () => ({}), + }} + value={value} + /> + ); +} diff --git a/src/ui/components/common/error.tsx b/src/ui/components/common/error.tsx new file mode 100644 index 00000000..b638ee95 --- /dev/null +++ b/src/ui/components/common/error.tsx @@ -0,0 +1,18 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { ExclamationCircleIcon } from '@heroicons/react/outline'; +import { classes } from 'lib/util'; + +type Props = React.HTMLProps; + +export function Error({ children, className }: Props) { + return ( +
+
+ + {children} +
+
+ ); +} diff --git a/src/ui/components/common/HeaderButtons.tsx b/src/ui/components/common/header-buttons.tsx similarity index 100% rename from src/ui/components/common/HeaderButtons.tsx rename to src/ui/components/common/header-buttons.tsx diff --git a/src/ui/components/common/index.ts b/src/ui/components/common/index.ts index 25565e91..88c560c3 100644 --- a/src/ui/components/common/index.ts +++ b/src/ui/components/common/index.ts @@ -1,14 +1,14 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './Button'; -export * from './Dropdown'; -export * from './HeaderButtons'; -export * from './Loader'; -export * from './Meter'; -export * from './Spinner'; -export * from './Switch'; -export * from './Tabs'; -export * from './SearchResults'; -export * from './ConnectionError'; -export * from './NoticeBanner'; +export * from './button'; +export * from './dropdown'; +export * from './header-buttons'; +export * from './loader'; +export * from './meter'; +export * from './spinner'; +export * from './switch'; +export * from './tabs'; +export * from './search-results'; +export * from './connection-error'; +export * from './notice-banner'; diff --git a/src/ui/components/common/loader.tsx b/src/ui/components/common/loader.tsx new file mode 100644 index 00000000..be1d9b4e --- /dev/null +++ b/src/ui/components/common/loader.tsx @@ -0,0 +1,20 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { Spinner } from './spinner'; + +interface Props extends React.HTMLAttributes { + isLoading?: boolean; + message?: React.ReactNode; +} + +export function Loader({ children, isLoading, message = 'Loading...' }: Props): React.ReactElement { + return isLoading ? ( +
+ +
{message}
+
+ ) : ( + <>{children} + ); +} diff --git a/src/ui/components/common/meter.tsx b/src/ui/components/common/meter.tsx new file mode 100644 index 00000000..33b78123 --- /dev/null +++ b/src/ui/components/common/meter.tsx @@ -0,0 +1,19 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +interface Props { + label?: React.ReactNode; + accessory?: React.ReactNode; + withAccessory?: boolean; +} + +export function Meter({ accessory, label, withAccessory }: Props) { + return ( +
+
+ {label} + {withAccessory &&
{accessory}
} +
+
+ ); +} diff --git a/src/ui/components/common/NoticeBanner.tsx b/src/ui/components/common/notice-banner.tsx similarity index 100% rename from src/ui/components/common/NoticeBanner.tsx rename to src/ui/components/common/notice-banner.tsx diff --git a/src/ui/components/common/NotificationIcon.tsx b/src/ui/components/common/notification-icon.tsx similarity index 96% rename from src/ui/components/common/NotificationIcon.tsx rename to src/ui/components/common/notification-icon.tsx index 82944702..44c1ae8f 100644 --- a/src/ui/components/common/NotificationIcon.tsx +++ b/src/ui/components/common/notification-icon.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { CheckIcon, ClockIcon, ExclamationCircleIcon } from '@heroicons/react/outline'; -import { Spinner } from './Spinner'; +import { Spinner } from './spinner'; import { TxStatus } from 'types'; import { classes } from 'lib/util'; diff --git a/src/ui/components/common/SearchResults.tsx b/src/ui/components/common/search-results.tsx similarity index 100% rename from src/ui/components/common/SearchResults.tsx rename to src/ui/components/common/search-results.tsx diff --git a/src/ui/components/common/SidePanel.tsx b/src/ui/components/common/side-panel.tsx similarity index 100% rename from src/ui/components/common/SidePanel.tsx rename to src/ui/components/common/side-panel.tsx diff --git a/src/ui/components/common/spinner.tsx b/src/ui/components/common/spinner.tsx new file mode 100644 index 00000000..b50f21b2 --- /dev/null +++ b/src/ui/components/common/spinner.tsx @@ -0,0 +1,34 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { classes } from 'lib/util'; + +interface Props extends React.HTMLAttributes { + strokeWidth?: number; + width?: number; + color?: string; + darkColor?: string; +} + +export function Spinner({ + className, + color = 'blue-500', + darkColor = color, + strokeWidth = 4, + width = 16, +}: Props) { + return ( +
+ ); +} diff --git a/src/ui/components/common/switch.tsx b/src/ui/components/common/switch.tsx new file mode 100644 index 00000000..f7c90082 --- /dev/null +++ b/src/ui/components/common/switch.tsx @@ -0,0 +1,38 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { Switch as HUISwitch } from '@headlessui/react'; +import { classes } from 'lib/util'; +import { SimpleSpread } from 'types'; + +type Props = SimpleSpread< + React.HTMLAttributes, + { + value: boolean; + onChange: (_: boolean) => void; + } +>; + +export function Switch({ children, className, onChange, value }: Props) { + return ( + + {children} + + ); +} diff --git a/src/ui/components/common/tabs.tsx b/src/ui/components/common/tabs.tsx new file mode 100644 index 00000000..37921ce3 --- /dev/null +++ b/src/ui/components/common/tabs.tsx @@ -0,0 +1,51 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import type { SetState } from 'types'; +import { classes } from 'lib/util'; + +interface Tab { + id: string; + isDisabled?: boolean; + label: React.ReactNode; +} + +interface Props extends React.HTMLAttributes { + children: React.ReactNode[]; + index: number; + setIndex: SetState; + tabs: Tab[]; +} + +export function Tabs({ children, index, setIndex, tabs }: Props) { + return ( + <> +
+
    + {tabs.map(({ id, label }, tabIndex) => { + return ( +
  • + +
  • + ); + })} +
+
+ {children.map((child, i) => { + return ( +
+ {child} +
+ ); + })} + + ); +} diff --git a/src/ui/components/contract/Interact.tsx b/src/ui/components/contract/Interact.tsx index 1980dfec..7d6e5bfc 100644 --- a/src/ui/components/contract/Interact.tsx +++ b/src/ui/components/contract/Interact.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { useEffect, useState, useRef, useMemo } from 'react'; -import { ResultsOutput } from './ResultsOutput'; +import { ResultsOutput } from './results-output'; import { AbiMessage, ContractExecResult, @@ -19,14 +19,14 @@ import { ArgumentForm, Form, FormField, OptionsForm } from 'ui/components/form'; import { BN_ZERO } from 'lib/bn'; import { useApi, useTransactions } from 'ui/contexts'; import { useWeight, useBalance, useArgValues } from 'ui/hooks'; -import { useStorageDepositLimit } from 'ui/hooks/useStorageDepositLimit'; +import { useStorageDepositLimit } from 'ui/hooks/use-storage-deposit-limit'; import { createMessageOptions } from 'ui/util/dropdown'; import { decodeStorageDeposit, getGasLimit, getStorageDepositLimit, transformUserInput, -} from 'lib/callOptions'; +} from 'lib/call-options'; import { getDecodedOutput } from 'lib/output'; interface Props { diff --git a/src/ui/components/contract/ContractRow.tsx b/src/ui/components/contract/contract-row.tsx similarity index 96% rename from src/ui/components/contract/ContractRow.tsx rename to src/ui/components/contract/contract-row.tsx index d0747761..1dcba422 100644 --- a/src/ui/components/contract/ContractRow.tsx +++ b/src/ui/components/contract/contract-row.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; -import { Identicon } from '../account/Identicon'; +import { Identicon } from '../account/identicon'; import { ContractDocument } from 'types'; import { useApi } from 'ui/contexts'; import { displayDate } from 'lib/util'; diff --git a/src/ui/components/contract/DryRunError.tsx b/src/ui/components/contract/dry-run-error.tsx similarity index 91% rename from src/ui/components/contract/DryRunError.tsx rename to src/ui/components/contract/dry-run-error.tsx index 5bd360e0..b8937eba 100644 --- a/src/ui/components/contract/DryRunError.tsx +++ b/src/ui/components/contract/dry-run-error.tsx @@ -1,7 +1,7 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { OutcomeItem } from './OutcomeItem'; +import { OutcomeItem } from './outcome-item'; import { RegistryError } from 'types'; export function DryRunError({ error }: { error: RegistryError }) { diff --git a/src/ui/components/contract/DryRunResult.tsx b/src/ui/components/contract/dry-run-result.tsx similarity index 96% rename from src/ui/components/contract/DryRunResult.tsx rename to src/ui/components/contract/dry-run-result.tsx index 73c17450..89d73a6a 100644 --- a/src/ui/components/contract/DryRunResult.tsx +++ b/src/ui/components/contract/dry-run-result.tsx @@ -2,13 +2,13 @@ // SPDX-License-Identifier: GPL-3.0-only import { AbiMessage } from '@polkadot/api-contract/types'; -import { DryRunError } from './DryRunError'; -import { OutcomeItem } from './OutcomeItem'; +import { DryRunError } from './dry-run-error'; +import { OutcomeItem } from './outcome-item'; import { classes } from 'lib/util'; import { ContractExecResult, Registry } from 'types'; import { useApi } from 'ui/contexts'; import { getDecodedOutput } from 'lib/output'; -import { decodeStorageDeposit } from 'lib/callOptions'; +import { decodeStorageDeposit } from 'lib/call-options'; interface Props { outcome: ContractExecResult; diff --git a/src/ui/components/contract/index.ts b/src/ui/components/contract/index.ts index 70f17151..06647227 100644 --- a/src/ui/components/contract/index.ts +++ b/src/ui/components/contract/index.ts @@ -1,8 +1,8 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './ContractRow'; +export * from './contract-row'; export * from './Interact'; -export * from './MetadataTab'; -export * from './ResultsOutput'; -export * from './TransactionResult'; +export * from './metadata-tab'; +export * from './results-output'; +export * from './transaction-result'; diff --git a/src/ui/components/contract/MetadataTab.tsx b/src/ui/components/contract/metadata-tab.tsx similarity index 97% rename from src/ui/components/contract/MetadataTab.tsx rename to src/ui/components/contract/metadata-tab.tsx index a1d8baf3..611379fb 100644 --- a/src/ui/components/contract/MetadataTab.tsx +++ b/src/ui/components/contract/metadata-tab.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { Abi } from 'types'; -import { MessageDocs } from 'ui/components/message/MessageDocs'; +import { MessageDocs } from 'ui/components/message/message-docs'; import { Button } from 'ui/components/common'; import { FormField, getValidation, InputFile, useMetadataField } from 'ui/components/form'; import { useDatabase } from 'ui/contexts'; diff --git a/src/ui/components/contract/OutcomeItem.tsx b/src/ui/components/contract/outcome-item.tsx similarity index 93% rename from src/ui/components/contract/OutcomeItem.tsx rename to src/ui/components/contract/outcome-item.tsx index 68e40010..444acb97 100644 --- a/src/ui/components/contract/OutcomeItem.tsx +++ b/src/ui/components/contract/outcome-item.tsx @@ -1,7 +1,7 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { CopyButton } from 'ui/components/common/CopyButton'; +import { CopyButton } from 'ui/components/common/copy-button'; export function OutcomeItem({ displayValue, diff --git a/src/ui/components/contract/ResultsOutput.tsx b/src/ui/components/contract/results-output.tsx similarity index 87% rename from src/ui/components/contract/ResultsOutput.tsx rename to src/ui/components/contract/results-output.tsx index 57129ad0..65809c16 100644 --- a/src/ui/components/contract/ResultsOutput.tsx +++ b/src/ui/components/contract/results-output.tsx @@ -1,9 +1,9 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { SidePanel } from '../common/SidePanel'; -import { TransactionResult } from './TransactionResult'; -import { DryRunResult } from './DryRunResult'; +import { SidePanel } from '../common/side-panel'; +import { TransactionResult } from './transaction-result'; +import { DryRunResult } from './dry-run-result'; import { CallResult, ContractExecResult, Registry, AbiMessage } from 'types'; interface Props { diff --git a/src/ui/components/contract/TransactionResult.tsx b/src/ui/components/contract/transaction-result.tsx similarity index 100% rename from src/ui/components/contract/TransactionResult.tsx rename to src/ui/components/contract/transaction-result.tsx diff --git a/src/ui/components/form/Bool.tsx b/src/ui/components/form/Bool.tsx index f21fa143..f5931bd0 100644 --- a/src/ui/components/form/Bool.tsx +++ b/src/ui/components/form/Bool.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { SimpleSpread, ValidFormField } from 'types'; -import { Dropdown } from 'ui/components/common/Dropdown'; +import { Dropdown } from 'ui/components/common/dropdown'; type Props = SimpleSpread, ValidFormField>; diff --git a/src/ui/components/form/Enum.tsx b/src/ui/components/form/Enum.tsx index ebbfb9d9..b30e8212 100644 --- a/src/ui/components/form/Enum.tsx +++ b/src/ui/components/form/Enum.tsx @@ -2,13 +2,13 @@ // SPDX-License-Identifier: GPL-3.0-only import { useCallback, useState } from 'react'; -import { Dropdown } from '../common/Dropdown'; -import { ArgSignature } from '../message/ArgSignature'; -import { FormField, getValidation } from './FormField'; +import { Dropdown } from '../common/dropdown'; +import { ArgSignature } from '../message/arg-signature'; +import { FormField, getValidation } from './form-field'; import { isNumber } from 'lib/util'; import { ArgComponentProps, OrFalsy, TypeDef } from 'types'; import { useApi } from 'ui/contexts'; -import { getInitValue } from 'lib/initValue'; +import { getInitValue } from 'lib/init-value'; interface Props extends ArgComponentProps> { components: React.ComponentType>[]; diff --git a/src/ui/components/form/InputBalance.tsx b/src/ui/components/form/Input-balance.tsx similarity index 97% rename from src/ui/components/form/InputBalance.tsx rename to src/ui/components/form/Input-balance.tsx index 657ec4c4..c44a3484 100644 --- a/src/ui/components/form/InputBalance.tsx +++ b/src/ui/components/form/Input-balance.tsx @@ -4,7 +4,7 @@ import React, { useState } from 'react'; import BN from 'bn.js'; -import { InputNumber } from './InputNumber'; +import { InputNumber } from './input-number'; import { classes } from 'lib/util'; import { ApiPromise, OrFalsy, SimpleSpread } from 'types'; import { useApi } from 'ui/contexts'; diff --git a/src/ui/components/form/InputBn.tsx b/src/ui/components/form/Input-bn.tsx similarity index 97% rename from src/ui/components/form/InputBn.tsx rename to src/ui/components/form/Input-bn.tsx index 31707a8c..a46a8fd7 100644 --- a/src/ui/components/form/InputBn.tsx +++ b/src/ui/components/form/Input-bn.tsx @@ -3,7 +3,7 @@ import { useCallback, useState } from 'react'; import BN from 'bn.js'; -import { InputNumber } from './InputNumber'; +import { InputNumber } from './input-number'; import { ArgComponentProps } from 'types'; type Props = ArgComponentProps; diff --git a/src/ui/components/form/InputBytes.tsx b/src/ui/components/form/Input-bytes.tsx similarity index 98% rename from src/ui/components/form/InputBytes.tsx rename to src/ui/components/form/Input-bytes.tsx index 6915488d..03fb42e9 100644 --- a/src/ui/components/form/InputBytes.tsx +++ b/src/ui/components/form/Input-bytes.tsx @@ -3,7 +3,7 @@ import { hexToU8a } from '@polkadot/util'; import React, { useCallback, useMemo, useState } from 'react'; -import { Input } from './Input'; +import { Input } from './input'; import { classes } from 'lib/util'; import { ArgComponentProps } from 'types'; diff --git a/src/ui/components/form/InputFile.tsx b/src/ui/components/form/Input-file.tsx similarity index 100% rename from src/ui/components/form/InputFile.tsx rename to src/ui/components/form/Input-file.tsx diff --git a/src/ui/components/form/Option.tsx b/src/ui/components/form/Option.tsx index 4bc6d752..d78113ea 100644 --- a/src/ui/components/form/Option.tsx +++ b/src/ui/components/form/Option.tsx @@ -2,13 +2,13 @@ // SPDX-License-Identifier: GPL-3.0-only import { useCallback, useEffect, useRef } from 'react'; -import { Switch } from '../common/Switch'; -import { Input } from './Input'; +import { Switch } from '../common/switch'; +import { Input } from './input'; import { ArgComponentProps, OrFalsy, Registry, TypeDef } from 'types'; import { useApi } from 'ui/contexts'; import { NOOP } from 'lib/util'; -import { useToggle } from 'ui/hooks/useToggle'; -import { getInitValue } from 'lib/initValue'; +import { useToggle } from 'ui/hooks/use-toggle'; +import { getInitValue } from 'lib/init-value'; interface Props extends ArgComponentProps { component: React.ComponentType>; diff --git a/src/ui/components/form/Struct.tsx b/src/ui/components/form/Struct.tsx index 52c49103..42cceef5 100644 --- a/src/ui/components/form/Struct.tsx +++ b/src/ui/components/form/Struct.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { encodeTypeDef } from '@polkadot/types'; -import { FormField } from './FormField'; +import { FormField } from './form-field'; import { TypeDefInfo, ArgComponentProps } from 'types'; type Props = ArgComponentProps> & { diff --git a/src/ui/components/form/Tuple.tsx b/src/ui/components/form/Tuple.tsx index e70a8c3c..d5ca8f04 100644 --- a/src/ui/components/form/Tuple.tsx +++ b/src/ui/components/form/Tuple.tsx @@ -3,7 +3,7 @@ import { encodeTypeDef } from '@polkadot/types'; import { useCallback } from 'react'; -import { FormField } from './FormField'; +import { FormField } from './form-field'; import { ArgComponentProps, OrFalsy, TypeDef } from 'types'; interface Props extends ArgComponentProps { diff --git a/src/ui/components/form/Vector.tsx b/src/ui/components/form/Vector.tsx index e9beb8af..ea94b2e1 100644 --- a/src/ui/components/form/Vector.tsx +++ b/src/ui/components/form/Vector.tsx @@ -5,11 +5,11 @@ import { encodeTypeDef } from '@polkadot/types'; import React, { useCallback } from 'react'; import { MinusIcon, PlusIcon } from '@heroicons/react/outline'; import { Button, Buttons } from '../common'; -import { FormField } from './FormField'; +import { FormField } from './form-field'; import { TypeDef, ArgComponentProps, OrFalsy } from 'types'; import { useApi } from 'ui/contexts'; -import { getInitValue } from 'lib/initValue'; +import { getInitValue } from 'lib/init-value'; interface Props extends ArgComponentProps { component: React.ComponentType>; @@ -43,7 +43,7 @@ export function Vector({ return (
-
diff --git a/src/ui/components/form/ArgumentForm.tsx b/src/ui/components/form/argument-form.tsx similarity index 91% rename from src/ui/components/form/ArgumentForm.tsx rename to src/ui/components/form/argument-form.tsx index 46239a84..28507127 100644 --- a/src/ui/components/form/ArgumentForm.tsx +++ b/src/ui/components/form/argument-form.tsx @@ -2,9 +2,9 @@ // SPDX-License-Identifier: GPL-3.0-only import { useMemo } from 'react'; -import { ArgSignature } from '../message/ArgSignature'; -import { Form, FormField } from './FormField'; -import { findComponent } from './findComponent'; +import { ArgSignature } from '../message/arg-signature'; +import { Form, FormField } from './form-field'; +import { findComponent } from './find-component'; import { AbiParam, Registry, SetState } from 'types'; import { classes } from 'lib/util'; diff --git a/src/ui/components/form/bool.tsx b/src/ui/components/form/bool.tsx new file mode 100644 index 00000000..f5931bd0 --- /dev/null +++ b/src/ui/components/form/bool.tsx @@ -0,0 +1,22 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { SimpleSpread, ValidFormField } from 'types'; +import { Dropdown } from 'ui/components/common/dropdown'; + +type Props = SimpleSpread, ValidFormField>; + +const options = [ + { + value: false, + label: 'false', + }, + { + value: true, + label: 'true', + }, +]; + +export function Bool({ value, onChange, ...props }: Props) { + return ; +} diff --git a/src/ui/components/form/enum.tsx b/src/ui/components/form/enum.tsx new file mode 100644 index 00000000..b30e8212 --- /dev/null +++ b/src/ui/components/form/enum.tsx @@ -0,0 +1,69 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { useCallback, useState } from 'react'; +import { Dropdown } from '../common/dropdown'; +import { ArgSignature } from '../message/arg-signature'; +import { FormField, getValidation } from './form-field'; +import { isNumber } from 'lib/util'; +import { ArgComponentProps, OrFalsy, TypeDef } from 'types'; +import { useApi } from 'ui/contexts'; +import { getInitValue } from 'lib/init-value'; + +interface Props extends ArgComponentProps> { + components: React.ComponentType>[]; +} + +export function Enum(props: Props) { + const { components, typeDef, nestingNumber, onChange: _onChange, registry, value } = props; + const variants = typeDef.sub as TypeDef[]; + const { accounts } = useApi(); + const [variantIndex, _setVariantIndex] = useState(0); + + const Component = components[variantIndex]; + + const onChange = useCallback( + (value: unknown): void => { + _onChange({ [variants[variantIndex].name as string]: value }); + }, + [_onChange, variants, variantIndex], + ); + + const setVariantIndex = useCallback( + (value: OrFalsy) => { + if (isNumber(value)) { + _setVariantIndex(value); + + _onChange({ + [variants[value].name as string]: getInitValue(registry, accounts || [], variants[value]), + }); + } + }, + [registry, accounts, _onChange, variants], + ); + + return ( + <> + ({ label: name, value: index }))} + value={variantIndex} + /> + {variants[variantIndex].type !== 'Null' && ( + } + {...getValidation(props)} + > + + + )} + + ); +} diff --git a/src/ui/components/form/findComponent.tsx b/src/ui/components/form/find-component.tsx similarity index 88% rename from src/ui/components/form/findComponent.tsx rename to src/ui/components/form/find-component.tsx index 2504e6d1..9df0f5cb 100644 --- a/src/ui/components/form/findComponent.tsx +++ b/src/ui/components/form/find-component.tsx @@ -1,20 +1,20 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { AddressSelect } from '../account/Select'; -import { Bool } from './Bool'; -import { Enum } from './Enum'; -import { Input } from './Input'; -import { InputBalance } from './InputBalance'; -import { InputBn } from './InputBn'; -import { InputBytes } from './InputBytes'; -import { InputHash } from './InputHash'; -import { Option } from './Option'; -import { Struct } from './Struct'; -import { SubForm } from './SubForm'; -import { Tuple } from './Tuple'; -import { Vector } from './Vector'; -import { VectorFixed } from './VectorFixed'; +import { AddressSelect } from '../account/select'; +import { Bool } from './bool'; +import { Enum } from './enum'; +import { Input } from './input'; +import { InputBalance } from './Input-balance'; +import { InputBn } from './Input-bn'; +import { InputBytes } from './Input-bytes'; +import { InputHash } from './input-hash'; +import { Option } from './option'; +import { Struct } from './struct'; +import { SubForm } from './sub-form'; +import { Tuple } from './tuple'; +import { Vector } from './vector'; +import { VectorFixed } from './vector-fixed'; import { ArgComponentProps, Registry, TypeDef, TypeDefInfo } from 'types'; function subComponents( diff --git a/src/ui/components/form/FormField.tsx b/src/ui/components/form/form-field.tsx similarity index 100% rename from src/ui/components/form/FormField.tsx rename to src/ui/components/form/form-field.tsx diff --git a/src/ui/components/form/hooks/index.ts b/src/ui/components/form/hooks/index.ts index 797170c3..905f12ea 100644 --- a/src/ui/components/form/hooks/index.ts +++ b/src/ui/components/form/hooks/index.ts @@ -1,4 +1,4 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './useMetadataField'; +export * from './use-metadata-field'; diff --git a/src/ui/components/form/hooks/useMetadataField.tsx b/src/ui/components/form/hooks/use-metadata-field.tsx similarity index 96% rename from src/ui/components/form/hooks/useMetadataField.tsx rename to src/ui/components/form/hooks/use-metadata-field.tsx index 1e14801a..04ddca9a 100644 --- a/src/ui/components/form/hooks/useMetadataField.tsx +++ b/src/ui/components/form/hooks/use-metadata-field.tsx @@ -4,7 +4,7 @@ import { useState, useMemo, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router'; import { FileState, OrFalsy, UseMetadata } from 'types'; -import { useMetadata } from 'ui/hooks/useMetadata'; +import { useMetadata } from 'ui/hooks/use-metadata'; import { useDatabase } from 'ui/contexts'; import { useDbQuery } from 'ui/hooks'; diff --git a/src/ui/components/form/index.ts b/src/ui/components/form/index.ts index c8a225fa..6ac60e73 100644 --- a/src/ui/components/form/index.ts +++ b/src/ui/components/form/index.ts @@ -2,15 +2,15 @@ // SPDX-License-Identifier: GPL-3.0-only export * from './hooks'; -export * from './FormField'; -export * from './Input'; -export * from './InputBalance'; -export * from './InputBn'; -export * from './InputFile'; -export * from './InputNumber'; -export * from './InputSalt'; -export * from './InputWeight'; -export * from './InputStorageDepositLimit'; -export * from './ArgumentForm'; -export * from './OptionsForm'; -export * from './Bool'; +export * from './form-field'; +export * from './input'; +export * from './Input-balance'; +export * from './Input-bn'; +export * from './Input-file'; +export * from './input-number'; +export * from './input-salt'; +export * from './input-weight'; +export * from './input-storage-deposit-limit'; +export * from './argument-form'; +export * from './options-form'; +export * from './bool'; diff --git a/src/ui/components/form/InputHash.tsx b/src/ui/components/form/input-hash.tsx similarity index 97% rename from src/ui/components/form/InputHash.tsx rename to src/ui/components/form/input-hash.tsx index 37d812a4..8e8f0397 100644 --- a/src/ui/components/form/InputHash.tsx +++ b/src/ui/components/form/input-hash.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { useCallback, useState } from 'react'; -import { InputHex } from './InputHex'; +import { InputHex } from './input-hex'; import { ArgComponentProps, Hash } from 'types'; type Props = ArgComponentProps; diff --git a/src/ui/components/form/InputHex.tsx b/src/ui/components/form/input-hex.tsx similarity index 97% rename from src/ui/components/form/InputHex.tsx rename to src/ui/components/form/input-hex.tsx index aab5b2be..e1535a53 100644 --- a/src/ui/components/form/InputHex.tsx +++ b/src/ui/components/form/input-hex.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { useCallback, useState } from 'react'; -import { Input } from './Input'; +import { Input } from './input'; import { classes } from 'lib/util'; interface Props { diff --git a/src/ui/components/form/InputNumber.tsx b/src/ui/components/form/input-number.tsx similarity index 100% rename from src/ui/components/form/InputNumber.tsx rename to src/ui/components/form/input-number.tsx diff --git a/src/ui/components/form/InputSalt.tsx b/src/ui/components/form/input-salt.tsx similarity index 91% rename from src/ui/components/form/InputSalt.tsx rename to src/ui/components/form/input-salt.tsx index 09345e60..b0cf7a68 100644 --- a/src/ui/components/form/InputSalt.tsx +++ b/src/ui/components/form/input-salt.tsx @@ -1,8 +1,8 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { Switch } from '../common/Switch'; -import { Input } from './Input'; +import { Switch } from '../common/switch'; +import { Input } from './input'; import { SimpleSpread, ValidFormField } from 'types'; type Props = SimpleSpread< diff --git a/src/ui/components/form/InputStorageDepositLimit.tsx b/src/ui/components/form/input-storage-deposit-limit.tsx similarity index 94% rename from src/ui/components/form/InputStorageDepositLimit.tsx rename to src/ui/components/form/input-storage-deposit-limit.tsx index 96cb3ca2..43f01842 100644 --- a/src/ui/components/form/InputStorageDepositLimit.tsx +++ b/src/ui/components/form/input-storage-deposit-limit.tsx @@ -4,8 +4,8 @@ import Big from 'big.js'; import { useMemo } from 'react'; import { Meter, Switch } from '../common'; -import { InputBalance } from './InputBalance'; -import { getValidation } from './FormField'; +import { InputBalance } from './Input-balance'; +import { getValidation } from './form-field'; import type { SimpleSpread, UseStorageDepositLimit } from 'types'; import { classes, isNull, isNumber } from 'lib/util'; diff --git a/src/ui/components/form/InputWeight.tsx b/src/ui/components/form/input-weight.tsx similarity index 95% rename from src/ui/components/form/InputWeight.tsx rename to src/ui/components/form/input-weight.tsx index 90345068..07a34fbe 100644 --- a/src/ui/components/form/InputWeight.tsx +++ b/src/ui/components/form/input-weight.tsx @@ -2,8 +2,8 @@ // SPDX-License-Identifier: GPL-3.0-only import BN from 'bn.js'; -import { Meter } from '../common/Meter'; -import { InputNumber } from './InputNumber'; +import { Meter } from '../common/meter'; +import { InputNumber } from './input-number'; import { UIGas } from 'types'; import { MAX_CALL_WEIGHT } from 'src/constants'; diff --git a/src/ui/components/form/input.tsx b/src/ui/components/form/input.tsx new file mode 100644 index 00000000..042af6a0 --- /dev/null +++ b/src/ui/components/form/input.tsx @@ -0,0 +1,50 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { SimpleSpread } from 'types'; +import { classes } from 'lib/util'; + +type Props = SimpleSpread< + React.InputHTMLAttributes, + { + isDisabled?: boolean; + isError?: boolean; + onChange: (_: string) => void; + value?: string | null; + } +>; + +export function Input({ + children, + className, + isDisabled = false, + isError = false, + onChange: _onChange, + placeholder, + value, + onFocus, + type = 'text', +}: Props) { + function onChange(e: React.ChangeEvent): void { + _onChange(e.target.value); + } + + return ( +
+ + {children} +
+ ); +} diff --git a/src/ui/components/form/option.tsx b/src/ui/components/form/option.tsx new file mode 100644 index 00000000..d78113ea --- /dev/null +++ b/src/ui/components/form/option.tsx @@ -0,0 +1,76 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { useCallback, useEffect, useRef } from 'react'; +import { Switch } from '../common/switch'; +import { Input } from './input'; +import { ArgComponentProps, OrFalsy, Registry, TypeDef } from 'types'; +import { useApi } from 'ui/contexts'; +import { NOOP } from 'lib/util'; +import { useToggle } from 'ui/hooks/use-toggle'; +import { getInitValue } from 'lib/init-value'; + +interface Props extends ArgComponentProps { + component: React.ComponentType>; + registry: Registry; + typeDef: TypeDef; +} + +export function Option({ + component: Component, + onChange: _onChange, + nestingNumber, + registry, + typeDef, + value = null, +}: Props) { + const { accounts } = useApi(); + const [isSupplied, toggleIsSupplied] = useToggle(value !== null); + const isSuppliedRef = useRef(isSupplied); + + const onChange = useCallback( + (value: OrFalsy): void => { + if (!isSupplied) { + _onChange(null); + + return; + } + + _onChange(value); + }, + [_onChange, isSupplied], + ); + + useEffect((): void => { + if (isSupplied && !isSuppliedRef.current && value === null && accounts) { + onChange(getInitValue(registry, accounts, typeDef.sub as TypeDef)); + isSuppliedRef.current = true; + } else if (!isSupplied && isSuppliedRef.current && value !== null) { + onChange(null); + isSuppliedRef.current = false; + } + }, [accounts, registry, onChange, value, isSupplied, typeDef.sub]); + + return ( +
+ {isSupplied ? ( +
+ +
+ ) : ( +
+ +
+ )} +
+ +
+
+ ); +} diff --git a/src/ui/components/form/OptionsForm.tsx b/src/ui/components/form/options-form.tsx similarity index 89% rename from src/ui/components/form/OptionsForm.tsx rename to src/ui/components/form/options-form.tsx index bf399df7..af75235d 100644 --- a/src/ui/components/form/OptionsForm.tsx +++ b/src/ui/components/form/options-form.tsx @@ -3,10 +3,10 @@ import { UIGas, UseBalance, UseStorageDepositLimit } from 'types'; -import { InputWeight } from 'ui/components/form/InputWeight'; -import { InputBalance } from 'ui/components/form/InputBalance'; -import { InputStorageDepositLimit } from 'ui/components/form/InputStorageDepositLimit'; -import { FormField } from 'ui/components/form/FormField'; +import { InputWeight } from 'ui/components/form/input-weight'; +import { InputBalance } from 'ui/components/form/Input-balance'; +import { InputStorageDepositLimit } from 'ui/components/form/input-storage-deposit-limit'; +import { FormField } from 'ui/components/form/form-field'; interface Props { isPayable: boolean; diff --git a/src/ui/components/form/struct.tsx b/src/ui/components/form/struct.tsx new file mode 100644 index 00000000..42cceef5 --- /dev/null +++ b/src/ui/components/form/struct.tsx @@ -0,0 +1,47 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { encodeTypeDef } from '@polkadot/types'; +import { FormField } from './form-field'; +import { TypeDefInfo, ArgComponentProps } from 'types'; + +type Props = ArgComponentProps> & { + components: React.ComponentType>[]; +}; + +export function Struct({ components, value, nestingNumber, onChange, registry, typeDef }: Props) { + const _onChange = (name: string) => (newEntry: unknown) => { + const newValue = { ...value, [name]: newEntry }; + onChange(newValue); + }; + const subTypes = + typeDef.info === TypeDefInfo.Si + ? registry.lookup.getTypeDef(typeDef.type as `Lookup${number}`).sub + : typeDef.sub; + return ( +
+ {subTypes && + components && + components.map((Component, index) => { + const subType = Array.isArray(subTypes) ? subTypes[index] : subTypes; + const name = subType.displayName || subType.name || ''; + + return ( + + + + ); + })} +
+ ); +} diff --git a/src/ui/components/form/SubForm.tsx b/src/ui/components/form/sub-form.tsx similarity index 100% rename from src/ui/components/form/SubForm.tsx rename to src/ui/components/form/sub-form.tsx diff --git a/src/ui/components/form/tuple.tsx b/src/ui/components/form/tuple.tsx new file mode 100644 index 00000000..d5ca8f04 --- /dev/null +++ b/src/ui/components/form/tuple.tsx @@ -0,0 +1,53 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { encodeTypeDef } from '@polkadot/types'; +import { useCallback } from 'react'; +import { FormField } from './form-field'; +import { ArgComponentProps, OrFalsy, TypeDef } from 'types'; + +interface Props extends ArgComponentProps { + components: React.ComponentType>[]; +} + +export function Tuple({ + className, + components, + nestingNumber, + onChange: _onChange, + registry, + typeDef, + value, +}: Props) { + const onChange = useCallback( + (index: number) => + (newValue: OrFalsy): void => { + _onChange(value.map((argAtIndex, atIndex) => (atIndex === index ? newValue : argAtIndex))); + }, + [_onChange, value], + ); + + return ( +
+ {components.map((Component, index) => { + const subType = (typeDef.sub as TypeDef[])[index]; + + return ( + + + + ); + })} +
+ ); +} diff --git a/src/ui/components/form/VectorFixed.tsx b/src/ui/components/form/vector-fixed.tsx similarity index 97% rename from src/ui/components/form/VectorFixed.tsx rename to src/ui/components/form/vector-fixed.tsx index 7e10b1c4..7a64dbcc 100644 --- a/src/ui/components/form/VectorFixed.tsx +++ b/src/ui/components/form/vector-fixed.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { useCallback } from 'react'; -import { FormField } from './FormField'; +import { FormField } from './form-field'; import { ArgComponentProps, OrFalsy } from 'types'; interface Props extends ArgComponentProps { diff --git a/src/ui/components/form/vector.tsx b/src/ui/components/form/vector.tsx new file mode 100644 index 00000000..ea94b2e1 --- /dev/null +++ b/src/ui/components/form/vector.tsx @@ -0,0 +1,87 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { encodeTypeDef } from '@polkadot/types'; +import React, { useCallback } from 'react'; +import { MinusIcon, PlusIcon } from '@heroicons/react/outline'; +import { Button, Buttons } from '../common'; +import { FormField } from './form-field'; +import { TypeDef, ArgComponentProps, OrFalsy } from 'types'; + +import { useApi } from 'ui/contexts'; +import { getInitValue } from 'lib/init-value'; + +interface Props extends ArgComponentProps { + component: React.ComponentType>; +} + +export function Vector({ + component: Component, + nestingNumber, + onChange: _onChange, + registry, + typeDef, + value = [], +}: Props) { + const { accounts } = useApi(); + const subType = typeDef.sub as TypeDef; + + const onAddRow = useCallback((): void => { + _onChange([...value, getInitValue(registry, accounts || [], subType)]); + }, [_onChange, value, accounts, registry, subType]); + + const onRemoveRow = useCallback(() => _onChange(value.slice(0, -1)), [_onChange, value]); + + const onChange = useCallback( + (index: number) => + (newValue: OrFalsy): void => { + _onChange(value.map((argAtIndex, atIndex) => (atIndex === index ? newValue : argAtIndex))); + }, + [_onChange, value], + ); + + return ( +
+
+ + + + + +
+ {(value || []).map((element, index) => { + return ( + + + + ); + })} +
+ ); +} diff --git a/src/ui/components/homepage/Contracts.tsx b/src/ui/components/homepage/Contracts.tsx index 17aa1c11..b734babc 100644 --- a/src/ui/components/homepage/Contracts.tsx +++ b/src/ui/components/homepage/Contracts.tsx @@ -4,7 +4,7 @@ import { FolderOpenIcon, TrashIcon } from '@heroicons/react/outline'; import { useCallback, useState } from 'react'; import { Link } from 'react-router-dom'; -import { ContractRow } from '../contract/ContractRow'; +import { ContractRow } from '../contract/contract-row'; import { ForgetAllContractsModal } from 'ui/components/modal'; import { useDatabase } from 'ui/contexts'; import { useDbQuery } from 'ui/hooks'; diff --git a/src/ui/components/homepage/contracts.tsx b/src/ui/components/homepage/contracts.tsx new file mode 100644 index 00000000..b734babc --- /dev/null +++ b/src/ui/components/homepage/contracts.tsx @@ -0,0 +1,56 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { FolderOpenIcon, TrashIcon } from '@heroicons/react/outline'; +import { useCallback, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { ContractRow } from '../contract/contract-row'; +import { ForgetAllContractsModal } from 'ui/components/modal'; +import { useDatabase } from 'ui/contexts'; +import { useDbQuery } from 'ui/hooks'; + +export function Contracts(): React.ReactElement | null { + const { db } = useDatabase(); + const [isOpen, setIsOpen] = useState(false); + const [contracts, isLoading] = useDbQuery(() => db.contracts.toArray(), [db]); + const forgetAllContracts = useCallback(() => db.contracts.clear(), [db]); + + if (isLoading || !contracts) { + return null; + } + + if (contracts.length === 0) { + return ( +
+ +
You haven't uploaded any contracts yet on this browser.
+ + Upload a new contract + +
+ ); + } + + return ( + <> + +
+
+ {contracts?.map(contract => { + return ; + })} +
+
+ +
+
+ + ); +} diff --git a/src/ui/components/homepage/HelpBox.tsx b/src/ui/components/homepage/help-box.tsx similarity index 95% rename from src/ui/components/homepage/HelpBox.tsx rename to src/ui/components/homepage/help-box.tsx index ade20658..f59daf25 100644 --- a/src/ui/components/homepage/HelpBox.tsx +++ b/src/ui/components/homepage/help-box.tsx @@ -1,7 +1,7 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { Button } from '../common/Button'; +import { Button } from '../common/button'; export function HelpBox(): React.ReactElement | null { return ( diff --git a/src/ui/components/homepage/index.ts b/src/ui/components/homepage/index.ts index 331d769d..b6dd1e0e 100644 --- a/src/ui/components/homepage/index.ts +++ b/src/ui/components/homepage/index.ts @@ -1,6 +1,6 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './Contracts'; -export * from './HelpBox'; -export * from './Statistics'; +export * from './contracts'; +export * from './help-box'; +export * from './statistics'; diff --git a/src/ui/components/homepage/statistics.tsx b/src/ui/components/homepage/statistics.tsx new file mode 100644 index 00000000..90bbcdac --- /dev/null +++ b/src/ui/components/homepage/statistics.tsx @@ -0,0 +1,61 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { useEffect, useMemo, useState } from 'react'; +import { useApi } from 'ui/contexts'; +import { AnyJson, ApiPromise, ChainProperties } from 'types'; + +function getChainType(systemChainType: ChainProperties['systemChainType']): string { + if (systemChainType.isDevelopment) return 'Development'; + if (systemChainType.isLocal) return 'Local'; + if (systemChainType.isLive) return 'Live'; + if (systemChainType.isCustom) return 'Custom'; + return 'Unknown'; +} + +export function Statistics(): React.ReactElement | null { + const { api, systemChain, systemName, systemChainType, tokenSymbol } = useApi(); + + const [blockNumber, setBlockNumber] = useState(''); + + useEffect(() => { + async function listenToBlocks(api: ApiPromise) { + return api.rpc.chain.subscribeNewHeads(header => { + setBlockNumber(header.number.toHuman()); + }); + } + let cleanUp: VoidFunction | undefined; + listenToBlocks(api) + .then(unsub => (cleanUp = unsub)) + .catch(console.error); + + return () => cleanUp && cleanUp(); + }, [api]); + + const entries = useMemo((): Record => { + return { + 'Chain Name': systemChainType.isDevelopment ? systemName : systemChain, + 'Chain Type': getChainType(systemChainType), + 'Highest Block': `#${blockNumber}`, + Token: tokenSymbol, + }; + }, [blockNumber, systemChain, systemChainType, systemName, tokenSymbol]); + + return ( + <> +
+ {Object.entries(entries).map(([label, value], i) => { + return ( +
+
{label}
+
{value}
+
+ ); + })} +
+ + ); +} diff --git a/src/ui/components/index.ts b/src/ui/components/index.ts index c17686d3..e4577a85 100644 --- a/src/ui/components/index.ts +++ b/src/ui/components/index.ts @@ -8,4 +8,4 @@ export * from './form'; export * from './homepage'; export * from './instantiate'; export * from './message'; -export * from './AwaitApis'; +export * from './await-apis'; diff --git a/src/ui/components/instantiate/Wizard.tsx b/src/ui/components/instantiate/Wizard.tsx index d8013cc8..93306fa7 100644 --- a/src/ui/components/instantiate/Wizard.tsx +++ b/src/ui/components/instantiate/Wizard.tsx @@ -1,10 +1,10 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { DryRun } from './DryRun'; -import { Step1 } from './Step1'; -import { Step2 } from './Step2'; -import { Step3 } from './Step3'; +import { DryRun } from './dry-run'; +import { Step1 } from './step-1'; +import { Step2 } from './step-2'; +import { Step3 } from './step-3'; import { useInstantiate } from 'ui/contexts'; export function Wizard() { diff --git a/src/ui/components/instantiate/AvailableCodeBundles.tsx b/src/ui/components/instantiate/available-code-bundles.tsx similarity index 96% rename from src/ui/components/instantiate/AvailableCodeBundles.tsx rename to src/ui/components/instantiate/available-code-bundles.tsx index c7a799ac..1ae65866 100644 --- a/src/ui/components/instantiate/AvailableCodeBundles.tsx +++ b/src/ui/components/instantiate/available-code-bundles.tsx @@ -3,8 +3,8 @@ import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router'; -import { FormField } from '../form/FormField'; -import { CodeHash } from './CodeHash'; +import { FormField } from '../form/form-field'; +import { CodeHash } from './code-hash'; import { CodeBundleDocument } from 'types'; import { useApi, useDatabase } from 'ui/contexts'; diff --git a/src/ui/components/instantiate/CodeHash.tsx b/src/ui/components/instantiate/code-hash.tsx similarity index 90% rename from src/ui/components/instantiate/CodeHash.tsx rename to src/ui/components/instantiate/code-hash.tsx index c2c4502c..51562319 100644 --- a/src/ui/components/instantiate/CodeHash.tsx +++ b/src/ui/components/instantiate/code-hash.tsx @@ -3,11 +3,11 @@ import { ChevronRightIcon, TrashIcon } from '@heroicons/react/outline'; import { useEffect, useMemo, useState } from 'react'; +import { CopyButton } from 'ui/components/common/copy-button'; import { checkOnChainCode } from 'services/chain'; import { SimpleSpread, VoidFn } from 'types'; import { useApi, useDatabase } from 'ui/contexts'; import { classes, truncate } from 'lib/util'; -import { CopyButton } from 'ui/components/common/CopyButton'; type Props = SimpleSpread< React.HTMLAttributes, @@ -79,13 +79,13 @@ export function CodeHash({ {isError &&
{error}
}
{onClick && isOnChain && ( - + )} {!isOnChain && ( <> Not on-chain )} diff --git a/src/ui/components/instantiate/DryRun.tsx b/src/ui/components/instantiate/dry-run.tsx similarity index 95% rename from src/ui/components/instantiate/DryRun.tsx rename to src/ui/components/instantiate/dry-run.tsx index 4703da2b..53186a69 100644 --- a/src/ui/components/instantiate/DryRun.tsx +++ b/src/ui/components/instantiate/dry-run.tsx @@ -2,11 +2,11 @@ // SPDX-License-Identifier: GPL-3.0-only import { CheckCircleIcon, ExclamationCircleIcon } from '@heroicons/react/outline'; -import { SidePanel } from '../common/SidePanel'; -import { Account } from '../account/Account'; -import { OutcomeItem } from '../contract/OutcomeItem'; +import { SidePanel } from '../common/side-panel'; +import { Account } from '../account/account'; +import { OutcomeItem } from '../contract/outcome-item'; import { useApi, useInstantiate } from 'ui/contexts'; -import { hasRevertFlag } from 'lib/hasRevertFlag'; +import { hasRevertFlag } from 'lib/has-revert-flag'; export function DryRun() { const { diff --git a/src/ui/components/instantiate/index.ts b/src/ui/components/instantiate/index.ts index 8fa62437..15c8bed1 100644 --- a/src/ui/components/instantiate/index.ts +++ b/src/ui/components/instantiate/index.ts @@ -1,6 +1,6 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './AvailableCodeBundles'; -export * from './LookUpCodeHash'; -export * from './Wizard'; +export * from './available-code-bundles'; +export * from './look-up-code-hash'; +export * from './wizard'; diff --git a/src/ui/components/instantiate/LookUpCodeHash.tsx b/src/ui/components/instantiate/look-up-code-hash.tsx similarity index 93% rename from src/ui/components/instantiate/LookUpCodeHash.tsx rename to src/ui/components/instantiate/look-up-code-hash.tsx index 01bc0f3a..7922b6c2 100644 --- a/src/ui/components/instantiate/LookUpCodeHash.tsx +++ b/src/ui/components/instantiate/look-up-code-hash.tsx @@ -4,10 +4,10 @@ import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router'; import { XCircleIcon } from '@heroicons/react/outline'; -import { Input } from '../form/Input'; -import { FormField } from '../form/FormField'; -import { SearchResults } from '../common/SearchResults'; -import { CodeHash } from './CodeHash'; +import { Input } from '../form/input'; +import { FormField } from '../form/form-field'; +import { SearchResults } from '../common/search-results'; +import { CodeHash } from './code-hash'; import { checkOnChainCode, filterOnChainCode } from 'services/chain'; import { classes, isValidCodeHash } from 'lib/util'; import { useApi, useDatabase } from 'ui/contexts'; diff --git a/src/ui/components/instantiate/Step1.tsx b/src/ui/components/instantiate/step-1.tsx similarity index 96% rename from src/ui/components/instantiate/Step1.tsx rename to src/ui/components/instantiate/step-1.tsx index 0ab46e09..23689c23 100644 --- a/src/ui/components/instantiate/Step1.tsx +++ b/src/ui/components/instantiate/step-1.tsx @@ -3,14 +3,14 @@ import { useEffect, useState } from 'react'; import { useParams } from 'react-router'; -import { Button, Buttons } from '../common/Button'; +import { Button, Buttons } from '../common/button'; import { Input, InputFile, Form, FormField, useMetadataField, getValidation } from '../form'; -import { Loader } from '../common/Loader'; +import { Loader } from '../common/loader'; import { AccountSelect } from '../account'; import { MessageDocs } from '../message'; import { Metadata } from '../metadata'; -import { CodeHash } from './CodeHash'; -import { useNonEmptyString } from 'ui/hooks/useNonEmptyString'; +import { CodeHash } from './code-hash'; +import { useNonEmptyString } from 'ui/hooks/use-non-empty-string'; import { useApi, useDatabase, useInstantiate } from 'ui/contexts'; import { useDbQuery } from 'ui/hooks'; diff --git a/src/ui/components/instantiate/Step2.tsx b/src/ui/components/instantiate/step-2.tsx similarity index 98% rename from src/ui/components/instantiate/Step2.tsx rename to src/ui/components/instantiate/step-2.tsx index 9d77bdce..3b27dbf8 100644 --- a/src/ui/components/instantiate/Step2.tsx +++ b/src/ui/components/instantiate/step-2.tsx @@ -3,6 +3,7 @@ import { useEffect, useMemo, useState } from 'react'; import { useParams } from 'react-router'; +import { hasRevertFlag } from 'lib/has-revert-flag'; import { isNumber, genRanHex } from 'lib/util'; import { Button, Buttons, Dropdown } from 'ui/components/common'; import { @@ -29,9 +30,8 @@ import { encodeSalt, getGasLimit, getStorageDepositLimit, -} from 'lib/callOptions'; +} from 'lib/call-options'; import { BN_ZERO } from 'lib/bn'; -import { hasRevertFlag } from 'lib/hasRevertFlag'; function validateSalt(value: OrFalsy) { if (!!value && value.length === 66) { diff --git a/src/ui/components/instantiate/Step3.tsx b/src/ui/components/instantiate/step-3.tsx similarity index 97% rename from src/ui/components/instantiate/Step3.tsx rename to src/ui/components/instantiate/step-3.tsx index 00d00cc4..e3ea519f 100644 --- a/src/ui/components/instantiate/Step3.tsx +++ b/src/ui/components/instantiate/step-3.tsx @@ -3,8 +3,8 @@ import { useParams } from 'react-router'; import { useEffect, useState } from 'react'; -import { Account } from '../account/Account'; -import { Button, Buttons } from '../common/Button'; +import { Account } from '../account/account'; +import { Button, Buttons } from '../common/button'; import { useApi, useInstantiate, useTransactions } from 'ui/contexts'; import { truncate } from 'lib/util'; import { SubmittableResult } from 'types'; diff --git a/src/ui/components/instantiate/wizard.tsx b/src/ui/components/instantiate/wizard.tsx new file mode 100644 index 00000000..93306fa7 --- /dev/null +++ b/src/ui/components/instantiate/wizard.tsx @@ -0,0 +1,30 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { DryRun } from './dry-run'; +import { Step1 } from './step-1'; +import { Step2 } from './step-2'; +import { Step3 } from './step-3'; +import { useInstantiate } from 'ui/contexts'; + +export function Wizard() { + const { + step, + data: { metadata }, + } = useInstantiate(); + + return ( +
+
+ + {metadata && } + {step === 3 && } +
+ {step === 2 && ( + + )} +
+ ); +} diff --git a/src/ui/components/message/ArgSignature.tsx b/src/ui/components/message/arg-signature.tsx similarity index 100% rename from src/ui/components/message/ArgSignature.tsx rename to src/ui/components/message/arg-signature.tsx diff --git a/src/ui/components/message/index.ts b/src/ui/components/message/index.ts index 988f4377..8a49034d 100644 --- a/src/ui/components/message/index.ts +++ b/src/ui/components/message/index.ts @@ -1,6 +1,6 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './ArgSignature'; -export * from './MessageDocs'; -export * from './MessageSignature'; +export * from './arg-signature'; +export * from './message-docs'; +export * from './message-signature'; diff --git a/src/ui/components/message/MessageDocs.tsx b/src/ui/components/message/message-docs.tsx similarity index 96% rename from src/ui/components/message/MessageDocs.tsx rename to src/ui/components/message/message-docs.tsx index 9c419fd3..afa5a6a9 100644 --- a/src/ui/components/message/MessageDocs.tsx +++ b/src/ui/components/message/message-docs.tsx @@ -5,7 +5,7 @@ import { Disclosure } from '@headlessui/react'; import { ChevronUpIcon } from '@heroicons/react/solid'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; -import { MessageSignature } from './MessageSignature'; +import { MessageSignature } from './message-signature'; import type { AbiMessage, Registry } from 'types'; import { classes } from 'lib/util'; diff --git a/src/ui/components/message/MessageSignature.tsx b/src/ui/components/message/message-signature.tsx similarity index 97% rename from src/ui/components/message/MessageSignature.tsx rename to src/ui/components/message/message-signature.tsx index 13f5a4f4..8b98a1e4 100644 --- a/src/ui/components/message/MessageSignature.tsx +++ b/src/ui/components/message/message-signature.tsx @@ -3,7 +3,7 @@ import { encodeTypeDef } from '@polkadot/types/create'; import { DatabaseIcon } from '@heroicons/react/outline'; -import { ArgSignature } from './ArgSignature'; +import { ArgSignature } from './arg-signature'; import type { AbiMessage, Registry } from 'types'; import { classes } from 'lib/util'; diff --git a/src/ui/components/metadata/index.ts b/src/ui/components/metadata/index.ts index 4d92e06f..c3f7b946 100644 --- a/src/ui/components/metadata/index.ts +++ b/src/ui/components/metadata/index.ts @@ -1,4 +1,4 @@ // Copyright 2023 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './Metadata'; +export * from './metadata'; diff --git a/src/ui/components/metadata/metadata.tsx b/src/ui/components/metadata/metadata.tsx new file mode 100644 index 00000000..5cb9c1f2 --- /dev/null +++ b/src/ui/components/metadata/metadata.tsx @@ -0,0 +1,44 @@ +// Copyright 2023 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { classes } from 'lib/util'; +import { Abi } from 'types'; + +interface Props extends React.HTMLAttributes { + metadata: Abi; +} + +export function Metadata({ metadata, className = '', ...restOfProps }: Props) { + return ( +
+
+
Contract Hash
+
+ {metadata.info.contract.hash.toHex()} +
+
+
+
Language
+
{metadata.info.source.language}
+
+
+
Compiler
+
{metadata.info.source.compiler}
+
+
+
Contract version
+
{metadata.info.contract.version}
+
+
+
Authors
+
{metadata.info.contract.authors}
+
+
+ ); +} diff --git a/src/ui/components/modal/ForgetAllContractsModal.tsx b/src/ui/components/modal/forget-all-contracts-modal.tsx similarity index 94% rename from src/ui/components/modal/ForgetAllContractsModal.tsx rename to src/ui/components/modal/forget-all-contracts-modal.tsx index 39affa3f..b72c21de 100644 --- a/src/ui/components/modal/ForgetAllContractsModal.tsx +++ b/src/ui/components/modal/forget-all-contracts-modal.tsx @@ -3,8 +3,8 @@ import { TrashIcon } from '@heroicons/react/outline'; import { useCallback, useState } from 'react'; -import type { ModalProps } from './ModalBase'; -import { ModalBase as Modal } from './ModalBase'; +import type { ModalProps } from './modal-base'; +import { ModalBase as Modal } from './modal-base'; interface Props extends ModalProps { confirm: () => Promise; diff --git a/src/ui/components/modal/ForgetContractModal.tsx b/src/ui/components/modal/forget-contract-modal.tsx similarity index 92% rename from src/ui/components/modal/ForgetContractModal.tsx rename to src/ui/components/modal/forget-contract-modal.tsx index 61ffca99..7629abf2 100644 --- a/src/ui/components/modal/ForgetContractModal.tsx +++ b/src/ui/components/modal/forget-contract-modal.tsx @@ -2,8 +2,8 @@ // SPDX-License-Identifier: GPL-3.0-only import { TrashIcon } from '@heroicons/react/outline'; -import { ModalBase as Modal } from './ModalBase'; -import type { ModalProps } from './ModalBase'; +import { ModalBase as Modal } from './modal-base'; +import type { ModalProps } from './modal-base'; interface Props extends ModalProps { confirm: () => void; diff --git a/src/ui/components/modal/HelpModal.tsx b/src/ui/components/modal/help-modal.tsx similarity index 74% rename from src/ui/components/modal/HelpModal.tsx rename to src/ui/components/modal/help-modal.tsx index 9c7c0fc4..69cea72a 100644 --- a/src/ui/components/modal/HelpModal.tsx +++ b/src/ui/components/modal/help-modal.tsx @@ -3,9 +3,9 @@ import { ChevronRightIcon } from '@heroicons/react/outline'; import { BookOpenIcon } from '@heroicons/react/solid'; -import { GithubLogo, StackExchangeLogo } from './Logos'; -import { ModalBase as Modal } from './ModalBase'; -import type { ModalProps } from './ModalBase'; +import { GithubLogo, StackExchangeLogo } from './logos'; +import { ModalBase as Modal } from './modal-base'; +import type { ModalProps } from './modal-base'; export const HelpModal = ({ isOpen, setIsOpen }: Omit) => { return ( @@ -13,14 +13,14 @@ export const HelpModal = ({ isOpen, setIsOpen }: Omit) => { diff --git a/src/ui/components/modal/index.ts b/src/ui/components/modal/index.ts index 30a8d98e..fdb98531 100644 --- a/src/ui/components/modal/index.ts +++ b/src/ui/components/modal/index.ts @@ -1,6 +1,6 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './ForgetAllContractsModal'; -export * from './ForgetContractModal'; -export * from './HelpModal'; +export * from './forget-all-contracts-modal'; +export * from './forget-contract-modal'; +export * from './help-modal'; diff --git a/src/ui/components/modal/logos.tsx b/src/ui/components/modal/logos.tsx new file mode 100644 index 00000000..15b04d07 --- /dev/null +++ b/src/ui/components/modal/logos.tsx @@ -0,0 +1,33 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +export const GithubLogo = () => { + return ( + + + + ); +}; +export const StackExchangeLogo = () => { + return ( + + + + + + + ); +}; diff --git a/src/ui/components/modal/ModalBase.tsx b/src/ui/components/modal/modal-base.tsx similarity index 100% rename from src/ui/components/modal/ModalBase.tsx rename to src/ui/components/modal/modal-base.tsx diff --git a/src/ui/components/modal/SettingsModal.tsx b/src/ui/components/modal/settings-modal.tsx similarity index 77% rename from src/ui/components/modal/SettingsModal.tsx rename to src/ui/components/modal/settings-modal.tsx index d61a7177..949cedf2 100644 --- a/src/ui/components/modal/SettingsModal.tsx +++ b/src/ui/components/modal/settings-modal.tsx @@ -1,10 +1,10 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { CustomEndpoint } from '../settings/CustomEndpoint'; -import { ThemeMode } from '../settings/ThemeMode'; -import type { ModalProps } from './ModalBase'; -import { ModalBase as Modal } from './ModalBase'; +import { CustomEndpoint } from '../settings/custom-endpoint'; +import { ThemeMode } from '../settings/theme-mode'; +import type { ModalProps } from './modal-base'; +import { ModalBase as Modal } from './modal-base'; export const SettingsModal = ({ isOpen, setIsOpen }: Omit) => { return ( diff --git a/src/ui/components/settings/CustomEndpoint.tsx b/src/ui/components/settings/custom-endpoint.tsx similarity index 90% rename from src/ui/components/settings/CustomEndpoint.tsx rename to src/ui/components/settings/custom-endpoint.tsx index 1887cabf..c2f36596 100644 --- a/src/ui/components/settings/CustomEndpoint.tsx +++ b/src/ui/components/settings/custom-endpoint.tsx @@ -5,9 +5,9 @@ import { useCallback, useState } from 'react'; import { useNavigate } from 'react-router'; import { LOCAL, LOCAL_STORAGE_KEY } from '../../../constants'; -import { useLocalStorage } from '../../hooks/useLocalStorage'; -import { Button } from '../common/Button'; -import { Input } from '../form/Input'; +import { useLocalStorage } from '../../hooks/use-local-storage'; +import { Button } from '../common/button'; +import { Input } from '../form/input'; import { isValidWsUrl } from 'lib/util'; export function CustomEndpoint() { diff --git a/src/ui/components/settings/index.ts b/src/ui/components/settings/index.ts index 67134df0..6ed531ac 100644 --- a/src/ui/components/settings/index.ts +++ b/src/ui/components/settings/index.ts @@ -1,5 +1,5 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './CustomEndpoint'; -export * from './ThemeMode'; +export * from './custom-endpoint'; +export * from './theme-mode'; diff --git a/src/ui/components/settings/ThemeMode.tsx b/src/ui/components/settings/theme-mode.tsx similarity index 93% rename from src/ui/components/settings/ThemeMode.tsx rename to src/ui/components/settings/theme-mode.tsx index 20be6b3a..d40384df 100644 --- a/src/ui/components/settings/ThemeMode.tsx +++ b/src/ui/components/settings/theme-mode.tsx @@ -1,7 +1,7 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import { Dropdown } from 'ui/components/common/Dropdown'; +import { Dropdown } from 'ui/components/common/dropdown'; import { useTheme } from 'ui/contexts'; const options = [ diff --git a/src/ui/components/transactions.tsx b/src/ui/components/transactions.tsx new file mode 100644 index 00000000..22378a89 --- /dev/null +++ b/src/ui/components/transactions.tsx @@ -0,0 +1,63 @@ +// Copyright 2022 @paritytech/contracts-ui authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { BellIcon, XIcon } from '@heroicons/react/outline'; +import { NotificationIcon } from './common/notification-icon'; +import { classes, isEmptyObj } from 'lib/util'; +import type { QueuedTxOptions, TransactionsState } from 'types'; + +export function Transactions({ + dismiss, + txs, +}: React.HTMLAttributes & TransactionsState) { + return ( +
+ {Object.entries(txs).map(([id, tx]: [string, QueuedTxOptions | undefined]) => { + const { status, events, extrinsic } = tx || {}; + const isComplete = status === 'error' || status === 'success'; + + return ( +
+
+ +
+
{extrinsic?.registry.findMetaCall(extrinsic.callIndex).method}
+
{status}
+
+ {isComplete && ( + dismiss(parseInt(id))} + /> + )} +
+ {isComplete && events && !isEmptyObj(events) && ( +
+ +
+ {Object.keys(events).map(eventName => { + const times = events[eventName] > 1 ? ` (x${events[eventName]})` : ''; + return ( +
+ {`${eventName}${times}`} +
+ ); + })} +
+ dismiss(parseInt(id))} /> +
+ )} +
+ ); + })} +
+ ); +} diff --git a/src/ui/contexts/ApiContext.tsx b/src/ui/contexts/api.context.tsx similarity index 95% rename from src/ui/contexts/ApiContext.tsx rename to src/ui/contexts/api.context.tsx index 1eb4b485..6c13521e 100644 --- a/src/ui/contexts/ApiContext.tsx +++ b/src/ui/contexts/api.context.tsx @@ -9,9 +9,9 @@ import { keyring } from '@polkadot/ui-keyring'; import { LOCAL_STORAGE_KEY, ROCOCO_CONTRACTS } from '../../constants'; import { ApiPromise, ApiState, ChainProperties, Account, Status, WeightV2 } from 'types'; import { isValidWsUrl, isKeyringLoaded } from 'lib/util'; -import { useLocalStorage } from 'ui/hooks/useLocalStorage'; -import { NoticeBanner } from 'ui/components/common/NoticeBanner'; -import { getChainProperties } from 'src/services/chain/chainProps'; +import { useLocalStorage } from 'ui/hooks/use-local-storage'; +import { NoticeBanner } from 'ui/components/common/notice-banner'; +import { getChainProperties } from 'src/services/chain'; // fixes internal pjs type mismatch `Type 'string' is not assignable to type '`0x${string}`'` export interface InjectedAccountWithMetaOverride { diff --git a/src/ui/contexts/DatabaseContext.tsx b/src/ui/contexts/database.context.tsx similarity index 96% rename from src/ui/contexts/DatabaseContext.tsx rename to src/ui/contexts/database.context.tsx index 5333faaf..7ac71230 100644 --- a/src/ui/contexts/DatabaseContext.tsx +++ b/src/ui/contexts/database.context.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { createContext, useContext, useEffect, useState } from 'react'; -import { useApi } from './ApiContext'; +import { useApi } from './api.context'; import { Database } from 'src/services/db'; import { DbState } from 'types'; diff --git a/src/ui/contexts/index.tsx b/src/ui/contexts/index.tsx index 97f62348..3689a8a4 100644 --- a/src/ui/contexts/index.tsx +++ b/src/ui/contexts/index.tsx @@ -1,8 +1,8 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './ApiContext'; -export * from './DatabaseContext'; -export * from './InstantiateContext'; -export * from './TransactionsContext'; -export * from './ThemeContext'; +export * from './api.context'; +export * from './database.context'; +export * from './instantiate.context'; +export * from './transactions.context'; +export * from './theme.context'; diff --git a/src/ui/contexts/InstantiateContext.tsx b/src/ui/contexts/instantiate.context.tsx similarity index 100% rename from src/ui/contexts/InstantiateContext.tsx rename to src/ui/contexts/instantiate.context.tsx diff --git a/src/ui/contexts/ThemeContext.tsx b/src/ui/contexts/theme.context.tsx similarity index 94% rename from src/ui/contexts/ThemeContext.tsx rename to src/ui/contexts/theme.context.tsx index 036b0c32..7068e55c 100644 --- a/src/ui/contexts/ThemeContext.tsx +++ b/src/ui/contexts/theme.context.tsx @@ -3,7 +3,7 @@ import { createContext, useContext, useEffect } from 'react'; import { LOCAL_STORAGE_KEY } from '../../constants'; -import { useLocalStorage } from 'ui/hooks/useLocalStorage'; +import { useLocalStorage } from 'ui/hooks/use-local-storage'; type Theme = 'light' | 'dark'; type Props = { diff --git a/src/ui/contexts/TransactionsContext.tsx b/src/ui/contexts/transactions.context.tsx similarity index 97% rename from src/ui/contexts/TransactionsContext.tsx rename to src/ui/contexts/transactions.context.tsx index f8920fed..f23d0a32 100644 --- a/src/ui/contexts/TransactionsContext.tsx +++ b/src/ui/contexts/transactions.context.tsx @@ -4,9 +4,9 @@ import { createContext, useState, useContext, useEffect } from 'react'; import { web3FromAddress } from '@polkadot/extension-dapp'; import { keyring } from '@polkadot/ui-keyring'; -import { useApi } from './ApiContext'; +import { useApi } from './api.context'; import { TxOptions, TransactionsState, TransactionsQueue, TxStatusMap } from 'types'; -import { Transactions } from 'ui/components/Transactions'; +import { Transactions } from 'ui/components/transactions'; import { isEmptyObj } from 'lib/util'; let nextId = 1; diff --git a/src/ui/hooks/index.ts b/src/ui/hooks/index.ts index 6b07289a..65332e25 100644 --- a/src/ui/hooks/index.ts +++ b/src/ui/hooks/index.ts @@ -1,13 +1,13 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './useLocalStorage'; -export * from './useDbQuery'; -export * from './useWeight'; -export * from './useBalance'; -export * from './useFormField'; -export * from './useArgValues'; -export * from './useNewContract'; -export * from './useStorageDepositLimit'; -export * from './useToggle'; -export * from './useStoredContract'; +export * from './use-local-storage'; +export * from './use-db-query'; +export * from './use-weight'; +export * from './use-balance'; +export * from './use-form-field'; +export * from './use-arg-values'; +export * from './use-new-contract'; +export * from './use-storage-deposit-limit'; +export * from './use-toggle'; +export * from './use-stored-contract'; diff --git a/src/ui/hooks/useArgValues.ts b/src/ui/hooks/use-arg-values.ts similarity index 90% rename from src/ui/hooks/useArgValues.ts rename to src/ui/hooks/use-arg-values.ts index 0c77a52f..0a173b1e 100644 --- a/src/ui/hooks/useArgValues.ts +++ b/src/ui/hooks/use-arg-values.ts @@ -2,10 +2,10 @@ // SPDX-License-Identifier: GPL-3.0-only import { useEffect, useMemo, useRef, useState } from 'react'; -import { useApi } from 'ui/contexts/ApiContext'; +import { useApi } from 'ui/contexts/api.context'; import { AbiMessage, AbiParam, Account, Registry, SetState } from 'types'; -import { getInitValue } from 'lib/initValue'; -import { transformUserInput } from 'lib/callOptions'; +import { getInitValue } from 'lib/init-value'; +import { transformUserInput } from 'lib/call-options'; type ArgValues = Record; diff --git a/src/ui/hooks/useBalance.ts b/src/ui/hooks/use-balance.ts similarity index 95% rename from src/ui/hooks/useBalance.ts rename to src/ui/hooks/use-balance.ts index 1063366e..bfdbbc5e 100644 --- a/src/ui/hooks/useBalance.ts +++ b/src/ui/hooks/use-balance.ts @@ -3,9 +3,9 @@ import BN from 'bn.js'; import { useCallback } from 'react'; -import { useFormField } from './useFormField'; +import { useFormField } from './use-form-field'; import { toBalance, toSats, BN_ONE, BN_TWO, BN_ZERO, isBn } from 'lib/bn'; -import { useApi } from 'ui/contexts/ApiContext'; +import { useApi } from 'ui/contexts/api.context'; import type { UseBalance, Validation } from 'types'; type BitLength = 8 | 16 | 32 | 64 | 128 | 256; diff --git a/src/ui/hooks/useDbQuery.ts b/src/ui/hooks/use-db-query.ts similarity index 100% rename from src/ui/hooks/useDbQuery.ts rename to src/ui/hooks/use-db-query.ts diff --git a/src/ui/hooks/useFormField.ts b/src/ui/hooks/use-form-field.ts similarity index 100% rename from src/ui/hooks/useFormField.ts rename to src/ui/hooks/use-form-field.ts diff --git a/src/ui/hooks/useIsMounted.ts b/src/ui/hooks/use-is-mounted.ts similarity index 100% rename from src/ui/hooks/useIsMounted.ts rename to src/ui/hooks/use-is-mounted.ts diff --git a/src/ui/hooks/useLocalStorage.ts b/src/ui/hooks/use-local-storage.ts similarity index 100% rename from src/ui/hooks/useLocalStorage.ts rename to src/ui/hooks/use-local-storage.ts diff --git a/src/ui/hooks/useMetadata.ts b/src/ui/hooks/use-metadata.ts similarity index 98% rename from src/ui/hooks/useMetadata.ts rename to src/ui/hooks/use-metadata.ts index 5fdfce0b..33af91de 100644 --- a/src/ui/hooks/useMetadata.ts +++ b/src/ui/hooks/use-metadata.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { useEffect, useState } from 'react'; -import { useApi } from 'ui/contexts/ApiContext'; +import { useApi } from 'ui/contexts/api.context'; import { Abi, ApiPromise, FileState, MetadataState, UseMetadata, Validation, VoidFn } from 'types'; type OnChange = (_: FileState | undefined, __?: Record) => void; diff --git a/src/ui/hooks/useNewContract.ts b/src/ui/hooks/use-new-contract.ts similarity index 100% rename from src/ui/hooks/useNewContract.ts rename to src/ui/hooks/use-new-contract.ts diff --git a/src/ui/hooks/useNonEmptyString.ts b/src/ui/hooks/use-non-empty-string.ts similarity index 92% rename from src/ui/hooks/useNonEmptyString.ts rename to src/ui/hooks/use-non-empty-string.ts index 98ca9525..78f31a00 100644 --- a/src/ui/hooks/useNonEmptyString.ts +++ b/src/ui/hooks/use-non-empty-string.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { useCallback } from 'react'; -import { useFormField } from './useFormField'; +import { useFormField } from './use-form-field'; import type { ValidFormField, Validation } from 'types'; export function useNonEmptyString(initialValue = ''): ValidFormField { diff --git a/src/ui/hooks/useStorageDepositLimit.ts b/src/ui/hooks/use-storage-deposit-limit.ts similarity index 87% rename from src/ui/hooks/useStorageDepositLimit.ts rename to src/ui/hooks/use-storage-deposit-limit.ts index e7096fd1..26ad0c7a 100644 --- a/src/ui/hooks/useStorageDepositLimit.ts +++ b/src/ui/hooks/use-storage-deposit-limit.ts @@ -4,9 +4,9 @@ import type BN from 'bn.js'; import { useEffect, useState } from 'react'; -import { useBalance } from './useBalance'; -import { useToggle } from './useToggle'; -import { useApi } from 'ui/contexts/ApiContext'; +import { useBalance } from './use-balance'; +import { useToggle } from './use-toggle'; +import { useApi } from 'ui/contexts/api.context'; import type { OrFalsy, UseStorageDepositLimit } from 'types'; import { BN_ZERO } from 'lib/bn'; diff --git a/src/ui/hooks/useStoredContract.ts b/src/ui/hooks/use-stored-contract.ts similarity index 100% rename from src/ui/hooks/useStoredContract.ts rename to src/ui/hooks/use-stored-contract.ts diff --git a/src/ui/hooks/useToggle.ts b/src/ui/hooks/use-toggle.ts similarity index 93% rename from src/ui/hooks/useToggle.ts rename to src/ui/hooks/use-toggle.ts index e07fc851..a1d6db9e 100644 --- a/src/ui/hooks/useToggle.ts +++ b/src/ui/hooks/use-toggle.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { useCallback, useEffect, useState } from 'react'; -import { useIsMounted } from './useIsMounted'; +import { useIsMounted } from './use-is-mounted'; import type { UseToggle } from 'types'; // Simple wrapper for a true/false toggle diff --git a/src/ui/hooks/useWeight.ts b/src/ui/hooks/use-weight.ts similarity index 100% rename from src/ui/hooks/useWeight.ts rename to src/ui/hooks/use-weight.ts diff --git a/src/ui/index.tsx b/src/ui/index.tsx index f6b2ea68..3a793cb8 100644 --- a/src/ui/index.tsx +++ b/src/ui/index.tsx @@ -4,7 +4,7 @@ import { Buffer } from 'buffer'; import { createRoot } from 'react-dom/client'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; -import App from 'ui/components/App'; +import App from 'ui/components/app'; import 'react-tooltip/dist/react-tooltip.css'; import './styles/main.css'; import '@polkadot/api-augment'; diff --git a/src/ui/layout/index.ts b/src/ui/layout/index.ts index 06398b55..3422af2f 100644 --- a/src/ui/layout/index.ts +++ b/src/ui/layout/index.ts @@ -1,4 +1,4 @@ // Copyright 2022 @paritytech/contracts-ui authors & contributors // SPDX-License-Identifier: GPL-3.0-only -export * from './RootLayout'; +export * from './root.layout'; diff --git a/src/ui/layout/RootLayout.tsx b/src/ui/layout/root.layout.tsx similarity index 100% rename from src/ui/layout/RootLayout.tsx rename to src/ui/layout/root.layout.tsx diff --git a/src/ui/layout/sidebar/Footer.tsx b/src/ui/layout/sidebar/Footer.tsx index d1c138be..c04c87a7 100644 --- a/src/ui/layout/sidebar/Footer.tsx +++ b/src/ui/layout/sidebar/Footer.tsx @@ -4,7 +4,7 @@ import { ChatAltIcon, CogIcon } from '@heroicons/react/outline'; import { useCallback, useState } from 'react'; import { HelpModal } from 'ui/components/modal'; -import { SettingsModal } from 'ui/components/modal/SettingsModal'; +import { SettingsModal } from 'ui/components/modal/settings-modal'; type ModalName = 'help' | 'settings'; @@ -26,19 +26,19 @@ export function Footer() {