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.

4 changes: 2 additions & 2 deletions __mocks__/react-native-onyx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import type {ConnectOptions, OnyxKey} from 'react-native-onyx';

// eslint-disable-next-line no-restricted-imports
import Onyx, {useOnyx} from 'react-native-onyx';
import Onyx, {useOnyx, useOnyxState} from 'react-native-onyx';

let connectCallbackDelay = 0;
function addDelayToConnectCallback(delay: number) {
Expand Down Expand Up @@ -41,4 +41,4 @@ const reactNativeOnyxMock: ReactNativeOnyxMock = {

export default reactNativeOnyxMock;

export {useOnyx};
export {useOnyx, useOnyxState};
2 changes: 0 additions & 2 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,6 @@ const ONYXKEYS = {
VISIBLE_REPORT_ACTIONS: 'visibleReportActions',
NON_PERSONAL_AND_WORKSPACE_CARD_LIST: 'nonPersonalAndWorkspaceCardList',
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',
Expand Down Expand Up @@ -2022,7 +2021,6 @@ type OnyxDerivedValuesMapping = {
[ONYXKEYS.DERIVED.VISIBLE_REPORT_ACTIONS]: OnyxTypes.VisibleReportActionsDerivedValue;
[ONYXKEYS.DERIVED.NON_PERSONAL_AND_WORKSPACE_CARD_LIST]: OnyxTypes.NonPersonalAndWorkspaceCardListDerivedValue;
[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;
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Icon from '@components/Icon';

import useCardFeedErrors from '@hooks/useCardFeedErrors';
import useHasApprovalWorkflowWithNonMemberApprover from '@hooks/useHasApprovalWorkflowWithNonMemberApprover';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useOnyx from '@hooks/useOnyx';
Expand Down Expand Up @@ -32,8 +33,7 @@ type WorkspaceRowBrickRoadIndicatorProps = {
policyID: string;
};

const createCardFeedErrorsSelector = (workspaceAccountID: number) => (cardFeedErrors: OnyxEntry<CardFeedErrors>) =>
!!cardFeedErrors?.shouldShowRbrForWorkspaceAccountID?.[workspaceAccountID];
const createCardFeedErrorsSelector = (workspaceAccountID: number) => (cardFeedErrors: CardFeedErrors) => !!cardFeedErrors.shouldShowRbrForWorkspaceAccountID[workspaceAccountID];

const createPolicyErrorsSelector = (connectionSyncProgress: OnyxEntry<PolicyConnectionSyncProgress>) => (policy: OnyxEntry<Policy>) =>
getUberConnectionErrorDirectlyFromPolicy(policy) ||
Expand All @@ -51,7 +51,7 @@ function WorkspaceRowBrickRoadIndicator({policyID}: WorkspaceRowBrickRoadIndicat
const icons = useMemoizedLazyExpensifyIcons(['DotIndicator']);
const workspaceAccountID = useWorkspaceAccountID(policyID);
const [hasReimbursementAccountErrors] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {selector: hasReimbursementAccountErrorsSelector});
const [hasCardFeedErrors] = useOnyx(ONYXKEYS.DERIVED.CARD_FEED_ERRORS, {selector: createCardFeedErrorsSelector(workspaceAccountID)});
const hasCardFeedErrors = useCardFeedErrors(createCardFeedErrorsSelector(workspaceAccountID));
const [connectionSyncProgress] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`);
const [hasPolicyErrors] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {selector: createPolicyErrorsSelector(connectionSyncProgress)});
const [isHRCompleteSetupNeeded] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {selector: isMergeHRCompleteSetupNeededSelector});
Expand Down
46 changes: 21 additions & 25 deletions src/hooks/useCardFeedErrors.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
import ONYXKEYS from '@src/ONYXKEYS';
import type {CardFeedErrors, CardFeedErrorState} from '@src/types/onyx/DerivedValues';
import type {CardFeeds, WorkspaceCardsList} from '@src/types/onyx';
import type {CardFeedErrors} from '@src/types/onyx/DerivedValues';

import useOnyx from './useOnyx';
import type {OnyxCollection} from 'react-native-onyx';

const DEFAULT_CARD_FEED_ERROR_STATE: CardFeedErrorState = {
shouldShowRBR: false,
isFeedConnectionBroken: false,
shouldPromptBrokenConnection: false,
hasFeedErrors: false,
hasWorkspaceErrors: false,
hasFeedConnectionIssue: false,
};
import {getCardFeedErrors} from '@selectors/CardFeedErrors';
import {useOnyxState} from 'react-native-onyx';

const DEFAULT_CARD_FEED_ERRORS: CardFeedErrors = {
cardFeedErrors: {},
cardsWithBrokenFeedConnection: {},
personalCardsWithBrokenConnection: {},
shouldShowRbrForWorkspaceAccountID: {},
shouldShowRbrForFeedNameWithDomainID: {},
all: DEFAULT_CARD_FEED_ERROR_STATE,
companyCards: DEFAULT_CARD_FEED_ERROR_STATE,
expensifyCard: DEFAULT_CARD_FEED_ERROR_STATE,
personalCard: DEFAULT_CARD_FEED_ERROR_STATE,
};
const CARD_FEED_ERRORS_DEPENDENCIES = [ONYXKEYS.CARD_LIST, ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST, ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, ONYXKEYS.CURRENT_DATE];

function useCardFeedErrors(): CardFeedErrors {
const [cardFeedErrors] = useOnyx(ONYXKEYS.DERIVED.CARD_FEED_ERRORS);

return cardFeedErrors ?? DEFAULT_CARD_FEED_ERRORS;
function useCardFeedErrors(): CardFeedErrors;
function useCardFeedErrors<TSelected>(selector: (cardFeedErrors: CardFeedErrors) => TSelected): TSelected;
function useCardFeedErrors<TSelected>(selector?: (cardFeedErrors: CardFeedErrors) => TSelected): CardFeedErrors | TSelected {
return useOnyxState(
(state) => {
// useOnyxState's state view types a collection key as one member, but at runtime it returns the whole collection
/* eslint-disable @typescript-eslint/no-unsafe-type-assertion */
const allWorkspaceCards = state[ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST] as OnyxCollection<WorkspaceCardsList>;
const cardFeeds = state[ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER] as OnyxCollection<CardFeeds>;
/* eslint-enable @typescript-eslint/no-unsafe-type-assertion */
const cardFeedErrors = getCardFeedErrors(state[ONYXKEYS.CARD_LIST], allWorkspaceCards, cardFeeds, state[ONYXKEYS.CURRENT_DATE]);
return selector ? selector(cardFeedErrors) : cardFeedErrors;
},
{dependencies: CARD_FEED_ERRORS_DEPENDENCIES},
);
}

export default useCardFeedErrors;
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 @@ -4,7 +4,6 @@ import type {ValueOf} from 'type-fest';

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';
Expand All @@ -28,7 +27,6 @@ const ONYX_DERIVED_VALUES = {
[ONYXKEYS.DERIVED.VISIBLE_REPORT_ACTIONS]: visibleReportActionsConfig,
[ONYXKEYS.DERIVED.NON_PERSONAL_AND_WORKSPACE_CARD_LIST]: nonPersonalAndWorkspaceCardListConfig,
[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,
Expand Down
Loading
Loading