Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate POLICY_MEMBERS #39489

Merged
merged 29 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d3d4805
Remove policyMembersDraft and policyMembers part-1
ZhenjaHorbach Apr 3, 2024
5e84a32
Remove policyMembersDraft and policyMembers part-2
ZhenjaHorbach Apr 3, 2024
e154c4a
Remove policyMembersDraft and policyMembers part-3
ZhenjaHorbach Apr 3, 2024
72a467f
Remove policyMembers from WorkspaceWorkflowsApproverPage and revert c…
ZhenjaHorbach Apr 6, 2024
224f2b7
Remove policyMembers from ReportScreenIDSetter and refactor PolicyMem…
ZhenjaHorbach Apr 6, 2024
99c6a28
Remove policyMembers from SidebarLinksData
ZhenjaHorbach Apr 6, 2024
23235b6
Remove policyMembers from WorkspaceMembersPage
ZhenjaHorbach Apr 6, 2024
b3cc1d0
Remove POLICY_MEMBERS from utils
ZhenjaHorbach Apr 6, 2024
fbe42b2
Make a little code refactoring
ZhenjaHorbach Apr 6, 2024
51b290c
Fix conflicts and update branch
ZhenjaHorbach Apr 6, 2024
a9c77e9
Fix ts issue
ZhenjaHorbach Apr 6, 2024
1bc67dc
Refactor code and fix some issues
ZhenjaHorbach Apr 6, 2024
afa8239
Update PolicyMembersUtils
ZhenjaHorbach Apr 8, 2024
d682d32
Fix bug with selected item on WorkspaceMemberDetailsRoleSelectionPage
ZhenjaHorbach Apr 8, 2024
2f65c5f
Fix conflicts and update branch
ZhenjaHorbach Apr 8, 2024
657e5ec
Fix comments
ZhenjaHorbach Apr 8, 2024
57ae55d
Fix eslint issues
ZhenjaHorbach Apr 8, 2024
fd47bb4
Fix ts and eslint issues
ZhenjaHorbach Apr 8, 2024
5d8ce6c
Fix conflicts and update branch
ZhenjaHorbach Apr 9, 2024
9809d45
Fix bug and rename policyMembers
ZhenjaHorbach Apr 9, 2024
26c2ab4
Fix conflicts and update branch
ZhenjaHorbach Apr 9, 2024
851ee9b
Fix eslint issue
ZhenjaHorbach Apr 9, 2024
a4c72ec
Fix bug with paddingTop on RoleModal
ZhenjaHorbach Apr 10, 2024
9ab0516
Fix conflicts and update branch
ZhenjaHorbach Apr 14, 2024
2fc2ddd
Fix eslint issue
ZhenjaHorbach Apr 14, 2024
91f9002
Add test for employeeList
ZhenjaHorbach Apr 14, 2024
c72dfe1
Fix conflicts
ZhenjaHorbach Apr 15, 2024
48545bb
Update leaveWorkspace
ZhenjaHorbach Apr 15, 2024
905134e
Fix conflicts and update branch
ZhenjaHorbach Apr 16, 2024
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
4 changes: 0 additions & 4 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,7 @@ const ONYXKEYS = {
COLLECTION: {
DOWNLOAD: 'download_',
POLICY: 'policy_',
POLICY_MEMBERS: 'policyMembers_',
POLICY_DRAFTS: 'policyDrafts_',
POLICY_MEMBERS_DRAFTS: 'policyMembersDrafts_',
POLICY_JOIN_MEMBER: 'policyJoinMember_',
POLICY_CATEGORIES: 'policyCategories_',
POLICY_RECENTLY_USED_CATEGORIES: 'policyRecentlyUsedCategories_',
Expand Down Expand Up @@ -518,8 +516,6 @@ type OnyxCollectionValuesMapping = {
[ONYXKEYS.COLLECTION.POLICY_DRAFTS]: OnyxTypes.Policy;
[ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: OnyxTypes.PolicyCategories;
[ONYXKEYS.COLLECTION.POLICY_TAGS]: OnyxTypes.PolicyTagList;
[ONYXKEYS.COLLECTION.POLICY_MEMBERS]: OnyxTypes.PolicyMembers;
[ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS]: OnyxTypes.PolicyMember;
[ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES]: OnyxTypes.RecentlyUsedCategories;
[ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyMembers;
[ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT]: OnyxTypes.InvitedEmailsToAccountIDs;
Expand Down
13 changes: 3 additions & 10 deletions src/components/Indicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ import * as PolicyUtils from '@libs/PolicyUtils';
import * as UserUtils from '@libs/UserUtils';
import * as PaymentMethods from '@userActions/PaymentMethods';
import ONYXKEYS from '@src/ONYXKEYS';
import type {BankAccountList, FundList, LoginList, Policy, PolicyMembers, ReimbursementAccount, UserWallet, WalletTerms} from '@src/types/onyx';
import type {BankAccountList, FundList, LoginList, Policy, ReimbursementAccount, UserWallet, WalletTerms} from '@src/types/onyx';

type CheckingMethod = () => boolean;

type IndicatorOnyxProps = {
/** The employee list of all policies (coming from Onyx) */
allPolicyMembers: OnyxCollection<PolicyMembers>;

/** All the user's policies (from Onyx via withFullPolicy) */
policies: OnyxCollection<Policy>;

Expand All @@ -40,14 +37,13 @@ type IndicatorOnyxProps = {

type IndicatorProps = IndicatorOnyxProps;

function Indicator({reimbursementAccount, allPolicyMembers, policies, bankAccountList, fundList, userWallet, walletTerms, loginList}: IndicatorOnyxProps) {
function Indicator({reimbursementAccount, policies, bankAccountList, fundList, userWallet, walletTerms, loginList}: IndicatorOnyxProps) {
const theme = useTheme();
const styles = useThemeStyles();

// If a policy was just deleted from Onyx, then Onyx will pass a null value to the props, and
// those should be cleaned out before doing any error checking
const cleanPolicies = Object.fromEntries(Object.entries(policies ?? {}).filter(([, policy]) => policy?.id));
const cleanAllPolicyMembers = Object.fromEntries(Object.entries(allPolicyMembers ?? {}).filter(([, policyMembers]) => !!policyMembers));

// All of the error & info-checking methods are put into an array. This is so that using _.some() will return
// early as soon as the first error / info condition is returned. This makes the checks very efficient since
Expand All @@ -57,7 +53,7 @@ function Indicator({reimbursementAccount, allPolicyMembers, policies, bankAccoun
() => PaymentMethods.hasPaymentMethodError(bankAccountList, fundList),
() => Object.values(cleanPolicies).some(PolicyUtils.hasPolicyError),
() => Object.values(cleanPolicies).some(PolicyUtils.hasCustomUnitsError),
() => Object.values(cleanAllPolicyMembers).some(PolicyUtils.hasPolicyMemberError),
() => Object.values(cleanPolicies).some(PolicyUtils.hasEmployeeListError),
() => Object.keys(reimbursementAccount?.errors ?? {}).length > 0,
() => !!loginList && UserUtils.hasLoginListError(loginList),

Expand All @@ -77,9 +73,6 @@ function Indicator({reimbursementAccount, allPolicyMembers, policies, bankAccoun
Indicator.displayName = 'Indicator';

export default withOnyx<IndicatorProps, IndicatorOnyxProps>({
allPolicyMembers: {
key: ONYXKEYS.COLLECTION.POLICY_MEMBERS,
},
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
Expand Down
19 changes: 9 additions & 10 deletions src/libs/Navigation/AppNavigator/ReportScreenIDSetter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import usePermissions from '@hooks/usePermissions';
import {getPolicyMembersByIdWithoutCurrentUser} from '@libs/PolicyUtils';
import * as ReportUtils from '@libs/ReportUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Policy, PolicyMembers, Report, ReportMetadata} from '@src/types/onyx';
import type {PersonalDetailsList, Policy, Report, ReportMetadata} from '@src/types/onyx';
import type {ReportScreenWrapperProps} from './ReportScreenWrapper';

type ReportScreenIDSetterComponentProps = {
Expand All @@ -16,8 +16,8 @@ type ReportScreenIDSetterComponentProps = {
/** The policies which the user has access to */
policies: OnyxCollection<Policy>;

/** Members of all the workspaces the user is member of */
policyMembers: OnyxCollection<PolicyMembers>;
/** The personal details of the person who is logged in */
personalDetails: OnyxEntry<PersonalDetailsList>;

/** Whether user is a new user */
isFirstTimeNewExpensifyUser: OnyxEntry<boolean>;
Expand Down Expand Up @@ -58,7 +58,7 @@ const getLastAccessedReportID = (
};

// This wrapper is reponsible for opening the last accessed report if there is no reportID specified in the route params
function ReportScreenIDSetter({route, reports, policies, policyMembers = {}, navigation, isFirstTimeNewExpensifyUser = false, reportMetadata, accountID}: ReportScreenIDSetterProps) {
function ReportScreenIDSetter({route, reports, policies, navigation, isFirstTimeNewExpensifyUser = false, reportMetadata, accountID, personalDetails}: ReportScreenIDSetterProps) {
const {canUseDefaultRooms} = usePermissions();
const {activeWorkspaceID} = useActiveWorkspace();

Expand All @@ -73,7 +73,7 @@ function ReportScreenIDSetter({route, reports, policies, policyMembers = {}, nav
return;
}

const policyMemberAccountIDs = getPolicyMembersByIdWithoutCurrentUser(policyMembers, activeWorkspaceID, accountID);
const policyMemberAccountIDs = getPolicyMembersByIdWithoutCurrentUser(policies, personalDetails, activeWorkspaceID, accountID);

// If there is no reportID in route, try to find last accessed and use it for setParams
const reportID = getLastAccessedReportID(
Expand All @@ -92,7 +92,7 @@ function ReportScreenIDSetter({route, reports, policies, policyMembers = {}, nav
if (reportID) {
navigation.setParams({reportID: String(reportID)});
}
}, [route, navigation, reports, canUseDefaultRooms, policies, isFirstTimeNewExpensifyUser, reportMetadata, activeWorkspaceID, policyMembers, accountID]);
}, [route, navigation, reports, canUseDefaultRooms, policies, isFirstTimeNewExpensifyUser, reportMetadata, activeWorkspaceID, personalDetails, accountID]);

// The ReportScreen without the reportID set will display a skeleton
// until the reportID is loaded and set in the route param
Expand All @@ -110,10 +110,6 @@ export default withOnyx<ReportScreenIDSetterProps, ReportScreenIDSetterComponent
key: ONYXKEYS.COLLECTION.POLICY,
allowStaleData: true,
},
policyMembers: {
key: ONYXKEYS.COLLECTION.POLICY_MEMBERS,
allowStaleData: true,
},
isFirstTimeNewExpensifyUser: {
key: ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER,
initialValue: false,
Expand All @@ -126,4 +122,7 @@ export default withOnyx<ReportScreenIDSetterProps, ReportScreenIDSetterComponent
key: ONYXKEYS.SESSION,
selector: (session) => session?.accountID,
},
personalDetails: {
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
},
})(ReportScreenIDSetter);
18 changes: 12 additions & 6 deletions src/libs/PolicyMembersUtils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import type {OnyxCollection} from 'react-native-onyx';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PolicyMembers} from '@src/types/onyx';
import type {PersonalDetailsList, Policy} from '@src/types/onyx';
import {getCurrentUserAccountID} from './actions/Report';
import {getPolicyMembersByIdWithoutCurrentUser} from './PolicyUtils';

let policyMembers: OnyxCollection<PolicyMembers>;
let policies: OnyxCollection<Policy> = {};
Onyx.connect({
luacmartins marked this conversation as resolved.
Show resolved Hide resolved
key: ONYXKEYS.COLLECTION.POLICY_MEMBERS,
key: ONYXKEYS.COLLECTION.POLICY,
waitForCollectionCallback: true,
callback: (value) => (policyMembers = value),
callback: (value) => (policies = value),
});

let allPersonalDetails: OnyxEntry<PersonalDetailsList> = {};
Onyx.connect({
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (val) => (allPersonalDetails = val),
});

function getPolicyMemberAccountIDs(policyID?: string) {
Expand All @@ -19,7 +25,7 @@ function getPolicyMemberAccountIDs(policyID?: string) {

const currentUserAccountID = getCurrentUserAccountID();

return getPolicyMembersByIdWithoutCurrentUser(policyMembers, policyID, currentUserAccountID);
return getPolicyMembersByIdWithoutCurrentUser(policies, allPersonalDetails, policyID, currentUserAccountID);
}

export default getPolicyMemberAccountIDs;
49 changes: 24 additions & 25 deletions src/libs/PolicyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ function getActivePolicies(policies: OnyxCollection<Policy>): Policy[] | undefin
}

/**
* Checks if we have any errors stored within the POLICY_MEMBERS. Determines whether we should show a red brick road error or not.
* Data structure: {accountID: {role:'user', errors: []}, accountID2: {role:'admin', errors: [{1231312313: 'Unable to do X'}]}, ...}
* Checks if we have any errors stored within the policy?.employeeList. Determines whether we should show a red brick road error or not.
*/
function hasPolicyMemberError(policyMembers: OnyxEntry<PolicyMembers>): boolean {
return Object.values(policyMembers ?? {}).some((member) => Object.keys(member?.errors ?? {}).length > 0);
function hasEmployeeListError(policy: OnyxEntry<Policy>): boolean {
return Object.values(policy?.employeeList ?? {}).some((employee) => Object.keys(employee?.errors ?? {}).length > 0);
}

/**
Expand Down Expand Up @@ -90,9 +89,8 @@ function getUnitRateValue(toLocaleDigit: (arg: string) => string, customUnitRate
/**
* Get the brick road indicator status for a policy. The policy has an error status if there is a policy member error, a custom unit error or a field error.
*/
function getPolicyBrickRoadIndicatorStatus(policy: OnyxEntry<Policy>, policyMembersCollection: OnyxCollection<PolicyMembers>): ValueOf<typeof CONST.BRICK_ROAD_INDICATOR_STATUS> | undefined {
const policyMembers = policyMembersCollection?.[`${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${policy?.id}`] ?? {};
if (hasPolicyMemberError(policyMembers) || hasCustomUnitsError(policy) || hasPolicyErrorFields(policy)) {
function getPolicyBrickRoadIndicatorStatus(policy: OnyxEntry<Policy>): ValueOf<typeof CONST.BRICK_ROAD_INDICATOR_STATUS> | undefined {
if (hasEmployeeListError(policy) || hasCustomUnitsError(policy) || hasPolicyErrorFields(policy)) {
return CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
}
return undefined;
Expand Down Expand Up @@ -135,38 +133,39 @@ const isPolicyMember = (policyID: string, policies: OnyxCollection<Policy>): boo
*
* We only return members without errors. Otherwise, the members with errors would immediately be removed before the user has a chance to read the error.
*/
function getMemberAccountIDsForWorkspace(policyMembers: OnyxEntry<PolicyMembers>, personalDetails: OnyxEntry<PersonalDetailsList>): MemberEmailsToAccountIDs {
function getMemberAccountIDsForWorkspace(employeeList: PolicyMembers | undefined, personalDetails: OnyxEntry<PersonalDetailsList>): MemberEmailsToAccountIDs {
const members = employeeList ?? {};
const memberEmailsToAccountIDs: MemberEmailsToAccountIDs = {};
Object.keys(policyMembers ?? {}).forEach((accountID) => {
const member = policyMembers?.[accountID];
Object.keys(members).forEach((email) => {
const member = members?.[email];
if (Object.keys(member?.errors ?? {})?.length > 0) {
return;
}
const personalDetail = personalDetails?.[accountID];
const personalDetail = Object.values(personalDetails ?? {})?.find((details) => details?.login === email);
luacmartins marked this conversation as resolved.
Show resolved Hide resolved
if (!personalDetail?.login) {
return;
}
memberEmailsToAccountIDs[personalDetail.login] = Number(accountID);
memberEmailsToAccountIDs[email] = Number(personalDetail.accountID);
});
return memberEmailsToAccountIDs;
}

/**
* Get login list that we should not show in the workspace invite options
*/
function getIneligibleInvitees(policyMembers: OnyxEntry<PolicyMembers>, personalDetails: OnyxEntry<PersonalDetailsList>): string[] {
function getIneligibleInvitees(employeeList?: PolicyMembers): string[] {
const members = employeeList ?? {};
const memberEmailsToExclude: string[] = [...CONST.EXPENSIFY_EMAILS];
Object.keys(policyMembers ?? {}).forEach((accountID) => {
const policyMember = policyMembers?.[accountID];
Object.keys(members).forEach((email) => {
const policyMember = members?.[email];
// Policy members that are pending delete or have errors are not valid and we should show them in the invite options (don't exclude them).
if (policyMember?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || Object.keys(policyMember?.errors ?? {}).length > 0) {
return;
}
const memberEmail = personalDetails?.[accountID]?.login;
if (!memberEmail) {
if (!email) {
return;
}
memberEmailsToExclude.push(memberEmail);
memberEmailsToExclude.push(email);
});

return memberEmailsToExclude;
Expand Down Expand Up @@ -278,12 +277,12 @@ function getPathWithoutPolicyID(path: string) {
return path.replace(CONST.REGEX.PATH_WITHOUT_POLICY_ID, '/');
}

function getPolicyMembersByIdWithoutCurrentUser(policyMembers: OnyxCollection<PolicyMembers>, currentPolicyID?: string, currentUserAccountID?: number) {
return policyMembers
? Object.keys(policyMembers[`${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${currentPolicyID}`] ?? {})
.map((policyMemberAccountID) => Number(policyMemberAccountID))
.filter((policyMemberAccountID) => policyMemberAccountID !== currentUserAccountID)
: [];
function getPolicyMembersByIdWithoutCurrentUser(policies: OnyxCollection<Policy>, personalDetails: OnyxEntry<PersonalDetailsList>, currentPolicyID?: string, currentUserAccountID?: number) {
const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${currentPolicyID}`] ?? null;
const policyMemberEmailsToAccountIDs = getMemberAccountIDsForWorkspace(policy?.employeeList, personalDetails);
return Object.values(policyMemberEmailsToAccountIDs)
.map((policyMemberAccountID) => Number(policyMemberAccountID))
.filter((policyMemberAccountID) => policyMemberAccountID !== currentUserAccountID);
}

function goBackFromInvalidPolicy() {
Expand Down Expand Up @@ -320,7 +319,7 @@ function getPolicyIDFromNavigationState() {
export {
getActivePolicies,
hasAccountingConnections,
hasPolicyMemberError,
hasEmployeeListError,
hasPolicyError,
hasPolicyErrorFields,
hasCustomUnitsError,
Expand Down
23 changes: 6 additions & 17 deletions src/libs/WorkspacesSettingsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import type {ValueOf} from 'type-fest';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Policy, PolicyMembers, ReimbursementAccount, Report} from '@src/types/onyx';
import type {Policy, ReimbursementAccount, Report} from '@src/types/onyx';
import type {Unit} from '@src/types/onyx/Policy';
import * as CurrencyUtils from './CurrencyUtils';
import type {Phrase, PhraseParameters} from './Localize';
import * as OptionsListUtils from './OptionsListUtils';
import {hasCustomUnitsError, hasPolicyError, hasPolicyMemberError, hasTaxRateError} from './PolicyUtils';
import {hasCustomUnitsError, hasEmployeeListError, hasPolicyError, hasTaxRateError} from './PolicyUtils';
import * as ReportActionsUtils from './ReportActionsUtils';
import * as ReportUtils from './ReportUtils';

Expand All @@ -33,16 +33,6 @@ Onyx.connect({
callback: (value) => (allPolicies = value),
});

let allPolicyMembers: OnyxCollection<PolicyMembers>;

Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY_MEMBERS,
waitForCollectionCallback: true,
callback: (val) => {
allPolicyMembers = val;
},
});

let reimbursementAccount: OnyxEntry<ReimbursementAccount>;

Onyx.connect({
Expand Down Expand Up @@ -75,25 +65,24 @@ const getBrickRoadForPolicy = (report: Report): BrickRoad => {
return shouldShowGreenDotIndicator ? CONST.BRICK_ROAD_INDICATOR_STATUS.INFO : undefined;
};

function hasGlobalWorkspaceSettingsRBR(policies: OnyxCollection<Policy>, policyMembers: OnyxCollection<PolicyMembers>) {
function hasGlobalWorkspaceSettingsRBR(policies: OnyxCollection<Policy>) {
// When attempting to open a policy with an invalid policyID, the policy collection is updated to include policy objects with error information.
// Only policies displayed on the policy list page should be verified. Otherwise, the user will encounter an RBR unrelated to any policies on the list.
const cleanPolicies = Object.fromEntries(Object.entries(policies ?? {}).filter(([, policy]) => policy?.id));

const cleanAllPolicyMembers = Object.fromEntries(Object.entries(policyMembers ?? {}).filter(([, policyMemberValues]) => !!policyMemberValues));
const errorCheckingMethods: CheckingMethod[] = [
() => Object.values(cleanPolicies).some(hasPolicyError),
() => Object.values(cleanPolicies).some(hasCustomUnitsError),
() => Object.values(cleanPolicies).some(hasTaxRateError),
() => Object.values(cleanAllPolicyMembers).some(hasPolicyMemberError),
() => Object.values(cleanPolicies).some(hasEmployeeListError),
() => Object.keys(reimbursementAccount?.errors ?? {}).length > 0,
];

return errorCheckingMethods.some((errorCheckingMethod) => errorCheckingMethod());
}

function hasWorkspaceSettingsRBR(policy: Policy) {
const policyMemberError = allPolicyMembers ? hasPolicyMemberError(allPolicyMembers[`${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${policy.id}`]) : false;
const policyMemberError = hasEmployeeListError(policy);
const taxRateError = hasTaxRateError(policy);

return Object.keys(reimbursementAccount?.errors ?? {}).length > 0 || hasPolicyError(policy) || hasCustomUnitsError(policy) || policyMemberError || taxRateError;
Expand Down Expand Up @@ -130,7 +119,7 @@ function getChatTabBrickRoad(policyID?: string): BrickRoad | undefined {

function checkIfWorkspaceSettingsTabHasRBR(policyID?: string) {
if (!policyID) {
return hasGlobalWorkspaceSettingsRBR(allPolicies, allPolicyMembers);
return hasGlobalWorkspaceSettingsRBR(allPolicies);
}
const policy = allPolicies ? allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] : null;

Expand Down
Loading
Loading