diff --git a/src/libs/API/parameters/OpenPolicyCategoriesPageParams.ts b/src/libs/API/parameters/OpenPolicyCategoriesPageParams.ts new file mode 100644 index 000000000000..375962d2b1a1 --- /dev/null +++ b/src/libs/API/parameters/OpenPolicyCategoriesPageParams.ts @@ -0,0 +1,5 @@ +type OpenPolicyCategoriesPageParams = { + policyID: string; +}; + +export default OpenPolicyCategoriesPageParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 679379c8089a..00e8b5e761ad 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -114,6 +114,7 @@ export type {default as OpenWorkspaceViewParams} from './OpenWorkspaceViewParams export type {default as OpenWorkspaceReimburseViewParams} from './OpenWorkspaceReimburseViewParams'; export type {default as OpenWorkspaceInvitePageParams} from './OpenWorkspaceInvitePageParams'; export type {default as OpenWorkspaceMembersPageParams} from './OpenWorkspaceMembersPageParams'; +export type {default as OpenPolicyCategoriesPageParams} from './OpenPolicyCategoriesPageParams'; export type {default as OpenDraftWorkspaceRequestParams} from './OpenDraftWorkspaceRequestParams'; export type {default as UpdateWorkspaceCustomUnitAndRateParams} from './UpdateWorkspaceCustomUnitAndRateParams'; export type {default as CreateWorkspaceFromIOUPaymentParams} from './CreateWorkspaceFromIOUPaymentParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index cacbfebdc120..ee4ce1ea3670 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -340,6 +340,7 @@ const READ_COMMANDS = { OPEN_WORKSPACE_REIMBURSE_VIEW: 'OpenWorkspaceReimburseView', OPEN_WORKSPACE: 'OpenWorkspace', OPEN_WORKSPACE_MEMBERS_PAGE: 'OpenWorkspaceMembersPage', + OPEN_POLICY_CATEGORIES_PAGE: 'OpenPolicyCategoriesPage', OPEN_WORKSPACE_INVITE_PAGE: 'OpenWorkspaceInvitePage', OPEN_DRAFT_WORKSPACE_REQUEST: 'OpenDraftWorkspaceRequest', } as const; @@ -374,6 +375,7 @@ type ReadCommandParameters = { [READ_COMMANDS.OPEN_WORKSPACE_REIMBURSE_VIEW]: Parameters.OpenWorkspaceReimburseViewParams; [READ_COMMANDS.OPEN_WORKSPACE]: Parameters.OpenWorkspaceParams; [READ_COMMANDS.OPEN_WORKSPACE_MEMBERS_PAGE]: Parameters.OpenWorkspaceMembersPageParams; + [READ_COMMANDS.OPEN_POLICY_CATEGORIES_PAGE]: Parameters.OpenPolicyCategoriesPageParams; [READ_COMMANDS.OPEN_WORKSPACE_INVITE_PAGE]: Parameters.OpenWorkspaceInvitePageParams; [READ_COMMANDS.OPEN_DRAFT_WORKSPACE_REQUEST]: Parameters.OpenDraftWorkspaceRequestParams; }; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 313c4deb9934..0935dd384f48 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -16,6 +16,7 @@ import type { DeleteWorkspaceAvatarParams, DeleteWorkspaceParams, OpenDraftWorkspaceRequestParams, + OpenPolicyCategoriesPageParams, OpenWorkspaceInvitePageParams, OpenWorkspaceMembersPageParams, OpenWorkspaceParams, @@ -1830,6 +1831,19 @@ function openWorkspaceMembersPage(policyID: string, clientMemberEmails: string[] API.read(READ_COMMANDS.OPEN_WORKSPACE_MEMBERS_PAGE, params); } +function openPolicyCategoriesPage(policyID: string) { + if (!policyID) { + Log.warn('openPolicyCategoriesPage invalid params', {policyID}); + return; + } + + const params: OpenPolicyCategoriesPageParams = { + policyID, + }; + + API.read(READ_COMMANDS.OPEN_POLICY_CATEGORIES_PAGE, params); +} + function openWorkspaceInvitePage(policyID: string, clientMemberEmails: string[]) { if (!policyID || !clientMemberEmails) { Log.warn('openWorkspaceInvitePage invalid params', {policyID, clientMemberEmails}); @@ -2516,6 +2530,7 @@ export { generatePolicyID, createWorkspace, openWorkspaceMembersPage, + openPolicyCategoriesPage, openWorkspaceInvitePage, openWorkspace, removeWorkspace, diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index d15011489bac..a66642ff7d5e 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -1,6 +1,6 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useMemo, useState} from 'react'; -import {View} from 'react-native'; +import React, {useEffect, useMemo, useState} from 'react'; +import {ActivityIndicator, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import Button from '@components/Button'; @@ -14,6 +14,7 @@ import TableListItem from '@components/SelectionList/TableListItem'; import Text from '@components/Text'; import WorkspaceEmptyStateSection from '@components/WorkspaceEmptyStateSection'; import useLocalize from '@hooks/useLocalize'; +import useNetwork from '@hooks/useNetwork'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; @@ -21,6 +22,8 @@ import Navigation from '@libs/Navigation/Navigation'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper'; +import * as Policy from '@userActions/Policy'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; @@ -48,6 +51,17 @@ function WorkspaceCategoriesPage({policyCategories, route}: WorkspaceCategoriesP const {translate} = useLocalize(); const [selectedCategories, setSelectedCategories] = useState>({}); + function fetchCategories() { + Policy.openPolicyCategoriesPage(route.params.policyID); + } + + const {isOffline} = useNetwork({onReconnect: fetchCategories}); + + useEffect(() => { + fetchCategories(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const categoryList = useMemo( () => Object.values(policyCategories ?? {}).map((value) => ({ @@ -97,6 +111,8 @@ function WorkspaceCategoriesPage({policyCategories, route}: WorkspaceCategoriesP Navigation.navigate(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(route.params.policyID, category.text)); }; + const isLoading = !isOffline && policyCategories === undefined; + const settingsButton = (