Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ function useGettingStartedItems(): UseGettingStartedItemsResult {

const emptyResult: UseGettingStartedItemsResult = {shouldShowSection: false, items: []};

// Hide the whole section as soon as every onboarding to-do is complete, instead of keeping it
// around for the full Getting Started window.
const buildResult = (builtItems: GettingStartedItem[]): UseGettingStartedItemsResult => {
if (builtItems.every((item) => item.isComplete)) {
return emptyResult;
}
return {shouldShowSection: true, items: builtItems};
};
Comment on lines +65 to +70

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JmillsExpensify
If we fill out all the checkboxes, but then fail to meet the conditions of one of the fields (for example, delete a custom category and the category checkbox will reset), the Getting Started slot will return
Are we okay with that?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's probably fine. Sounds like a bit of an edge case if you go to the effort of adding custom categories, just to delete them all to leave the defaults.


if (intent !== CONST.ONBOARDING_CHOICES.MANAGE_TEAM && intent !== CONST.ONBOARDING_CHOICES.TRACK_WORKSPACE) {
return emptyResult;
}
Expand Down Expand Up @@ -103,7 +112,7 @@ function useGettingStartedItems(): UseGettingStartedItemsResult {
route: ROUTES.WORKSPACE_MEMBERS.getRoute(activePolicyID),
});

return {shouldShowSection: true, items};
return buildResult(items);
}

const isDirectConnect = !!reportedIntegration && DIRECT_CONNECT_INTEGRATIONS.has(reportedIntegration);
Expand Down Expand Up @@ -153,7 +162,7 @@ function useGettingStartedItems(): UseGettingStartedItemsResult {
});
}

return {shouldShowSection: true, items};
return buildResult(items);
}

export default useGettingStartedItems;
Expand Down
79 changes: 79 additions & 0 deletions tests/unit/hooks/useGettingStartedItems.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1125,4 +1125,83 @@ describe('useGettingStartedItems', () => {
});
});
});

describe('hides the section once all to-dos are complete', () => {
const customCategory: PolicyCategories = {
'Custom Category': {
name: 'Custom Category',
enabled: true,
unencodedName: 'Custom Category',
areCommentsRequired: false,
'GL Code': '',
externalID: '',
origin: '',
previousCategoryName: undefined,
},
};

it('should stay visible for MANAGE_TEAM intent while at least one to-do is incomplete', async () => {
await setupManageTeamScenario({accounting: 'none', policy: {areCategoriesEnabled: true}});

const {result} = renderHook(() => useGettingStartedItems());
await waitForBatchedUpdates();

expect(result.current.shouldShowSection).toBe(true);
expect(result.current.items.some((item) => !item.isComplete)).toBe(true);
});

it('should hide the section for MANAGE_TEAM intent when every to-do is complete (within the 60-day window)', async () => {
const policyAccountID = 7777777;
// A commercial (custom) feed always counts as a linked company card feed, so the linkCompanyCards to-do is complete.
const commercialFeed = CONST.COMPANY_CARD.FEED_BANK_NAME.VISA;

// createWorkspace is always complete; complete categories (custom category) and company cards (a feed) so nothing is left.
await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${POLICY_ID}`, customCategory);
await Onyx.merge(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${policyAccountID}`, {
settings: {
companyCards: {
[commercialFeed]: {preferredPolicy: POLICY_ID, liabilityType: 'corporate'},
},
},
});
await setupManageTeamScenario({
accounting: 'none',
policy: {
policyAccountID,
areCategoriesEnabled: true,
areCompanyCardsEnabled: true,
areRulesEnabled: false,
},
});

const {result} = renderHook(() => useGettingStartedItems());
await waitFor(() => expect(result.current.shouldShowSection).toBe(false));
expect(result.current.items).toEqual([]);
});

it('should hide the section for TRACK_WORKSPACE intent when every to-do is complete', async () => {
const employeeList: PolicyEmployeeList = {
'owner@test.com': {email: 'owner@test.com', role: CONST.POLICY.ROLE.ADMIN},
'accountant@test.com': {email: 'accountant@test.com', role: CONST.POLICY.ROLE.USER},
};
await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${POLICY_ID}`, customCategory);
await setupTrackWorkspaceScenario({policy: {areCategoriesEnabled: true, employeeList}});

const {result} = renderHook(() => useGettingStartedItems());
await waitForBatchedUpdates();

expect(result.current.shouldShowSection).toBe(false);
expect(result.current.items).toEqual([]);
});

it('should stay visible for TRACK_WORKSPACE intent while at least one to-do is incomplete', async () => {
await setupTrackWorkspaceScenario();

const {result} = renderHook(() => useGettingStartedItems());
await waitForBatchedUpdates();

expect(result.current.shouldShowSection).toBe(true);
expect(result.current.items.some((item) => !item.isComplete)).toBe(true);
});
});
});
Loading