diff --git a/src/CONST.ts b/src/CONST.ts index 4e873163cc95..4b2b66ab5a2d 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -70,6 +70,7 @@ const selectableOnboardingChoices = { } as const; const backendOnboardingChoices = { + ADMIN: 'newDotAdmin', SUBMIT: 'newDotSubmit', } as const; @@ -90,14 +91,14 @@ const signupQualifiers = { SMB: 'smb', } as const; -const selfGuidedTourTask: OnboardingTaskType = { +const selfGuidedTourTask: OnboardingTask = { type: 'viewTour', autoCompleted: false, title: 'Take a 2-minute tour', description: ({navatticURL}) => `[Take a self-guided product tour](${navatticURL}) and learn about everything Expensify has to offer.`, }; -const onboardingEmployerOrSubmitMessage: OnboardingMessageType = { +const onboardingEmployerOrSubmitMessage: OnboardingMessage = { message: 'Getting paid back is as easy as sending a message. Let’s go over the basics.', video: { url: `${CLOUDFRONT_URL}/videos/guided-setup-get-paid-back-v2.mp4`, @@ -142,7 +143,7 @@ const onboardingEmployerOrSubmitMessage: OnboardingMessageType = { ], }; -const combinedTrackSubmitOnboardingEmployerOrSubmitMessage: OnboardingMessageType = { +const combinedTrackSubmitOnboardingEmployerOrSubmitMessage: OnboardingMessage = { ...onboardingEmployerOrSubmitMessage, tasks: [ { @@ -180,7 +181,7 @@ const combinedTrackSubmitOnboardingEmployerOrSubmitMessage: OnboardingMessageTyp ], }; -const onboardingPersonalSpendMessage: OnboardingMessageType = { +const onboardingPersonalSpendMessage: OnboardingMessage = { message: 'Here’s how to track your spend in a few clicks.', video: { url: `${CLOUDFRONT_URL}/videos/guided-setup-track-personal-v2.mp4`, @@ -208,7 +209,7 @@ const onboardingPersonalSpendMessage: OnboardingMessageType = { }, ], }; -const combinedTrackSubmitOnboardingPersonalSpendMessage: OnboardingMessageType = { +const combinedTrackSubmitOnboardingPersonalSpendMessage: OnboardingMessage = { ...onboardingPersonalSpendMessage, tasks: [ { @@ -231,11 +232,11 @@ const combinedTrackSubmitOnboardingPersonalSpendMessage: OnboardingMessageType = ], }; -type OnboardingPurposeType = ValueOf; +type OnboardingPurpose = ValueOf; -type OnboardingCompanySizeType = ValueOf; +type OnboardingCompanySize = ValueOf; -type OnboardingAccountingType = ValueOf | null; +type OnboardingAccounting = ValueOf | null; const onboardingInviteTypes = { IOU: 'iou', @@ -251,9 +252,9 @@ const onboardingCompanySize = { LARGE: '1001+', } as const; -type OnboardingInviteType = ValueOf; +type OnboardingInvite = ValueOf; -type OnboardingTaskType = { +type OnboardingTask = { type: string; autoCompleted: boolean; title: @@ -278,10 +279,17 @@ type OnboardingTaskType = { ) => string); }; -type OnboardingMessageType = { +type OnboardingMessage = { + /** Text message that will be displayed first */ message: string; + + /** Video object to be displayed after initial description message */ video?: Video; - tasks: OnboardingTaskType[]; + + /** List of tasks connected with the message, they will have a checkbox and a separate report for more information */ + tasks: OnboardingTask[]; + + /** Type of task described in a string format */ type?: string; }; @@ -5055,18 +5063,67 @@ const CONST = { }, ], }, + [onboardingChoices.ADMIN]: { + message: "As an admin, learn how to manage your team's workspace and submit expenses yourself.", + video: { + url: `${CLOUDFRONT_URL}/videos/guided-setup-manage-team-v2.mp4`, + thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-manage-team.jpg`, + duration: 55, + width: 1280, + height: 960, + }, + tasks: [ + { + type: 'meetSetupSpecialist', + autoCompleted: false, + title: 'Meet your setup specialist', + description: + '*Meet your setup specialist* who can answer any questions as you get started with Expensify. Yes, a real human!' + + '\n' + + 'Chat with them in your #admins room or schedule a call today.', + }, + { + type: 'reviewWorkspaceSettings', + autoCompleted: false, + title: 'Review your workspace settings', + description: + "Here's how to review and update your workspace settings:" + + '\n' + + '1. Click your profile picture.' + + '2. Click *Workspaces* > [Your workspace].' + + '\n' + + "Make any changes there and we'll track them in the #admins room.", + }, + { + type: 'submitExpense', + autoCompleted: false, + title: 'Submit an expense', + description: + '*Submit an expense* by entering an amount or scanning a receipt.\n' + + '\n' + + 'Here’s how to submit an expense:\n' + + '\n' + + '1. Click the green *+* button.\n' + + '2. Choose *Submit expense*.\n' + + '3. Enter an amount or scan a receipt.\n' + + '4. Add your reimburser to the request.\n' + + '\n' + + 'Then, send your request and wait for that sweet “Cha-ching!” when it’s complete.', + }, + ], + }, [onboardingChoices.LOOKING_AROUND]: { message: "Expensify is best known for expense and corporate card management, but we do a lot more than that. Let me know what you're interested in and I'll help get you started.", tasks: [], }, - } satisfies Record, + } satisfies Record, COMBINED_TRACK_SUBMIT_ONBOARDING_MESSAGES: { [combinedTrackSubmitOnboardingChoices.PERSONAL_SPEND]: combinedTrackSubmitOnboardingPersonalSpendMessage, [combinedTrackSubmitOnboardingChoices.EMPLOYER]: combinedTrackSubmitOnboardingEmployerOrSubmitMessage, [combinedTrackSubmitOnboardingChoices.SUBMIT]: combinedTrackSubmitOnboardingEmployerOrSubmitMessage, - } satisfies Record, OnboardingMessageType>, + } satisfies Record, OnboardingMessage>, REPORT_FIELD_TITLE_FIELD_ID: 'text_title', @@ -6229,14 +6286,14 @@ export type { Country, IOUAction, IOUType, - OnboardingPurposeType, - OnboardingCompanySizeType, + OnboardingPurpose, + OnboardingCompanySize, IOURequestType, SubscriptionType, FeedbackSurveyOptionID, CancellationType, - OnboardingInviteType, - OnboardingAccountingType, + OnboardingInvite, + OnboardingAccounting, }; export default CONST; diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index c5ec21b8b1c2..b4510a2faeed 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -1,6 +1,6 @@ import type {ValueOf} from 'type-fest'; import type CONST from './CONST'; -import type {OnboardingCompanySizeType, OnboardingPurposeType} from './CONST'; +import type {OnboardingCompanySize} from './CONST'; import type Platform from './libs/getPlatform/types'; import type * as FormTypes from './types/form'; import type * as OnyxTypes from './types/onyx'; @@ -982,9 +982,9 @@ type OnyxValuesMapping = { [ONYXKEYS.MAX_CANVAS_AREA]: number; [ONYXKEYS.MAX_CANVAS_HEIGHT]: number; [ONYXKEYS.MAX_CANVAS_WIDTH]: number; - [ONYXKEYS.ONBOARDING_PURPOSE_SELECTED]: OnboardingPurposeType; - [ONYXKEYS.ONBOARDING_COMPANY_SIZE]: OnboardingCompanySizeType; - [ONYXKEYS.ONBOARDING_CUSTOM_CHOICES]: OnboardingPurposeType[] | []; + [ONYXKEYS.ONBOARDING_PURPOSE_SELECTED]: OnyxTypes.OnboardingPurpose; + [ONYXKEYS.ONBOARDING_COMPANY_SIZE]: OnboardingCompanySize; + [ONYXKEYS.ONBOARDING_CUSTOM_CHOICES]: OnyxTypes.OnboardingPurpose[] | []; [ONYXKEYS.ONBOARDING_ERROR_MESSAGE]: string; [ONYXKEYS.ONBOARDING_POLICY_ID]: string; [ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID]: string; diff --git a/src/libs/API/parameters/CompleteGuidedSetupParams.ts b/src/libs/API/parameters/CompleteGuidedSetupParams.ts index 6ff45ecc424a..febb1a47d8b6 100644 --- a/src/libs/API/parameters/CompleteGuidedSetupParams.ts +++ b/src/libs/API/parameters/CompleteGuidedSetupParams.ts @@ -1,14 +1,15 @@ -import type {OnboardingAccountingType, OnboardingCompanySizeType, OnboardingPurposeType} from '@src/CONST'; +import type {OnboardingAccounting, OnboardingCompanySize} from '@src/CONST'; +import type {OnboardingPurpose} from '@src/types/onyx'; type CompleteGuidedSetupParams = { firstName: string; lastName: string; actorAccountID: number; guidedSetupData: string; - engagementChoice: OnboardingPurposeType; + engagementChoice: OnboardingPurpose; paymentSelected?: string; - companySize?: OnboardingCompanySizeType; - userReportedIntegration?: OnboardingAccountingType; + companySize?: OnboardingCompanySize; + userReportedIntegration?: OnboardingAccounting; policyID?: string; }; diff --git a/src/libs/API/parameters/OpenReportParams.ts b/src/libs/API/parameters/OpenReportParams.ts index 0f9cb7075fce..a665313580e8 100644 --- a/src/libs/API/parameters/OpenReportParams.ts +++ b/src/libs/API/parameters/OpenReportParams.ts @@ -14,6 +14,7 @@ type OpenReportParams = { chatType?: string; optimisticAccountIDList?: string; file?: File | CustomRNImageManipulatorResult; + guidedSetupData?: string; }; export default OpenReportParams; diff --git a/src/libs/TourUtils.ts b/src/libs/TourUtils.ts index a88ee47cc563..141ed6b23a2b 100644 --- a/src/libs/TourUtils.ts +++ b/src/libs/TourUtils.ts @@ -1,8 +1,8 @@ import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; -import type {OnboardingPurposeType} from '@src/CONST'; +import type {OnboardingPurpose} from '@src/CONST'; -function getNavatticURL(environment: ValueOf, introSelected?: OnboardingPurposeType) { +function getNavatticURL(environment: ValueOf, introSelected?: OnboardingPurpose) { const adminTourURL = environment === CONST.ENVIRONMENT.PRODUCTION ? CONST.NAVATTIC.ADMIN_TOUR_PRODUCTION : CONST.NAVATTIC.ADMIN_TOUR_STAGING; const employeeTourURL = environment === CONST.ENVIRONMENT.PRODUCTION ? CONST.NAVATTIC.EMPLOYEE_TOUR_PRODUCTION : CONST.NAVATTIC.EMPLOYEE_TOUR_STAGING; return introSelected === CONST.SELECTABLE_ONBOARDING_CHOICES.MANAGE_TEAM ? adminTourURL : employeeTourURL; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 5ec2e81b8c01..9abe98106d38 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7372,12 +7372,12 @@ function completePaymentOnboarding(paymentSelected: ValueOf (quickAction = val), }); -let allReportDraftComments: Record = {}; +let introSelected: OnyxEntry = {}; +Onyx.connect({ + key: ONYXKEYS.NVP_INTRO_SELECTED, + callback: (val) => (introSelected = val), +}); +let allReportDraftComments: Record = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, waitForCollectionCallback: true, @@ -843,6 +856,39 @@ function openReport( accountIDList: participantAccountIDList ? participantAccountIDList.join(',') : '', parentReportActionID, }; + + const isInviteOnboardingComplete = introSelected?.isInviteOnboardingComplete ?? false; + + if (introSelected && !isInviteOnboardingComplete) { + const {choice, inviteType} = introSelected; + const isInviteIOUorInvoice = inviteType === CONST.ONBOARDING_INVITE_TYPES.IOU || inviteType === CONST.ONBOARDING_INVITE_TYPES.INVOICE; + const isInviteChoiceCorrect = choice === CONST.ONBOARDING_CHOICES.ADMIN || choice === CONST.ONBOARDING_CHOICES.SUBMIT || choice === CONST.ONBOARDING_CHOICES.CHAT_SPLIT; + + if (isInviteChoiceCorrect && !isInviteIOUorInvoice) { + const onboardingMessage = CONST.ONBOARDING_MESSAGES[choice]; + if (choice === CONST.ONBOARDING_CHOICES.CHAT_SPLIT) { + const updatedTasks = onboardingMessage.tasks.map((task) => (task.type === 'startChat' ? {...task, autoCompleted: true} : task)); + onboardingMessage.tasks = updatedTasks; + } + + const onboardingData = prepareOnboardingOptimisticData(choice, onboardingMessage); + + optimisticData.push(...onboardingData.optimisticData, { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.NVP_INTRO_SELECTED, + value: { + isInviteOnboardingComplete: true, + }, + }); + + successData.push(...onboardingData.successData); + + failureData.push(...onboardingData.failureData); + + parameters.guidedSetupData = JSON.stringify(onboardingData.guidedSetupData); + } + } + const isGroupChat = ReportUtils.isGroupChat(newReportObject); if (isGroupChat) { parameters.chatType = CONST.REPORT.CHAT_TYPE.GROUP; @@ -993,11 +1039,7 @@ function openReport( } else { // eslint-disable-next-line rulesdir/no-multiple-api-calls API.paginate(CONST.API_REQUEST_TYPE.WRITE, WRITE_COMMANDS.OPEN_REPORT, parameters, {optimisticData, successData, failureData}, paginationConfig, { - checkAndFixConflictingRequest: (persistedRequests) => - resolveDuplicationConflictAction( - persistedRequests, - (request) => request.command === WRITE_COMMANDS.OPEN_REPORT && request.data?.reportID === reportID && request.data?.emailList === parameters.emailList, - ), + checkAndFixConflictingRequest: (persistedRequests) => resolveOpenReportDuplicationConflictAction(persistedRequests, parameters), }); } } @@ -3415,16 +3457,12 @@ function getReportPrivateNote(reportID: string | undefined) { API.read(READ_COMMANDS.GET_REPORT_PRIVATE_NOTE, parameters, {optimisticData, successData, failureData}); } -function completeOnboarding( - engagementChoice: OnboardingPurposeType, +function prepareOnboardingOptimisticData( + engagementChoice: OnboardingPurpose, data: ValueOf, - firstName = '', - lastName = '', adminsChatReportID?: string, onboardingPolicyID?: string, - paymentSelected?: string, - companySize?: OnboardingCompanySizeType, - userReportedIntegration?: OnboardingAccountingType, + userReportedIntegration?: OnboardingAccounting, ) { // If the user has the "combinedTrackSubmit" beta enabled we'll show different tasks for track and submit expense. if (Permissions.canUseCombinedTrackSubmit()) { @@ -3839,6 +3877,28 @@ function completeOnboarding( guidedSetupData.push(...tasksForParameters); + return {optimisticData, successData, failureData, guidedSetupData, actorAccountID}; +} + +function completeOnboarding( + engagementChoice: OnboardingPurpose, + data: ValueOf, + firstName = '', + lastName = '', + adminsChatReportID?: string, + onboardingPolicyID?: string, + paymentSelected?: string, + companySize?: OnboardingCompanySize, + userReportedIntegration?: OnboardingAccounting, +) { + const {optimisticData, successData, failureData, guidedSetupData, actorAccountID} = prepareOnboardingOptimisticData( + engagementChoice, + data, + adminsChatReportID, + onboardingPolicyID, + userReportedIntegration, + ); + const parameters: CompleteGuidedSetupParams = { engagementChoice, firstName, diff --git a/src/libs/actions/RequestConflictUtils.ts b/src/libs/actions/RequestConflictUtils.ts index e363ff02a127..7e1092016e28 100644 --- a/src/libs/actions/RequestConflictUtils.ts +++ b/src/libs/actions/RequestConflictUtils.ts @@ -1,6 +1,6 @@ import type {OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; -import type {UpdateCommentParams} from '@libs/API/parameters'; +import type {OpenReportParams, UpdateCommentParams} from '@libs/API/parameters'; import {WRITE_COMMANDS} from '@libs/API/types'; import ONYXKEYS from '@src/ONYXKEYS'; import type OnyxRequest from '@src/types/onyx/Request'; @@ -50,6 +50,37 @@ function resolveDuplicationConflictAction(persistedRequests: OnyxRequest[], requ }; } +function resolveOpenReportDuplicationConflictAction(persistedRequests: OnyxRequest[], parameters: OpenReportParams): ConflictActionData { + for (let index = 0; index < persistedRequests.length; index++) { + const request = persistedRequests.at(index); + if (request && request.command === WRITE_COMMANDS.OPEN_REPORT && request.data?.reportID === parameters.reportID && request.data?.emailList === parameters.emailList) { + // If the previous request had guided setup data, we can safely ignore the new request + if (request.data.guidedSetupData) { + return { + conflictAction: { + type: 'noAction', + }, + }; + } + + // In other cases it's safe to replace the previous request with the new one + return { + conflictAction: { + type: 'replace', + index, + }, + }; + } + } + + // If we didn't find any request to replace, we should push the new request + return { + conflictAction: { + type: 'push', + }, + }; +} + function resolveCommentDeletionConflicts(persistedRequests: OnyxRequest[], reportActionID: string, originalReportID: string): ConflictActionData { const commentIndicesToDelete: number[] = []; const commentCouldBeThread: Record = {}; @@ -144,4 +175,10 @@ function resolveEditCommentWithNewAddCommentRequest(persistedRequests: OnyxReque } as ConflictActionData; } -export {resolveDuplicationConflictAction, resolveCommentDeletionConflicts, resolveEditCommentWithNewAddCommentRequest, createUpdateCommentMatcher}; +export { + resolveDuplicationConflictAction, + resolveOpenReportDuplicationConflictAction, + resolveCommentDeletionConflicts, + resolveEditCommentWithNewAddCommentRequest, + createUpdateCommentMatcher, +}; diff --git a/src/libs/actions/Welcome/index.ts b/src/libs/actions/Welcome/index.ts index 5a92ff5e5435..230b212292e2 100644 --- a/src/libs/actions/Welcome/index.ts +++ b/src/libs/actions/Welcome/index.ts @@ -4,8 +4,9 @@ import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; import {SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import Log from '@libs/Log'; -import type {OnboardingCompanySizeType, OnboardingPurposeType} from '@src/CONST'; +import type {OnboardingCompanySize} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {OnboardingPurpose} from '@src/types/onyx'; import type Onboarding from '@src/types/onyx/Onboarding'; import type TryNewDot from '@src/types/onyx/TryNewDot'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -90,15 +91,15 @@ function checkOnboardingDataReady() { resolveOnboardingFlowStatus(); } -function setOnboardingCustomChoices(value: OnboardingPurposeType[]) { +function setOnboardingCustomChoices(value: OnboardingPurpose[]) { Onyx.set(ONYXKEYS.ONBOARDING_CUSTOM_CHOICES, value ?? []); } -function setOnboardingPurposeSelected(value: OnboardingPurposeType) { +function setOnboardingPurposeSelected(value: OnboardingPurpose) { Onyx.set(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, value ?? null); } -function setOnboardingCompanySize(value: OnboardingCompanySizeType) { +function setOnboardingCompanySize(value: OnboardingCompanySize) { Onyx.set(ONYXKEYS.ONBOARDING_COMPANY_SIZE, value); } diff --git a/src/pages/OnboardingAccounting/BaseOnboardingAccounting.tsx b/src/pages/OnboardingAccounting/BaseOnboardingAccounting.tsx index 6e3e4c62aeda..faf531765edd 100644 --- a/src/pages/OnboardingAccounting/BaseOnboardingAccounting.tsx +++ b/src/pages/OnboardingAccounting/BaseOnboardingAccounting.tsx @@ -25,13 +25,13 @@ import * as Policy from '@userActions/Policy/Policy'; import * as Report from '@userActions/Report'; import * as Welcome from '@userActions/Welcome'; import CONST from '@src/CONST'; -import type {OnboardingAccountingType} from '@src/CONST'; +import type {OnboardingAccounting} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {} from '@src/types/onyx/Bank'; import type {BaseOnboardingAccountingProps} from './types'; type OnboardingListItem = ListItem & { - keyForList: OnboardingAccountingType; + keyForList: OnboardingAccounting; }; function BaseOnboardingAccounting({shouldUseNativeStyles, route}: BaseOnboardingAccountingProps) { @@ -51,7 +51,7 @@ function BaseOnboardingAccounting({shouldUseNativeStyles, route}: BaseOnboarding const {canUseDefaultRooms} = usePermissions(); const {activeWorkspaceID} = useActiveWorkspace(); - const [userReportedIntegration, setUserReportedIntegration] = useState(undefined); + const [userReportedIntegration, setUserReportedIntegration] = useState(undefined); const [error, setError] = useState(''); const isVsb = onboardingValues && 'signupQualifier' in onboardingValues && onboardingValues.signupQualifier === CONST.ONBOARDING_SIGNUP_QUALIFIERS.VSB; diff --git a/src/pages/OnboardingEmployees/BaseOnboardingEmployees.tsx b/src/pages/OnboardingEmployees/BaseOnboardingEmployees.tsx index 1dd8807cc26e..fee409c6480d 100644 --- a/src/pages/OnboardingEmployees/BaseOnboardingEmployees.tsx +++ b/src/pages/OnboardingEmployees/BaseOnboardingEmployees.tsx @@ -15,13 +15,13 @@ import Navigation from '@libs/Navigation/Navigation'; import * as Policy from '@userActions/Policy/Policy'; import * as Welcome from '@userActions/Welcome'; import CONST from '@src/CONST'; -import type {OnboardingCompanySizeType} from '@src/CONST'; +import type {OnboardingCompanySize} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {BaseOnboardingEmployeesProps} from './types'; type OnboardingListItem = ListItem & { - keyForList: OnboardingCompanySizeType; + keyForList: OnboardingCompanySize; }; function BaseOnboardingEmployees({shouldUseNativeStyles, route}: BaseOnboardingEmployeesProps) { const styles = useThemeStyles(); @@ -30,7 +30,7 @@ function BaseOnboardingEmployees({shouldUseNativeStyles, route}: BaseOnboardingE const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); - const [selectedCompanySize, setSelectedCompanySize] = useState(onboardingCompanySize); + const [selectedCompanySize, setSelectedCompanySize] = useState(onboardingCompanySize); const [error, setError] = useState(''); const companySizeOptions: OnboardingListItem[] = useMemo(() => { diff --git a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx index 3b05c6bb40a8..74d2facf55dc 100644 --- a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx +++ b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx @@ -22,15 +22,15 @@ import type {TOnboardingRef} from '@libs/OnboardingRefManager'; import variables from '@styles/variables'; import * as Welcome from '@userActions/Welcome'; import CONST from '@src/CONST'; -import type {OnboardingPurposeType} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type {OnboardingPurpose} from '@src/types/onyx'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; import type {BaseOnboardingPurposeProps} from './types'; const selectableOnboardingChoices = Object.values(CONST.SELECTABLE_ONBOARDING_CHOICES); -function getOnboardingChoices(customChoices: OnboardingPurposeType[]) { +function getOnboardingChoices(customChoices: OnboardingPurpose[]) { if (customChoices.length === 0) { return selectableOnboardingChoices; } diff --git a/src/pages/home/report/SystemChatReportFooterMessage.tsx b/src/pages/home/report/SystemChatReportFooterMessage.tsx index 4775b7ff6487..a000550751e3 100644 --- a/src/pages/home/report/SystemChatReportFooterMessage.tsx +++ b/src/pages/home/report/SystemChatReportFooterMessage.tsx @@ -1,6 +1,5 @@ import React, {useMemo} from 'react'; -import {useOnyx, withOnyx} from 'react-native-onyx'; -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import Banner from '@components/Banner'; import * as Expensicons from '@components/Icon/Expensicons'; import Text from '@components/Text'; @@ -10,29 +9,17 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as PolicyUtils from '@libs/PolicyUtils'; import Navigation from '@navigation/Navigation'; import * as ReportInstance from '@userActions/Report'; -import type {OnboardingPurposeType} from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Policy as PolicyType} from '@src/types/onyx'; -type SystemChatReportFooterMessageOnyxProps = { - /** Saved onboarding purpose selected by the user */ - choice: OnyxEntry; - - /** The list of this user's policies */ - policies: OnyxCollection; - - /** policyID for main workspace */ - activePolicyID: OnyxEntry>; -}; - -type SystemChatReportFooterMessageProps = SystemChatReportFooterMessageOnyxProps; - -function SystemChatReportFooterMessage({choice, policies, activePolicyID}: SystemChatReportFooterMessageProps) { +function SystemChatReportFooterMessage() { const {translate} = useLocalize(); const styles = useThemeStyles(); const [currentUserLogin] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.email}); + const [choice] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); + const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); + const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); const adminChatReportID = useMemo(() => { const adminPolicy = activePolicyID @@ -88,14 +75,4 @@ function SystemChatReportFooterMessage({choice, policies, activePolicyID}: Syste SystemChatReportFooterMessage.displayName = 'SystemChatReportFooterMessage'; -export default withOnyx({ - choice: { - key: ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, - }, - policies: { - key: ONYXKEYS.COLLECTION.POLICY, - }, - activePolicyID: { - key: ONYXKEYS.NVP_ACTIVE_POLICY_ID, - }, -})(SystemChatReportFooterMessage); +export default SystemChatReportFooterMessage; diff --git a/src/types/onyx/IntroSelected.ts b/src/types/onyx/IntroSelected.ts index 0e1b4ec60ae4..edeb79d34113 100644 --- a/src/types/onyx/IntroSelected.ts +++ b/src/types/onyx/IntroSelected.ts @@ -1,15 +1,16 @@ -import type {OnboardingInviteType, OnboardingPurposeType} from '@src/CONST'; +import type {OnboardingInvite} from '@src/CONST'; +import type {OnboardingPurpose} from './index'; /** Model of onboarding */ -type IntroSelected = Partial<{ +type IntroSelected = { /** The choice that the user selected in the engagement modal */ - choice: OnboardingPurposeType; + choice?: OnboardingPurpose; /** The invite type */ - inviteType: OnboardingInviteType; + inviteType?: OnboardingInvite; /** Whether the onboarding is complete */ - isInviteOnboardingComplete: boolean; -}>; + isInviteOnboardingComplete?: boolean; +}; export default IntroSelected; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 7702da678105..79c2b4f230d4 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -1,3 +1,4 @@ +import type {OnboardingPurpose} from '@src/CONST'; import type Account from './Account'; import type AccountData from './AccountData'; import type {ApprovalWorkflowOnyx} from './ApprovalWorkflow'; @@ -236,5 +237,6 @@ export type { SaveSearch, RecentSearchItem, ImportedSpreadsheet, + OnboardingPurpose, ValidateMagicCodeAction, };