Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui: improve phrasing and display rescanning alert #693

Merged
merged 3 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/components/CreateWallet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ describe('<CreateWallet />', () => {
;(apiMock.getSession as jest.Mock).mockResolvedValue(neverResolvingPromise)
})

it('should display alert when rescanning is active', async () => {
;(apiMock.getSession as jest.Mock).mockResolvedValueOnce({
ok: true,
json: () =>
Promise.resolve({
rescanning: true,
}),
})

await act(async () => setup({}))

expect(screen.getByText('create_wallet.title')).toBeVisible()
expect(screen.getByTestId('alert-rescanning')).toBeVisible()
expect(screen.queryByText('create_wallet.button_create')).not.toBeInTheDocument()
})

it('should render without errors', () => {
act(() => setup({}))

Expand Down
44 changes: 33 additions & 11 deletions src/components/CreateWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ export default function CreateWallet({ parentRoute, startWallet }: CreateWalletP
const [alert, setAlert] = useState<SimpleAlert>()
const [createdWallet, setCreatedWallet] = useState<CreatedWalletWithAuth>()

const isCreated = useMemo(() => !!createdWallet?.walletFileName && !!createdWallet?.auth, [createdWallet])
const canCreate = useMemo(
() => !isCreated && !serviceInfo?.walletFileName && !serviceInfo?.rescanning,
[isCreated, serviceInfo],
)

const createWallet = useCallback(
async ({ walletName, password }) => {
setAlert(undefined)
Expand Down Expand Up @@ -152,17 +158,33 @@ export default function CreateWallet({ parentRoute, startWallet }: CreateWalletP
<PageTitle title={t('create_wallet.title')} />
)}
{alert && <rb.Alert variant={alert.variant}>{alert.message}</rb.Alert>}
{serviceInfo?.walletFileName && !createdWallet ? (
<rb.Alert variant="warning">
<Trans i18nKey="create_wallet.alert_other_wallet_unlocked">
Currently <strong>{{ walletName: walletDisplayName(serviceInfo.walletFileName) }}</strong> is active. You
need to lock it first.
<Link to={routes.walletList} className="alert-link">
Go back
</Link>
.
</Trans>
</rb.Alert>
{!canCreate && !isCreated ? (
<>
{serviceInfo?.walletFileName && (
<rb.Alert variant="warning">
<Trans i18nKey="create_wallet.alert_other_wallet_unlocked">
Currently <strong>{{ walletName: walletDisplayName(serviceInfo.walletFileName) }}</strong> is active.
You need to lock it first.
<Link to={routes.walletList} className="alert-link">
Go back
</Link>
.
</Trans>
</rb.Alert>
)}
{serviceInfo?.rescanning === true && (
<rb.Alert variant="warning" data-testid="alert-rescanning">
<Trans i18nKey="create_wallet.alert_rescan_in_progress">
Rescanning the timechain is currently in progress. Please wait until the process finishes and then try
again.
<Link to={routes.walletList} className="alert-link">
Go back
</Link>
.
</Trans>
</rb.Alert>
)}
</>
) : (
<>
<PreventLeavingPageByMistake />
Expand Down
4 changes: 2 additions & 2 deletions src/components/ImportWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ export default function ImportWallet({ parentRoute, startWallet }: ImportWalletP
const [importDetailsFormValues, setImportDetailsFormValues] = useState<ImportWalletDetailsFormValues>()
const [recoveredWallet, setRecoveredWallet] = useState<RecoveredWalletWithAuth>()

const isRecovered = useMemo(() => !!recoveredWallet?.walletFileName && recoveredWallet?.auth, [recoveredWallet])
const isRecovered = useMemo(() => !!recoveredWallet?.walletFileName && !!recoveredWallet?.auth, [recoveredWallet])
const canRecover = useMemo(
() => !isRecovered && !serviceInfo?.walletFileName && !serviceInfo?.rescanning,
[isRecovered, serviceInfo],
Expand Down Expand Up @@ -571,7 +571,7 @@ export default function ImportWallet({ parentRoute, startWallet }: ImportWalletP
</rb.Alert>
)}
{serviceInfo?.rescanning === true && (
<rb.Alert variant="warning">
<rb.Alert variant="warning" data-testid="alert-rescanning">
<Trans i18nKey="import_wallet.alert_rescan_in_progress">
Rescanning the timechain is currently in progress. Please wait until the process finishes and then try
again.
Expand Down
10 changes: 5 additions & 5 deletions src/components/Wallet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('<Wallet />', () => {
act(() => setup({ walletFileName: dummyWalletFileName }))

expect(screen.getByText(walletDisplayName(dummyWalletFileName))).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_inactive')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_locked')).toBeInTheDocument()
expect(screen.queryByPlaceholderText('wallets.wallet_preview.placeholder_password')).not.toBeInTheDocument()
expect(screen.queryByText('wallets.wallet_preview.button_unlock')).not.toBeInTheDocument()
expect(screen.queryByText('wallets.wallet_preview.button_open')).not.toBeInTheDocument()
Expand All @@ -62,7 +62,7 @@ describe('<Wallet />', () => {
it('should unlock inactive wallet successfully', async () => {
await act(async () => setup({ walletFileName: dummyWalletFileName, unlockWallet: mockUnlockWallet }))

expect(screen.getByText('wallets.wallet_preview.wallet_inactive')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_locked')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.button_unlock')).toBeInTheDocument()
expect(screen.getByPlaceholderText('wallets.wallet_preview.placeholder_password')).toBeInTheDocument()
expect(screen.queryByText('wallets.wallet_preview.button_open')).not.toBeInTheDocument()
Expand Down Expand Up @@ -93,7 +93,7 @@ describe('<Wallet />', () => {
)

expect(screen.getByText(walletDisplayName(dummyWalletFileName))).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_active')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_unlocked')).toBeInTheDocument()
expect(screen.queryByPlaceholderText('wallets.wallet_preview.placeholder_password')).toBeInTheDocument()
expect(screen.queryByText('wallets.wallet_preview.button_unlock')).toBeInTheDocument()
expect(screen.queryByText('wallets.wallet_preview.button_open')).not.toBeInTheDocument()
Expand All @@ -110,7 +110,7 @@ describe('<Wallet />', () => {
)

expect(screen.getByText(walletDisplayName(dummyWalletFileName))).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_active')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_unlocked')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.button_open')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.button_lock')).toBeInTheDocument()
expect(screen.queryByPlaceholderText('wallets.wallet_preview.placeholder_password')).not.toBeInTheDocument()
Expand All @@ -126,7 +126,7 @@ describe('<Wallet />', () => {
}),
)

expect(screen.getByText('wallets.wallet_preview.wallet_active')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_unlocked')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.button_lock')).toBeInTheDocument()

await act(async () => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/Wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ export default function Wallet({
</rb.Card.Title>

{isActive ? (
<span className="text-success">{t('wallets.wallet_preview.wallet_active')}</span>
<span className="text-success">{t('wallets.wallet_preview.wallet_unlocked')}</span>
) : (
<span className="text-muted">{t('wallets.wallet_preview.wallet_inactive')}</span>
<span className="text-muted">{t('wallets.wallet_preview.wallet_locked')}</span>
)}
</div>

Expand Down
29 changes: 23 additions & 6 deletions src/components/Wallets.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import user from '@testing-library/user-event'
import * as apiMock from '../libs/JmWalletApi'

import Wallets from './Wallets'
import { walletDisplayName } from '../utils'
import { CurrentWallet } from '../context/WalletContext'

jest.mock('../libs/JmWalletApi', () => ({
Expand Down Expand Up @@ -44,7 +43,7 @@ describe('<Wallets />', () => {
;(apiMock.getGetinfo as jest.Mock).mockResolvedValue(neverResolvingPromise)
})

it('should render without errors', () => {
it('should display loading indicator while fetching data', () => {
const neverResolvingPromise = new Promise(() => {})
;(apiMock.getSession as jest.Mock).mockResolvedValueOnce(neverResolvingPromise)
;(apiMock.getWalletAll as jest.Mock).mockResolvedValueOnce(neverResolvingPromise)
Expand Down Expand Up @@ -75,6 +74,24 @@ describe('<Wallets />', () => {
expect(screen.getByText('wallets.button_new_wallet')).toBeInTheDocument()
})

it('should display alert when rescanning is active', async () => {
;(apiMock.getWalletAll as jest.Mock).mockResolvedValueOnce({
ok: false,
})
;(apiMock.getSession as jest.Mock).mockResolvedValueOnce({
ok: true,
json: () =>
Promise.resolve({
rescanning: true,
}),
})

await act(async () => setup({}))

expect(screen.getByText('wallets.title')).toBeVisible()
expect(screen.getByTestId('alert-rescanning')).toBeVisible()
})

it('should display big call-to-action buttons if no wallet has been created yet', async () => {
;(apiMock.getSession as jest.Mock).mockResolvedValueOnce({
ok: true,
Expand Down Expand Up @@ -214,7 +231,7 @@ describe('<Wallets />', () => {

await act(async () => setup({}))

expect(screen.getByText('wallets.wallet_preview.wallet_inactive')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_locked')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.button_unlock')).toBeInTheDocument()
expect(screen.getByPlaceholderText('wallets.wallet_preview.placeholder_password')).toBeInTheDocument()

Expand Down Expand Up @@ -261,7 +278,7 @@ describe('<Wallets />', () => {

await act(async () => setup({}))

expect(screen.getByText('wallets.wallet_preview.wallet_inactive')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_locked')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.button_unlock')).toBeInTheDocument()
expect(screen.getByPlaceholderText('wallets.wallet_preview.placeholder_password')).toBeInTheDocument()

Expand Down Expand Up @@ -313,7 +330,7 @@ describe('<Wallets />', () => {
}),
)

expect(screen.getByText('wallets.wallet_preview.wallet_active')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_unlocked')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.button_lock')).toBeInTheDocument()

await act(async () => {
Expand Down Expand Up @@ -361,7 +378,7 @@ describe('<Wallets />', () => {
}),
)

expect(screen.getByText('wallets.wallet_preview.wallet_active')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.wallet_unlocked')).toBeInTheDocument()
expect(screen.getByText('wallets.wallet_preview.button_lock')).toBeInTheDocument()

await act(async () => {
Expand Down
5 changes: 5 additions & 0 deletions src/components/Wallets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ export default function Wallets({ currentWallet, startWallet, stopWallet }: Wall
subtitle={walletList?.length === 0 ? t('wallets.subtitle_no_wallets') : undefined}
center={true}
/>
{serviceInfo?.rescanning === true && (
<rb.Alert variant="info" data-testid="alert-rescanning">
{t('app.alert_rescan_in_progress')}
</rb.Alert>
)}
{alert && <Alert {...alert} />}
{isLoading ? (
<div className="d-flex justify-content-center align-items-center">
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@
"alert_wallet_already_locked": "{{ walletName }} already locked.",
"wallet_active": "Active",
"wallet_inactive": "Inactive",
"wallet_locked": "Locked",
"wallet_unlocked": "Unlocked",
"placeholder_password": "Password",
"button_open": "Open",
"button_lock": "Lock",
Expand All @@ -123,6 +125,7 @@
"title_wallet_created": "Wallet created successfully!",
"subtitle_wallet_created": "Please write down your seed phrase and password! Without this information you will not be able to access and recover your wallet!",
"alert_other_wallet_unlocked": "Currently <1>{{ walletName }}</1> is active. You need to lock it first. <3>Go back</3>.",
"alert_rescan_in_progress": "Rescanning the timechain is currently in progress. Please wait until the process finishes and then try again. <1>Go back</1>.",
"feedback_valid": "Looks good!",
"label_wallet_name": "Wallet name",
"placeholder_wallet_name": "Your Wallet...",
Expand Down