From 24c64b8f09b5f04bb04244f32eeed5fe41b82537 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Mon, 11 Mar 2024 22:52:48 +0330 Subject: [PATCH 01/23] feat: implment DaoDataListItem --- .../daoDataListItem.stories.tsx | 62 +++++++++++++++++++ .../daoDataListItem/daoDataListItem.test.tsx | 41 ++++++++++++ .../dao/daoDataListItem/daoDataListItem.tsx | 43 +++++++++++++ .../components/dao/daoDataListItem/index.ts | 5 ++ src/modules/components/dao/index.ts | 1 + 5 files changed, 152 insertions(+) create mode 100644 src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx create mode 100644 src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx create mode 100644 src/modules/components/dao/daoDataListItem/daoDataListItem.tsx create mode 100644 src/modules/components/dao/daoDataListItem/index.ts diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx new file mode 100644 index 000000000..06f8d03df --- /dev/null +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx @@ -0,0 +1,62 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { DataList } from '../../../../core/components/dataList'; +import { DaoDataListItem } from './daoDataListItem'; + +const meta: Meta = { + title: 'Modules/Components/Dao/DaoDataListItem', + component: DaoDataListItem, + tags: ['autodocs'], + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/file/P0GeJKqILL7UXvaqu5Jj7V/v1.1.0?type=design&node-id=3259-11363&mode=dev', + }, + }, +}; + +type Story = StoryObj; + +/** + * Default usage example of the DaoDataListItem component. + */ +export const Default: Story = { + args: { + name: 'Patito DAO', + src: 'https://cdn.discordapp.com/icons/672466989217873929/acffa3e9e09ac5962ff803a5f8649040.webp?size=240', + description: + 'Papito DAO is responsible for maximizing effective coordination and collaboration between different Patito teams and enabling them to perform at their best ability with the highest velocity they can achieve. Our main focus is on managing the day-to-day tasks of the Patito Guilds, such as enabling contractual relationships, legal operations, accounting, finance, and HR. We are also responsible for addressing any issues that may arise within the teams and deploying new tools, and infrastructure to ensure smooth operations.', + plugin: 'token-based', + network: 'Ethereum Mainnet', + daoAddressOrEns: 'patito.dao.eth', + }, + render: (props) => ( + + + + + + ), +}; + +/** + * Usage of the DaoDataListItem without an image src. + */ +export const Mobile: Story = { + args: { + name: 'Patito DAO', + description: + 'Papito DAO is responsible for maximizing effective coordination and collaboration between different Patito teams and enabling them to perform at their best ability with the highest velocity they can achieve. Our main focus is on managing the day-to-day tasks of the Patito Guilds, such as enabling contractual relationships, legal operations, accounting, finance, and HR. We are also responsible for addressing any issues that may arise within the teams and deploying new tools, and infrastructure to ensure smooth operations.', + plugin: 'token-based', + network: 'Ethereum Mainnet', + daoAddressOrEns: 'patito.dao.eth', + }, + render: (props) => ( + + + + + + ), +}; + +export default meta; diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx new file mode 100644 index 000000000..a4529bb30 --- /dev/null +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx @@ -0,0 +1,41 @@ +import { render, screen } from '@testing-library/react'; +import { DataListContextProvider } from '../../../../core/components/dataList/dataListContext'; +import { dataListTestUtils } from '../../../../core/components/dataList/dataListTestUtils'; +import { DaoDataListItem, type IDaoDataListItemProps } from './daoDataListItem'; + +describe(' component', () => { + const createTestComponent = (values?: { + props?: Partial; + context?: Partial; + }) => { + const completeProps = { + ...values?.props, + }; + + return ( + + + + ); + }; + + it('renders a link with the given content', () => { + const props = { children: 'test-data-list-item', href: '/test' }; + render(createTestComponent({ props })); + expect(screen.getByRole('link', { name: props.children })).toBeInTheDocument(); + }); + + it('marks the item as hidden when the data list is on initialLoading state', () => { + const context = { state: 'initialLoading' as const }; + const props = { href: '/test' }; + render(createTestComponent({ context, props })); + expect(screen.queryByRole('link')).not.toBeInTheDocument(); + }); + + it('marks the item as hidden when the data list is on loading state with no elements being currently rendered', () => { + const context = { state: 'loading' as const, childrenItemCount: 0 }; + const props = { href: '/test' }; + render(createTestComponent({ context, props })); + expect(screen.queryByRole('link')).not.toBeInTheDocument(); + }); +}); diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx new file mode 100644 index 000000000..962f9e006 --- /dev/null +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx @@ -0,0 +1,43 @@ +import type React from 'react'; +import { DataList, Heading, Icon, IconType } from '../../../../core'; +import { DaoAvatar, type IDaoAvatarProps } from '../daoAvatar'; + +export interface IDaoDataListItemProps extends IDaoAvatarProps { + plugin: 'token-based' | 'multisig'; + network: string; + description?: string; + daoAddressOrEns?: string; +} + +export const DaoDataListItem: React.FC = (props) => { + const { name, src, description, network, plugin, daoAddressOrEns } = props; + + return ( + +
+
+
+ + {name} + + + {daoAddressOrEns} + +
+ +
+
{description}
+
+
+ {network} + +
+
+ {plugin} + +
+
+
+
+ ); +}; diff --git a/src/modules/components/dao/daoDataListItem/index.ts b/src/modules/components/dao/daoDataListItem/index.ts new file mode 100644 index 000000000..6ea67eb74 --- /dev/null +++ b/src/modules/components/dao/daoDataListItem/index.ts @@ -0,0 +1,5 @@ +// export const DaoDataListItem = { +// structure, +// }; + +export { DaoDataListItem, type IDaoDataListItemProps } from './daoDataListItem'; diff --git a/src/modules/components/dao/index.ts b/src/modules/components/dao/index.ts index 88b95efc6..ed744f04f 100644 --- a/src/modules/components/dao/index.ts +++ b/src/modules/components/dao/index.ts @@ -1 +1,2 @@ export * from './daoAvatar'; +export * from './daoDataListItem'; From cc66327e4ccc9f71c68be2cc9e9f8a3f5295ea7a Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 12 Mar 2024 11:11:32 +0330 Subject: [PATCH 02/23] tests added --- .../daoDataListItem/daoDataListItem.test.tsx | 64 +++++++++++-------- .../dao/daoDataListItem/daoDataListItem.tsx | 8 +-- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx index a4529bb30..3e93bad9d 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx @@ -1,41 +1,51 @@ import { render, screen } from '@testing-library/react'; -import { DataListContextProvider } from '../../../../core/components/dataList/dataListContext'; -import { dataListTestUtils } from '../../../../core/components/dataList/dataListTestUtils'; +import { DataList } from '../../../../core/components/dataList'; import { DaoDataListItem, type IDaoDataListItemProps } from './daoDataListItem'; describe(' component', () => { - const createTestComponent = (values?: { - props?: Partial; - context?: Partial; - }) => { - const completeProps = { - ...values?.props, - }; - + const createTestComponent = (props?: Partial) => { return ( - - - + + + + + ); }; - it('renders a link with the given content', () => { - const props = { children: 'test-data-list-item', href: '/test' }; - render(createTestComponent({ props })); - expect(screen.getByRole('link', { name: props.children })).toBeInTheDocument(); + it('renders ensName and the daoName (in uppercase) as the avatar fallback', () => { + let name = 'a'; + let daoAddressOrEns = 'a.eth'; + const { rerender } = render(createTestComponent({ name, daoAddressOrEns })); + expect(screen.getByText(name.toUpperCase())).toBeInTheDocument(); + expect(screen.getByText(daoAddressOrEns)).toBeInTheDocument(); + + name = 'ab'; + daoAddressOrEns = 'ab.eth'; + rerender(createTestComponent({ name, daoAddressOrEns })); + expect(screen.getByText(name.toUpperCase())).toBeInTheDocument(); + expect(screen.getByText(daoAddressOrEns)).toBeInTheDocument(); + }); + + it('does not render the daoAddressOrEns if it is not provided', () => { + const name = 'a'; + render(createTestComponent({ name })); + expect(screen.queryByText(/.eth/)).not.toBeInTheDocument(); }); - it('marks the item as hidden when the data list is on initialLoading state', () => { - const context = { state: 'initialLoading' as const }; - const props = { href: '/test' }; - render(createTestComponent({ context, props })); - expect(screen.queryByRole('link')).not.toBeInTheDocument(); + it('renders the description with an ellipsis if it is more than two lines', () => { + const description = + 'This is a very long description that should be more than two lines. It should end with an ellipsis.'; + render(createTestComponent({ description })); + const descriptionElement = screen.getByText(/This is a very long description/); + expect(descriptionElement).toHaveClass('line-clamp-2'); }); - it('marks the item as hidden when the data list is on loading state with no elements being currently rendered', () => { - const context = { state: 'loading' as const, childrenItemCount: 0 }; - const props = { href: '/test' }; - render(createTestComponent({ context, props })); - expect(screen.queryByRole('link')).not.toBeInTheDocument(); + it('renders the network and plugin information correctly', () => { + const network = 'ethereum'; + const plugin = 'token-based'; + render(createTestComponent({ network, plugin })); + expect(screen.getByText(network)).toBeInTheDocument(); + expect(screen.getByText(plugin)).toBeInTheDocument(); }); }); diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx index 962f9e006..6e73a40a8 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx @@ -3,17 +3,17 @@ import { DataList, Heading, Icon, IconType } from '../../../../core'; import { DaoAvatar, type IDaoAvatarProps } from '../daoAvatar'; export interface IDaoDataListItemProps extends IDaoAvatarProps { - plugin: 'token-based' | 'multisig'; - network: string; description?: string; daoAddressOrEns?: string; + plugin?: string; + network?: string; } export const DaoDataListItem: React.FC = (props) => { - const { name, src, description, network, plugin, daoAddressOrEns } = props; + const { name, src, description, network, plugin = 'token-based', daoAddressOrEns } = props; return ( - +
From b2205c08b77fe0c03236df1c80afe90f7a2bef69 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 12 Mar 2024 11:17:14 +0330 Subject: [PATCH 03/23] add responsive support --- .../components/dao/daoDataListItem/daoDataListItem.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx index 6e73a40a8..144dcf123 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx @@ -26,13 +26,15 @@ export const DaoDataListItem: React.FC = (props) => {
-
{description}
+

+ {description} +

-
+
{network}
-
+
{plugin}
From 7fc474dbc1cd6c026cc82ad859229a1c9d6458df Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 12 Mar 2024 11:21:38 +0330 Subject: [PATCH 04/23] fix: final cleanup --- .../dao/daoDataListItem/daoDataListItem.stories.tsx | 4 ++-- src/modules/components/dao/daoDataListItem/index.ts | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx index 06f8d03df..8719703a0 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx @@ -30,7 +30,7 @@ export const Default: Story = { daoAddressOrEns: 'patito.dao.eth', }, render: (props) => ( - + @@ -51,7 +51,7 @@ export const Mobile: Story = { daoAddressOrEns: 'patito.dao.eth', }, render: (props) => ( - + diff --git a/src/modules/components/dao/daoDataListItem/index.ts b/src/modules/components/dao/daoDataListItem/index.ts index 6ea67eb74..1fb1c5754 100644 --- a/src/modules/components/dao/daoDataListItem/index.ts +++ b/src/modules/components/dao/daoDataListItem/index.ts @@ -1,5 +1 @@ -// export const DaoDataListItem = { -// structure, -// }; - export { DaoDataListItem, type IDaoDataListItemProps } from './daoDataListItem'; From fbddc6af9e34885ad004057568655a19a239bc81 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 12 Mar 2024 11:24:50 +0330 Subject: [PATCH 05/23] chore: update CHANGELOG.MD --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 298d9521b..df330dcf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Implement animations for `Dialog` and `DialogAlert` components - Implement `DaoAvatar` module component +- Implement `DaoDataListItem` module component - Implement `OdsModulesProvider` for using wagmi hooks on modules components ### Changed From 45d5073a1a69d39a436093d92e03daa55762d9b0 Mon Sep 17 00:00:00 2001 From: Sepehr Sanaei <46657145+sepehr2github@users.noreply.github.com> Date: Tue, 12 Mar 2024 14:41:54 +0330 Subject: [PATCH 06/23] Update CHANGELOG.md Co-authored-by: cgero.eth --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df330dcf1..6ec7bb9b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - Implement animations for `Dialog` and `DialogAlert` components -- Implement `DaoAvatar` module component -- Implement `DaoDataListItem` module component +- Implement `DaoAvatar` and `DaoDataListItem` module components - Implement `OdsModulesProvider` for using wagmi hooks on modules components ### Changed From 5006ac3a21f1a4f253dd008b45ff47acecec9289 Mon Sep 17 00:00:00 2001 From: Sepehr Sanaei <46657145+sepehr2github@users.noreply.github.com> Date: Tue, 12 Mar 2024 14:44:32 +0330 Subject: [PATCH 07/23] Update src/modules/components/dao/daoDataListItem/index.ts Co-authored-by: cgero.eth --- src/modules/components/dao/daoDataListItem/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/modules/components/dao/daoDataListItem/index.ts b/src/modules/components/dao/daoDataListItem/index.ts index 1fb1c5754..21e0337c0 100644 --- a/src/modules/components/dao/daoDataListItem/index.ts +++ b/src/modules/components/dao/daoDataListItem/index.ts @@ -1 +1,7 @@ -export { DaoDataListItem, type IDaoDataListItemProps } from './daoDataListItem'; +import { DaoDataListItemStructure } from './daoDataListItemStructure'; + +export const DaoDataListItem = { + Structure: DaoDataListItemStructure +} + +export type { IDaoDataListItemProps } from './daoDataListItem'; From 55b010216c5f528975d9b17b36df8a42176def3f Mon Sep 17 00:00:00 2001 From: Sepehr Sanaei <46657145+sepehr2github@users.noreply.github.com> Date: Tue, 12 Mar 2024 14:44:41 +0330 Subject: [PATCH 08/23] Update src/modules/components/dao/daoDataListItem/daoDataListItem.tsx Co-authored-by: cgero.eth --- src/modules/components/dao/daoDataListItem/daoDataListItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx index 144dcf123..3a6d04cfe 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx @@ -34,7 +34,7 @@ export const DaoDataListItem: React.FC = (props) => { {network}
-
+
{plugin}
From aafac5e798bad2b3feed7f57d17355d9aa601965 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 12 Mar 2024 14:52:42 +0330 Subject: [PATCH 09/23] fix: resolve comment --- .../daoDataListItem.stories.tsx | 6 +++--- .../daoDataListItem/daoDataListItem.test.tsx | 12 ++++++------ .../dao/daoDataListItem/daoDataListItem.tsx | 19 +++++++++++-------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx index 8719703a0..5f1abcb09 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx @@ -22,12 +22,12 @@ type Story = StoryObj; export const Default: Story = { args: { name: 'Patito DAO', - src: 'https://cdn.discordapp.com/icons/672466989217873929/acffa3e9e09ac5962ff803a5f8649040.webp?size=240', + logoSrc: 'https://cdn.discordapp.com/icons/672466989217873929/acffa3e9e09ac5962ff803a5f8649040.webp?size=240', description: 'Papito DAO is responsible for maximizing effective coordination and collaboration between different Patito teams and enabling them to perform at their best ability with the highest velocity they can achieve. Our main focus is on managing the day-to-day tasks of the Patito Guilds, such as enabling contractual relationships, legal operations, accounting, finance, and HR. We are also responsible for addressing any issues that may arise within the teams and deploying new tools, and infrastructure to ensure smooth operations.', plugin: 'token-based', network: 'Ethereum Mainnet', - daoAddressOrEns: 'patito.dao.eth', + ens: 'patito.dao.eth', }, render: (props) => ( @@ -48,7 +48,7 @@ export const Mobile: Story = { 'Papito DAO is responsible for maximizing effective coordination and collaboration between different Patito teams and enabling them to perform at their best ability with the highest velocity they can achieve. Our main focus is on managing the day-to-day tasks of the Patito Guilds, such as enabling contractual relationships, legal operations, accounting, finance, and HR. We are also responsible for addressing any issues that may arise within the teams and deploying new tools, and infrastructure to ensure smooth operations.', plugin: 'token-based', network: 'Ethereum Mainnet', - daoAddressOrEns: 'patito.dao.eth', + ens: 'patito.dao.eth', }, render: (props) => ( diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx index 3e93bad9d..55d4e754d 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx @@ -15,16 +15,16 @@ describe(' component', () => { it('renders ensName and the daoName (in uppercase) as the avatar fallback', () => { let name = 'a'; - let daoAddressOrEns = 'a.eth'; - const { rerender } = render(createTestComponent({ name, daoAddressOrEns })); + const ens = 'a.eth'; + const { rerender } = render(createTestComponent({ name, ens })); expect(screen.getByText(name.toUpperCase())).toBeInTheDocument(); - expect(screen.getByText(daoAddressOrEns)).toBeInTheDocument(); + expect(screen.getByText(ens)).toBeInTheDocument(); name = 'ab'; - daoAddressOrEns = 'ab.eth'; - rerender(createTestComponent({ name, daoAddressOrEns })); + const address = '0x123'; + rerender(createTestComponent({ name, address })); expect(screen.getByText(name.toUpperCase())).toBeInTheDocument(); - expect(screen.getByText(daoAddressOrEns)).toBeInTheDocument(); + expect(screen.getByText(address)).toBeInTheDocument(); }); it('does not render the daoAddressOrEns if it is not provided', () => { diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx index 144dcf123..64f61beaa 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx @@ -1,19 +1,22 @@ import type React from 'react'; -import { DataList, Heading, Icon, IconType } from '../../../../core'; -import { DaoAvatar, type IDaoAvatarProps } from '../daoAvatar'; +import { DataList, Heading, Icon, IconType, type IDataListItemProps } from '../../../../core'; +import { DaoAvatar } from '../daoAvatar'; -export interface IDaoDataListItemProps extends IDaoAvatarProps { +export interface IDaoDataListItemProps extends IDataListItemProps { + name?: string; + logoSrc?: string; description?: string; - daoAddressOrEns?: string; + address?: string; + ens?: string; plugin?: string; network?: string; } export const DaoDataListItem: React.FC = (props) => { - const { name, src, description, network, plugin = 'token-based', daoAddressOrEns } = props; + const { name, logoSrc, description, network, plugin = 'token-based', address, ens, ...otherProps } = props; return ( - +
@@ -21,10 +24,10 @@ export const DaoDataListItem: React.FC = (props) => { {name} - {daoAddressOrEns} + {ens ?? address}
- +

{description} From ebf3330db2886a9f7c83cdd54c48238adcd59840 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 12 Mar 2024 15:00:55 +0330 Subject: [PATCH 10/23] fix: update file names --- .../components/dao/daoDataListItem/index.ts | 7 ------- .../daoDataListItemStructure.stories.tsx} | 14 +++++++------- .../daoDataListItemStructure.test.tsx} | 8 ++++---- .../daoDataListItemStructure.tsx} | 4 ++-- .../dao/daoDataListItemStructure/index.ts | 7 +++++++ src/modules/components/dao/index.ts | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) delete mode 100644 src/modules/components/dao/daoDataListItem/index.ts rename src/modules/components/dao/{daoDataListItem/daoDataListItem.stories.tsx => daoDataListItemStructure/daoDataListItemStructure.stories.tsx} (87%) rename src/modules/components/dao/{daoDataListItem/daoDataListItem.test.tsx => daoDataListItemStructure/daoDataListItemStructure.test.tsx} (88%) rename src/modules/components/dao/{daoDataListItem/daoDataListItem.tsx => daoDataListItemStructure/daoDataListItemStructure.tsx} (91%) create mode 100644 src/modules/components/dao/daoDataListItemStructure/index.ts diff --git a/src/modules/components/dao/daoDataListItem/index.ts b/src/modules/components/dao/daoDataListItem/index.ts deleted file mode 100644 index 21e0337c0..000000000 --- a/src/modules/components/dao/daoDataListItem/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { DaoDataListItemStructure } from './daoDataListItemStructure'; - -export const DaoDataListItem = { - Structure: DaoDataListItemStructure -} - -export type { IDaoDataListItemProps } from './daoDataListItem'; diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx b/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.stories.tsx similarity index 87% rename from src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx rename to src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.stories.tsx index 5f1abcb09..b25e9fd3c 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.stories.tsx +++ b/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.stories.tsx @@ -1,10 +1,10 @@ import type { Meta, StoryObj } from '@storybook/react'; import { DataList } from '../../../../core/components/dataList'; -import { DaoDataListItem } from './daoDataListItem'; +import { DaoDataListItemStructure } from './daoDataListItemStructure'; -const meta: Meta = { +const meta: Meta = { title: 'Modules/Components/Dao/DaoDataListItem', - component: DaoDataListItem, + component: DaoDataListItemStructure, tags: ['autodocs'], parameters: { design: { @@ -14,7 +14,7 @@ const meta: Meta = { }, }; -type Story = StoryObj; +type Story = StoryObj; /** * Default usage example of the DaoDataListItem component. @@ -32,7 +32,7 @@ export const Default: Story = { render: (props) => ( - + ), @@ -41,7 +41,7 @@ export const Default: Story = { /** * Usage of the DaoDataListItem without an image src. */ -export const Mobile: Story = { +export const Fallback: Story = { args: { name: 'Patito DAO', description: @@ -53,7 +53,7 @@ export const Mobile: Story = { render: (props) => ( - + ), diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx b/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.test.tsx similarity index 88% rename from src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx rename to src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.test.tsx index 55d4e754d..95f1fb477 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.test.tsx +++ b/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.test.tsx @@ -1,13 +1,13 @@ import { render, screen } from '@testing-library/react'; import { DataList } from '../../../../core/components/dataList'; -import { DaoDataListItem, type IDaoDataListItemProps } from './daoDataListItem'; +import { DaoDataListItemStructure, type IDaoDataListItemStructureProps } from './daoDataListItemStructure'; -describe(' component', () => { - const createTestComponent = (props?: Partial) => { +describe(' component', () => { + const createTestComponent = (props?: Partial) => { return ( - + ); diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx b/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.tsx similarity index 91% rename from src/modules/components/dao/daoDataListItem/daoDataListItem.tsx rename to src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.tsx index cdc43da39..c432671b6 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItem.tsx +++ b/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.tsx @@ -2,7 +2,7 @@ import type React from 'react'; import { DataList, Heading, Icon, IconType, type IDataListItemProps } from '../../../../core'; import { DaoAvatar } from '../daoAvatar'; -export interface IDaoDataListItemProps extends IDataListItemProps { +export interface IDaoDataListItemStructureProps extends IDataListItemProps { name?: string; logoSrc?: string; description?: string; @@ -12,7 +12,7 @@ export interface IDaoDataListItemProps extends IDataListItemProps { network?: string; } -export const DaoDataListItem: React.FC = (props) => { +export const DaoDataListItemStructure: React.FC = (props) => { const { name, logoSrc, description, network, plugin = 'token-based', address, ens, ...otherProps } = props; return ( diff --git a/src/modules/components/dao/daoDataListItemStructure/index.ts b/src/modules/components/dao/daoDataListItemStructure/index.ts new file mode 100644 index 000000000..9de8fc4b7 --- /dev/null +++ b/src/modules/components/dao/daoDataListItemStructure/index.ts @@ -0,0 +1,7 @@ +import { DaoDataListItemStructure } from './daoDataListItemStructure'; + +export const DaoDataListItem = { + Structure: DaoDataListItemStructure, +}; + +export type { IDaoDataListItemStructureProps } from './daoDataListItemStructure'; diff --git a/src/modules/components/dao/index.ts b/src/modules/components/dao/index.ts index ed744f04f..f62db2add 100644 --- a/src/modules/components/dao/index.ts +++ b/src/modules/components/dao/index.ts @@ -1,2 +1,2 @@ export * from './daoAvatar'; -export * from './daoDataListItem'; +export * from './daoDataListItemStructure'; From 0b923442929e8b76c833f1899c2a5980b04b33b5 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Wed, 13 Mar 2024 11:51:33 +0330 Subject: [PATCH 11/23] resolve comments --- .../daoDataListItemStructure.stories.tsx | 4 +-- .../daoDataListItemStructure.test.tsx | 14 +++++---- .../daoDataListItemStructure.tsx | 29 ++++++++++++++++--- .../daoDataListItemStructure/index.ts | 0 .../components/dao/daoDataListItem/index.ts | 1 + src/modules/components/dao/index.ts | 2 +- 6 files changed, 37 insertions(+), 13 deletions(-) rename src/modules/components/dao/{ => daoDataListItem}/daoDataListItemStructure/daoDataListItemStructure.stories.tsx (95%) rename src/modules/components/dao/{ => daoDataListItem}/daoDataListItemStructure/daoDataListItemStructure.test.tsx (85%) rename src/modules/components/dao/{ => daoDataListItem}/daoDataListItemStructure/daoDataListItemStructure.tsx (75%) rename src/modules/components/dao/{ => daoDataListItem}/daoDataListItemStructure/index.ts (100%) create mode 100644 src/modules/components/dao/daoDataListItem/index.ts diff --git a/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.stories.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.stories.tsx similarity index 95% rename from src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.stories.tsx rename to src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.stories.tsx index b25e9fd3c..5dd7ec7a6 100644 --- a/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.stories.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.stories.tsx @@ -1,9 +1,9 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { DataList } from '../../../../core/components/dataList'; +import { DataList } from '../../../../../core'; import { DaoDataListItemStructure } from './daoDataListItemStructure'; const meta: Meta = { - title: 'Modules/Components/Dao/DaoDataListItem', + title: 'Modules/Components/Dao/DaoDataListItem/DaoDataListItem.Structure', component: DaoDataListItemStructure, tags: ['autodocs'], parameters: { diff --git a/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.test.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.test.tsx similarity index 85% rename from src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.test.tsx rename to src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.test.tsx index 95f1fb477..7d4091290 100644 --- a/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.test.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react'; -import { DataList } from '../../../../core/components/dataList'; +import { DataList } from '../../../../../core'; import { DaoDataListItemStructure, type IDaoDataListItemStructureProps } from './daoDataListItemStructure'; describe(' component', () => { @@ -14,20 +14,22 @@ describe(' component', () => { }; it('renders ensName and the daoName (in uppercase) as the avatar fallback', () => { - let name = 'a'; + const name = 'a'; const ens = 'a.eth'; - const { rerender } = render(createTestComponent({ name, ens })); + render(createTestComponent({ name, ens })); expect(screen.getByText(name.toUpperCase())).toBeInTheDocument(); expect(screen.getByText(ens)).toBeInTheDocument(); + }); - name = 'ab'; + it('renders name and the address', () => { + const name = 'ab'; const address = '0x123'; - rerender(createTestComponent({ name, address })); + render(createTestComponent({ name, address })); expect(screen.getByText(name.toUpperCase())).toBeInTheDocument(); expect(screen.getByText(address)).toBeInTheDocument(); }); - it('does not render the daoAddressOrEns if it is not provided', () => { + it('does not render the dao ENS name if it is not provided', () => { const name = 'a'; render(createTestComponent({ name })); expect(screen.queryByText(/.eth/)).not.toBeInTheDocument(); diff --git a/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx similarity index 75% rename from src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.tsx rename to src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx index c432671b6..f2158324f 100644 --- a/src/modules/components/dao/daoDataListItemStructure/daoDataListItemStructure.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx @@ -1,14 +1,35 @@ import type React from 'react'; -import { DataList, Heading, Icon, IconType, type IDataListItemProps } from '../../../../core'; -import { DaoAvatar } from '../daoAvatar'; +import { DataList, Heading, Icon, IconType, type IDataListItemProps } from '../../../../../core'; +import { DaoAvatar } from '../../daoAvatar'; export interface IDaoDataListItemStructureProps extends IDataListItemProps { + /** + * The name of the DAO. + */ name?: string; + /** + * The source of the logo for the DAO. + */ logoSrc?: string; + /** + * The description of the DAO. + */ description?: string; + /** + * The address of the DAO. + */ address?: string; + /** + * The ENS (Ethereum Name Service) address of the DAO. + */ ens?: string; + /** + * The plugin used by the DAO. + */ plugin?: string; + /** + * The network on which the DAO operates. + */ network?: string; } @@ -17,7 +38,7 @@ export const DaoDataListItemStructure: React.FC return ( -

+
@@ -27,7 +48,7 @@ export const DaoDataListItemStructure: React.FC {ens ?? address}
- +

{description} diff --git a/src/modules/components/dao/daoDataListItemStructure/index.ts b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/index.ts similarity index 100% rename from src/modules/components/dao/daoDataListItemStructure/index.ts rename to src/modules/components/dao/daoDataListItem/daoDataListItemStructure/index.ts diff --git a/src/modules/components/dao/daoDataListItem/index.ts b/src/modules/components/dao/daoDataListItem/index.ts new file mode 100644 index 000000000..b6fd5ed01 --- /dev/null +++ b/src/modules/components/dao/daoDataListItem/index.ts @@ -0,0 +1 @@ +export * from './daoDataListItemStructure'; diff --git a/src/modules/components/dao/index.ts b/src/modules/components/dao/index.ts index f62db2add..ed744f04f 100644 --- a/src/modules/components/dao/index.ts +++ b/src/modules/components/dao/index.ts @@ -1,2 +1,2 @@ export * from './daoAvatar'; -export * from './daoDataListItemStructure'; +export * from './daoDataListItem'; From 783084bc95db4a7843505ee7bc69e0bb41a5e92b Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Wed, 13 Mar 2024 12:12:12 +0330 Subject: [PATCH 12/23] fix: update classes --- .../daoDataListItemStructure/daoDataListItemStructure.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx index f2158324f..30d832d65 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx @@ -38,9 +38,9 @@ export const DaoDataListItemStructure: React.FC return ( -

+
-
+
{name} @@ -53,7 +53,7 @@ export const DaoDataListItemStructure: React.FC

{description}

-
+
{network} From 704482d26d6e23fdeea5694a0c3e9010be6130a6 Mon Sep 17 00:00:00 2001 From: Sepehr Sanaei <46657145+sepehr2github@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:52:23 +0330 Subject: [PATCH 13/23] Update CHANGELOG.md Co-authored-by: cgero.eth --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e33d6aa0..db89c3233 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - Implement animations for `Dialog` and `DialogAlert` components -- Implement `DaoAvatar` and `MemberAvatar` and `DaoDataListItem` module components +- Implement `DaoAvatar`, `MemberAvatar` and `DaoDataListItem` module components - Implement `OdsModulesProvider` for using wagmi hooks on modules components ### Changed From af7c4fb910978db6b09aaa72f0989f8a52045d59 Mon Sep 17 00:00:00 2001 From: Sepehr Sanaei <46657145+sepehr2github@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:52:35 +0330 Subject: [PATCH 14/23] Update src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx Co-authored-by: cgero.eth --- .../daoDataListItemStructure/daoDataListItemStructure.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx index 30d832d65..c1675e6e2 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx @@ -25,6 +25,7 @@ export interface IDaoDataListItemStructureProps extends IDataListItemProps { ens?: string; /** * The plugin used by the DAO. + * @default token-based */ plugin?: string; /** From 5267ae7dff834473b8002815cecd93487f3e4b24 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Wed, 13 Mar 2024 15:11:50 +0330 Subject: [PATCH 15/23] fix: update padding based on figma sizes --- .../daoDataListItemStructure/daoDataListItemStructure.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx index c1675e6e2..5dfe202f2 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx +++ b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx @@ -39,7 +39,7 @@ export const DaoDataListItemStructure: React.FC return ( -
+
From 95ef87dd386307411734ab24a962b1bd1b1bb38d Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Wed, 13 Mar 2024 19:28:06 +0330 Subject: [PATCH 16/23] update changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e1373417..803cee07c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Added + +- Implement `DaoDataListItem` module component + ## [1.0.20] - 2024-03-13 ### Fixed @@ -19,7 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - Implement animations for `Dialog` and `DialogAlert` components -- Implement `DaoAvatar`, `MemberAvatar` and `DaoDataListItem` module components +- Implement `DaoAvatar` and `MemberAvatar` module components - Implement `OdsModulesProvider` for using wagmi hooks on modules components - Introduce component customisations for the z-index property of the `Dropdown` and `Dialogs` components From 3b469f8c4c4911fda3761b981ab3ce29c8962887 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Fri, 15 Mar 2024 11:04:37 +0330 Subject: [PATCH 17/23] feature: added AssetDataListItem.Structure --- CHANGELOG.md | 1 + .../assetDataListItemStructure.stories.tsx | 61 ++++++++++ .../assetDataListItemStructure.test.tsx | 78 +++++++++++++ .../assetDataListItemStructure.tsx | 105 ++++++++++++++++++ .../assetDataListItemStructure/index.ts | 7 ++ .../asset/assetDataListItem/index.ts | 1 + src/modules/components/asset/index.ts | 1 + 7 files changed, 254 insertions(+) create mode 100644 src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx create mode 100644 src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx create mode 100644 src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx create mode 100644 src/modules/components/asset/assetDataListItem/assetDataListItemStructure/index.ts create mode 100644 src/modules/components/asset/assetDataListItem/index.ts create mode 100644 src/modules/components/asset/index.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index ca84d2d31..5060ba097 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - Implement `DaoDataListItem` module component +- Implement `AssetDataListItem` module component - Implement `StatePingAnimation` core component ## [1.0.20] - 2024-03-13 diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx new file mode 100644 index 000000000..989ab7ac9 --- /dev/null +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx @@ -0,0 +1,61 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { DataList } from '../../../../../core/components/dataList'; +import { AssetDataListItemStructure } from './assetDataListItemStructure'; + +const meta: Meta = { + title: 'Modules/Components/asset/AssetDataListItem/AssetDataListItem.Structure', + component: AssetDataListItemStructure, + tags: ['autodocs'], + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/file/P0GeJKqILL7UXvaqu5Jj7V/v1.1.0?type=design&node-id=3259-11363&mode=dev', + }, + }, +}; + +type Story = StoryObj; + +/** + * Default usage example of the DaoDataListItem component. + */ +export const Default: Story = { + args: { + logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', + tokenName: 'Ethereum', + amount: 420.69, + symbol: 'ETH', + USDAmount: 1230000, + changedAmount: 420.69, + changedPercentage: 0.05, + }, + render: (props) => ( + + + + + + ), +}; + +/** + * Usage of the DaoDataListItem without an image src and 0 changes. + */ +export const Fallback: Story = { + args: { + logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', + tokenName: 'Ethereum', + amount: 420.69, + symbol: 'ETH', + USDAmount: 1230000, + }, + render: (props) => ( + + + + + + ), +}; + +export default meta; diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx new file mode 100644 index 000000000..b55ff28f5 --- /dev/null +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx @@ -0,0 +1,78 @@ +import { render, screen } from '@testing-library/react'; +import { DataList } from '../../../../../core'; +import { AssetDataListItemStructure, type IAssetDataListItemStructureProps } from './assetDataListItemStructure'; + +describe(' component', () => { + const createTestComponent = (props?: Partial) => { + return ( + + + + + + ); + }; + + it('renders tokenName, symbol, and the logoSrc', () => { + const props = { + logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', + tokenName: 'Ethereum', + amount: 420.69, + symbol: 'ETH', + USDAmount: 1230000, + changedAmount: 420.69, + changedPercentage: 0.05, + }; + + render(createTestComponent(props)); + expect(screen.getByText(props.tokenName)).toBeInTheDocument(); + expect(screen.getByText(props.symbol)).toBeInTheDocument(); + }); + + it('handles zero changedAmount and changedPercentage as neutral', () => { + const props = { + logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', + tokenName: 'Ethereum', + amount: 420.69, + symbol: 'ETH', + USDAmount: 1230000, + changedAmount: 0, + changedPercentage: 0, + }; + + render(createTestComponent(props)); + expect(screen.getByText('$0.00')).toBeInTheDocument(); // Assuming component shows '0' for zero changedAmount + expect(screen.getByText('0%')).toBeInTheDocument(); // Assuming Tag component renders '0%' for zero changedPercentage + }); + + it('handle not passing changedAmount and changedPercentage', async () => { + const props = { + logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', + tokenName: 'Ethereum', + amount: 420.69, + symbol: 'ETH', + USDAmount: 1230000, + }; + + render(createTestComponent(props)); + expect(screen.getByText('0%')).toBeInTheDocument(); + const USDAmount = await screen.findByText(/1.23/); + expect(USDAmount).toHaveTextContent('$1.23M'); + }); + + it('handle not passing changedPercentage', async () => { + const props = { + logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', + tokenName: 'Ethereum', + amount: -420.69, + symbol: 'ETH', + USDAmount: 1230000, + changedAmount: 420.69, + changedPercentage: 0.05, + }; + + render(createTestComponent(props)); + const tagElement = await screen.findByText(/\+ 5%/); + expect(tagElement).toHaveTextContent('+ 5%'); + }); +}); diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx new file mode 100644 index 000000000..dc5ad5d44 --- /dev/null +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx @@ -0,0 +1,105 @@ +import classNames from 'classnames'; +import type React from 'react'; +import { Avatar, DataList, NumberFormat, Tag, formatterUtils, type IDataListItemProps } from '../../../../../core'; + +export interface IAssetDataListItemStructureProps extends IDataListItemProps { + /** + * The source of the logo for the token. + */ + logoSrc?: string; + /** + * The name of the Token. + */ + tokenName?: string; + /** + * The symbol of the Token. + */ + symbol?: string; + /** + * The amount of the Token. + */ + amount?: number | string; + /** + * The price of the Token. + */ + USDAmount?: number | string; + /** + * changed price amount (E.g. in last 24h). + */ + changedAmount?: number | string; + /** + * changed price amount ratio (E.g. in last 24h). + */ + changedPercentage?: number | string; +} + +export const AssetDataListItemStructure: React.FC = (props) => { + const { logoSrc, tokenName, amount, symbol, USDAmount, changedAmount, changedPercentage, ...otherProps } = props; + + const formattedChangedAmount = Number(Number(changedAmount).toFixed(2)); + const formattedChangedPercentage = Number(Number(changedPercentage).toFixed(2)); + + const sign = (value: number) => (value > 0 ? '+' : value < 0 ? '-' : ''); + const changedAmountSign = sign(formattedChangedAmount); + const changedPercentageSign = sign(formattedChangedPercentage); + + const changedAmountClasses = classNames( + 'text-sm font-normal leading-tight md:text-base', + { 'text-success-800': formattedChangedAmount > 0 }, + { 'text-neutral-500': formattedChangedAmount === 0 }, + { 'text-critical-800': formattedChangedAmount < 0 }, + ); + + return ( + +
+ +
+
+ {tokenName} +

+ + {formatterUtils.formatNumber(amount, { + format: NumberFormat.TOKEN_AMOUNT_SHORT, + fallback: '', + })}{' '} + + {symbol} +

+
+
+ + {formatterUtils.formatNumber(USDAmount, { + format: NumberFormat.FIAT_TOTAL_SHORT, + fallback: '-', + })} + +
+ + {changedAmountSign} + {formatterUtils.formatNumber(Math.abs(formattedChangedAmount || 0), { + format: NumberFormat.FIAT_TOTAL_SHORT, + })} + + 0 + ? 'success' + : formattedChangedPercentage < 0 + ? 'critical' + : 'neutral' + } + /> +
+
+
+
+
+ ); +}; diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/index.ts b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/index.ts new file mode 100644 index 000000000..85f31b135 --- /dev/null +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/index.ts @@ -0,0 +1,7 @@ +import { AssetDataListItemStructure } from './assetDataListItemStructure'; + +export const AssetDataListItem = { + Structure: AssetDataListItemStructure, +}; + +export type { IAssetDataListItemStructureProps } from './assetDataListItemStructure'; diff --git a/src/modules/components/asset/assetDataListItem/index.ts b/src/modules/components/asset/assetDataListItem/index.ts new file mode 100644 index 000000000..1d3893834 --- /dev/null +++ b/src/modules/components/asset/assetDataListItem/index.ts @@ -0,0 +1 @@ +export * from './assetDataListItemStructure'; \ No newline at end of file diff --git a/src/modules/components/asset/index.ts b/src/modules/components/asset/index.ts new file mode 100644 index 000000000..e64cc0259 --- /dev/null +++ b/src/modules/components/asset/index.ts @@ -0,0 +1 @@ +export * from './assetDataListItem'; From 234f6c185594cb09ce1d530749916e384e5f4028 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Fri, 15 Mar 2024 11:11:32 +0330 Subject: [PATCH 18/23] fix: comments --- .../assetDataListItemStructure.stories.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx index 989ab7ac9..6eab5a7c7 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx @@ -17,7 +17,7 @@ const meta: Meta = { type Story = StoryObj; /** - * Default usage example of the DaoDataListItem component. + * Default usage example of the AssetDataListItem component. */ export const Default: Story = { args: { @@ -39,7 +39,7 @@ export const Default: Story = { }; /** - * Usage of the DaoDataListItem without an image src and 0 changes. + * Usage of the AssetDataListItem without changedAmount and changedPercentage. */ export const Fallback: Story = { args: { From 10505a55836bedd3ffdb8f579bbb62842a654246 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 19 Mar 2024 11:29:11 +0330 Subject: [PATCH 19/23] fix: prettier --- src/modules/components/asset/assetDataListItem/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/components/asset/assetDataListItem/index.ts b/src/modules/components/asset/assetDataListItem/index.ts index 1d3893834..cff9dcf51 100644 --- a/src/modules/components/asset/assetDataListItem/index.ts +++ b/src/modules/components/asset/assetDataListItem/index.ts @@ -1 +1 @@ -export * from './assetDataListItemStructure'; \ No newline at end of file +export * from './assetDataListItemStructure'; From 7791714b3c875fe93bdab794b12223e86109d649 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 26 Mar 2024 12:03:58 +0330 Subject: [PATCH 20/23] resolve comments --- .../assetDataListItemStructure.stories.tsx | 17 ++-- .../assetDataListItemStructure.test.tsx | 31 +++----- .../assetDataListItemStructure.tsx | 79 +++++++++---------- .../assetDataListItemStructure/index.ts | 8 +- .../asset/assetDataListItem/index.ts | 8 +- .../daoDataListItemStructure/index.ts | 8 +- .../components/dao/daoDataListItem/index.ts | 8 +- src/modules/components/index.ts | 1 + .../member/memberDataListItem/index.ts | 8 +- .../memberDataListItemStructure/index.ts | 8 +- 10 files changed, 79 insertions(+), 97 deletions(-) diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx index 6eab5a7c7..9959796dd 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx @@ -1,15 +1,15 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { DataList } from '../../../../../core/components/dataList'; +import { DataList } from '../../../../../core'; import { AssetDataListItemStructure } from './assetDataListItemStructure'; const meta: Meta = { - title: 'Modules/Components/asset/AssetDataListItem/AssetDataListItem.Structure', + title: 'Modules/Components/Asset/AssetDataListItem/AssetDataListItem.Structure', component: AssetDataListItemStructure, tags: ['autodocs'], parameters: { design: { type: 'figma', - url: 'https://www.figma.com/file/P0GeJKqILL7UXvaqu5Jj7V/v1.1.0?type=design&node-id=3259-11363&mode=dev', + url: 'https://www.figma.com/file/P0GeJKqILL7UXvaqu5Jj7V/v1.1.0?type=design&node-id=8079-18352&mode=design&t=MR1awSDoExtPDiEd-4', }, }, }; @@ -22,12 +22,11 @@ type Story = StoryObj; export const Default: Story = { args: { logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', - tokenName: 'Ethereum', + name: 'Ethereum', amount: 420.69, symbol: 'ETH', - USDAmount: 1230000, - changedAmount: 420.69, - changedPercentage: 0.05, + fiatPrice: 3654.76, + priceChange: 15, }, render: (props) => ( @@ -44,10 +43,10 @@ export const Default: Story = { export const Fallback: Story = { args: { logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', - tokenName: 'Ethereum', + name: 'Ethereum', amount: 420.69, symbol: 'ETH', - USDAmount: 1230000, + fiatPrice: 3654.76, }, render: (props) => ( diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx index b55ff28f5..8bb925c07 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react'; import { DataList } from '../../../../../core'; import { AssetDataListItemStructure, type IAssetDataListItemStructureProps } from './assetDataListItemStructure'; -describe(' component', () => { +describe(' component', () => { const createTestComponent = (props?: Partial) => { return ( @@ -15,29 +15,18 @@ describe(' component', () => { it('renders tokenName, symbol, and the logoSrc', () => { const props = { - logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', - tokenName: 'Ethereum', - amount: 420.69, + name: 'Ethereum', symbol: 'ETH', - USDAmount: 1230000, - changedAmount: 420.69, - changedPercentage: 0.05, }; render(createTestComponent(props)); - expect(screen.getByText(props.tokenName)).toBeInTheDocument(); + expect(screen.getByText(props.name)).toBeInTheDocument(); expect(screen.getByText(props.symbol)).toBeInTheDocument(); }); - it('handles zero changedAmount and changedPercentage as neutral', () => { + it('handles zero priceChange as neutral', () => { const props = { - logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', - tokenName: 'Ethereum', - amount: 420.69, - symbol: 'ETH', - USDAmount: 1230000, - changedAmount: 0, - changedPercentage: 0, + priceChange: 0, }; render(createTestComponent(props)); @@ -48,10 +37,10 @@ describe(' component', () => { it('handle not passing changedAmount and changedPercentage', async () => { const props = { logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', - tokenName: 'Ethereum', + name: 'Ethereum', amount: 420.69, symbol: 'ETH', - USDAmount: 1230000, + fiatPrice: 3654.76, }; render(createTestComponent(props)); @@ -63,12 +52,10 @@ describe(' component', () => { it('handle not passing changedPercentage', async () => { const props = { logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', - tokenName: 'Ethereum', + name: 'Ethereum', amount: -420.69, symbol: 'ETH', - USDAmount: 1230000, - changedAmount: 420.69, - changedPercentage: 0.05, + fiatPrice: 3654.76, }; render(createTestComponent(props)); diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx index dc5ad5d44..93928df35 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx @@ -1,62 +1,60 @@ import classNames from 'classnames'; import type React from 'react'; +import { useMemo } from 'react'; import { Avatar, DataList, NumberFormat, Tag, formatterUtils, type IDataListItemProps } from '../../../../../core'; export interface IAssetDataListItemStructureProps extends IDataListItemProps { /** - * The source of the logo for the token. + * The logo source of the asset */ logoSrc?: string; /** - * The name of the Token. + * The name of the asset. */ - tokenName?: string; + name?: string; /** - * The symbol of the Token. + * The symbol of the asset. */ symbol?: string; /** - * The amount of the Token. + * The amount of the asset. */ amount?: number | string; /** - * The price of the Token. + * The fiat price of the asset. */ - USDAmount?: number | string; + fiatPrice?: number | string; /** - * changed price amount (E.g. in last 24h). + * the price change in percentage of the asset (E.g. in last 24h). */ - changedAmount?: number | string; - /** - * changed price amount ratio (E.g. in last 24h). - */ - changedPercentage?: number | string; + priceChange?: number; } export const AssetDataListItemStructure: React.FC = (props) => { - const { logoSrc, tokenName, amount, symbol, USDAmount, changedAmount, changedPercentage, ...otherProps } = props; + const { logoSrc, name, amount, symbol, fiatPrice, priceChange = 0, ...otherProps } = props; - const formattedChangedAmount = Number(Number(changedAmount).toFixed(2)); - const formattedChangedPercentage = Number(Number(changedPercentage).toFixed(2)); + const usdAmountChanged = useMemo(() => { + const usdAmount = (amount ? Number(amount) : 0) * (fiatPrice ? Number(fiatPrice) : 0); + const oldUsdAmount = (100 / (priceChange + 100)) * usdAmount; + return usdAmount - oldUsdAmount; + }, [amount, fiatPrice, priceChange]); const sign = (value: number) => (value > 0 ? '+' : value < 0 ? '-' : ''); - const changedAmountSign = sign(formattedChangedAmount); - const changedPercentageSign = sign(formattedChangedPercentage); const changedAmountClasses = classNames( 'text-sm font-normal leading-tight md:text-base', - { 'text-success-800': formattedChangedAmount > 0 }, - { 'text-neutral-500': formattedChangedAmount === 0 }, - { 'text-critical-800': formattedChangedAmount < 0 }, + { 'text-success-800': usdAmountChanged > 0 }, + { 'text-neutral-500': usdAmountChanged === 0 }, + { 'text-critical-800': usdAmountChanged < 0 }, ); return ( -
+
-
- {tokenName} +
+ {name}

{formatterUtils.formatNumber(amount, { @@ -64,37 +62,34 @@ export const AssetDataListItemStructure: React.FC - {symbol} + {symbol}

-
+
- {formatterUtils.formatNumber(USDAmount, { - format: NumberFormat.FIAT_TOTAL_SHORT, - fallback: '-', - })} + {formatterUtils.formatNumber( + (amount ? Number(amount) : 0) * (fiatPrice ? Number(fiatPrice) : 0), + { + format: NumberFormat.FIAT_TOTAL_SHORT, + fallback: '-', + }, + )} -
+
- {changedAmountSign} - {formatterUtils.formatNumber(Math.abs(formattedChangedAmount || 0), { + {sign(usdAmountChanged)} + {formatterUtils.formatNumber(Math.abs(usdAmountChanged), { format: NumberFormat.FIAT_TOTAL_SHORT, })} 0 - ? 'success' - : formattedChangedPercentage < 0 - ? 'critical' - : 'neutral' - } + variant={priceChange > 0 ? 'success' : priceChange < 0 ? 'critical' : 'neutral'} />
diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/index.ts b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/index.ts index 85f31b135..489e9785e 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/index.ts +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/index.ts @@ -1,7 +1 @@ -import { AssetDataListItemStructure } from './assetDataListItemStructure'; - -export const AssetDataListItem = { - Structure: AssetDataListItemStructure, -}; - -export type { IAssetDataListItemStructureProps } from './assetDataListItemStructure'; +export { AssetDataListItemStructure, type IAssetDataListItemStructureProps } from './assetDataListItemStructure'; diff --git a/src/modules/components/asset/assetDataListItem/index.ts b/src/modules/components/asset/assetDataListItem/index.ts index cff9dcf51..85f31b135 100644 --- a/src/modules/components/asset/assetDataListItem/index.ts +++ b/src/modules/components/asset/assetDataListItem/index.ts @@ -1 +1,7 @@ -export * from './assetDataListItemStructure'; +import { AssetDataListItemStructure } from './assetDataListItemStructure'; + +export const AssetDataListItem = { + Structure: AssetDataListItemStructure, +}; + +export type { IAssetDataListItemStructureProps } from './assetDataListItemStructure'; diff --git a/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/index.ts b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/index.ts index 9de8fc4b7..b2858938d 100644 --- a/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/index.ts +++ b/src/modules/components/dao/daoDataListItem/daoDataListItemStructure/index.ts @@ -1,7 +1 @@ -import { DaoDataListItemStructure } from './daoDataListItemStructure'; - -export const DaoDataListItem = { - Structure: DaoDataListItemStructure, -}; - -export type { IDaoDataListItemStructureProps } from './daoDataListItemStructure'; +export { DaoDataListItemStructure, type IDaoDataListItemStructureProps } from './daoDataListItemStructure'; diff --git a/src/modules/components/dao/daoDataListItem/index.ts b/src/modules/components/dao/daoDataListItem/index.ts index b6fd5ed01..9de8fc4b7 100644 --- a/src/modules/components/dao/daoDataListItem/index.ts +++ b/src/modules/components/dao/daoDataListItem/index.ts @@ -1 +1,7 @@ -export * from './daoDataListItemStructure'; +import { DaoDataListItemStructure } from './daoDataListItemStructure'; + +export const DaoDataListItem = { + Structure: DaoDataListItemStructure, +}; + +export type { IDaoDataListItemStructureProps } from './daoDataListItemStructure'; diff --git a/src/modules/components/index.ts b/src/modules/components/index.ts index 0da2bb7ef..57d4cb8d7 100644 --- a/src/modules/components/index.ts +++ b/src/modules/components/index.ts @@ -1,3 +1,4 @@ +export * from './asset'; export * from './dao'; export * from './member'; export * from './odsModulesProvider'; diff --git a/src/modules/components/member/memberDataListItem/index.ts b/src/modules/components/member/memberDataListItem/index.ts index 3ebb05790..8bdc5bc5c 100644 --- a/src/modules/components/member/memberDataListItem/index.ts +++ b/src/modules/components/member/memberDataListItem/index.ts @@ -1 +1,7 @@ -export * from './memberDataListItemStructure'; +import { MemberDataListItemStructure } from './memberDataListItemStructure'; + +export const MemberDataListItem = { + Structure: MemberDataListItemStructure, +}; + +export type { IMemberDataListItemProps } from './memberDataListItemStructure'; diff --git a/src/modules/components/member/memberDataListItem/memberDataListItemStructure/index.ts b/src/modules/components/member/memberDataListItem/memberDataListItemStructure/index.ts index 8bdc5bc5c..22ef3ce48 100644 --- a/src/modules/components/member/memberDataListItem/memberDataListItemStructure/index.ts +++ b/src/modules/components/member/memberDataListItem/memberDataListItemStructure/index.ts @@ -1,7 +1 @@ -import { MemberDataListItemStructure } from './memberDataListItemStructure'; - -export const MemberDataListItem = { - Structure: MemberDataListItemStructure, -}; - -export type { IMemberDataListItemProps } from './memberDataListItemStructure'; +export { MemberDataListItemStructure, type IMemberDataListItemProps } from './memberDataListItemStructure'; From c805883c767fb7798c26bbb5641bf726dd470f6e Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 26 Mar 2024 12:27:58 +0330 Subject: [PATCH 21/23] chore: update tests --- .../assetDataListItemStructure.stories.tsx | 7 ++-- .../assetDataListItemStructure.test.tsx | 32 +++++++++---------- .../assetDataListItemStructure.tsx | 2 +- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx index 9959796dd..18d333237 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx @@ -42,11 +42,8 @@ export const Default: Story = { */ export const Fallback: Story = { args: { - logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', - name: 'Ethereum', - amount: 420.69, - symbol: 'ETH', - fiatPrice: 3654.76, + amount: 0, + priceChange: 0, }, render: (props) => ( diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx index 8bb925c07..c53512a1d 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx @@ -24,42 +24,40 @@ describe(' component', () => { expect(screen.getByText(props.symbol)).toBeInTheDocument(); }); - it('handles zero priceChange as neutral', () => { + it('renders amount, fiat price', async () => { const props = { - priceChange: 0, + amount: 420.69, + fiatPrice: 3654.76, }; render(createTestComponent(props)); - expect(screen.getByText('$0.00')).toBeInTheDocument(); // Assuming component shows '0' for zero changedAmount - expect(screen.getByText('0%')).toBeInTheDocument(); // Assuming Tag component renders '0%' for zero changedPercentage + const USDAmount = await screen.findByText(/1.54/); + expect(USDAmount).toHaveTextContent('$1.54M'); + expect(screen.getByText(props.amount)).toBeInTheDocument(); }); - it('handle not passing changedAmount and changedPercentage', async () => { + it('handles zero priceChange as neutral', () => { const props = { - logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', - name: 'Ethereum', - amount: 420.69, - symbol: 'ETH', - fiatPrice: 3654.76, + amount: 0, + priceChange: 0, }; render(createTestComponent(props)); - expect(screen.getByText('0%')).toBeInTheDocument(); - const USDAmount = await screen.findByText(/1.23/); - expect(USDAmount).toHaveTextContent('$1.23M'); + const elements = screen.queryAllByText('$0.00'); + expect(elements.length).toBeGreaterThan(0); // assuming both asset price and changed price amount are 0.00 + expect(screen.getByText('0%')).toBeInTheDocument(); // Assuming Tag component renders '0%' for zero changedPercentage }); - it('handle not passing changedPercentage', async () => { + it('handle not passing priceChange', async () => { const props = { logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', name: 'Ethereum', - amount: -420.69, + amount: 420.69, symbol: 'ETH', fiatPrice: 3654.76, }; render(createTestComponent(props)); - const tagElement = await screen.findByText(/\+ 5%/); - expect(tagElement).toHaveTextContent('+ 5%'); + expect(screen.getByText('0%')).toBeInTheDocument(); }); }); diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx index 93928df35..51815e779 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx @@ -31,7 +31,7 @@ export interface IAssetDataListItemStructureProps extends IDataListItemProps { } export const AssetDataListItemStructure: React.FC = (props) => { - const { logoSrc, name, amount, symbol, fiatPrice, priceChange = 0, ...otherProps } = props; + const { logoSrc, name = '-', amount = 0, symbol, fiatPrice = 0, priceChange = 0, ...otherProps } = props; const usdAmountChanged = useMemo(() => { const usdAmount = (amount ? Number(amount) : 0) * (fiatPrice ? Number(fiatPrice) : 0); From 6b41b2261da7c3d235dccbd07a1381e1999a971d Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Tue, 26 Mar 2024 13:20:30 +0330 Subject: [PATCH 22/23] fix: remove logoSrc separator --- .../assetDataListItemStructure.test.tsx | 2 +- .../assetDataListItemStructure/assetDataListItemStructure.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx index c53512a1d..e64e39247 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx @@ -45,7 +45,7 @@ describe(' component', () => { render(createTestComponent(props)); const elements = screen.queryAllByText('$0.00'); expect(elements.length).toBeGreaterThan(0); // assuming both asset price and changed price amount are 0.00 - expect(screen.getByText('0%')).toBeInTheDocument(); // Assuming Tag component renders '0%' for zero changedPercentage + expect(screen.getByText('0%')).toBeInTheDocument(); // Assuming Tag component renders '0%' for zero priceChange }); it('handle not passing priceChange', async () => { diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx index 51815e779..18ff12a95 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx @@ -51,7 +51,7 @@ export const AssetDataListItemStructure: React.FC
- +
{name} From 4dd40e1329969713f12f3b7df6500514799244c3 Mon Sep 17 00:00:00 2001 From: sepehr sanaee Date: Wed, 27 Mar 2024 12:33:45 +0330 Subject: [PATCH 23/23] resolve round 2 --- .../assetDataListItemStructure.stories.tsx | 5 +- .../assetDataListItemStructure.test.tsx | 25 +++-- .../assetDataListItemStructure.tsx | 99 +++++++++++-------- 3 files changed, 77 insertions(+), 52 deletions(-) diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx index 18d333237..75d37c1ca 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.stories.tsx @@ -42,8 +42,9 @@ export const Default: Story = { */ export const Fallback: Story = { args: { - amount: 0, - priceChange: 0, + name: 'Ethereum', + amount: 420.69, + symbol: 'ETH', }, render: (props) => ( diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx index e64e39247..cf7f0dff9 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.test.tsx @@ -3,20 +3,28 @@ import { DataList } from '../../../../../core'; import { AssetDataListItemStructure, type IAssetDataListItemStructureProps } from './assetDataListItemStructure'; describe(' component', () => { - const createTestComponent = (props?: Partial) => { + const createTestComponent = (props: Partial = {}) => { + const completeProps: IAssetDataListItemStructureProps = { + name: 'Ethereum', + symbol: 'ETH', + amount: 420.69, + ...props, + }; + return ( - + ); }; - it('renders tokenName, symbol, and the logoSrc', () => { + it('renders tokenName and symbol', () => { const props = { name: 'Ethereum', symbol: 'ETH', + amount: 420.69, }; render(createTestComponent(props)); @@ -26,6 +34,8 @@ describe(' component', () => { it('renders amount, fiat price', async () => { const props = { + name: 'Ethereum', + symbol: 'ETH', amount: 420.69, fiatPrice: 3654.76, }; @@ -36,21 +46,20 @@ describe(' component', () => { expect(screen.getByText(props.amount)).toBeInTheDocument(); }); - it('handles zero priceChange as neutral', () => { + it('handles not passing fiat price', () => { const props = { + name: 'Ethereum', + symbol: 'ETH', amount: 0, priceChange: 0, }; render(createTestComponent(props)); - const elements = screen.queryAllByText('$0.00'); - expect(elements.length).toBeGreaterThan(0); // assuming both asset price and changed price amount are 0.00 - expect(screen.getByText('0%')).toBeInTheDocument(); // Assuming Tag component renders '0%' for zero priceChange + expect(screen.getByText('Unknown')).toBeInTheDocument(); // Assuming Tag component renders '0%' for zero priceChange }); it('handle not passing priceChange', async () => { const props = { - logoSrc: 'https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628', name: 'Ethereum', amount: 420.69, symbol: 'ETH', diff --git a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx index 18ff12a95..216ed69db 100644 --- a/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx +++ b/src/modules/components/asset/assetDataListItem/assetDataListItemStructure/assetDataListItemStructure.tsx @@ -4,36 +4,40 @@ import { useMemo } from 'react'; import { Avatar, DataList, NumberFormat, Tag, formatterUtils, type IDataListItemProps } from '../../../../../core'; export interface IAssetDataListItemStructureProps extends IDataListItemProps { - /** - * The logo source of the asset - */ - logoSrc?: string; /** * The name of the asset. */ - name?: string; + name: string; /** * The symbol of the asset. */ - symbol?: string; + symbol: string; /** * The amount of the asset. */ - amount?: number | string; + amount: number | string; + /** + * The logo source of the asset + */ + logoSrc?: string; /** * The fiat price of the asset. */ fiatPrice?: number | string; /** * the price change in percentage of the asset (E.g. in last 24h). + * @default 0 */ priceChange?: number; } export const AssetDataListItemStructure: React.FC = (props) => { - const { logoSrc, name = '-', amount = 0, symbol, fiatPrice = 0, priceChange = 0, ...otherProps } = props; + const { logoSrc, name, amount, symbol, fiatPrice, priceChange = 0, ...otherProps } = props; const usdAmountChanged = useMemo(() => { + if (!fiatPrice || !priceChange) { + return 0; + } const usdAmount = (amount ? Number(amount) : 0) * (fiatPrice ? Number(fiatPrice) : 0); const oldUsdAmount = (100 / (priceChange + 100)) * usdAmount; return usdAmount - oldUsdAmount; @@ -48,50 +52,61 @@ export const AssetDataListItemStructure: React.FC
- +
+ +
{name}

- - {formatterUtils.formatNumber(amount, { - format: NumberFormat.TOKEN_AMOUNT_SHORT, - fallback: '', - })}{' '} - + {`${formattedAmount}`} {symbol}

-
- - {formatterUtils.formatNumber( - (amount ? Number(amount) : 0) * (fiatPrice ? Number(fiatPrice) : 0), - { - format: NumberFormat.FIAT_TOTAL_SHORT, - fallback: '-', - }, - )} - -
- - {sign(usdAmountChanged)} - {formatterUtils.formatNumber(Math.abs(usdAmountChanged), { - format: NumberFormat.FIAT_TOTAL_SHORT, - })} - - 0 ? 'success' : priceChange < 0 ? 'critical' : 'neutral'} - /> -
+
+ {fiatPrice ? ( + <> + + {formattedPrice} + +
+ + {sign(usdAmountChanged)} + {formattedPriceChanged} + + 0 ? 'success' : priceChange < 0 ? 'critical' : 'neutral'} + /> +
+ + ) : ( + Unknown + )}