Skip to content
Draft
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
901 changes: 228 additions & 673 deletions .github/actions/javascript/authorChecklist/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/awaitStagingDeploys/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/bumpVersion/index.js

Large diffs are not rendered by default.

903 changes: 229 additions & 674 deletions .github/actions/javascript/checkAndroidStatus/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/checkDeployBlockers/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/checkSVGCompression/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/failureNotifier/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/formatCodeCovComment/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/generateHelpPreviewComment/index.js

Large diffs are not rendered by default.

903 changes: 229 additions & 674 deletions .github/actions/javascript/getAndroidRolloutPercentage/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/getArtifactInfo/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/getDeployPullRequestList/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/getPreviousVersion/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/getPullRequestDetails/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/getPullRequestIncrementalChanges/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/isAuthorizedContributor/index.js

Large diffs are not rendered by default.

1,208 changes: 369 additions & 839 deletions .github/actions/javascript/isDeployChecklistLocked/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/markPullRequestsAsDeployed/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/postOrReplaceComment/index.js

Large diffs are not rendered by default.

1,208 changes: 369 additions & 839 deletions .github/actions/javascript/proposalPoliceComment/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/reopenIssueWithComment/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/reviewerChecklist/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/validateReassureOutput/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/verifySignedCommits/index.js

Large diffs are not rendered by default.

