From 0cc5caa809e05afbee99b431151094d74807bedd Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 6 Mar 2024 14:57:36 +0100 Subject: [PATCH 1/8] migrate ReportActionItemImages.stories.js to TypeScript --- .../ReportActionItemImages.tsx | 1 + ....js => ReportActionItemImages.stories.tsx} | 34 +++++++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) rename src/stories/{ReportActionItemImages.stories.js => ReportActionItemImages.stories.tsx} (84%) diff --git a/src/components/ReportActionItem/ReportActionItemImages.tsx b/src/components/ReportActionItem/ReportActionItemImages.tsx index 74ecc1a2adbd..ffc12957dcb4 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.tsx +++ b/src/components/ReportActionItem/ReportActionItemImages.tsx @@ -109,3 +109,4 @@ function ReportActionItemImages({images, size, total, isHovered = false}: Report ReportActionItemImages.displayName = 'ReportActionItemImages'; export default ReportActionItemImages; +export type {ReportActionItemImagesProps}; diff --git a/src/stories/ReportActionItemImages.stories.js b/src/stories/ReportActionItemImages.stories.tsx similarity index 84% rename from src/stories/ReportActionItemImages.stories.js rename to src/stories/ReportActionItemImages.stories.tsx index fe86f50f7e34..810b3e18aaf3 100644 --- a/src/stories/ReportActionItemImages.stories.js +++ b/src/stories/ReportActionItemImages.stories.tsx @@ -1,18 +1,22 @@ +import type {ComponentMeta, ComponentStory} from '@storybook/react'; import React from 'react'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; +import type {ReportActionItemImagesProps} from '@components/ReportActionItem/ReportActionItemImages'; import ReportActionItemImages from '@components/ReportActionItem/ReportActionItemImages'; +type ReportActionItemImagesStory = ComponentStory; + /** * We use the Component Story Format for writing stories. Follow the docs here: * * https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format */ -const story = { +const story: ComponentMeta = { title: 'Components/ReportActionItemImages', component: ReportActionItemImages, }; -function Template(args) { +function Template(props: ReportActionItemImagesProps) { return ( ( )} @@ -31,14 +35,14 @@ function Template(args) { // Arguments can be passed to the component by binding // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args -const Default = Template.bind({}); +const Default: ReportActionItemImagesStory = Template.bind({}); Default.args = { images: [{image: 'https://c02.purpledshub.com/uploads/sites/41/2021/05/sleeping-cat-27126ee.jpg', thumbnail: ''}], size: 1, total: 1, }; -const DisplayEReceipt = Template.bind({}); +const DisplayEReceipt: ReportActionItemImagesStory = Template.bind({}); DisplayEReceipt.args = { images: [ { @@ -53,6 +57,8 @@ DisplayEReceipt.args = { mccGroup: 'Commuter', created: '2023-07-24 13:46:20', hasEReceipt: true, + comment: {}, + reportID: 'REPORT_1', }, }, ], @@ -60,7 +66,7 @@ DisplayEReceipt.args = { total: 1, }; -const DisplayMultipleEReceipts = Template.bind({}); +const DisplayMultipleEReceipts: ReportActionItemImagesStory = Template.bind({}); DisplayMultipleEReceipts.args = { images: [ { @@ -75,6 +81,8 @@ DisplayMultipleEReceipts.args = { mccGroup: 'Commuter', created: '2023-07-24 13:46:20', hasEReceipt: true, + comment: {}, + reportID: 'REPORT_1', }, }, { @@ -89,6 +97,8 @@ DisplayMultipleEReceipts.args = { mccGroup: 'Goods', created: '2022-03-21 13:46:20', hasEReceipt: true, + comment: {}, + reportID: 'REPORT_2', }, }, { @@ -103,6 +113,8 @@ DisplayMultipleEReceipts.args = { mccGroup: 'Airlines', created: '2023-07-24 13:46:20', hasEReceipt: true, + comment: {}, + reportID: 'REPORT_3', }, }, ], @@ -110,7 +122,7 @@ DisplayMultipleEReceipts.args = { total: 3, }; -const TwoImages = Template.bind({}); +const TwoImages: ReportActionItemImagesStory = Template.bind({}); TwoImages.args = { images: [ { @@ -126,7 +138,7 @@ TwoImages.args = { total: 2, }; -const ThreeImages = Template.bind({}); +const ThreeImages: ReportActionItemImagesStory = Template.bind({}); ThreeImages.args = { images: [ { @@ -146,7 +158,7 @@ ThreeImages.args = { total: 3, }; -const FourImages = Template.bind({}); +const FourImages: ReportActionItemImagesStory = Template.bind({}); FourImages.args = { images: [ { @@ -170,7 +182,7 @@ FourImages.args = { total: 4, }; -const ThreePlusTwoImages = Template.bind({}); +const ThreePlusTwoImages: ReportActionItemImagesStory = Template.bind({}); ThreePlusTwoImages.args = { images: [ { @@ -190,7 +202,7 @@ ThreePlusTwoImages.args = { total: 5, }; -const ThreePlusTenImages = Template.bind({}); +const ThreePlusTenImages: ReportActionItemImagesStory = Template.bind({}); ThreePlusTenImages.args = { images: [ { From 8a0020de5e7882597beedf194609aa824071d4d9 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 6 Mar 2024 15:22:29 +0100 Subject: [PATCH 2/8] migrate EReceiptThumbnail.stories.js to TypeScript --- src/components/EReceiptThumbnail.tsx | 1 + ...tories.js => EReceiptThumbail.stories.tsx} | 48 ++++++++++--------- 2 files changed, 27 insertions(+), 22 deletions(-) rename src/stories/{EReceiptThumbail.stories.js => EReceiptThumbail.stories.tsx} (62%) diff --git a/src/components/EReceiptThumbnail.tsx b/src/components/EReceiptThumbnail.tsx index f5f9b5fc5f06..023dcc16e696 100644 --- a/src/components/EReceiptThumbnail.tsx +++ b/src/components/EReceiptThumbnail.tsx @@ -114,3 +114,4 @@ export default withOnyx({ key: ({transactionID}) => `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, }, })(EReceiptThumbnail); +export type {EReceiptThumbnailProps, EReceiptThumbnailOnyxProps}; diff --git a/src/stories/EReceiptThumbail.stories.js b/src/stories/EReceiptThumbail.stories.tsx similarity index 62% rename from src/stories/EReceiptThumbail.stories.js rename to src/stories/EReceiptThumbail.stories.tsx index bea32fb0213c..1feb811e57c8 100644 --- a/src/stories/EReceiptThumbail.stories.js +++ b/src/stories/EReceiptThumbail.stories.tsx @@ -1,52 +1,56 @@ /* eslint-disable react/jsx-props-no-spreading */ +import type {ComponentMeta, ComponentStory} from '@storybook/react'; import React from 'react'; import {View} from 'react-native'; +import type {EReceiptThumbnailOnyxProps, EReceiptThumbnailProps} from '@components/EReceiptThumbnail'; import EReceiptThumbnail from '@components/EReceiptThumbnail'; +type EReceiptThumbnailStory = ComponentStory; + /** * We use the Component Story Format for writing stories. Follow the docs here: * * https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format */ -const story = { +const story: ComponentMeta = { title: 'Components/EReceiptThumbnail', component: EReceiptThumbnail, }; -function Template(args) { +function Template(props: Omit) { return ( @@ -54,77 +58,77 @@ function Template(args) { ); } -const Default = Template.bind({}); +const Default: EReceiptThumbnailStory = Template.bind({}); Default.args = { transactionID: 'FAKE_1', }; -const Airlines = Template.bind({}); +const Airlines: EReceiptThumbnailStory = Template.bind({}); Airlines.args = { transactionID: 'FAKE_2', }; -const Commuter = Template.bind({}); +const Commuter: EReceiptThumbnailStory = Template.bind({}); Commuter.args = { transactionID: 'FAKE_3', }; -const Gas = Template.bind({}); +const Gas: EReceiptThumbnailStory = Template.bind({}); Gas.args = { transactionID: 'FAKE_4', }; -const Goods = Template.bind({}); +const Goods: EReceiptThumbnailStory = Template.bind({}); Goods.args = { transactionID: 'FAKE_5', }; -const Groceries = Template.bind({}); +const Groceries: EReceiptThumbnailStory = Template.bind({}); Groceries.args = { transactionID: 'FAKE_6', }; -const Hotel = Template.bind({}); +const Hotel: EReceiptThumbnailStory = Template.bind({}); Hotel.args = { transactionID: 'FAKE_7', }; -const Mail = Template.bind({}); +const Mail: EReceiptThumbnailStory = Template.bind({}); Mail.args = { transactionID: 'FAKE_8', }; -const Meals = Template.bind({}); +const Meals: EReceiptThumbnailStory = Template.bind({}); Meals.args = { transactionID: 'FAKE_9', }; -const Rental = Template.bind({}); +const Rental: EReceiptThumbnailStory = Template.bind({}); Rental.args = { transactionID: 'FAKE_10', }; -const Services = Template.bind({}); +const Services: EReceiptThumbnailStory = Template.bind({}); Services.args = { transactionID: 'FAKE_11', }; -const Taxi = Template.bind({}); +const Taxi: EReceiptThumbnailStory = Template.bind({}); Taxi.args = { transactionID: 'FAKE_12', }; -const Miscellaneous = Template.bind({}); +const Miscellaneous: EReceiptThumbnailStory = Template.bind({}); Miscellaneous.args = { transactionID: 'FAKE_13', }; -const Utilities = Template.bind({}); +const Utilities: EReceiptThumbnailStory = Template.bind({}); Utilities.args = { transactionID: 'FAKE_14', }; -const invalidMCC = Template.bind({}); +const invalidMCC: EReceiptThumbnailStory = Template.bind({}); invalidMCC.args = { transactionID: 'FAKE_15', }; From dd08632575858f828fceb2c9c10e4b54b75ca22f Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 7 Mar 2024 10:42:47 +0100 Subject: [PATCH 3/8] migrate EReceipt.stories.js to TypeScript --- src/components/EReceipt.tsx | 1 + ...eceipt.stories.js => EReceipt.stories.tsx} | 48 +++++++++++-------- 2 files changed, 29 insertions(+), 20 deletions(-) rename src/stories/{EReceipt.stories.js => EReceipt.stories.tsx} (81%) diff --git a/src/components/EReceipt.tsx b/src/components/EReceipt.tsx index 183d88ba1c6a..40f5d242d005 100644 --- a/src/components/EReceipt.tsx +++ b/src/components/EReceipt.tsx @@ -105,3 +105,4 @@ export default withOnyx({ key: ({transactionID}) => `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, }, })(EReceipt); +export type {EReceiptProps, EReceiptOnyxProps}; diff --git a/src/stories/EReceipt.stories.js b/src/stories/EReceipt.stories.tsx similarity index 81% rename from src/stories/EReceipt.stories.js rename to src/stories/EReceipt.stories.tsx index d4f2b58cb213..55a4cc6cb9b4 100644 --- a/src/stories/EReceipt.stories.js +++ b/src/stories/EReceipt.stories.tsx @@ -1,8 +1,16 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + /* eslint-disable rulesdir/prefer-actions-set-data */ +import type {ComponentMeta, ComponentStory} from '@storybook/react'; import React from 'react'; +import type {NullishDeep} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; +import type {EReceiptOnyxProps, EReceiptProps} from '@components/EReceipt'; import EReceipt from '@components/EReceipt'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {Transaction} from '@src/types/onyx'; + +type EReceiptStory = ComponentStory; const transactionData = { [`${ONYXKEYS.COLLECTION.TRANSACTION}FAKE_1`]: { @@ -146,7 +154,7 @@ const transactionData = { created: '2023-01-11 13:46:20', hasEReceipt: true, }, -}; +} as Record<`${typeof ONYXKEYS.COLLECTION.TRANSACTION}${string}`, NullishDeep>; Onyx.mergeCollection(ONYXKEYS.COLLECTION.TRANSACTION, transactionData); Onyx.merge('cardList', { @@ -159,92 +167,92 @@ Onyx.merge('cardList', { * * https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format */ -const story = { +const story: ComponentMeta = { title: 'Components/EReceipt', component: EReceipt, }; -function Template(args) { +function Template(props: Omit) { // eslint-disable-next-line react/jsx-props-no-spreading - return ; + return ; } -const Default = Template.bind({}); +const Default: EReceiptStory = Template.bind({}); Default.args = { transactionID: 'FAKE_1', }; -const Airlines = Template.bind({}); +const Airlines: EReceiptStory = Template.bind({}); Airlines.args = { transactionID: 'FAKE_2', }; -const Commuter = Template.bind({}); +const Commuter: EReceiptStory = Template.bind({}); Commuter.args = { transactionID: 'FAKE_3', }; -const Gas = Template.bind({}); +const Gas: EReceiptStory = Template.bind({}); Gas.args = { transactionID: 'FAKE_4', }; -const Goods = Template.bind({}); +const Goods: EReceiptStory = Template.bind({}); Goods.args = { transactionID: 'FAKE_5', }; -const Groceries = Template.bind({}); +const Groceries: EReceiptStory = Template.bind({}); Groceries.args = { transactionID: 'FAKE_6', }; -const Hotel = Template.bind({}); +const Hotel: EReceiptStory = Template.bind({}); Hotel.args = { transactionID: 'FAKE_7', }; -const Mail = Template.bind({}); +const Mail: EReceiptStory = Template.bind({}); Mail.args = { transactionID: 'FAKE_8', }; -const Meals = Template.bind({}); +const Meals: EReceiptStory = Template.bind({}); Meals.args = { transactionID: 'FAKE_9', }; -const Rental = Template.bind({}); +const Rental: EReceiptStory = Template.bind({}); Rental.args = { transactionID: 'FAKE_10', }; -const Services = Template.bind({}); +const Services: EReceiptStory = Template.bind({}); Services.args = { transactionID: 'FAKE_11', }; -const Taxi = Template.bind({}); +const Taxi: EReceiptStory = Template.bind({}); Taxi.args = { transactionID: 'FAKE_12', }; -const Miscellaneous = Template.bind({}); +const Miscellaneous: EReceiptStory = Template.bind({}); Miscellaneous.args = { transactionID: 'FAKE_13', }; -const Utilities = Template.bind({}); +const Utilities: EReceiptStory = Template.bind({}); Utilities.args = { transactionID: 'FAKE_14', }; -const invalidMCC = Template.bind({}); +const invalidMCC: EReceiptStory = Template.bind({}); invalidMCC.args = { transactionID: 'FAKE_15', }; -const veryLong = Template.bind({}); +const veryLong: EReceiptStory = Template.bind({}); veryLong.args = { transactionID: 'FAKE_16', }; From 77eafb33394ef26c7b0728e34d1cc9c6cfadbd75 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 7 Mar 2024 13:11:54 +0100 Subject: [PATCH 4/8] start migrating SelectionList.stories.js to TypeScript --- ...t.stories.js => SelectionList.stories.tsx} | 122 +++++++++--------- 1 file changed, 61 insertions(+), 61 deletions(-) rename src/stories/{SelectionList.stories.js => SelectionList.stories.tsx} (69%) diff --git a/src/stories/SelectionList.stories.js b/src/stories/SelectionList.stories.tsx similarity index 69% rename from src/stories/SelectionList.stories.js rename to src/stories/SelectionList.stories.tsx index 6c289097552b..17eb538437ec 100644 --- a/src/stories/SelectionList.stories.js +++ b/src/stories/SelectionList.stories.tsx @@ -1,18 +1,19 @@ +import type {ComponentMeta} from '@storybook/react'; import React, {useMemo, useState} from 'react'; -import _ from 'underscore'; import Badge from '@components/Badge'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; // eslint-disable-next-line no-restricted-imports import {defaultStyles} from '@styles/index'; import CONST from '@src/CONST'; +import type { BaseSelectionListProps, ListItem } from '@components/SelectionList/types'; /** * We use the Component Story Format for writing stories. Follow the docs here: * * https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format */ -const story = { +const story: ComponentMeta = { title: 'Components/SelectionList', component: SelectionList, }; @@ -62,24 +63,24 @@ const SECTIONS = [ }, ]; -function Default(args) { +function Default(props: BaseSelectionListProps) { const [selectedIndex, setSelectedIndex] = useState(1); - const sections = _.map(args.sections, (section) => { - const data = _.map(section.data, (item, index) => { - const isSelected = selectedIndex === index + section.indexOffset; + const sections = props.sections.map((section) => { + const data = section.data.map((item, index) => { + const isSelected = selectedIndex === index + (section?.indexOffset ?? 0); return {...item, isSelected}; }); return {...section, data}; }); - const onSelectRow = (item) => { - _.forEach(sections, (section) => { - const newSelectedIndex = _.findIndex(section.data, (option) => option.keyForList === item.keyForList); + const onSelectRow = (item: ListItem) => { + sections.forEach((section) => { + const newSelectedIndex = section.data.findIndex((option) => option.keyForList === item.keyForList); if (newSelectedIndex >= 0) { - setSelectedIndex(newSelectedIndex + section.indexOffset); + setSelectedIndex(newSelectedIndex + (section?.indexOffset ?? 0)); } }); }; @@ -87,7 +88,7 @@ function Default(args) { return ( ) { const [searchText, setSearchText] = useState(''); const [selectedIndex, setSelectedIndex] = useState(1); - const sections = _.map(args.sections, (section) => { - const data = _.reduce( - section.data, + const sections = props.sections.map((section) => { + const data = section.data.reduce( (memo, item, index) => { if (!item.text.toLowerCase().includes(searchText.trim().toLowerCase())) { return memo; } - const isSelected = selectedIndex === index + section.indexOffset; + const isSelected = selectedIndex === index + (section?.indexOffset ?? 0); memo.push({...item, isSelected}); return memo; }, @@ -123,12 +123,12 @@ function WithTextInput(args) { return {...section, data}; }); - const onSelectRow = (item) => { - _.forEach(sections, (section) => { - const newSelectedIndex = _.findIndex(section.data, (option) => option.keyForList === item.keyForList); + const onSelectRow = (item: ListItem) => { + sections.forEach((section) => { + const newSelectedIndex = section.data.findIndex((option) => option.keyForList === item.keyForList); if (newSelectedIndex >= 0) { - setSelectedIndex(newSelectedIndex + section.indexOffset); + setSelectedIndex(newSelectedIndex + (section?.indexOffset ?? 0)); } }); }; @@ -136,7 +136,7 @@ function WithTextInput(args) { return ( {}, }; -function WithHeaderMessage(props) { +function WithHeaderMessage(props: BaseSelectionListProps) { return ( ) { const [selectedIndex, setSelectedIndex] = useState(1); - const sections = _.map(args.sections, (section) => { - const data = _.map(section.data, (item, index) => { - const isSelected = selectedIndex === index + section.indexOffset; + const sections = props.sections.map((section) => { + const data = section.data.map((item, index) => { + const isSelected = selectedIndex === index + (section?.indexOffset ?? 0); return { ...item, @@ -189,19 +189,19 @@ function WithAlternateText(args) { return {...section, data}; }); - const onSelectRow = (item) => { - _.forEach(sections, (section) => { - const newSelectedIndex = _.findIndex(section.data, (option) => option.keyForList === item.keyForList); + const onSelectRow = (item: ListItem) => { + sections.forEach((section) => { + const newSelectedIndex = section.data.findIndex((option) => option.keyForList === item.keyForList); if (newSelectedIndex >= 0) { - setSelectedIndex(newSelectedIndex + section.indexOffset); + setSelectedIndex(newSelectedIndex + (section?.indexOffset ?? 0)); } }); }; return ( @@ -212,17 +212,17 @@ WithAlternateText.args = { ...Default.args, }; -function MultipleSelection(args) { +function MultipleSelection(props: BaseSelectionListProps) { const [selectedIds, setSelectedIds] = useState(['option-1', 'option-2']); const memo = useMemo(() => { - const allIds = []; + const allIds: string [] = []; - const sections = _.map(args.sections, (section) => { - const data = _.map(section.data, (item, index) => { + const sections = props.sections.map((section) => { + const data = section.data.map((item, index) => { allIds.push(item.keyForList); - const isSelected = _.contains(selectedIds, item.keyForList); - const isAdmin = index + section.indexOffset === 0; + const isSelected = selectedIds.includes(item.keyForList); + const isAdmin = index + (section?.indexOffset ?? 0) === 0; return { ...item, @@ -244,10 +244,10 @@ function MultipleSelection(args) { }); return {sections, allIds}; - }, [args.sections, selectedIds]); + }, [props.sections, selectedIds]); - const onSelectRow = (item) => { - const newSelectedIds = _.contains(selectedIds, item.keyForList) ? _.without(selectedIds, item.keyForList) : [...selectedIds, item.keyForList]; + const onSelectRow = (item: ListItem) => { + const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((i) => i !== item.keyForList) : [...selectedIds, item.keyForList]; setSelectedIds(newSelectedIds); }; @@ -262,7 +262,7 @@ function MultipleSelection(args) { return ( {}, }; -function WithSectionHeader(args) { +function WithSectionHeader(props: BaseSelectionListProps) { const [selectedIds, setSelectedIds] = useState(['option-1', 'option-2']); const memo = useMemo(() => { - const allIds = []; + const allIds: string[] = []; - const sections = _.map(args.sections, (section, sectionIndex) => { - const data = _.map(section.data, (item, itemIndex) => { + const sections = props.sections.map((section, sectionIndex) => { + const data = section.data.map((item, itemIndex) => { allIds.push(item.keyForList); - const isSelected = _.contains(selectedIds, item.keyForList); - const isAdmin = itemIndex + section.indexOffset === 0; + const isSelected = selectedIds.includes(item.keyForList); + const isAdmin = itemIndex + (section?.indexOffset ?? 0) === 0; return { ...item, @@ -309,10 +309,10 @@ function WithSectionHeader(args) { }); return {sections, allIds}; - }, [args.sections, selectedIds]); + }, [props.sections, selectedIds]); - const onSelectRow = (item) => { - const newSelectedIds = _.contains(selectedIds, item.keyForList) ? _.without(selectedIds, item.keyForList) : [...selectedIds, item.keyForList]; + const onSelectRow = (item: ListItem) => { + const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((i) => i !== item.keyForList) : [...selectedIds, item.keyForList]; setSelectedIds(newSelectedIds); }; @@ -327,7 +327,7 @@ function WithSectionHeader(args) { return ( ) { const [selectedIds, setSelectedIds] = useState(['option-1', 'option-2']); const memo = useMemo(() => { - const allIds = []; + const allIds: string[] = []; - const sections = _.map(args.sections, (section, sectionIndex) => { - const data = _.map(section.data, (item, itemIndex) => { + const sections = props.sections.map((section, sectionIndex) => { + const data = section.data.map((item, itemIndex) => { allIds.push(item.keyForList); - const isSelected = _.contains(selectedIds, item.keyForList); - const isAdmin = itemIndex + section.indexOffset === 0; + const isSelected = selectedIds.includes(item.keyForList); + const isAdmin = itemIndex + (section?.indexOffset ?? 0) === 0; return { ...item, @@ -372,10 +372,10 @@ function WithConfirmButton(args) { }); return {sections, allIds}; - }, [args.sections, selectedIds]); + }, [props.sections, selectedIds]); - const onSelectRow = (item) => { - const newSelectedIds = _.contains(selectedIds, item.keyForList) ? _.without(selectedIds, item.keyForList) : [...selectedIds, item.keyForList]; + const onSelectRow = (item: ListItem) => { + const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((i) => i !== item.keyForList) : [...selectedIds, item.keyForList]; setSelectedIds(newSelectedIds); }; @@ -390,7 +390,7 @@ function WithConfirmButton(args) { return ( Date: Fri, 8 Mar 2024 10:29:34 +0100 Subject: [PATCH 5/8] migrate SelectionList.stories.js to TypeScript --- src/stories/SelectionList.stories.tsx | 34 ++++++++++++++++----------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/stories/SelectionList.stories.tsx b/src/stories/SelectionList.stories.tsx index 17eb538437ec..5de229b3ed44 100644 --- a/src/stories/SelectionList.stories.tsx +++ b/src/stories/SelectionList.stories.tsx @@ -6,8 +6,11 @@ import RadioListItem from '@components/SelectionList/RadioListItem'; // eslint-disable-next-line no-restricted-imports import {defaultStyles} from '@styles/index'; import CONST from '@src/CONST'; +import withNavigationFallback from '@components/withNavigationFallback'; import type { BaseSelectionListProps, ListItem } from '@components/SelectionList/types'; +const SelectionListWithNavigation = withNavigationFallback(SelectionList); + /** * We use the Component Story Format for writing stories. Follow the docs here: * @@ -86,7 +89,7 @@ function Default(props: BaseSelectionListProps) { }; return ( - ) { const [selectedIndex, setSelectedIndex] = useState(1); const sections = props.sections.map((section) => { - const data = section.data.reduce( + const data = section.data.reduce>( (memo, item, index) => { if (!item.text.toLowerCase().includes(searchText.trim().toLowerCase())) { return memo; @@ -134,7 +137,7 @@ function WithTextInput(props: BaseSelectionListProps) { }; return ( - ) { }); }; return ( - ) { } WithAlternateText.args = { - ...Default.args, + // ...Default.args, + sections: SECTIONS, + onSelectRow: () => {}, + initiallyFocusedOptionKey: 'option-2', }; function MultipleSelection(props: BaseSelectionListProps) { const [selectedIds, setSelectedIds] = useState(['option-1', 'option-2']); const memo = useMemo(() => { - const allIds: string [] = []; + const allIds: string[] = []; const sections = props.sections.map((section) => { const data = section.data.map((item, index) => { @@ -228,7 +234,7 @@ function MultipleSelection(props: BaseSelectionListProps) { ...item, isSelected, alternateText: `${item.keyForList}@email.com`, - accountID: item.keyForList, + accountID: Number(item.keyForList), login: item.text, rightElement: isAdmin && ( ) { }; return ( - ) { ...item, isSelected, alternateText: `${item.keyForList}@email.com`, - accountID: item.keyForList, + accountID: Number(item.keyForList), login: item.text, rightElement: isAdmin && ( ) { }; return ( - ) { const data = section.data.map((item, itemIndex) => { allIds.push(item.keyForList); const isSelected = selectedIds.includes(item.keyForList); - const isAdmin = itemIndex + (section?.indexOffset ?? 0) === 0; + const isAdmin = itemIndex + (section.indexOffset ?? 0) === 0; return { ...item, isSelected, alternateText: `${item.keyForList}@email.com`, - accountID: item.keyForList, + accountID: Number(item.keyForList), login: item.text, rightElement: isAdmin && ( ) { }; return ( - Date: Fri, 8 Mar 2024 10:59:53 +0100 Subject: [PATCH 6/8] Fix SelectionList.stories.tsx --- src/stories/SelectionList.stories.tsx | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/stories/SelectionList.stories.tsx b/src/stories/SelectionList.stories.tsx index 5de229b3ed44..7e723d26d4c5 100644 --- a/src/stories/SelectionList.stories.tsx +++ b/src/stories/SelectionList.stories.tsx @@ -3,11 +3,11 @@ import React, {useMemo, useState} from 'react'; import Badge from '@components/Badge'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; +import type {BaseSelectionListProps, ListItem} from '@components/SelectionList/types'; +import withNavigationFallback from '@components/withNavigationFallback'; // eslint-disable-next-line no-restricted-imports import {defaultStyles} from '@styles/index'; import CONST from '@src/CONST'; -import withNavigationFallback from '@components/withNavigationFallback'; -import type { BaseSelectionListProps, ListItem } from '@components/SelectionList/types'; const SelectionListWithNavigation = withNavigationFallback(SelectionList); @@ -110,18 +110,15 @@ function WithTextInput(props: BaseSelectionListProps) { const [selectedIndex, setSelectedIndex] = useState(1); const sections = props.sections.map((section) => { - const data = section.data.reduce>( - (memo, item, index) => { - if (!item.text.toLowerCase().includes(searchText.trim().toLowerCase())) { - return memo; - } - - const isSelected = selectedIndex === index + (section?.indexOffset ?? 0); - memo.push({...item, isSelected}); + const data = section.data.reduce>((memo, item, index) => { + if (!item.text.toLowerCase().includes(searchText.trim().toLowerCase())) { return memo; - }, - [], - ); + } + + const isSelected = selectedIndex === index + (section?.indexOffset ?? 0); + memo.push({...item, isSelected}); + return memo; + }, []); return {...section, data}; }); @@ -207,6 +204,7 @@ function WithAlternateText(props: BaseSelectionListProps) { {...props} sections={sections} onSelectRow={onSelectRow} + ListItem={RadioListItem} /> ); } @@ -412,4 +410,4 @@ WithConfirmButton.args = { }; export {Default, WithTextInput, WithHeaderMessage, WithAlternateText, MultipleSelection, WithSectionHeader, WithConfirmButton}; -export default story; \ No newline at end of file +export default story; From 07a34ac36b0d153e0330ddce142049bc7e750909 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Fri, 8 Mar 2024 11:19:42 +0100 Subject: [PATCH 7/8] remove unnecessary comment --- src/stories/SelectionList.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stories/SelectionList.stories.tsx b/src/stories/SelectionList.stories.tsx index 7e723d26d4c5..e7b137d4ff2f 100644 --- a/src/stories/SelectionList.stories.tsx +++ b/src/stories/SelectionList.stories.tsx @@ -210,7 +210,6 @@ function WithAlternateText(props: BaseSelectionListProps) { } WithAlternateText.args = { - // ...Default.args, sections: SECTIONS, onSelectRow: () => {}, initiallyFocusedOptionKey: 'option-2', From fab486a98f7dbd1f56ebcaa758dc21e8669fc4b6 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Fri, 8 Mar 2024 17:59:38 +0100 Subject: [PATCH 8/8] apply suggested changes --- src/stories/EReceipt.stories.tsx | 9 +++------ src/stories/SelectionList.stories.tsx | 12 +++++------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/stories/EReceipt.stories.tsx b/src/stories/EReceipt.stories.tsx index 55a4cc6cb9b4..f652c08df6f6 100644 --- a/src/stories/EReceipt.stories.tsx +++ b/src/stories/EReceipt.stories.tsx @@ -1,14 +1,11 @@ -/* eslint-disable @typescript-eslint/naming-convention */ - -/* eslint-disable rulesdir/prefer-actions-set-data */ +/* eslint-disable @typescript-eslint/naming-convention, rulesdir/prefer-actions-set-data */ import type {ComponentMeta, ComponentStory} from '@storybook/react'; import React from 'react'; -import type {NullishDeep} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {EReceiptOnyxProps, EReceiptProps} from '@components/EReceipt'; import EReceipt from '@components/EReceipt'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Transaction} from '@src/types/onyx'; +import type CollectionDataSet from '@src/types/utils/CollectionDataSet'; type EReceiptStory = ComponentStory; @@ -154,7 +151,7 @@ const transactionData = { created: '2023-01-11 13:46:20', hasEReceipt: true, }, -} as Record<`${typeof ONYXKEYS.COLLECTION.TRANSACTION}${string}`, NullishDeep>; +} as CollectionDataSet; Onyx.mergeCollection(ONYXKEYS.COLLECTION.TRANSACTION, transactionData); Onyx.merge('cardList', { diff --git a/src/stories/SelectionList.stories.tsx b/src/stories/SelectionList.stories.tsx index e7b137d4ff2f..aeef37589761 100644 --- a/src/stories/SelectionList.stories.tsx +++ b/src/stories/SelectionList.stories.tsx @@ -110,7 +110,7 @@ function WithTextInput(props: BaseSelectionListProps) { const [selectedIndex, setSelectedIndex] = useState(1); const sections = props.sections.map((section) => { - const data = section.data.reduce>((memo, item, index) => { + const data = section.data.reduce((memo, item, index) => { if (!item.text.toLowerCase().includes(searchText.trim().toLowerCase())) { return memo; } @@ -210,9 +210,7 @@ function WithAlternateText(props: BaseSelectionListProps) { } WithAlternateText.args = { - sections: SECTIONS, - onSelectRow: () => {}, - initiallyFocusedOptionKey: 'option-2', + ...Default.args, }; function MultipleSelection(props: BaseSelectionListProps) { @@ -250,7 +248,7 @@ function MultipleSelection(props: BaseSelectionListProps) { }, [props.sections, selectedIds]); const onSelectRow = (item: ListItem) => { - const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((i) => i !== item.keyForList) : [...selectedIds, item.keyForList]; + const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((id) => id !== item.keyForList) : [...selectedIds, item.keyForList]; setSelectedIds(newSelectedIds); }; @@ -315,7 +313,7 @@ function WithSectionHeader(props: BaseSelectionListProps) { }, [props.sections, selectedIds]); const onSelectRow = (item: ListItem) => { - const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((i) => i !== item.keyForList) : [...selectedIds, item.keyForList]; + const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((id) => id !== item.keyForList) : [...selectedIds, item.keyForList]; setSelectedIds(newSelectedIds); }; @@ -378,7 +376,7 @@ function WithConfirmButton(props: BaseSelectionListProps) { }, [props.sections, selectedIds]); const onSelectRow = (item: ListItem) => { - const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((i) => i !== item.keyForList) : [...selectedIds, item.keyForList]; + const newSelectedIds = selectedIds.includes(item.keyForList) ? selectedIds.filter((id) => id !== item.keyForList) : [...selectedIds, item.keyForList]; setSelectedIds(newSelectedIds); };