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

Fix: Multisig select #2669

Merged
merged 2 commits into from
Nov 18, 2024
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
12 changes: 7 additions & 5 deletions src/renderer/entities/wallet/lib/wallet-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ function isNovaWallet(wallet?: Wallet): wallet is NovaWalletWallet {
function isWalletConnect(wallet?: Wallet): wallet is WalletConnectWallet {
return wallet?.type === WalletType.WALLET_CONNECT;
}

function isProxied(wallet?: Wallet): wallet is ProxiedWallet {
return wallet?.type === WalletType.PROXIED;
}
Expand All @@ -87,6 +88,7 @@ const VALID_SIGNATORY_WALLET_TYPES = [
WalletType.WALLET_CONNECT,
WalletType.NOVA_WALLET,
];

function isValidSignatory(wallet?: Wallet): boolean {
if (!wallet) return false;

Expand Down Expand Up @@ -133,8 +135,8 @@ function getAccountBy(wallets: Wallet[], accountFn: (account: Account, wallet: W
* object and its parent Wallet object and returns a boolean indicating
* whether it should be included in the result. Defaults to undefined.
*
* @returns {Wallet | undefined} - The matching Wallet object, or undefined if
* no matching Wallet is found.
* @returns {Wallet | null} - The matching Wallet object, or undefined if no
* matching Wallet is found.
*/
function getWalletFilteredAccounts(
wallets: Wallet[],
Expand Down Expand Up @@ -164,8 +166,8 @@ function getWalletsFilteredAccounts(
walletFn?: (wallet: Wallet) => boolean;
accountFn?: (account: Account, wallet: Wallet) => boolean;
},
): Wallet[] | undefined {
if (!predicates.walletFn && !predicates.accountFn) return undefined;
): Wallet[] | null {
if (!predicates.walletFn && !predicates.accountFn) return null;

const result = wallets.reduce<Wallet[]>((acc, wallet) => {
if (!predicates.walletFn || predicates.walletFn(wallet)) {
Expand All @@ -181,5 +183,5 @@ function getWalletsFilteredAccounts(
return acc;
}, []);

return result.length > 0 ? result : undefined;
return result.length > 0 ? result : null;
}
48 changes: 42 additions & 6 deletions src/renderer/shared/ui-kit/Select/Select.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type Meta, type StoryObj } from '@storybook/react';
import { useState } from 'react';

import { Icon } from '@/shared/ui';
import { Box } from '../Box/Box';

import { Select } from './Select';
Expand All @@ -17,12 +18,10 @@ const meta: Meta<typeof Select> = {
return (
<Box width="200px">
<Select {...params} placeholder="Select a fruit" value={value} onChange={onChange}>
<Select.Content>
<Select.Item value="item_1">Apple</Select.Item>
<Select.Item value="item_2">Orange</Select.Item>
<Select.Item value="item_3">Watermelon</Select.Item>
<Select.Item value="item_4">Banana</Select.Item>
</Select.Content>
<Select.Item value="item_1">Apple</Select.Item>
<Select.Item value="item_2">Orange</Select.Item>
<Select.Item value="item_3">Watermelon</Select.Item>
<Select.Item value="item_4">Banana-nana-nana-nana-nana-nana</Select.Item>
</Select>
</Box>
);
Expand All @@ -35,6 +34,43 @@ type Story = StoryObj<typeof Select>;

export const Default: Story = {};

export const RichContent: Story = {
render: (args) => {
const [value, onChange] = useState('item_4');

return (
<Box width="200px">
<Select {...args} placeholder="Select a fruit" value={value} onChange={onChange}>
<Select.Item value="item_1">
<Box direction="row" verticalAlign="center" gap={2}>
<Icon name="btc" size={12} className="shrink-0" />
<span className="truncate">Apple</span>
</Box>
</Select.Item>
<Select.Item value="item_2">
<Box direction="row" verticalAlign="center" gap={2}>
<Icon name="usd" size={12} className="shrink-0" />
<span className="truncate">Orange</span>
</Box>
</Select.Item>
<Select.Item value="item_3">
<Box direction="row" verticalAlign="center" gap={2}>
<Icon name="eur" size={12} className="shrink-0" />
<span className="truncate">Watermelon</span>
</Box>
</Select.Item>
<Select.Item value="item_4">
<Box direction="row" verticalAlign="center" gap={2}>
<Icon name="rub" size={12} className="shrink-0" />
<span className="truncate">Banana-nana-nana-nana-nana-nana</span>
</Box>
</Select.Item>
</Select>
</Box>
);
},
};

export const Invalid: Story = {
args: {
invalid: true,
Expand Down
17 changes: 8 additions & 9 deletions src/renderer/shared/ui-kit/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const Root = ({
<Context.Provider value={ctx}>
<RadixSelect.Root open={open} disabled={disabled} value={value} onOpenChange={onToggle} onValueChange={onChange}>
<Button placeholder={placeholder} />
{children}
<Content>{children}</Content>
</RadixSelect.Root>
</Context.Provider>
);
Expand All @@ -63,7 +63,7 @@ const Button = ({ placeholder }: TriggerProps) => {
return (
<RadixSelect.Trigger
className={cnTw(
'w-full px-[11px] py-[7px]',
'relative flex w-full items-center py-[7px] pl-[11px] pr-6',
'rounded border text-footnote outline-offset-1',
'enabled:hover:shadow-card-shadow',
'data-[state=open]:border-active-container-border',
Expand All @@ -75,10 +75,10 @@ const Button = ({ placeholder }: TriggerProps) => {
},
)}
>
<div className="flex items-center justify-between">
<div className="overflow-hidden">
<RadixSelect.Value placeholder={placeholder} />
<Icon name="down" size={16} className="shrink-0" />
</div>
<Icon name="down" size={16} className="absolute right-1.5 top-1/2 shrink-0 -translate-y-1/2" />
</RadixSelect.Trigger>
);
};
Expand All @@ -102,8 +102,8 @@ const Content = ({ children }: PropsWithChildren) => {
elevation={1}
className={cnTw(
'z-50 flex flex-col',
'h-max max-h-[--radix-popper-available-height] max-w-60',
'min-w-20 overflow-hidden duration-100 animate-in fade-in zoom-in-95',
'h-max max-h-[--radix-popper-available-height] min-w-20',
'overflow-hidden duration-100 animate-in fade-in zoom-in-95',
{
'border-border-dark bg-background-dark': theme === 'dark',
},
Expand Down Expand Up @@ -131,21 +131,20 @@ const Item = ({ value, children }: PropsWithChildren<ItemProps>) => {
<RadixSelect.Item
value={value}
className={cnTw(
'flex cursor-pointer rounded p-2 text-footnote text-text-secondary',
'flex w-full cursor-pointer rounded p-2 text-footnote text-text-secondary',
'focus:bg-action-background-hover focus:outline-none data-[highlighted]:bg-action-background-hover',
{
'focus:bg-block-background-hover data-[highlighted]:bg-background-item-hover': theme === 'dark',
},
)}
>
<RadixSelect.ItemText asChild>
<div className="h-full w-full">{children}</div>
<div className="h-full w-full truncate">{children}</div>
</RadixSelect.ItemText>
</RadixSelect.Item>
);
};

export const Select = Object.assign(Root, {
Content,
Item,
});
4 changes: 2 additions & 2 deletions src/renderer/widgets/CreateWallet/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Account, type Chain, type Transaction } from '@/shared/core';
import { type Account, type ChainId, type Transaction } from '@/shared/core';

export const enum Step {
NAME_NETWORK,
Expand All @@ -11,7 +11,7 @@ export const enum Step {

export type FormParams = {
threshold: number;
chain: Chain;
chainId: ChainId;
name: string;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { allSettled, fork } from 'effector';

import { type Account, type Chain } from '@/shared/core';
import { type Account, type ChainId } from '@/shared/core';
import { networkModel } from '@/entities/network';
import { walletModel } from '@/entities/wallet';
import { confirmModel } from '../confirm-model';
Expand All @@ -20,7 +20,7 @@ describe('widgets/CreateWallet/model/confirm-model', () => {
});

const store = {
chain: { chainId: '0x00' } as unknown as Chain,
chainId: '0x00' as ChainId,
account: { walletId: signerWallet.id } as unknown as Account,
signer: { walletId: signerWallet.id } as unknown as Account,
threshold: 2,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { allSettled, fork } from 'effector';

import { type Account, type Chain, ConnectionStatus } from '@/shared/core';
import { type Account, type ChainId, ConnectionStatus } from '@/shared/core';
import { toAddress } from '@/shared/lib/utils';
import { networkModel } from '@/entities/network';
import { walletModel } from '@/entities/wallet';
Expand Down Expand Up @@ -60,14 +60,14 @@ describe('widgets/CreateWallet/model/form-model', () => {
await allSettled(flowModel.events.signerSelected, { scope, params: signerWallet.accounts[0] });

expect(scope.getState(flowModel.$step)).toEqual(Step.NAME_NETWORK);
await allSettled(formModel.$createMultisigForm.fields.chain.onChange, { scope, params: testChain });
await allSettled(formModel.$createMultisigForm.fields.chainId.onChange, { scope, params: testChain.chainId });
await allSettled(formModel.$createMultisigForm.fields.name.onChange, { scope, params: 'some name' });
await allSettled(formModel.$createMultisigForm.fields.threshold.onChange, { scope, params: 2 });

await allSettled(formModel.$createMultisigForm.submit, { scope });

const store = {
chain: { chainId: '0x00' } as unknown as Chain,
chainId: '0x00' as ChainId,
account: { walletId: signerWallet.id } as unknown as Account,
signer: { walletId: signerWallet.id } as unknown as Account,
threshold: 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ describe('widgets/CreateWallet/model/form-model', () => {
});

await allSettled(formModel.$createMultisigForm.fields.threshold.onChange, { scope, params: 2 });
await allSettled(formModel.$createMultisigForm.fields.chain.onChange, { scope, params: testChain });
await allSettled(formModel.$createMultisigForm.fields.chainId.onChange, { scope, params: testChain.chainId });

expect(scope.getState(formModel.$multisigAccountId)).toEqual(multisigWallet.accounts[0].accountId);
});
Expand All @@ -91,7 +91,7 @@ describe('widgets/CreateWallet/model/form-model', () => {
.set(walletModel._test.$allWallets, [initiatorWallet, signerWallet, wrongChainWallet]),
});

await allSettled(formModel.$createMultisigForm.fields.chain.onChange, { scope, params: testChain });
await allSettled(formModel.$createMultisigForm.fields.chainId.onChange, { scope, params: testChain.chainId });

expect(scope.getState(formModel.$availableAccounts)).toEqual([
...initiatorWallet.accounts,
Expand All @@ -109,7 +109,7 @@ describe('widgets/CreateWallet/model/form-model', () => {
.set(signatoryModel.$signatories, []),
});

await allSettled(formModel.$createMultisigForm.fields.chain.onChange, { scope, params: testChain });
await allSettled(formModel.$createMultisigForm.fields.chainId.onChange, { scope, params: testChain.chainId });
await allSettled(signatoryModel.events.changeSignatory, {
scope,
params: { index: 0, name: 'test', address: toAddress(signerWallet.accounts[0].accountId), walletId: '1' },
Expand Down
9 changes: 7 additions & 2 deletions src/renderer/widgets/CreateWallet/model/__tests__/mock.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { type ApiPromise } from '@polkadot/api';

import {
type Account,
AccountType,
type Chain,
type ChainAccount,
ChainOptions,
ChainType,
type MultisigAccount,
SigningType,
type Wallet,
WalletType,
Expand All @@ -30,7 +30,12 @@ export const multisigWallet = {
isActive: false,
type: WalletType.MULTISIG,
signingType: SigningType.MULTISIG,
accounts: [{ accountId: '0x7f7cc72b17ac5d762869e97af14ebcc561590b6cc9eeeac7a3cdadde646c95c3' } as unknown as Account],
accounts: [
{
accountId: '0x7f7cc72b17ac5d762869e97af14ebcc561590b6cc9eeeac7a3cdadde646c95c3',
type: AccountType.MULTISIG,
} as unknown as MultisigAccount,
],
} as Wallet;

export const signerWallet = {
Expand Down
3 changes: 1 addition & 2 deletions src/renderer/widgets/CreateWallet/model/confirm-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ const $api = combine(
store: $confirmStore,
},
({ apis, store }) => {
return store?.chain ? apis[store.chain.chainId] : undefined;
return store ? apis[store.chainId] : null;
},
{ skipVoid: false },
);

const $signerWallet = combine(
Expand Down
Loading
Loading