901 changes: 228 additions & 673 deletions .github/actions/javascript/verifyStagingBuildsSucceeded/index.js

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,6 @@ const ONYXKEYS = {
PERSONAL_AND_WORKSPACE_CARD_LIST: 'personalAndWorkspaceCardList',
CARD_FEED_ERRORS: 'cardFeedErrors',
RAM_ONLY_SORTED_REPORT_ACTIONS: 'sortedReportActions',
LOGIN_TO_ACCOUNT_ID_MAP: 'loginToAccountIDMap',
GUIDE_ACCOUNT_IDS: 'guideAccountIDs',
SPEND_DATA_SIGNATURE: 'spendDataSignature',
ONE_ON_ONE_CHAT_REPORT_IDS: 'oneOnOneChatReportIDs',
Expand Down Expand Up @@ -2024,7 +2023,6 @@ type OnyxDerivedValuesMapping = {
[ONYXKEYS.DERIVED.PERSONAL_AND_WORKSPACE_CARD_LIST]: OnyxTypes.PersonalAndWorkspaceCardListDerivedValue;
[ONYXKEYS.DERIVED.CARD_FEED_ERRORS]: OnyxTypes.CardFeedErrorsDerivedValue;
[ONYXKEYS.DERIVED.RAM_ONLY_SORTED_REPORT_ACTIONS]: OnyxTypes.SortedReportActionsDerivedValue;
[ONYXKEYS.DERIVED.LOGIN_TO_ACCOUNT_ID_MAP]: OnyxTypes.LoginToAccountIDMapDerivedValue;
[ONYXKEYS.DERIVED.SPEND_DATA_SIGNATURE]: OnyxTypes.SpendDataSignatureDerivedValue;
[ONYXKEYS.DERIVED.GUIDE_ACCOUNT_IDS]: OnyxTypes.GuideAccountIDsDerivedValue;
[ONYXKEYS.DERIVED.ONE_ON_ONE_CHAT_REPORT_IDS]: OnyxTypes.OneOnOneChatReportIDsDerivedValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import UserPills from '@components/UserPills';

import useAttendees from '@hooks/useAttendees';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useLoginToAccountIDMap from '@hooks/useLoginToAccountIDMap';

import {enrichAndSortAttendees} from '@libs/AttendeeUtils';
import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute';
Expand All @@ -17,7 +17,6 @@ import {callFunctionIfActionIsAllowed} from '@userActions/Session';
import CONST from '@src/CONST';
import type {IOUAction, IOUType} from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import {DYNAMIC_ROUTES} from '@src/ROUTES';
import type * as OnyxTypes from '@src/types/onyx';

Expand All @@ -44,7 +43,7 @@ function AttendeeField({formattedAmountPerAttendee, isReadOnly, transactionID, a
const {shouldUseDropdownRows} = useExpenseFormLayout();
const {translate, localeCompare} = useLocalize();
const personalDetailsList = usePersonalDetails();
const [loginToAccountIDMap] = useOnyx(ONYXKEYS.DERIVED.LOGIN_TO_ACCOUNT_ID_MAP);
const loginToAccountIDMap = useLoginToAccountIDMap();
const shouldDisplayAttendeesError = formError === 'violations.missingAttendees';

const attendeeSlice = useTransactionSelector(transactionID, attendeeSliceSelector);
Expand Down
3 changes: 2 additions & 1 deletion src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import useEnvironment from '@hooks/useEnvironment';
import useHasMultipleSplitChildren from '@hooks/useHasMultipleSplitChildren';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useLoginToAccountIDMap from '@hooks/useLoginToAccountIDMap';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePermissions from '@hooks/usePermissions';
Expand Down Expand Up @@ -224,7 +225,7 @@ function MoneyRequestView({
const {convertToDisplayString, getCurrencySymbol, getCurrencyDecimals} = useCurrencyListActions();
const {getReportRHPActiveRoute} = useActiveRoute();
const {showConfirmModal} = useConfirmModal();
const [loginToAccountIDMap] = useOnyx(ONYXKEYS.DERIVED.LOGIN_TO_ACCOUNT_ID_MAP);
const loginToAccountIDMap = useLoginToAccountIDMap();

const {currentSearchResults} = useSearchResultsContext();

Expand Down
10 changes: 5 additions & 5 deletions src/components/Search/SearchList/ListItem/AttendeesCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import UserDetailsTooltip from '@components/UserDetailsTooltip';

import useDefaultAvatars from '@hooks/useDefaultAvatars';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import {useAllPersonalDetailsWithoutSnapshots} from '@hooks/usePersonalDetails';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
Expand All @@ -17,10 +17,10 @@ import colors from '@styles/theme/colors';
import variables from '@styles/variables';

import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Attendee} from '@src/types/onyx/IOU';
import type {Icon as IconType} from '@src/types/onyx/OnyxCommon';

import {accountIDsByLoginsSelector} from '@selectors/PersonalDetails';
import React from 'react';
import {View} from 'react-native';

Expand All @@ -32,9 +32,9 @@ type AttendeesCellProps = {

function AttendeesCell({attendees, isHovered, isPressed}: AttendeesCellProps) {
const defaultAvatars = useDefaultAvatars();
const [loginToAccountIDMap] = useOnyx(ONYXKEYS.DERIVED.LOGIN_TO_ACCOUNT_ID_MAP);
const attendeeIcons: IconType[] = attendees.map((attendee) => {
const accountID = loginToAccountIDMap?.[attendee.email ?? ''] ?? CONST.DEFAULT_NUMBER_ID;
const [attendeeAccountIDs] = useAllPersonalDetailsWithoutSnapshots(accountIDsByLoginsSelector(attendees.map((attendee) => attendee.email)));
const attendeeIcons: IconType[] = attendees.map((attendee, index) => {
const accountID = attendeeAccountIDs?.at(index) ?? CONST.DEFAULT_NUMBER_ID;
return {
id: accountID,
name: attendee.displayName ?? attendee.email,
Expand Down
7 changes: 5 additions & 2 deletions src/components/Table/TableBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ function TableBodyList({contentContainerStyle, emptyMessage, onLayout, style, ..
noResultsStateElement,
tableListMetadata,
isEmptyResult,
isDefaultViewEmpty,
scrollWidth,
tableWidth,
} = useTableContext<TableData>();
Expand Down Expand Up @@ -337,8 +338,10 @@ function TableBodyList({contentContainerStyle, emptyMessage, onLayout, style, ..
</View>
);

const emptyStateContent =
tableListMetadata.hasPageHeader && isEmptyResult ? (noResultsStateElement ?? EmptyResultComponent) : (emptyStateElement ?? renderListComponent(ListEmptyComponent));
// When the default view hides every row (e.g. all workspaces are archived), no search or filter is active,
// so show the empty state rather than "No results".
const shouldShowNoResultsState = tableListMetadata.hasPageHeader && isEmptyResult && !isDefaultViewEmpty;
const emptyStateContent = shouldShowNoResultsState ? (noResultsStateElement ?? EmptyResultComponent) : (emptyStateElement ?? renderListComponent(ListEmptyComponent));
const footerElement = renderListComponent(ListFooterComponent);
// Consumer footer flex growth is useful below normal rows, but inside the combined empty-state
// footer it can expand over the page header. Preserve the remaining style while disabling growth.
Expand Down
5 changes: 3 additions & 2 deletions src/components/Table/TableEmptyStates/TableNoResultsState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ type TableNoResultsStateProps = Omit<GenericEmptyStateComponentProps, 'headerMed
export default function TableNoResultsState(emptyStateProps: TableNoResultsStateProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {isEmptyResult, tableListMetadata} = useTableContext();
const {isEmptyResult, isDefaultViewEmpty, tableListMetadata} = useTableContext();
const illustrations = useMemoizedLazyIllustrations(['EmptyShelves']);

if (!isEmptyResult) {
// The default view hiding every row is not a search/filter result, so the empty state handles it instead.
if (!isEmptyResult || isDefaultViewEmpty) {
return null;
}

Expand Down
10 changes: 10 additions & 0 deletions src/hooks/useLoginToAccountIDMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {loginToAccountIDMapSelector} from '@selectors/PersonalDetails';

import {useAllPersonalDetailsWithoutSnapshots} from './usePersonalDetails';

function useLoginToAccountIDMap() {
const [loginToAccountIDMap] = useAllPersonalDetailsWithoutSnapshots(loginToAccountIDMapSelector);
return loginToAccountIDMap;
}

export default useLoginToAccountIDMap;
4 changes: 2 additions & 2 deletions src/libs/AttendeeUtils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {LocaleContextProps} from '@components/LocaleContextProvider';

import CONST from '@src/CONST';
import type {LoginToAccountIDMapDerivedValue, PersonalDetailsList, PolicyCategories} from '@src/types/onyx';
import type {PersonalDetailsList, PolicyCategories} from '@src/types/onyx';
import type {Attendee} from '@src/types/onyx/IOU';
import type {CurrentUserPersonalDetails} from '@src/types/onyx/PersonalDetails';

Expand Down Expand Up @@ -134,7 +134,7 @@ type AttendeeWithAccountID = Attendee & {accountID?: number};
*/
function enrichAndSortAttendees(
attendees: Attendee[] | undefined,
loginToAccountIDMap: OnyxEntry<LoginToAccountIDMapDerivedValue>,
loginToAccountIDMap: OnyxEntry<Record<string, number>>,
personalDetailsList: OnyxEntry<PersonalDetailsList>,
localeCompare: LocaleContextProps['localeCompare'],
): AttendeeWithAccountID[] | undefined {
Expand Down
2 changes: 0 additions & 2 deletions src/libs/actions/OnyxDerived/ONYX_DERIVED_VALUES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import type {OnyxDerivedValueConfig} from './types';

import cardFeedErrorsConfig from './configs/cardFeedErrors';
import guideAccountIDsConfig from './configs/guideAccountIDs';
import loginToAccountIDMapConfig from './configs/loginToAccountIDMap';
import nonPersonalAndWorkspaceCardListConfig from './configs/nonPersonalAndWorkspaceCardList';
import oneOnOneChatReportIDsConfig from './configs/oneOnOneChatReportIDs';
import outstandingReportsByPolicyIDConfig from './configs/outstandingReportsByPolicyID';
Expand All @@ -30,7 +29,6 @@ const ONYX_DERIVED_VALUES = {
[ONYXKEYS.DERIVED.PERSONAL_AND_WORKSPACE_CARD_LIST]: personalAndWorkspaceCardListConfig,
[ONYXKEYS.DERIVED.CARD_FEED_ERRORS]: cardFeedErrorsConfig,
[ONYXKEYS.DERIVED.RAM_ONLY_SORTED_REPORT_ACTIONS]: sortedReportActionsConfig,
[ONYXKEYS.DERIVED.LOGIN_TO_ACCOUNT_ID_MAP]: loginToAccountIDMapConfig,
[ONYXKEYS.DERIVED.GUIDE_ACCOUNT_IDS]: guideAccountIDsConfig,
[ONYXKEYS.DERIVED.SPEND_DATA_SIGNATURE]: spendDataSignatureConfig,
[ONYXKEYS.DERIVED.ONE_ON_ONE_CHAT_REPORT_IDS]: oneOnOneChatReportIDsConfig,
Expand Down
37 changes: 0 additions & 37 deletions src/libs/actions/OnyxDerived/configs/loginToAccountIDMap.ts

This file was deleted.

39 changes: 39 additions & 0 deletions src/selectors/PersonalDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,43 @@ const optimisticPersonalDetailsSelector = (personalDetailsList: OnyxEntry<Person
return optimisticPersonalDetails;
};

const loginToAccountIDMapCache = new WeakMap<PersonalDetailsList, Record<string, number>>();

/**
* Maps each lowercased login to its accountID. When two accounts share a login, a closed or optimistic one loses to the other.
* Cached on the list reference, so every Search row that reads it after the same write shares one build.
*/
const loginToAccountIDMapSelector = (personalDetailsList: OnyxEntry<PersonalDetailsList>): Record<string, number> => {
if (!personalDetailsList) {
return {};
}

const cachedLoginToAccountIDMap = loginToAccountIDMapCache.get(personalDetailsList);
if (cachedLoginToAccountIDMap) {
return cachedLoginToAccountIDMap;
}

const loginToAccountIDMap: Record<string, number> = {};
for (const personalDetails of Object.values(personalDetailsList)) {
if (!personalDetails?.login) {
continue;
}
const login = personalDetails.login.toLowerCase();
const existingAccountID = loginToAccountIDMap[login];
const existingDetail = existingAccountID === undefined ? undefined : personalDetailsList[existingAccountID];
if (!existingDetail || existingDetail.isClosed || existingDetail.isOptimisticPersonalDetail) {
loginToAccountIDMap[login] = personalDetails.accountID;
}
}
loginToAccountIDMapCache.set(personalDetailsList, loginToAccountIDMap);
return loginToAccountIDMap;
};

const accountIDsByLoginsSelector = (logins: Array<string | undefined>) => (personalDetailsList: OnyxEntry<PersonalDetailsList>) => {
const loginToAccountIDMap = loginToAccountIDMapSelector(personalDetailsList);
return logins.map((login) => loginToAccountIDMap[login ?? ''] ?? CONST.DEFAULT_NUMBER_ID);
};

const newAccountIDsAndLoginsSelector = (invitedEmailsToAccountIDs: InvitedEmailsToAccountIDs | undefined) => (personalDetailsList: OnyxEntry<PersonalDetailsList>) =>
getNewAccountIDsAndLogins(invitedEmailsToAccountIDs, personalDetailsList);

Expand Down Expand Up @@ -125,6 +162,8 @@ export {
accountIDToLoginSelector,
isPersonalDetailOptimistic,
optimisticPersonalDetailsSelector,
loginToAccountIDMapSelector,
accountIDsByLoginsSelector,
createDisplayDetailsByAccountIDsSelector,
newAccountIDsAndLoginsSelector,
displayNameSelector,
Expand Down
9 changes: 0 additions & 9 deletions src/types/onyx/DerivedValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,6 @@ type SortedReportActionsDerivedValue = {
*/
type PersonalAndWorkspaceCardListDerivedValue = CardList;

/**
* The derived value mapping each user's login (lowercased) to their accountID.
*
* Replaces the imperative `emailToPersonalDetailsCache` login lookup that was built via `Onyx.connect`
* in `PersonalDetailsUtils` (see issue #66391). Keys are lowercased since logins/emails are case-insensitive.
*/
type LoginToAccountIDMapDerivedValue = Record<string, number>;

/**
* The accountIDs of every Expensify Guide known to the personal details list, sorted ascending.
* Lets callers check for a guide participant without re-scanning the whole list (see issue #66413).
Expand Down Expand Up @@ -255,7 +247,6 @@ export type {
NonPersonalAndWorkspaceCardListDerivedValue,
PersonalAndWorkspaceCardListDerivedValue,
CardFeedErrorsDerivedValue,
LoginToAccountIDMapDerivedValue,
GuideAccountIDsDerivedValue,
SpendDataSignatureDerivedValue,
OneOnOneChatReportIDsDerivedValue,
Expand Down
2 changes: 0 additions & 2 deletions src/types/onyx/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import type {
CardFeedErrorsDerivedValue,
GuideAccountIDsDerivedValue,
SpendDataSignatureDerivedValue,
LoginToAccountIDMapDerivedValue,
NonPersonalAndWorkspaceCardListDerivedValue,
OneOnOneChatReportIDsDerivedValue,
OutstandingReportsByPolicyIDDerivedValue,
Expand Down Expand Up @@ -501,7 +500,6 @@ export type {
NonPersonalAndWorkspaceCardListDerivedValue,
PersonalAndWorkspaceCardListDerivedValue,
CardFeedErrorsDerivedValue,
LoginToAccountIDMapDerivedValue,
GuideAccountIDsDerivedValue,
SpendDataSignatureDerivedValue,
OneOnOneChatReportIDsDerivedValue,
Expand Down
Loading
Loading