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

feat: create workspace at the end of the actionable whisper #41465

Merged
merged 10 commits into from
May 6, 2024
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ const ONYXKEYS = {
POLICY_DRAFTS: 'policyDrafts_',
POLICY_JOIN_MEMBER: 'policyJoinMember_',
POLICY_CATEGORIES: 'policyCategories_',
POLICY_CATEGORIES_DRAFT: 'policyCategoriesDraft_',
POLICY_RECENTLY_USED_CATEGORIES: 'policyRecentlyUsedCategories_',
POLICY_TAGS: 'policyTags_',
POLICY_RECENTLY_USED_TAGS: 'nvp_recentlyUsedTags_',
Expand All @@ -335,6 +336,7 @@ const ONYXKEYS = {
WORKSPACE_INVITE_MEMBERS_DRAFT: 'workspaceInviteMembersDraft_',
WORKSPACE_INVITE_MESSAGE_DRAFT: 'workspaceInviteMessageDraft_',
REPORT: 'report_',
REPORT_DRAFT: 'reportDraft_',
// REPORT_METADATA is a perf optimization used to hold loading states (isLoadingInitialReportActions, isLoadingOlderReportActions, isLoadingNewerReportActions).
// A lot of components are connected to the Report entity and do not care about the actions. Setting the loading state
// directly on the report caused a lot of unnecessary re-renders
Expand Down Expand Up @@ -538,13 +540,15 @@ type OnyxCollectionValuesMapping = {
[ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy;
[ONYXKEYS.COLLECTION.POLICY_DRAFTS]: OnyxTypes.Policy;
[ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: OnyxTypes.PolicyCategories;
[ONYXKEYS.COLLECTION.POLICY_CATEGORIES_DRAFT]: OnyxTypes.PolicyCategories;
[ONYXKEYS.COLLECTION.POLICY_TAGS]: OnyxTypes.PolicyTagList;
[ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES]: OnyxTypes.RecentlyUsedCategories;
[ONYXKEYS.COLLECTION.POLICY_HAS_CONNECTIONS_DATA_BEEN_FETCHED]: boolean;
[ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyEmployeeList;
[ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT]: OnyxTypes.InvitedEmailsToAccountIDs;
[ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MESSAGE_DRAFT]: string;
[ONYXKEYS.COLLECTION.REPORT]: OnyxTypes.Report;
[ONYXKEYS.COLLECTION.REPORT_DRAFT]: OnyxTypes.Report;
[ONYXKEYS.COLLECTION.REPORT_METADATA]: OnyxTypes.ReportMetadata;
[ONYXKEYS.COLLECTION.REPORT_ACTIONS]: OnyxTypes.ReportActions;
[ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS]: OnyxTypes.ReportActionsDrafts;
Expand Down
12 changes: 8 additions & 4 deletions src/components/CategoryPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {ListItem} from './SelectionList/types';

type CategoryPickerOnyxProps = {
policyCategories: OnyxEntry<OnyxTypes.PolicyCategories>;
policyCategoriesDraft: OnyxEntry<OnyxTypes.PolicyCategories>;
policyRecentlyUsedCategories: OnyxEntry<OnyxTypes.RecentlyUsedCategories>;
};

Expand All @@ -25,7 +26,7 @@ type CategoryPickerProps = CategoryPickerOnyxProps & {
onSubmit: (item: ListItem) => void;
};

function CategoryPicker({selectedCategory, policyCategories, policyRecentlyUsedCategories, onSubmit}: CategoryPickerProps) {
function CategoryPicker({selectedCategory, policyCategories, policyRecentlyUsedCategories, policyCategoriesDraft, onSubmit}: CategoryPickerProps) {
const {translate} = useLocalize();
const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState('');

Expand All @@ -45,7 +46,7 @@ function CategoryPicker({selectedCategory, policyCategories, policyRecentlyUsedC
}, [selectedCategory]);

const [sections, headerMessage, shouldShowTextInput] = useMemo(() => {
const validPolicyRecentlyUsedCategories = policyRecentlyUsedCategories?.filter((p) => !isEmptyObject(p));
const validPolicyRecentlyUsedCategories = policyRecentlyUsedCategories?.filter?.((p) => !isEmptyObject(p));
const {categoryOptions} = OptionsListUtils.getFilteredOptions(
[],
[],
Expand All @@ -56,7 +57,7 @@ function CategoryPicker({selectedCategory, policyCategories, policyRecentlyUsedC
false,
false,
true,
policyCategories ?? {},
policyCategories ?? policyCategoriesDraft ?? {},
validPolicyRecentlyUsedCategories,
false,
);
Expand All @@ -68,7 +69,7 @@ function CategoryPicker({selectedCategory, policyCategories, policyRecentlyUsedC
const showInput = !isCategoriesCountBelowThreshold;

return [categoryOptions, header, showInput];
}, [policyRecentlyUsedCategories, debouncedSearchValue, selectedOptions, policyCategories]);
}, [policyRecentlyUsedCategories, debouncedSearchValue, selectedOptions, policyCategories, policyCategoriesDraft]);

const selectedOptionKey = useMemo(() => (sections?.[0]?.data ?? []).filter((category) => category.searchText === selectedCategory)[0]?.keyForList, [sections, selectedCategory]);

Expand All @@ -93,6 +94,9 @@ export default withOnyx<CategoryPickerProps, CategoryPickerOnyxProps>({
policyCategories: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`,
},
policyCategoriesDraft: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES_DRAFT}${policyID}`,
},
policyRecentlyUsedCategories: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES}${policyID}`,
},
Expand Down
22 changes: 19 additions & 3 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,18 @@ type MoneyRequestConfirmationListOnyxProps = {
/** Collection of categories attached to a policy */
policyCategories: OnyxEntry<OnyxTypes.PolicyCategories>;

/** Collection of draft categories attached to a policy */
policyCategoriesDraft: OnyxEntry<OnyxTypes.PolicyCategories>;

/** Collection of tags attached to a policy */
policyTags: OnyxEntry<OnyxTypes.PolicyTagList>;

/** The policy of the report */
policy: OnyxEntry<OnyxTypes.Policy>;

/** The draft policy of the report */
policyDraft: OnyxEntry<OnyxTypes.Policy>;

/** The session of the logged in user */
session: OnyxEntry<OnyxTypes.Session>;

Expand Down Expand Up @@ -193,10 +199,12 @@ function MoneyRequestConfirmationList({
iouType = CONST.IOU.TYPE.SUBMIT,
isScanRequest = false,
iouAmount,
policyCategories,
policyCategories: policyCategoriesReal,
policyCategoriesDraft,
mileageRates,
isDistanceRequest = false,
policy,
policy: policyReal,
policyDraft,
isPolicyExpenseChat = false,
iouCategory = '',
shouldShowSmartScanFields = true,
Expand Down Expand Up @@ -227,6 +235,8 @@ function MoneyRequestConfirmationList({
allPolicies,
action = CONST.IOU.ACTION.CREATE,
}: MoneyRequestConfirmationListProps) {
const policy = policyReal ?? policyDraft;
const policyCategories = policyCategoriesReal ?? policyCategoriesDraft;
const theme = useTheme();
const styles = useThemeStyles();
const {translate, toLocaleDigit} = useLocalize();
Expand Down Expand Up @@ -469,8 +479,8 @@ function MoneyRequestConfirmationList({
);
} else {
const formattedSelectedParticipants = selectedParticipants.map((participant) => ({
...participant,
isDisabled: !participant.isPolicyExpenseChat && !participant.isSelfDM && ReportUtils.isOptimisticPersonalDetail(participant.accountID ?? -1),
...participant,
}));
sections.push({
title: translate('common.to'),
Expand Down Expand Up @@ -1120,6 +1130,9 @@ export default withOnyx<MoneyRequestConfirmationListProps, MoneyRequestConfirmat
policyCategories: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`,
},
policyCategoriesDraft: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES_DRAFT}${policyID}`,
},
policyTags: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
},
Expand All @@ -1134,6 +1147,9 @@ export default withOnyx<MoneyRequestConfirmationListProps, MoneyRequestConfirmat
policy: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
},
policyDraft: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${policyID}`,
},
lastSelectedDistanceRates: {
key: ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES,
},
Expand Down
1 change: 1 addition & 0 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ function getReportOption(participant: Participant): ReportUtils.OptionData {
option.text = ReportUtils.getPolicyName(report);
option.alternateText = Localize.translateLocal('workspace.common.workspace');
}
option.isDisabled = ReportUtils.isDraftReport(participant.reportID);
option.selected = participant.selected;
option.isSelected = participant.selected;
return option;
Expand Down
52 changes: 44 additions & 8 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,13 @@ Onyx.connect({
callback: (value) => (allReports = value),
});

let allReportsDraft: OnyxCollection<Report>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT_DRAFT,
waitForCollectionCallback: true,
callback: (value) => (allReportsDraft = value),
});

let allPolicies: OnyxCollection<Policy>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY,
Expand Down Expand Up @@ -591,11 +598,23 @@ function getChatType(report: OnyxEntry<Report> | Participant | EmptyObject): Val
* Get the report given a reportID
*/
function getReport(reportID: string | undefined): OnyxEntry<Report> {
if (!allReports) {
if (!allReports && !allReportsDraft) {
return null;
}

return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
const draftReport = allReportsDraft?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportID}`];

return report ?? draftReport ?? null;
}

/**
* Check if a report is a draft report
*/
function isDraftReport(reportID: string | undefined): boolean {
const draftReport = allReportsDraft?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportID}`];

return !!draftReport;
}

/**
Expand Down Expand Up @@ -905,8 +924,8 @@ function isGroupPolicy(policyType: string): boolean {
/**
* Whether the provided report belongs to a Free, Collect or Control policy
*/
function isReportInGroupPolicy(report: OnyxEntry<Report>): boolean {
const policyType = getPolicyType(report, allPolicies);
function isReportInGroupPolicy(report: OnyxEntry<Report>, policy?: OnyxEntry<Policy>): boolean {
const policyType = policy?.type ?? getPolicyType(report, allPolicies);
return isGroupPolicy(policyType);
}

Expand Down Expand Up @@ -4626,7 +4645,7 @@ function buildOptimisticClosedReportAction(emailClosingReport: string, policyNam
};
}

function buildOptimisticWorkspaceChats(policyID: string, policyName: string): OptimisticWorkspaceChats {
function buildOptimisticWorkspaceChats(policyID: string, policyName: string, expenseReportId?: string): OptimisticWorkspaceChats {
const announceChatData = buildOptimisticChatReport(
currentUserAccountID ? [currentUserAccountID] : [],
CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE,
Expand Down Expand Up @@ -4665,7 +4684,23 @@ function buildOptimisticWorkspaceChats(policyID: string, policyName: string): Op
[adminsCreatedAction.reportActionID]: adminsCreatedAction,
};

const expenseChatData = buildOptimisticChatReport([currentUserAccountID ?? -1], '', CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, policyID, currentUserAccountID, true, policyName);
const expenseChatData = buildOptimisticChatReport(
[currentUserAccountID ?? -1],
'',
CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT,
policyID,
currentUserAccountID,
true,
policyName,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
expenseReportId,
);
const expenseChatReportID = expenseChatData.reportID;
const expenseReportCreatedAction = buildOptimisticCreatedReportAction(currentUserEmail ?? '');
const expenseReportActionData = {
Expand Down Expand Up @@ -6390,15 +6425,15 @@ function createDraftTransactionAndNavigateToParticipantSelector(transactionID: s
} as Transaction);

const filteredPolicies = Object.values(allPolicies ?? {}).filter(
(policy) => policy?.type !== CONST.POLICY.TYPE.PERSONAL && policy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE,
(policy) => policy && policy.type !== CONST.POLICY.TYPE.PERSONAL && policy.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE,
);

if (actionName === CONST.IOU.ACTION.SUBMIT || (allPolicies && filteredPolicies.length > 0)) {
Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_PARTICIPANTS.getRoute(CONST.IOU.TYPE.SUBMIT, transactionID, reportID, undefined, actionName));
return;
}

const {expenseChatReportID, policyID, policyName} = PolicyActions.createWorkspace();
const {expenseChatReportID, policyID, policyName} = PolicyActions.createDraftWorkspace();
const isCategorizing = actionName === CONST.IOU.ACTION.CATEGORIZE;

IOU.setMoneyRequestParticipants(transactionID, [
Expand Down Expand Up @@ -6712,6 +6747,7 @@ export {
getInvoiceChatByParticipants,
shouldShowMerchantColumn,
isCurrentUserInvoiceReceiver,
isDraftReport,
};

export type {
Expand Down
Loading
Loading