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
8 changes: 5 additions & 3 deletions src/hooks/useWorkspaceList.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {useMemo} from 'react';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import * as Expensicons from '@components/Icon/Expensicons';
import type {LocaleContextProps} from '@components/LocaleContextProvider';
import type {ListItem, SectionListDataType} from '@components/SelectionList/types';
import {isPolicyAdmin, shouldShowPolicy, sortWorkspacesBySelected} from '@libs/PolicyUtils';
import {getDefaultWorkspaceAvatar} from '@libs/ReportUtils';
Expand All @@ -23,10 +24,11 @@ type UseWorkspaceListParams = {
shouldShowPendingDeletePolicy: boolean;
selectedPolicyIDs: string[] | undefined;
searchTerm: string;
localeCompare: LocaleContextProps['localeCompare'];
additionalFilter?: (policy: OnyxEntry<Policy>) => boolean;
};

function useWorkspaceList({policies, currentUserLogin, selectedPolicyIDs, searchTerm, shouldShowPendingDeletePolicy, additionalFilter}: UseWorkspaceListParams) {
function useWorkspaceList({policies, currentUserLogin, selectedPolicyIDs, searchTerm, shouldShowPendingDeletePolicy, localeCompare, additionalFilter}: UseWorkspaceListParams) {
const usersWorkspaces = useMemo(() => {
if (!policies || isEmptyObject(policies)) {
return [];
Expand Down Expand Up @@ -61,9 +63,9 @@ function useWorkspaceList({policies, currentUserLogin, selectedPolicyIDs, search
const filteredAndSortedUserWorkspaces = useMemo<WorkspaceListItem[]>(
() =>
tokenizedSearch(usersWorkspaces, searchTerm, (policy) => [policy.text]).sort((policy1, policy2) =>
sortWorkspacesBySelected({policyID: policy1.policyID, name: policy1.text}, {policyID: policy2.policyID, name: policy2.text}, selectedPolicyIDs),
sortWorkspacesBySelected({policyID: policy1.policyID, name: policy1.text}, {policyID: policy2.policyID, name: policy2.text}, selectedPolicyIDs, localeCompare),
),
[searchTerm, usersWorkspaces, selectedPolicyIDs],
[searchTerm, usersWorkspaces, selectedPolicyIDs, localeCompare],
);

const sections = useMemo(() => {
Expand Down
12 changes: 10 additions & 2 deletions src/libs/PolicyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import {shouldShowQBOReimbursableExportDestinationAccountError} from './actions/connections/QuickbooksOnline';
import {getCurrentUserAccountID, getCurrentUserEmail} from './actions/Report';
import {getCategoryApproverRule} from './CategoryUtils';
import localeCompare from './LocaleCompare';
import {translateLocal} from './Localize';
import Navigation from './Navigation/Navigation';
import {isOffline as isOfflineNetworkStore} from './Network/NetworkStore';
Expand All @@ -60,18 +59,18 @@
let activePolicyId: OnyxEntry<string>;
let isLoadingReportData = true;

Onyx.connect({

Check warning on line 62 in src/libs/PolicyUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY,
waitForCollectionCallback: true,
callback: (value) => (allPolicies = value),
});

Onyx.connect({

Check warning on line 68 in src/libs/PolicyUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.NVP_ACTIVE_POLICY_ID,
callback: (value) => (activePolicyId = value),
});

Onyx.connect({

Check warning on line 73 in src/libs/PolicyUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.IS_LOADING_REPORT_DATA,
initWithStoredValues: false,
callback: (value) => (isLoadingReportData = value ?? false),
Expand Down Expand Up @@ -1084,6 +1083,7 @@
policy: Policy | undefined,
importField: ValueOf<typeof CONST.NETSUITE_CONFIG.IMPORT_CUSTOM_FIELDS>,
translate: LocaleContextProps['translate'],
localeCompare: LocaleContextProps['localeCompare'],
): string | undefined {
const fieldData = policy?.connections?.netsuite?.options?.config.syncOptions?.[importField] ?? [];
if (fieldData.length === 0) {
Expand Down Expand Up @@ -1194,7 +1194,15 @@
* @param workspace2 Details of the second workspace to be compared.
* @param selectedWorkspaceID ID of the selected workspace which needs to be at the beginning.
*/
const sortWorkspacesBySelected = (workspace1: WorkspaceDetails, workspace2: WorkspaceDetails, selectedWorkspaceIDs: string[] | undefined): number => {
const sortWorkspacesBySelected = (
workspace1: WorkspaceDetails,
workspace2: WorkspaceDetails,
selectedWorkspaceIDs: string[] | undefined,
localeCompare: LocaleContextProps['localeCompare'],
): number => {
if (workspace1.policyID && selectedWorkspaceIDs?.includes(workspace1?.policyID) && workspace2.policyID && selectedWorkspaceIDs?.includes(workspace2.policyID)) {
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.

Nice catch

return localeCompare(workspace1.name?.toLowerCase() ?? '', workspace2.name?.toLowerCase() ?? '');
}
if (workspace1.policyID && selectedWorkspaceIDs?.includes(workspace1?.policyID)) {
return -1;
}
Expand Down
3 changes: 2 additions & 1 deletion src/pages/ReportChangeWorkspacePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function ReportChangeWorkspacePage({report, route}: ReportChangeWorkspacePagePro
const {isOffline} = useNetwork();
const styles = useThemeStyles();
const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState('');
const {translate, formatPhoneNumber} = useLocalize();
const {translate, formatPhoneNumber, localeCompare} = useLocalize();

const [policies, fetchStatus] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true});
const [reportNextStep] = useOnyx(`${ONYXKEYS.COLLECTION.NEXT_STEP}${reportID}`, {canBeMissing: true});
Expand Down Expand Up @@ -70,6 +70,7 @@ function ReportChangeWorkspacePage({report, route}: ReportChangeWorkspacePagePro
shouldShowPendingDeletePolicy: false,
selectedPolicyIDs: report.policyID ? [report.policyID] : undefined,
searchTerm: debouncedSearchTerm,
localeCompare,
additionalFilter: (newPolicy) => isWorkspaceEligibleForReportChange(newPolicy, report, policies),
});

Expand Down
1 change: 1 addition & 0 deletions src/pages/Search/AdvancedSearchFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ function AdvancedSearchFilters() {
shouldShowPendingDeletePolicy: false,
selectedPolicyIDs: undefined,
searchTerm: '',
localeCompare,
});

// When looking if a user has any categories to display, we want to ignore the policies that are of type PERSONAL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const updateWorkspaceFilter = (policyID: string[] | null) => {

function SearchFiltersWorkspacePage() {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {translate, localeCompare} = useLocalize();
const {isOffline} = useNetwork();

const [searchAdvancedFiltersForm] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {canBeMissing: true});
Expand All @@ -45,6 +45,7 @@ function SearchFiltersWorkspacePage() {
shouldShowPendingDeletePolicy: false,
selectedPolicyIDs: selectedOptions,
searchTerm: debouncedSearchTerm,
localeCompare,
});

const selectWorkspace = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function IOURequestStepPerDiemWorkspace({
},
transaction,
}: IOURequestStepPerDiemWorkspaceProps) {
const {translate} = useLocalize();
const {translate, localeCompare} = useLocalize();
const {login: currentUserLogin, accountID} = useCurrentUserPersonalDetails();
const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true});

Expand All @@ -46,6 +46,7 @@ function IOURequestStepPerDiemWorkspace({
{policyID: policy1.id, name: policy1.name},
{policyID: policy2.id, name: policy2.name},
selectedWorkspace?.policyID ? [selectedWorkspace?.policyID] : [],
localeCompare,
),
)
.map((policy) => ({
Expand All @@ -63,7 +64,7 @@ function IOURequestStepPerDiemWorkspace({
],
isSelected: selectedWorkspace?.policyID === policy.id,
}));
}, [allPolicies, currentUserLogin, selectedWorkspace]);
}, [allPolicies, currentUserLogin, selectedWorkspace, localeCompare]);

const selectWorkspace = (item: WorkspaceListItem) => {
const policyExpenseReportID = getPolicyExpenseChat(accountID, item.value)?.reportID;
Expand Down
5 changes: 3 additions & 2 deletions src/pages/iou/request/step/IOURequestStepSendFrom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type IOURequestStepSendFromProps = WithWritableReportOrNotFoundProps<typeof SCRE
WithFullTransactionOrNotFoundProps<typeof SCREENS.MONEY_REQUEST.STEP_SEND_FROM>;

function IOURequestStepSendFrom({route, transaction}: IOURequestStepSendFromProps) {
const {translate} = useLocalize();
const {translate, localeCompare} = useLocalize();
const {transactionID, backTo} = route.params;
const [currentUserLogin] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.email, canBeMissing: false});
const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true});
Expand All @@ -42,6 +42,7 @@ function IOURequestStepSendFrom({route, transaction}: IOURequestStepSendFromProp
{policyID: policy1.id, name: policy1.name},
{policyID: policy2.id, name: policy2.name},
selectedWorkspace?.policyID ? [selectedWorkspace?.policyID] : [],
localeCompare,
),
)
.map((policy) => ({
Expand All @@ -59,7 +60,7 @@ function IOURequestStepSendFrom({route, transaction}: IOURequestStepSendFromProp
],
isSelected: selectedWorkspace?.policyID === policy.id,
}));
}, [allPolicies, currentUserLogin, selectedWorkspace]);
}, [allPolicies, currentUserLogin, selectedWorkspace, localeCompare]);

