diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 1c7831782..d91a9ebf5 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -2207,10 +2207,21 @@ "message": "Default account (the first one)" }, "defaultNetworksGroup": { - "message": "Default" + "message": "Default Networks" }, "customNetworksGroup": { - "message": "Custom" + "message": "Custom Networks" + }, + "chainTestnetsGroup": { + "message": "$chain$ Testnets", + "placeholders": { + "chain": { + "content": "$1" + } + } + }, + "customTestnetsGroup": { + "message": "Custom Testnets" }, "active": { "message": "Active" @@ -2254,32 +2265,26 @@ "removeNetwork": { "message": "Remove Network" }, - "removeNetworkModalTitle": { - "message": "Remove $network$?", - "placeholders": { - "network": { - "content": "$1" - } - } + "removeNetworkModalTitleLeftPart": { + "message": "Remove " + }, + "removeNetworkModalTitleRightPart": { + "message": "?" }, "removeNetworkModalDescription": { "message": "You won’t be able to check the assets on this\nnetwork anymore." }, - "editSomeRpc": { - "message": "Edit $name$ RPC", - "placeholders": { - "name": { - "content": "$1" - } - } + "editSomeRpcLeftPart": { + "message": "Edit " }, - "editSomeBlockExplorer": { - "message": "Edit $name$", - "placeholders": { - "name": { - "content": "$1" - } - } + "editSomeRpcRightPart": { + "message": " RPC" + }, + "editSomeBlockExplorerLeftPart": { + "message": "Edit " + }, + "editSomeBlockExplorerRightPart": { + "message": "" }, "rpcDoesNotRespond": { "message": "RPC doesn’t respond" @@ -2306,24 +2311,20 @@ } } }, - "confirmDeleteRpcTitle": { - "message": "Delete $name$ RPC?", - "placeholders": { - "name": { - "content": "$1" - } - } + "confirmDeleteRpcTitleLeftPart": { + "message": "Delete " + }, + "confirmDeleteRpcTitleRightPart": { + "message": " RPC?" }, "confirmDeleteRpcDescription": { "message": "This will remove the RPC from the list and automatically switch the network to the default RPC endpoint." }, - "confirmDeleteBlockExplorerTitle": { - "message": "Delete $name$?", - "placeholders": { - "name": { - "content": "$1" - } - } + "confirmDeleteBlockExplorerTitleLeftPart": { + "message": "Delete " + }, + "confirmDeleteBlockExplorerTitleRightPart": { + "message": "?" }, "confirmDeleteBlockExplorerDescription": { "message": "This will remove the block explorer from the list and automatically switch the network to the default one." diff --git a/src/app/atoms/PageModal/index.tsx b/src/app/atoms/PageModal/index.tsx index 410137ba9..448794752 100644 --- a/src/app/atoms/PageModal/index.tsx +++ b/src/app/atoms/PageModal/index.tsx @@ -1,4 +1,4 @@ -import React, { PropsWithChildren, memo } from 'react'; +import React, { FC, PropsWithChildren, ReactNode } from 'react'; import clsx from 'clsx'; import Modal from 'react-modal'; @@ -15,8 +15,9 @@ import { IconBase } from '../IconBase'; import ModStyles from './styles.module.css'; interface Props extends TestIDProps { - title: string; + title: ReactNode | ReactNode[]; opened: boolean; + headerClassName?: string; shouldShowBackButton?: boolean; onRequestClose: EmptyFn; onGoBack?: EmptyFn; @@ -25,52 +26,60 @@ interface Props extends TestIDProps { export const CLOSE_ANIMATION_TIMEOUT = 300; -export const PageModal = memo>( - ({ title, opened, shouldShowBackButton, onRequestClose, onGoBack, children, testID, animated = true }) => { - const { fullPage } = useAppEnv(); +export const PageModal: FC> = ({ + title, + opened, + headerClassName, + shouldShowBackButton, + onRequestClose, + onGoBack, + children, + testID, + animated = true +}) => { + const { fullPage } = useAppEnv(); - return ( - -
-
- {shouldShowBackButton && ( - - )} -
+ return ( + +
+
+ {shouldShowBackButton && ( + + )} +
-
{title}
+
{title}
-
- -
+
+
+
-
{children}
-
- ); - } -); +
{children}
+ + ); +}; diff --git a/src/app/atoms/SettingsCell.tsx b/src/app/atoms/SettingsCell.tsx index cca98ffbe..aaaa3b602 100644 --- a/src/app/atoms/SettingsCell.tsx +++ b/src/app/atoms/SettingsCell.tsx @@ -12,6 +12,7 @@ interface SettingsCellPropsBase

{ cellIcon?: ReactNode; cellName: ReactNode; cellNameClassName?: string; + wrapCellName?: boolean; Component: 'div' | FC

; } @@ -29,7 +30,8 @@ export const SettingsCell =

({ className, cellIcon, cellName, - cellNameClassName = 'text-font-medium-bold', + cellNameClassName = 'text-left text-font-medium-bold flex-1', + wrapCellName = true, isLast = true, children, Component, @@ -37,14 +39,12 @@ export const SettingsCell =

({ }: SettingsCellProps

) => { return ( -

- {cellIcon} + {cellIcon} - {cellName} -
+ {wrapCellName ? {cellName} : cellName} {children} diff --git a/src/app/atoms/action-modal/action-modal.tsx b/src/app/atoms/action-modal/action-modal.tsx index c11e2b541..ea0f430e9 100644 --- a/src/app/atoms/action-modal/action-modal.tsx +++ b/src/app/atoms/action-modal/action-modal.tsx @@ -19,36 +19,39 @@ export interface ActionModalProps { onClose?: EmptyFn; children?: ReactNode | ReactNode[]; title?: ReactNode; + headerClassName?: string; className?: string; } -export const ActionModal = memo(({ onClose, children, hasCloseButton = true, title }) => { - const { fullPage } = useAppEnv(); +export const ActionModal = memo( + ({ onClose, children, hasCloseButton = true, headerClassName, title }) => { + const { fullPage } = useAppEnv(); - return ( - -
-

{title}

- {hasCloseButton && ( - + return ( + - {children} - - ); -}); + onRequestClose={onClose} + > +
+

{title}

+ {hasCloseButton && ( + + )} +
+ {children} + + ); + } +); diff --git a/src/app/layouts/PageLayout/DefaultHeader.tsx b/src/app/layouts/PageLayout/DefaultHeader.tsx index 949e12f3a..d6fc54602 100644 --- a/src/app/layouts/PageLayout/DefaultHeader.tsx +++ b/src/app/layouts/PageLayout/DefaultHeader.tsx @@ -69,7 +69,7 @@ export const DefaultHeader = memo>(
{pageTitle && ( -
{pageTitle}
+
{pageTitle}
)}
{headerRightElem}
diff --git a/src/app/pages/ChainSettings/index.tsx b/src/app/pages/ChainSettings/index.tsx index b9b786eee..1d029f607 100644 --- a/src/app/pages/ChainSettings/index.tsx +++ b/src/app/pages/ChainSettings/index.tsx @@ -1,12 +1,7 @@ import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { ToggleSwitch } from 'app/atoms'; -import { - ActionModal, - ActionModalBodyContainer, - ActionModalButton, - ActionModalButtonsContainer -} from 'app/atoms/action-modal'; +import { ActionModalBodyContainer, ActionModalButton, ActionModalButtonsContainer } from 'app/atoms/action-modal'; import { ActionsButtonsBox } from 'app/atoms/PageModal/actions-buttons-box'; import { SettingsCell } from 'app/atoms/SettingsCell'; import { SettingsCellGroup } from 'app/atoms/SettingsCellGroup'; @@ -29,6 +24,7 @@ import { TempleChainKind } from 'temple/types'; import { ManageUrlEntitiesView } from './manage-url-entities-view'; import { ChainSettingsSelectors } from './selectors'; +import { ShortenedEntityNameActionModal } from './shortened-entity-name-action-modal'; import { useChainOperations } from './use-chain-operations'; interface ChainSettingsProps { @@ -97,9 +93,9 @@ const ChainExistentSettings = memo(({ chain, bottomE activeItemId={chain.rpc.id} title={} items={chain.allRpcs} - editModalTitleI18nKey="editSomeRpc" + editModalTitleI18nKeyBase="editSomeRpc" createModalTitle={t('addSomeRpc', chain.name)} - confirmDeleteTitleI18nKey="confirmDeleteRpcTitle" + confirmDeleteTitleI18nKeyBase="confirmDeleteRpcTitle" confirmDeleteDescriptionI18nKey="confirmDeleteRpcDescription" deleteLabelI18nKey="deleteRpc" successfullyAddedMessageI18nKey="rpcAdded" @@ -119,9 +115,9 @@ const ChainExistentSettings = memo(({ chain, bottomE activeItemId={chain.activeBlockExplorer?.id ?? ''} title={} items={chain.allBlockExplorers} - editModalTitleI18nKey="editSomeBlockExplorer" + editModalTitleI18nKeyBase="editSomeBlockExplorer" createModalTitle={t('addSomeBlockExplorer', chain.name)} - confirmDeleteTitleI18nKey="confirmDeleteBlockExplorerTitle" + confirmDeleteTitleI18nKeyBase="confirmDeleteBlockExplorerTitle" deleteLabelI18nKey="deleteBlockExplorer" confirmDeleteDescriptionI18nKey="confirmDeleteBlockExplorerDescription" successfullyAddedMessageI18nKey="blockExplorerAdded" @@ -149,7 +145,11 @@ const ChainExistentSettings = memo(({ chain, bottomE )} {removeChainModalIsOpen && ( - + : chain.name} + hasCloseButton={false} + >

@@ -172,7 +172,7 @@ const ChainExistentSettings = memo(({ chain, bottomE - + )} ); @@ -196,7 +196,7 @@ export const ChainSettings = memo(props => { return ( {pageTitle}} onBottomEdgeVisibilityChange={setBottomEdgeIsVisible} bottomEdgeThreshold={16} > diff --git a/src/app/pages/ChainSettings/manage-url-entities-view/create-modal.tsx b/src/app/pages/ChainSettings/manage-url-entities-view/create-modal.tsx index d517b552e..445d9125f 100644 --- a/src/app/pages/ChainSettings/manage-url-entities-view/create-modal.tsx +++ b/src/app/pages/ChainSettings/manage-url-entities-view/create-modal.tsx @@ -92,6 +92,7 @@ export const CreateUrlEntityModal = memo( required: t('required'), validate: (value: string) => (namesToExclude.includes(value) ? t('mustBeUnique') : true) })} + disabled={isSubmitting} label={t('name')} id="createurlentity-name" placeholder="Ethereum" @@ -102,6 +103,7 @@ export const CreateUrlEntityModal = memo( } testID={activeCheckboxTestID} /> diff --git a/src/app/pages/ChainSettings/manage-url-entities-view/edit-modal.tsx b/src/app/pages/ChainSettings/manage-url-entities-view/edit-modal.tsx index 9e432fd4c..6dace4252 100644 --- a/src/app/pages/ChainSettings/manage-url-entities-view/edit-modal.tsx +++ b/src/app/pages/ChainSettings/manage-url-entities-view/edit-modal.tsx @@ -3,12 +3,7 @@ import React, { useCallback, useState } from 'react'; import { Controller, useForm } from 'react-hook-form-v7'; import { FormField, IconBase, ToggleSwitch } from 'app/atoms'; -import { - ActionModal, - ActionModalBodyContainer, - ActionModalButton, - ActionModalButtonsContainer -} from 'app/atoms/action-modal'; +import { ActionModalBodyContainer, ActionModalButton, ActionModalButtonsContainer } from 'app/atoms/action-modal'; import { PageModal } from 'app/atoms/PageModal'; import { ActionsButtonsBox } from 'app/atoms/PageModal/actions-buttons-box'; import { ScrollView } from 'app/atoms/PageModal/scroll-view'; @@ -23,6 +18,8 @@ import { useBooleanState } from 'lib/ui/hooks'; import { shouldDisableSubmitButton } from 'lib/ui/should-disable-submit-button'; import { ChainSettingsSelectors } from '../selectors'; +import { ShortenedEntityNameActionModal } from '../shortened-entity-name-action-modal'; +import { ShortenedEntityNameActionTitle } from '../shortened-entity-name-action-title'; import { UrlEntityBase } from './types'; import { UrlInput } from './url-input'; @@ -43,8 +40,8 @@ interface EditUrlEntityModalProps { namesToExclude: string[]; urlsToExclude: string[]; activeI18nKey: TID; - titleI18nKey: TID; - confirmDeleteTitleI18nKey: TID; + titleI18nKeyBase: 'editSomeRpc' | 'editSomeBlockExplorer'; + confirmDeleteTitleI18nKeyBase: 'confirmDeleteRpcTitle' | 'confirmDeleteBlockExplorerTitle'; confirmDeleteDescriptionI18nKey: TID; deleteLabelI18nKey: TID; urlInputPlaceholder: string; @@ -64,8 +61,8 @@ export const EditUrlEntityModal = ({ namesToExclude, urlsToExclude, activeI18nKey, - titleI18nKey, - confirmDeleteTitleI18nKey, + titleI18nKeyBase, + confirmDeleteTitleI18nKeyBase, confirmDeleteDescriptionI18nKey, deleteLabelI18nKey, urlInputPlaceholder, @@ -82,7 +79,7 @@ export const EditUrlEntityModal = ({ mode: 'onChange' }); const { control, register, handleSubmit, formState } = formReturn; - const { errors, submitCount } = formState; + const { errors, submitCount, isSubmitting } = formState; const isSubmitted = submitCount > 0; const displayedName = entity.nameI18nKey ? t(entity.nameI18nKey) : entity.name; @@ -107,7 +104,12 @@ export const EditUrlEntityModal = ({ return ( <> - + } + >

({ } Component="div"> } /> @@ -136,11 +138,12 @@ export const EditUrlEntityModal = ({ id="editurlentity-name" placeholder="Ethereum" errorCaption={isSubmitted && errors.name?.message} - disabled={!isEditable} + disabled={!isEditable || isSubmitting} testID={ChainSettingsSelectors.nameInput} /> ({ size="L" color="primary" type="submit" + loading={isSubmitting} disabled={shouldDisableSubmitButton({ errors, formState, otherErrors: [submitError] })} testID={ChainSettingsSelectors.saveButton} > @@ -181,10 +185,11 @@ export const EditUrlEntityModal = ({ {removeModalIsOpen && ( -

@@ -210,7 +215,7 @@ export const EditUrlEntityModal = ({ - + )} ); diff --git a/src/app/pages/ChainSettings/manage-url-entities-view/index.tsx b/src/app/pages/ChainSettings/manage-url-entities-view/index.tsx index b803f8486..3049caf4e 100644 --- a/src/app/pages/ChainSettings/manage-url-entities-view/index.tsx +++ b/src/app/pages/ChainSettings/manage-url-entities-view/index.tsx @@ -18,9 +18,9 @@ interface ManageUrlEntitiesViewProps { title: ReactNode; items: T[]; activeItemId: string; - editModalTitleI18nKey: TID; + editModalTitleI18nKeyBase: 'editSomeRpc' | 'editSomeBlockExplorer'; activeI18nKey: TID; - confirmDeleteTitleI18nKey: TID; + confirmDeleteTitleI18nKeyBase: 'confirmDeleteRpcTitle' | 'confirmDeleteBlockExplorerTitle'; confirmDeleteDescriptionI18nKey: TID; deleteLabelI18nKey: TID; successfullyAddedMessageI18nKey: TID; @@ -40,9 +40,9 @@ export const ManageUrlEntitiesView = ({ title, items, activeItemId, - editModalTitleI18nKey, + editModalTitleI18nKeyBase, activeI18nKey, - confirmDeleteTitleI18nKey, + confirmDeleteTitleI18nKeyBase, confirmDeleteDescriptionI18nKey, deleteLabelI18nKey, successfullyAddedMessageI18nKey, @@ -95,7 +95,8 @@ export const ManageUrlEntitiesView = ({ {title}} + cellName={{title}} + wrapCellName={false} Component="div" >