From a8b35da23622d07fef939dfe4cf5b967e223ccb6 Mon Sep 17 00:00:00 2001 From: Filip Solecki Date: Thu, 1 Feb 2024 09:13:38 +0100 Subject: [PATCH] Migrate WorkspaceSwitcherPage --- ...tcherPage.js => WorkspaceSwitcherPage.tsx} | 181 +++++++++--------- 1 file changed, 93 insertions(+), 88 deletions(-) rename src/pages/{WorkspaceSwitcherPage.js => WorkspaceSwitcherPage.tsx} (65%) diff --git a/src/pages/WorkspaceSwitcherPage.js b/src/pages/WorkspaceSwitcherPage.tsx similarity index 65% rename from src/pages/WorkspaceSwitcherPage.js rename to src/pages/WorkspaceSwitcherPage.tsx index 9972a7bac5ba..7cd7897af28e 100644 --- a/src/pages/WorkspaceSwitcherPage.js +++ b/src/pages/WorkspaceSwitcherPage.tsx @@ -1,9 +1,7 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import PropTypes from 'prop-types'; import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; +import type {OnyxCollection} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -26,51 +24,39 @@ import {getWorkspacesBrickRoads, getWorkspacesUnreadStatuses} from '@libs/Worksp import * as App from '@userActions/App'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import SCREENS from '@src/SCREENS'; +import type {Policy} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import WorkspaceCardCreateAWorkspace from './workspace/card/WorkspaceCardCreateAWorkspace'; -const sortWorkspacesBySelected = (workspace1, workspace2, selectedWorkspaceID) => { +type SimpleWorkspaceItem = { + text?: string; + policyID?: string; + isPolicyAdmin?: boolean; +}; + +const sortWorkspacesBySelected = (workspace1: SimpleWorkspaceItem, workspace2: SimpleWorkspaceItem, selectedWorkspaceID: string | undefined): number => { if (workspace1.policyID === selectedWorkspaceID) { return -1; } if (workspace2.policyID === selectedWorkspaceID) { return 1; } - return workspace1.text.toLowerCase().localeCompare(workspace2.text.toLowerCase()); + return workspace1.text?.toLowerCase().localeCompare(workspace2.text?.toLowerCase() ?? '') ?? 0; }; -const propTypes = { +type WorkspaceSwitcherPageOnyxProps = { /** The list of this user's policies */ - policies: PropTypes.objectOf( - PropTypes.shape({ - /** The ID of the policy */ - id: PropTypes.string, - - /** The name of the policy */ - name: PropTypes.string, - - /** The type of the policy */ - type: PropTypes.string, - - /** The user's role in the policy */ - role: PropTypes.string, - - /** The current action that is waiting to happen on the policy */ - pendingAction: PropTypes.oneOf(_.values(CONST.RED_BRICK_ROAD_PENDING_ACTION)), - }), - ), + policies: OnyxCollection; }; -const defaultProps = { - policies: {}, -}; +type WorkspaceSwitcherPageProps = WorkspaceSwitcherPageOnyxProps; -function WorkspaceSwitcherPage({policies}) { +function WorkspaceSwitcherPage({policies}: WorkspaceSwitcherPageProps) { const theme = useTheme(); const styles = useThemeStyles(); const {isOffline} = useNetwork(); - const [selectedOption, setSelectedOption] = useState(); - const [searchTerm, setSearchTerm] = useState(''); + const [selectedOption, setSelectedOption] = useState(undefined); + const [searchTerm, setSearchTerm] = useState(); const {inputCallbackRef} = useAutoFocusInput(); const {translate} = useLocalize(); const {activeWorkspaceID, setActiveWorkspaceID} = useActiveWorkspace(); @@ -79,16 +65,16 @@ function WorkspaceSwitcherPage({policies}) { const unreadStatusesForPolicies = useMemo(() => getWorkspacesUnreadStatuses(), []); const getIndicatorTypeForPolicy = useCallback( - (policyId) => { + (policyId?: string) => { if (policyId && policyId !== activeWorkspaceID) { return brickRoadsForPolicies[policyId]; } - if (_.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD.RBR)) { + if (Object.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD.RBR)) { return CONST.BRICK_ROAD.RBR; } - if (_.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD.GBR)) { + if (Object.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD.GBR)) { return CONST.BRICK_ROAD.GBR; } @@ -99,62 +85,69 @@ function WorkspaceSwitcherPage({policies}) { const hasUnreadData = useCallback( // TO DO: Implement checking if policy has some unread data - // eslint-disable-next-line no-unused-vars - (policyId) => { + (policyId?: string) => { if (policyId) { return unreadStatusesForPolicies[policyId]; } - return _.some(_.values(unreadStatusesForPolicies), (status) => status); + return Object.values(unreadStatusesForPolicies).some((status) => status); }, [unreadStatusesForPolicies], ); - const selectPolicy = (option) => { - const {policyID, isPolicyAdmin} = option; + const selectPolicy = useCallback( + (option?: SimpleWorkspaceItem) => { + if (!option) { + return; + } - if (policyID) { - setSelectedOption(option); - } else { - setSelectedOption(undefined); - } - setActiveWorkspaceID(policyID); - Navigation.goBack(); - if (policyID !== activeWorkspaceID) { - Navigation.navigateWithSwitchPolicyID({policyID, isPolicyAdmin}); - } - }; + const {policyID, isPolicyAdmin} = option; - const usersWorkspaces = useMemo( - () => - _.chain(policies) - .filter((policy) => PolicyUtils.shouldShowPolicy(policy, isOffline)) - .map((policy) => ({ - text: policy.name, - policyID: policy.id, - brickRoadIndicator: getIndicatorTypeForPolicy(policy.id), - icons: [ - { - source: policy.avatar ? policy.avatar : ReportUtils.getDefaultWorkspaceAvatar(policy.name), - fallbackIcon: Expensicons.FallbackWorkspaceAvatar, - name: policy.name, - type: CONST.ICON_TYPE_WORKSPACE, - }, - ], - boldStyle: hasUnreadData(policy.id), - keyForList: policy.id, - isPolicyAdmin: PolicyUtils.isPolicyAdmin(policy), - })) - .value(), - [policies, getIndicatorTypeForPolicy, hasUnreadData], + if (policyID) { + setSelectedOption(option); + } else { + setSelectedOption(undefined); + } + setActiveWorkspaceID(policyID); + Navigation.goBack(); + if (policyID !== activeWorkspaceID) { + Navigation.navigateWithSwitchPolicyID({policyID, isPolicyAdmin}); + } + }, + [activeWorkspaceID, setActiveWorkspaceID], ); + const usersWorkspaces = useMemo(() => { + if (!policies || isEmptyObject(policies)) { + return []; + } + + return Object.values(policies) + .filter((policy) => PolicyUtils.shouldShowPolicy(policy, !!isOffline)) + .map((policy) => ({ + text: policy?.name, + policyID: policy?.id, + brickRoadIndicator: getIndicatorTypeForPolicy(policy?.id), + icons: [ + { + source: policy?.avatar ? policy.avatar : ReportUtils.getDefaultWorkspaceAvatar(policy?.name), + fallbackIcon: Expensicons.FallbackWorkspaceAvatar, + name: policy?.name, + type: CONST.ICON_TYPE_WORKSPACE, + }, + ], + boldStyle: hasUnreadData(policy?.id), + keyForList: policy?.id, + isPolicyAdmin: PolicyUtils.isPolicyAdmin(policy), + })); + }, [policies, getIndicatorTypeForPolicy, hasUnreadData, isOffline]); + const filteredAndSortedUserWorkspaces = useMemo( () => - _.filter(usersWorkspaces, (policy) => policy.text.toLowerCase().includes(searchTerm.toLowerCase())).sort((policy1, policy2) => - sortWorkspacesBySelected(policy1, policy2, activeWorkspaceID), - ), - [searchTerm, usersWorkspaces], + usersWorkspaces + .filter((policy) => policy.text?.toLowerCase().includes(searchTerm?.toLowerCase() ?? '')) + .sort((policy1, policy2) => sortWorkspacesBySelected(policy1, policy2, activeWorkspaceID)), + [searchTerm, usersWorkspaces, activeWorkspaceID], ); const usersWorkspacesSectionData = useMemo( @@ -192,10 +185,9 @@ function WorkspaceSwitcherPage({policies}) { ( <> - 0 ? [styles.mb0] : [styles.mb3])]}> + 0 ? [styles.mb1] : [styles.mb3])]}> { App.createWorkspaceWithPolicyDraftAndNavigateToIt(); @@ -239,12 +232,13 @@ function WorkspaceSwitcherPage({policies}) { {usersWorkspaces.length > 0 ? ( = CONST.WORKSPACE_SWITCHER.MINIMUM_WORKSPACES_TO_SHOW_SEARCH} - onChangeText={(newSearchTerm) => setSearchTerm(newSearchTerm)} + onChangeText={setSearchTerm} selectedOptions={selectedOption ? [selectedOption] : []} onSelectRow={selectPolicy} shouldPreventDefaultFocusOnSelectRow @@ -266,22 +260,35 @@ function WorkspaceSwitcherPage({policies}) { )} ), - [inputCallbackRef, setSearchTerm, searchTerm, selectPolicy, selectedOption, styles, theme.textSupporting, translate, usersWorkspaces.length, usersWorkspacesSectionData], + [ + inputCallbackRef, + setSearchTerm, + searchTerm, + selectPolicy, + selectedOption, + styles, + theme.textSupporting, + translate, + usersWorkspaces.length, + usersWorkspacesSectionData, + activeWorkspaceID, + theme.icon, + headerMessage, + ], ); useEffect(() => { if (!activeWorkspaceID) { return; } - const optionToSet = _.find(usersWorkspaces, (option) => option.policyID === activeWorkspaceID); + const optionToSet = usersWorkspaces.find((option) => option.policyID === activeWorkspaceID); setSelectedOption(optionToSet); }, [activeWorkspaceID, usersWorkspaces]); return ( - + {everythingSection} @@ -290,11 +297,9 @@ function WorkspaceSwitcherPage({policies}) { ); } -WorkspaceSwitcherPage.propTypes = propTypes; -WorkspaceSwitcherPage.defaultProps = defaultProps; WorkspaceSwitcherPage.displayName = 'WorkspaceSwitcherPage'; -export default withOnyx({ +export default withOnyx({ policies: { key: ONYXKEYS.COLLECTION.POLICY, },