const navigateBack = () => {
Navigation.goBack(backTo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';

function NetSuiteImportPage({policy}: WithPolicyConnectionsProps) {
const {translate} = useLocalize();
const {translate, localeCompare} = useLocalize();
const styles = useThemeStyles();
const {isBetaEnabled} = usePermissions();

Expand Down Expand Up @@ -131,7 +131,7 @@ function NetSuiteImportPage({policy}: WithPolicyConnectionsProps) {
shouldDisableStrikeThrough
>
<MenuItemWithTopDescription
title={getNetSuiteImportCustomFieldLabel(policy, importField, translate)}
title={getNetSuiteImportCustomFieldLabel(policy, importField, translate, localeCompare)}
description={translate(`workspace.netsuite.import.importCustomFields.${importField}.title`)}
shouldShowRightIcon
onPress={() => {
Expand Down
39 changes: 39 additions & 0 deletions tests/unit/PolicyUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
getUnitRateValue,
isUserInvitedToWorkspace,
shouldShowPolicy,
sortWorkspacesBySelected,
} from '@libs/PolicyUtils';
import {isWorkspaceEligibleForReportChange} from '@libs/ReportUtils';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -854,4 +855,42 @@ describe('PolicyUtils', () => {
expect(tagList.name).toEqual(expected);
});
});
describe('sortWorkspacesBySelected', () => {
it('should order workspaces with selected workspace first', () => {
const workspace1 = {policyID: '1', name: 'Workspace 1'};
const workspace2 = {policyID: '2', name: 'Workspace 2'};
const selectedWorkspace1 = {policyID: '3', name: 'Workspace 3'};
const selectedWorkspace2 = {policyID: '4', name: 'Workspace 4'};
expect(sortWorkspacesBySelected(workspace1, workspace2, ['3', '4'], TestHelper.localeCompare)).toBe(-1);
expect(sortWorkspacesBySelected(workspace1, selectedWorkspace1, ['3', '4'], TestHelper.localeCompare)).toBe(1);
expect(sortWorkspacesBySelected(selectedWorkspace1, selectedWorkspace2, ['3', '4'], TestHelper.localeCompare)).toBe(-1);
Comment thread
shubham1206agra marked this conversation as resolved.
});

it('should order workspaces using name if no workspace is selected', () => {
const workspace1 = {policyID: '1', name: 'Workspace 1'};
const workspace2 = {policyID: '2', name: 'Workspace 2'};
const workspace3 = {policyID: '3', name: 'Workspace 3'};
const workspace4 = {policyID: '4', name: 'Workspace 4'};
expect(sortWorkspacesBySelected(workspace1, workspace2, undefined, TestHelper.localeCompare)).toBe(-1);
expect(sortWorkspacesBySelected(workspace1, workspace3, undefined, TestHelper.localeCompare)).toBe(-1);
expect(sortWorkspacesBySelected(workspace3, workspace4, undefined, TestHelper.localeCompare)).toBe(-1);
});

it('should sort workspaces when using this method correctly', () => {
const unsortedWorkspaces = [
{policyID: '2', name: 'Workspace 2'},
{policyID: '1', name: 'Workspace 1'},
{policyID: '4', name: 'Workspace 4'},
{policyID: '3', name: 'Workspace 3'},
];
const selectedWorkspaceIDs = ['3', '4'];
const sortedWorkspaces = unsortedWorkspaces.sort((a, b) => sortWorkspacesBySelected(a, b, selectedWorkspaceIDs, TestHelper.localeCompare));
expect(sortedWorkspaces).toEqual([
{policyID: '3', name: 'Workspace 3'},
{policyID: '4', name: 'Workspace 4'},
{policyID: '1', name: 'Workspace 1'},
{policyID: '2', name: 'Workspace 2'},
]);
});
});
});
Loading