From bc79188272bd54569c98f1a6dd67baf69ea750a0 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Fri, 22 Dec 2023 12:25:57 +0100 Subject: [PATCH] Add logic for gbr/rbr and unread chats --- src/CONST.ts | 4 +- src/libs/Navigation/linkingConfig.ts | 2 +- ...{BrickRoadsUtils.ts => WorkspacesUtils.ts} | 32 +++- src/pages/WorkspaceSwitcherPage.js | 159 ++++++++++++------ 4 files changed, 143 insertions(+), 54 deletions(-) rename src/libs/{BrickRoadsUtils.ts => WorkspacesUtils.ts} (75%) diff --git a/src/CONST.ts b/src/CONST.ts index 2ef0d6c9a155..ed4901415dc3 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3038,8 +3038,8 @@ const CONST = { CAROUSEL: 3, }, BRICK_ROAD: { - GBR: 'GBR', - RBR: 'RBR', + GBR: 'info', + RBR: 'error', }, } as const; diff --git a/src/libs/Navigation/linkingConfig.ts b/src/libs/Navigation/linkingConfig.ts index eb3877516b3b..bbdc1319c154 100644 --- a/src/libs/Navigation/linkingConfig.ts +++ b/src/libs/Navigation/linkingConfig.ts @@ -263,7 +263,7 @@ const linkingConfig: LinkingOptions = { }, [SCREENS.WORKSPACE.NAME]: ROUTES.WORKSPACE_NAME.route, }, - }, + }, [SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: { screens: { [SCREENS.PRIVATE_NOTES.VIEW]: ROUTES.PRIVATE_NOTES_VIEW.route, diff --git a/src/libs/BrickRoadsUtils.ts b/src/libs/WorkspacesUtils.ts similarity index 75% rename from src/libs/BrickRoadsUtils.ts rename to src/libs/WorkspacesUtils.ts index 5116ce4f2e92..caba82d9ca70 100644 --- a/src/libs/BrickRoadsUtils.ts +++ b/src/libs/WorkspacesUtils.ts @@ -69,5 +69,35 @@ function getWorkspacesBrickRoads(): Record { return workspacesBrickRoadsMap; } -export {getBrickRoadForPolicy, getWorkspacesBrickRoads}; +/** + * @returns a map where the keys are policyIDs and the values are truthy booleans if policy has unread content + */ +function getWorkspacesUnreadStatuses(): Record { + if(!allReports) { + return {}; + } + + const workspacesUnreadStatuses: Record = {} + + Object.keys(allReports).forEach((report) => { + const policyID = allReports?.[report]?.policyID; + const policyReport = allReports ? allReports[report] : null; + if (!policyID || !policyReport) { + return; + } + + const unreadStatus = ReportUtils.isUnread(policyReport); + + if(unreadStatus) { + workspacesUnreadStatuses[policyID] = true; + } + else { + workspacesUnreadStatuses[policyID] = false; + } + }) + + return workspacesUnreadStatuses; +} + +export {getBrickRoadForPolicy, getWorkspacesBrickRoads, getWorkspacesUnreadStatuses}; export type {BrickRoad}; diff --git a/src/pages/WorkspaceSwitcherPage.js b/src/pages/WorkspaceSwitcherPage.js index 9ea0f9380a05..f670af604b8f 100644 --- a/src/pages/WorkspaceSwitcherPage.js +++ b/src/pages/WorkspaceSwitcherPage.js @@ -4,23 +4,24 @@ import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import HeaderPageLayout from '@components/HeaderPageLayout'; +import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import OptionRow from '@components/OptionRow'; import OptionsSelector from '@components/OptionsSelector'; +import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import Text from '@components/Text'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import {getWorkspacesBrickRoads, getWorkspacesUnreadStatuses} from '@libs/WorkspacesUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import SCREENS from '@src/SCREENS'; -import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; -import Icon from '@components/Icon'; -import useLocalize from '@hooks/useLocalize'; import WorkspaceCardCreateAWorkspace from './workspace/card/WorkspaceCardCreateAWorkspace'; const propTypes = { @@ -52,7 +53,7 @@ const defaultProps = { }; const MINIMUM_WORKSPACES_TO_SHOW_SEARCH = 8; -const EXPENSIFY_TITLE = 'Expensify' +const EXPENSIFY_TITLE = 'Expensify'; function WorkspaceSwitcherPage({policies, activeWorkspaceID}) { const theme = useTheme(); @@ -63,19 +64,36 @@ function WorkspaceSwitcherPage({policies, activeWorkspaceID}) { const {inputCallbackRef} = useAutoFocusInput(); const {translate} = useLocalize(); - const getIndicatorTypeForPolicy = useCallback( - // TO DO: Wait for missing logic to be implemented in other PR - // CONST.BRICK_ROAD_INDICATOR_STATUS.INFO or CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR - // eslint-disable-next-line no-unused-vars - (policyId) => undefined, - [], - ); + const brickRoadsForPolicies = getWorkspacesBrickRoads(); + const unreadStatusesForPolicies = getWorkspacesUnreadStatuses(); + + const getIndicatorTypeForPolicy = useCallback((policyId) => { + if (policyId && policyId !== activeWorkspaceID) { + return brickRoadsForPolicies[policyId]; + } + + if(_.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD.RBR)) { + return CONST.BRICK_ROAD.RBR; + } + + if(_.values(brickRoadsForPolicies).includes(CONST.BRICK_ROAD.GBR)) { + return CONST.BRICK_ROAD.GBR; + } + + return undefined + }, [activeWorkspaceID, brickRoadsForPolicies]); const hasUnreadData = useCallback( // TO DO: Implement checking if policy has some unread data // eslint-disable-next-line no-unused-vars - (policyId) => false, - [], + (policyId) => { + if(policyId) { + return unreadStatusesForPolicies[policyId]; + } + + return _.some(_.values(unreadStatusesForPolicies), (status) => status) + }, + [unreadStatusesForPolicies], ); const selectPolicy = useCallback((option) => { @@ -164,54 +182,95 @@ function WorkspaceSwitcherPage({policies, activeWorkspaceID}) { ); - }, [activeWorkspaceID, getIndicatorTypeForPolicy, hasUnreadData, selectPolicy, styles.alignItemsCenter, styles.flexRow, styles.justifyContentBetween, styles.label, styles.mb3, styles.mh4, theme.textSupporting, translate]); - + }, [ + activeWorkspaceID, + getIndicatorTypeForPolicy, + hasUnreadData, + selectPolicy, + styles.alignItemsCenter, + styles.flexRow, + styles.justifyContentBetween, + styles.label, + styles.mb3, + styles.mh4, + theme.textSupporting, + translate, + ]); + const workspacesSection = useMemo( () => ( <> 0 ? [styles.mb1] : [styles.mb3])]}> - - - {translate('common.workspaces')} - - + {translate('common.workspaces')} + + - {({hovered}) => ( - - )} - + {({hovered}) => ( + + )} + - {usersWorkspaces.length > 0 ? : } + {usersWorkspaces.length > 0 ? ( + + ) : ( + + )} ), - [inputCallbackRef, onChangeText, searchTerm, selectPolicy, selectedOption, styles.alignItemsEnd, styles.borderRadiusNormal, styles.buttonDefaultBG, styles.buttonHoveredBG, styles.flexRow, styles.justifyContentBetween, styles.label, styles.mb1, styles.mb3, styles.mh4, styles.mt0, styles.mt2, styles.mt3, styles.p2, styles.pt0, theme.textSupporting, translate, usersWorkspaces.length, usersWorkspacesSectionData], + [ + inputCallbackRef, + onChangeText, + searchTerm, + selectPolicy, + selectedOption, + styles.alignItemsEnd, + styles.borderRadiusNormal, + styles.buttonDefaultBG, + styles.buttonHoveredBG, + styles.flexRow, + styles.justifyContentBetween, + styles.label, + styles.mb1, + styles.mb3, + styles.mh4, + styles.mt0, + styles.mt2, + styles.mt3, + styles.p2, + styles.pt0, + theme.textSupporting, + translate, + usersWorkspaces.length, + usersWorkspacesSectionData, + ], ); useEffect(() => {