From 329aa95d3520fc035b382375d3a19467b5c90a26 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 20 Feb 2024 15:22:49 +0100 Subject: [PATCH 1/7] [TS migration] Migrate 'NewTask' page to TypeScript --- src/ONYXKEYS.ts | 2 +- src/libs/actions/Task.ts | 14 +- ...tionPage.js => NewTaskDescriptionPage.tsx} | 74 +++----- ...ilsPage.js => NewTaskDetailsPage copy.tsx} | 94 ++++------ src/pages/tasks/NewTaskDetailsPage.tsx | 128 +++++++++++++ .../tasks/{NewTaskPage.js => NewTaskPage.tsx} | 171 +++++++----------- ...wTaskTitlePage.js => NewTaskTitlePage.tsx} | 73 +++----- 7 files changed, 302 insertions(+), 254 deletions(-) rename src/pages/tasks/{NewTaskDescriptionPage.js => NewTaskDescriptionPage.tsx} (62%) rename src/pages/tasks/{NewTaskDetailsPage.js => NewTaskDetailsPage copy.tsx} (61%) create mode 100644 src/pages/tasks/NewTaskDetailsPage.tsx rename src/pages/tasks/{NewTaskPage.js => NewTaskPage.tsx} (53%) rename src/pages/tasks/{NewTaskTitlePage.js => NewTaskTitlePage.tsx} (64%) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 9d35994875e1..af0b62781bbd 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -409,7 +409,7 @@ type OnyxFormValuesMapping = { [ONYXKEYS.FORMS.HOME_ADDRESS_FORM]: FormTypes.Form; [ONYXKEYS.FORMS.NEW_ROOM_FORM]: FormTypes.NewRoomForm; [ONYXKEYS.FORMS.ROOM_SETTINGS_FORM]: FormTypes.Form; - [ONYXKEYS.FORMS.NEW_TASK_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.NEW_TASK_FORM]: FormTypes.NewTaskForm; [ONYXKEYS.FORMS.EDIT_TASK_FORM]: FormTypes.Form; [ONYXKEYS.FORMS.MONEY_REQUEST_DESCRIPTION_FORM]: FormTypes.Form; [ONYXKEYS.FORMS.MONEY_REQUEST_MERCHANT_FORM]: FormTypes.Form; diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 28cecf460a5f..37395778f846 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -84,7 +84,7 @@ function createTaskAndNavigate( assigneeEmail: string, assigneeAccountID = 0, assigneeChatReport: OnyxEntry = null, - policyID = CONST.POLICY.OWNER_EMAIL_FAKE, + policyID: string = CONST.POLICY.OWNER_EMAIL_FAKE, ) { const optimisticTaskReport = ReportUtils.buildOptimisticTaskReport(currentUserAccountID, assigneeAccountID, parentReportID, title, description, policyID); @@ -656,8 +656,8 @@ function clearOutTaskInfoAndNavigate(reportID: string) { /** * Get the assignee data */ -function getAssignee(assigneeAccountID: number, personalDetails: OnyxTypes.PersonalDetailsList): Assignee { - const details = personalDetails[assigneeAccountID]; +function getAssignee(assigneeAccountID: number, personalDetails: OnyxEntry): Assignee { + const details = personalDetails?.[assigneeAccountID]; if (!details) { return { @@ -677,7 +677,7 @@ function getAssignee(assigneeAccountID: number, personalDetails: OnyxTypes.Perso /** * Get the share destination data * */ -function getShareDestination(reportID: string, reports: OnyxCollection, personalDetails: OnyxTypes.PersonalDetailsList): ShareDestination { +function getShareDestination(reportID: string, reports: OnyxCollection, personalDetails: OnyxEntry): ShareDestination { const report = reports?.[`report_${reportID}`] ?? null; const participantAccountIDs = report?.participantAccountIDs ?? []; @@ -688,8 +688,8 @@ function getShareDestination(reportID: string, reports: OnyxCollection; }; const parser = new ExpensiMark(); -function NewTaskDescriptionPage(props) { +function NewTaskDescriptionPage({task}: NewTaskDescriptionPageProps) { const styles = useThemeStyles(); + const {translate} = useLocalize(); const {inputCallbackRef} = useAutoFocusInput(); - const onSubmit = (values) => { - Task.setDescriptionValue(values.taskDescription); + const onSubmit = (values: FormOnyxValues) => { + TaskActions.setDescriptionValue(values.taskDescription); Navigation.goBack(ROUTES.NEW_TASK); }; - /** - * @param {Object} values - form input values passed by the Form component - * @returns {Boolean} - */ - function validate(values) { + const validate = (values: FormOnyxValues) => { const errors = {}; if (values.taskDescription.length > CONST.DESCRIPTION_LIMIT) { @@ -60,7 +47,7 @@ function NewTaskDescriptionPage(props) { } return errors; - } + }; return ( <> Task.dismissModalAndClearOutTaskInfo()} + title={translate('task.description')} + onCloseButtonPress={() => TaskActions.dismissModalAndClearOutTaskInfo()} onBackButtonPress={() => Navigation.goBack(ROUTES.NEW_TASK)} /> validate(values)} - onSubmit={(values) => onSubmit(values)} + validate={validate} + onSubmit={onSubmit} enabledWhenOffline > { inputCallbackRef(el); @@ -96,7 +83,7 @@ function NewTaskDescriptionPage(props) { }} autoGrowHeight shouldSubmitForm - containerStyles={[styles.autoGrowHeightMultilineInput]} + containerStyles={styles.autoGrowHeightMultilineInput} /> @@ -106,14 +93,9 @@ function NewTaskDescriptionPage(props) { } NewTaskDescriptionPage.displayName = 'NewTaskDescriptionPage'; -NewTaskDescriptionPage.propTypes = propTypes; -NewTaskDescriptionPage.defaultProps = defaultProps; -export default compose( - withOnyx({ - task: { - key: ONYXKEYS.TASK, - }, - }), - withLocalize, -)(NewTaskDescriptionPage); +export default withOnyx({ + task: { + key: ONYXKEYS.TASK, + }, +})(NewTaskDescriptionPage); diff --git a/src/pages/tasks/NewTaskDetailsPage.js b/src/pages/tasks/NewTaskDetailsPage copy.tsx similarity index 61% rename from src/pages/tasks/NewTaskDetailsPage.js rename to src/pages/tasks/NewTaskDetailsPage copy.tsx index e4533b637dee..a7d98724a2f1 100644 --- a/src/pages/tasks/NewTaskDetailsPage.js +++ b/src/pages/tasks/NewTaskDetailsPage copy.tsx @@ -1,58 +1,47 @@ import ExpensiMark from 'expensify-common/lib/ExpensiMark'; -import PropTypes from 'prop-types'; import React, {useEffect, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; -import * as Task from '@userActions/Task'; +import * as TaskActions from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import INPUT_IDS from '@src/types/form/NewTaskForm'; +import type {Task} from '@src/types/onyx'; -const propTypes = { - /** Task title and description data */ - task: PropTypes.shape({ - title: PropTypes.string, - description: PropTypes.string, - }), - - ...withLocalizePropTypes, -}; - -const defaultProps = { - task: {}, +type NewTaskDetailsPageProps = { + /** Grab the Share title of the Task */ + task: OnyxEntry; }; const parser = new ExpensiMark(); -function NewTaskDetailsPage(props) { +function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { const styles = useThemeStyles(); - const [taskTitle, setTaskTitle] = useState(props.task.title); - const [taskDescription, setTaskDescription] = useState(props.task.description || ''); + const {translate} = useLocalize(); + const [taskTitle, setTaskTitle] = useState(task?.title ?? ''); + const [taskDescription, setTaskDescription] = useState(task?.description ?? ''); const {inputCallbackRef} = useAutoFocusInput(); useEffect(() => { - setTaskTitle(props.task.title); - setTaskDescription(parser.htmlToMarkdown(parser.replace(props.task.description || ''))); - }, [props.task]); + setTaskTitle(task?.title ?? ''); + setTaskDescription(parser.htmlToMarkdown(parser.replace(task?.description ?? ''))); + }, [task]); - /** - * @param {Object} values - form input values passed by the Form component - * @returns {Boolean} - */ - function validate(values) { + const validate = (values: FormOnyxValues) => { const errors = {}; if (!values.taskTitle) { @@ -66,14 +55,14 @@ function NewTaskDetailsPage(props) { } return errors; - } + }; // On submit, we want to call the assignTask function and wait to validate // the response - function onSubmit(values) { - Task.setDetailsValue(values.taskTitle, values.taskDescription); + const onSubmit = (values: FormOnyxValues) => { + TaskActions.setDetailsValue(values.taskTitle, values.taskDescription); Navigation.navigate(ROUTES.NEW_TASK); - } + }; return ( Task.dismissModalAndClearOutTaskInfo()} + title={translate('newTaskPage.assignTask')} + onCloseButtonPress={() => TaskActions.dismissModalAndClearOutTaskInfo()} shouldShowBackButton - onBackButtonPress={() => Task.dismissModalAndClearOutTaskInfo()} + onBackButtonPress={() => TaskActions.dismissModalAndClearOutTaskInfo()} /> validate(values)} - onSubmit={(values) => onSubmit(values)} + validate={validate} + onSubmit={onSubmit} enabledWhenOffline > setTaskTitle(value)} + onValueChange={setTaskDescription} autoCorrect={false} /> setTaskDescription(value)} + onValueChange={setTaskDescription} /> @@ -129,14 +120,9 @@ function NewTaskDetailsPage(props) { } NewTaskDetailsPage.displayName = 'NewTaskDetailsPage'; -NewTaskDetailsPage.propTypes = propTypes; -NewTaskDetailsPage.defaultProps = defaultProps; -export default compose( - withOnyx({ - task: { - key: ONYXKEYS.TASK, - }, - }), - withLocalize, -)(NewTaskDetailsPage); +export default withOnyx({ + task: { + key: ONYXKEYS.TASK, + }, +})(NewTaskDetailsPage); diff --git a/src/pages/tasks/NewTaskDetailsPage.tsx b/src/pages/tasks/NewTaskDetailsPage.tsx new file mode 100644 index 000000000000..a7d98724a2f1 --- /dev/null +++ b/src/pages/tasks/NewTaskDetailsPage.tsx @@ -0,0 +1,128 @@ +import ExpensiMark from 'expensify-common/lib/ExpensiMark'; +import React, {useEffect, useState} from 'react'; +import {View} from 'react-native'; +import {withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; +import FormProvider from '@components/Form/FormProvider'; +import InputWrapper from '@components/Form/InputWrapper'; +import type {FormOnyxValues} from '@components/Form/types'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ScreenWrapper from '@components/ScreenWrapper'; +import TextInput from '@components/TextInput'; +import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as ErrorUtils from '@libs/ErrorUtils'; +import Navigation from '@libs/Navigation/Navigation'; +import * as TaskActions from '@userActions/Task'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import INPUT_IDS from '@src/types/form/NewTaskForm'; +import type {Task} from '@src/types/onyx'; + +type NewTaskDetailsPageProps = { + /** Grab the Share title of the Task */ + task: OnyxEntry; +}; + +const parser = new ExpensiMark(); + +function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const [taskTitle, setTaskTitle] = useState(task?.title ?? ''); + const [taskDescription, setTaskDescription] = useState(task?.description ?? ''); + + const {inputCallbackRef} = useAutoFocusInput(); + + useEffect(() => { + setTaskTitle(task?.title ?? ''); + setTaskDescription(parser.htmlToMarkdown(parser.replace(task?.description ?? ''))); + }, [task]); + + const validate = (values: FormOnyxValues) => { + const errors = {}; + + if (!values.taskTitle) { + // We error if the user doesn't enter a task name + ErrorUtils.addErrorMessage(errors, 'taskTitle', 'newTaskPage.pleaseEnterTaskName'); + } else if (values.taskTitle.length > CONST.TITLE_CHARACTER_LIMIT) { + ErrorUtils.addErrorMessage(errors, 'taskTitle', ['common.error.characterLimitExceedCounter', {length: values.taskTitle.length, limit: CONST.TITLE_CHARACTER_LIMIT}]); + } + if (values.taskDescription.length > CONST.DESCRIPTION_LIMIT) { + ErrorUtils.addErrorMessage(errors, 'taskDescription', ['common.error.characterLimitExceedCounter', {length: values.taskDescription.length, limit: CONST.DESCRIPTION_LIMIT}]); + } + + return errors; + }; + + // On submit, we want to call the assignTask function and wait to validate + // the response + const onSubmit = (values: FormOnyxValues) => { + TaskActions.setDetailsValue(values.taskTitle, values.taskDescription); + Navigation.navigate(ROUTES.NEW_TASK); + }; + + return ( + + TaskActions.dismissModalAndClearOutTaskInfo()} + shouldShowBackButton + onBackButtonPress={() => TaskActions.dismissModalAndClearOutTaskInfo()} + /> + + + + + + + + + + ); +} + +NewTaskDetailsPage.displayName = 'NewTaskDetailsPage'; + +export default withOnyx({ + task: { + key: ONYXKEYS.TASK, + }, +})(NewTaskDetailsPage); diff --git a/src/pages/tasks/NewTaskPage.js b/src/pages/tasks/NewTaskPage.tsx similarity index 53% rename from src/pages/tasks/NewTaskPage.js rename to src/pages/tasks/NewTaskPage.tsx index f77285190e62..3ca6e998d534 100644 --- a/src/pages/tasks/NewTaskPage.js +++ b/src/pages/tasks/NewTaskPage.tsx @@ -1,139 +1,113 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; import React, {useEffect, useMemo, useState} from 'react'; import {ScrollView, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MenuItem from '@components/MenuItem'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import compose from '@libs/compose'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; -import reportPropTypes from '@pages/reportPropTypes'; -import * as Task from '@userActions/Task'; +import * as TaskActions from '@userActions/Task'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type {PersonalDetailsList, Report, Task} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; -const propTypes = { +type NewTaskPageProps = { /** Task Creation Data */ - task: PropTypes.shape({ - assignee: PropTypes.string, - shareDestination: PropTypes.string, - title: PropTypes.string, - description: PropTypes.string, - parentReportID: PropTypes.string, - }), + task: OnyxEntry; /** All of the personal details for everyone */ - personalDetails: PropTypes.objectOf( - PropTypes.shape({ - /** Display name of the person */ - displayName: PropTypes.string, - - /** Avatar URL of the person */ - avatar: PropTypes.string, - - /** Login of the person */ - login: PropTypes.string, - }), - ), + personalDetails: OnyxEntry; /** All reports shared with the user */ - reports: PropTypes.objectOf(reportPropTypes), - - ...withLocalizePropTypes, + reports: OnyxCollection; }; -const defaultProps = { - task: {}, - personalDetails: {}, - reports: {}, -}; - -function NewTaskPage(props) { +function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { const styles = useThemeStyles(); - const [assignee, setAssignee] = useState({}); - const assigneeTooltipDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([props.task.assigneeAccountID], props.personalDetails), false); - const [shareDestination, setShareDestination] = useState({}); + const {translate} = useLocalize(); + const [assignee, setAssignee] = useState(); + const assigneeTooltipDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([task?.assigneeAccountID ?? 0], personalDetails), false); + const [shareDestination, setShareDestination] = useState(); const [title, setTitle] = useState(''); const [description, setDescription] = useState(''); const [errorMessage, setErrorMessage] = useState(''); - const [parentReport, setParentReport] = useState({}); + const [parentReport, setParentReport] = useState>(null); - const isAllowedToCreateTask = useMemo(() => _.isEmpty(parentReport) || ReportUtils.isAllowedToComment(parentReport), [parentReport]); + const isAllowedToCreateTask = useMemo(() => isEmptyObject(parentReport) || ReportUtils.isAllowedToComment(parentReport), [parentReport]); useEffect(() => { setErrorMessage(''); // If we have an assignee, we want to set the assignee data // If there's an issue with the assignee chosen, we want to notify the user - if (props.task.assignee) { - const displayDetails = Task.getAssignee(props.task.assigneeAccountID, props.personalDetails); + if (task?.assignee) { + const displayDetails = TaskActions.getAssignee(task?.assigneeAccountID ?? 0, personalDetails); setAssignee(displayDetails); } // We only set the parentReportID if we are creating a task from a report // this allows us to go ahead and set that report as the share destination // and disable the share destination selector - if (props.task.parentReportID) { - Task.setShareDestinationValue(props.task.parentReportID); + if (task?.parentReportID) { + TaskActions.setShareDestinationValue(task.parentReportID); } // If we have a share destination, we want to set the parent report and // the share destination data - if (props.task.shareDestination) { - setParentReport(lodashGet(props.reports, `report_${props.task.shareDestination}`, {})); - const displayDetails = Task.getShareDestination(props.task.shareDestination, props.reports, props.personalDetails); + if (task?.shareDestination) { + setParentReport(reports?.[`report_${task.shareDestination}`] ?? null); + const displayDetails = TaskActions.getShareDestination(task.shareDestination, reports, personalDetails); setShareDestination(displayDetails); } // If we have a title, we want to set the title - if (!_.isUndefined(props.task.title)) { - setTitle(props.task.title); + if (task?.title !== undefined) { + setTitle(task.title); } // If we have a description, we want to set the description - if (!_.isUndefined(props.task.description)) { - setDescription(props.task.description); + if (task?.description !== undefined) { + setDescription(task.description); } - }, [props]); + }, [personalDetails, reports, task?.assignee, task?.assigneeAccountID, task?.description, task?.parentReportID, task?.shareDestination, task?.title]); // On submit, we want to call the createTask function and wait to validate // the response function onSubmit() { - if (!props.task.title && !props.task.shareDestination) { + if (!task?.title && !task?.shareDestination) { setErrorMessage('newTaskPage.confirmError'); return; } - if (!props.task.title) { + if (!task?.title) { setErrorMessage('newTaskPage.pleaseEnterTaskName'); return; } - if (!props.task.shareDestination) { + if (!task?.shareDestination) { setErrorMessage('newTaskPage.pleaseEnterTaskDestination'); return; } playSound(SOUNDS.DONE); - Task.createTaskAndNavigate( - parentReport.reportID, - props.task.title, - props.task.description, - props.task.assignee, - props.task.assigneeAccountID, - props.task.assigneeChatReport, - parentReport.policyID, + TaskActions.createTaskAndNavigate( + parentReport?.reportID ?? '', + task.title, + task?.description ?? '', + task?.assignee ?? '', + task.assigneeAccountID, + task.assigneeChatReport, + parentReport?.policyID, ); } @@ -144,12 +118,12 @@ function NewTaskPage(props) { > Task.dismissModalAndClearOutTaskInfo()} + onBackButtonPress={() => TaskActions.dismissModalAndClearOutTaskInfo()} shouldShowLink={false} > Task.dismissModalAndClearOutTaskInfo()} + title={translate('newTaskPage.confirmTask')} + onCloseButtonPress={() => TaskActions.dismissModalAndClearOutTaskInfo()} shouldShowBackButton onBackButtonPress={() => { Navigation.goBack(ROUTES.NEW_TASK_DETAILS); @@ -163,16 +137,16 @@ function NewTaskPage(props) { // See: https://github.com/Expensify/App/issues/31441 scrollIndicatorInsets={{right: Number.MIN_VALUE}} > - + Navigation.navigate(ROUTES.NEW_TASK_TITLE)} shouldShowRightIcon /> Navigation.navigate(ROUTES.NEW_TASK_DESCRIPTION)} shouldShowRightIcon @@ -181,33 +155,33 @@ function NewTaskPage(props) { titleStyle={styles.flex1} /> Navigation.navigate(ROUTES.NEW_TASK_ASSIGNEE)} shouldShowRightIcon titleWithTooltips={assigneeTooltipDetails} /> Navigation.navigate(ROUTES.NEW_TASK_SHARE_DESTINATION)} - interactive={!props.task.parentReportID} - shouldShowRightIcon={!props.task.parentReportID} - titleWithTooltips={!shareDestination.shouldUseFullTitleToDisplay && shareDestination.displayNamesWithTooltips} + interactive={!task?.parentReportID} + shouldShowRightIcon={!task?.parentReportID} + titleWithTooltips={shareDestination?.shouldUseFullTitleToDisplay ? shareDestination?.displayNamesWithTooltips : []} /> onSubmit()} enabledWhenOffline - buttonText={props.translate('newTaskPage.confirmTask')} + buttonText={translate('newTaskPage.confirmTask')} containerStyles={[styles.mh0, styles.mt5, styles.flex1, styles.ph5]} /> @@ -218,20 +192,15 @@ function NewTaskPage(props) { } NewTaskPage.displayName = 'NewTaskPage'; -NewTaskPage.propTypes = propTypes; -NewTaskPage.defaultProps = defaultProps; - -export default compose( - withOnyx({ - task: { - key: ONYXKEYS.TASK, - }, - reports: { - key: ONYXKEYS.COLLECTION.REPORT, - }, - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, - }), - withLocalize, -)(NewTaskPage); + +export default withOnyx({ + task: { + key: ONYXKEYS.TASK, + }, + reports: { + key: ONYXKEYS.COLLECTION.REPORT, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, +})(NewTaskPage); diff --git a/src/pages/tasks/NewTaskTitlePage.js b/src/pages/tasks/NewTaskTitlePage.tsx similarity index 64% rename from src/pages/tasks/NewTaskTitlePage.js rename to src/pages/tasks/NewTaskTitlePage.tsx index 5b1f180c97d6..4bf6f7bee6f5 100644 --- a/src/pages/tasks/NewTaskTitlePage.js +++ b/src/pages/tasks/NewTaskTitlePage.tsx @@ -1,49 +1,37 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapperWithRef from '@components/Form/InputWrapper'; +import type {FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; -import * as Task from '@userActions/Task'; +import * as TaskActions from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import INPUT_IDS from '@src/types/form/NewTaskForm'; +import type {Task} from '@src/types/onyx'; -const propTypes = { +type NewTaskTitlePageProps = { /** Grab the Share title of the Task */ - task: PropTypes.shape({ - /** Title of the Task */ - title: PropTypes.string, - }), - - ...withLocalizePropTypes, -}; - -const defaultProps = { - task: { - title: '', - }, + task: OnyxEntry; }; -function NewTaskTitlePage(props) { +function NewTaskTitlePage({task}: NewTaskTitlePageProps) { const styles = useThemeStyles(); const {inputCallbackRef} = useAutoFocusInput(); - /** - * @param {Object} values - form input values passed by the Form component - * @returns {Boolean} - */ - function validate(values) { + const {translate} = useLocalize(); + + const validate = (values: FormOnyxValues) => { const errors = {}; if (!values.taskTitle) { @@ -54,14 +42,14 @@ function NewTaskTitlePage(props) { } return errors; - } + }; // On submit, we want to call the assignTask function and wait to validate // the response - function onSubmit(values) { - Task.setTitleValue(values.taskTitle); + const onSubmit = (values: FormOnyxValues) => { + TaskActions.setTitleValue(values.taskTitle); Navigation.goBack(ROUTES.NEW_TASK); - } + }; return ( Task.dismissModalAndClearOutTaskInfo()} + title={translate('task.title')} + onCloseButtonPress={() => TaskActions.dismissModalAndClearOutTaskInfo()} shouldShowBackButton onBackButtonPress={() => Navigation.goBack(ROUTES.NEW_TASK)} /> validate(values)} - onSubmit={(values) => onSubmit(values)} + validate={validate} + onSubmit={onSubmit} enabledWhenOffline > @@ -100,14 +88,9 @@ function NewTaskTitlePage(props) { } NewTaskTitlePage.displayName = 'NewTaskTitlePage'; -NewTaskTitlePage.propTypes = propTypes; -NewTaskTitlePage.defaultProps = defaultProps; -export default compose( - withOnyx({ - task: { - key: ONYXKEYS.TASK, - }, - }), - withLocalize, -)(NewTaskTitlePage); +export default withOnyx({ + task: { + key: ONYXKEYS.TASK, + }, +})(NewTaskTitlePage); From f16ad888c2991a229f183b1c8cedfa30c86a773b Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Thu, 22 Feb 2024 13:06:27 +0100 Subject: [PATCH 2/7] address comments --- src/pages/tasks/NewTaskDescriptionPage.tsx | 13 +- src/pages/tasks/NewTaskDetailsPage copy.tsx | 128 -------------------- src/pages/tasks/NewTaskDetailsPage.tsx | 17 ++- src/pages/tasks/NewTaskPage.tsx | 24 ++-- src/pages/tasks/NewTaskTitlePage.tsx | 12 +- 5 files changed, 44 insertions(+), 150 deletions(-) delete mode 100644 src/pages/tasks/NewTaskDetailsPage copy.tsx diff --git a/src/pages/tasks/NewTaskDescriptionPage.tsx b/src/pages/tasks/NewTaskDescriptionPage.tsx index 3422fa9d1b1f..623d13fdda26 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.tsx +++ b/src/pages/tasks/NewTaskDescriptionPage.tsx @@ -1,3 +1,4 @@ +import type {StackScreenProps} from '@react-navigation/stack'; import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import React from 'react'; import {View} from 'react-native'; @@ -5,7 +6,7 @@ import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapperWithRef from '@components/Form/InputWrapper'; -import type {FormOnyxValues} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; @@ -14,19 +15,23 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; +import type {NewTaskNavigatorParamList} from '@libs/Navigation/types'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import * as TaskActions from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/NewTaskForm'; import type {Task} from '@src/types/onyx'; -type NewTaskDescriptionPageProps = { +type NewTaskDescriptionPageOnyxProps = { /** Grab the Share title of the Task */ task: OnyxEntry; }; +type NewTaskDescriptionPageProps = NewTaskDescriptionPageOnyxProps & StackScreenProps; + const parser = new ExpensiMark(); function NewTaskDescriptionPage({task}: NewTaskDescriptionPageProps) { @@ -39,7 +44,7 @@ function NewTaskDescriptionPage({task}: NewTaskDescriptionPageProps) { Navigation.goBack(ROUTES.NEW_TASK); }; - const validate = (values: FormOnyxValues) => { + const validate = (values: FormOnyxValues): FormInputErrors => { const errors = {}; if (values.taskDescription.length > CONST.DESCRIPTION_LIMIT) { @@ -94,7 +99,7 @@ function NewTaskDescriptionPage({task}: NewTaskDescriptionPageProps) { NewTaskDescriptionPage.displayName = 'NewTaskDescriptionPage'; -export default withOnyx({ +export default withOnyx({ task: { key: ONYXKEYS.TASK, }, diff --git a/src/pages/tasks/NewTaskDetailsPage copy.tsx b/src/pages/tasks/NewTaskDetailsPage copy.tsx deleted file mode 100644 index a7d98724a2f1..000000000000 --- a/src/pages/tasks/NewTaskDetailsPage copy.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import ExpensiMark from 'expensify-common/lib/ExpensiMark'; -import React, {useEffect, useState} from 'react'; -import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; -import type {OnyxEntry} from 'react-native-onyx'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapper from '@components/Form/InputWrapper'; -import type {FormOnyxValues} from '@components/Form/types'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import TextInput from '@components/TextInput'; -import useAutoFocusInput from '@hooks/useAutoFocusInput'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import * as ErrorUtils from '@libs/ErrorUtils'; -import Navigation from '@libs/Navigation/Navigation'; -import * as TaskActions from '@userActions/Task'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import INPUT_IDS from '@src/types/form/NewTaskForm'; -import type {Task} from '@src/types/onyx'; - -type NewTaskDetailsPageProps = { - /** Grab the Share title of the Task */ - task: OnyxEntry; -}; - -const parser = new ExpensiMark(); - -function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const [taskTitle, setTaskTitle] = useState(task?.title ?? ''); - const [taskDescription, setTaskDescription] = useState(task?.description ?? ''); - - const {inputCallbackRef} = useAutoFocusInput(); - - useEffect(() => { - setTaskTitle(task?.title ?? ''); - setTaskDescription(parser.htmlToMarkdown(parser.replace(task?.description ?? ''))); - }, [task]); - - const validate = (values: FormOnyxValues) => { - const errors = {}; - - if (!values.taskTitle) { - // We error if the user doesn't enter a task name - ErrorUtils.addErrorMessage(errors, 'taskTitle', 'newTaskPage.pleaseEnterTaskName'); - } else if (values.taskTitle.length > CONST.TITLE_CHARACTER_LIMIT) { - ErrorUtils.addErrorMessage(errors, 'taskTitle', ['common.error.characterLimitExceedCounter', {length: values.taskTitle.length, limit: CONST.TITLE_CHARACTER_LIMIT}]); - } - if (values.taskDescription.length > CONST.DESCRIPTION_LIMIT) { - ErrorUtils.addErrorMessage(errors, 'taskDescription', ['common.error.characterLimitExceedCounter', {length: values.taskDescription.length, limit: CONST.DESCRIPTION_LIMIT}]); - } - - return errors; - }; - - // On submit, we want to call the assignTask function and wait to validate - // the response - const onSubmit = (values: FormOnyxValues) => { - TaskActions.setDetailsValue(values.taskTitle, values.taskDescription); - Navigation.navigate(ROUTES.NEW_TASK); - }; - - return ( - - TaskActions.dismissModalAndClearOutTaskInfo()} - shouldShowBackButton - onBackButtonPress={() => TaskActions.dismissModalAndClearOutTaskInfo()} - /> - - - - - - - - - - ); -} - -NewTaskDetailsPage.displayName = 'NewTaskDetailsPage'; - -export default withOnyx({ - task: { - key: ONYXKEYS.TASK, - }, -})(NewTaskDetailsPage); diff --git a/src/pages/tasks/NewTaskDetailsPage.tsx b/src/pages/tasks/NewTaskDetailsPage.tsx index a7d98724a2f1..f51a8acf0251 100644 --- a/src/pages/tasks/NewTaskDetailsPage.tsx +++ b/src/pages/tasks/NewTaskDetailsPage.tsx @@ -1,3 +1,4 @@ +import type {StackScreenProps} from '@react-navigation/stack'; import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import React, {useEffect, useState} from 'react'; import {View} from 'react-native'; @@ -5,7 +6,7 @@ import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; -import type {FormOnyxValues} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; @@ -14,25 +15,29 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; +import type {NewTaskNavigatorParamList} from '@libs/Navigation/types'; import * as TaskActions from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/NewTaskForm'; import type {Task} from '@src/types/onyx'; -type NewTaskDetailsPageProps = { +type NewTaskDetailsPageOnyxProps = { /** Grab the Share title of the Task */ task: OnyxEntry; }; +type NewTaskDetailsPageProps = NewTaskDetailsPageOnyxProps & StackScreenProps; + const parser = new ExpensiMark(); function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [taskTitle, setTaskTitle] = useState(task?.title ?? ''); - const [taskDescription, setTaskDescription] = useState(task?.description ?? ''); + const [taskTitle, setTaskTitle] = useState(task?.title ?? ''); + const [taskDescription, setTaskDescription] = useState(task?.description ?? ''); const {inputCallbackRef} = useAutoFocusInput(); @@ -41,7 +46,7 @@ function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { setTaskDescription(parser.htmlToMarkdown(parser.replace(task?.description ?? ''))); }, [task]); - const validate = (values: FormOnyxValues) => { + const validate = (values: FormOnyxValues): FormInputErrors => { const errors = {}; if (!values.taskTitle) { @@ -121,7 +126,7 @@ function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { NewTaskDetailsPage.displayName = 'NewTaskDetailsPage'; -export default withOnyx({ +export default withOnyx({ task: { key: ONYXKEYS.TASK, }, diff --git a/src/pages/tasks/NewTaskPage.tsx b/src/pages/tasks/NewTaskPage.tsx index 3ca6e998d534..62a513a75265 100644 --- a/src/pages/tasks/NewTaskPage.tsx +++ b/src/pages/tasks/NewTaskPage.tsx @@ -1,3 +1,4 @@ +import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect, useMemo, useState} from 'react'; import {ScrollView, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; @@ -12,16 +13,18 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import Navigation from '@libs/Navigation/Navigation'; +import type {NewTaskNavigatorParamList} from '@libs/Navigation/types'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; import * as TaskActions from '@userActions/Task'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; import type {PersonalDetailsList, Report, Task} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -type NewTaskPageProps = { +type NewTaskPageOnyxProps = { /** Task Creation Data */ task: OnyxEntry; @@ -32,11 +35,16 @@ type NewTaskPageProps = { reports: OnyxCollection; }; +type NewTaskPageProps = NewTaskPageOnyxProps & StackScreenProps; + function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const [assignee, setAssignee] = useState(); - const assigneeTooltipDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([task?.assigneeAccountID ?? 0], personalDetails), false); + const assigneeTooltipDetails = ReportUtils.getDisplayNamesWithTooltips( + OptionsListUtils.getPersonalDetailsForAccountIDs(task?.assigneeAccountID ? [task.assigneeAccountID] : [], personalDetails), + false, + ); const [shareDestination, setShareDestination] = useState(); const [title, setTitle] = useState(''); const [description, setDescription] = useState(''); @@ -51,7 +59,7 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { // If we have an assignee, we want to set the assignee data // If there's an issue with the assignee chosen, we want to notify the user if (task?.assignee) { - const displayDetails = TaskActions.getAssignee(task?.assigneeAccountID ?? 0, personalDetails); + const displayDetails = TaskActions.getAssignee(task?.assigneeAccountID ?? -1, personalDetails); setAssignee(displayDetails); } @@ -83,7 +91,7 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { // On submit, we want to call the createTask function and wait to validate // the response - function onSubmit() { + const onSubmit = () => { if (!task?.title && !task?.shareDestination) { setErrorMessage('newTaskPage.confirmError'); return; @@ -109,7 +117,7 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { task.assigneeChatReport, parentReport?.policyID, ); - } + }; return ( - + onSubmit()} + onSubmit={onSubmit} enabledWhenOffline buttonText={translate('newTaskPage.confirmTask')} containerStyles={[styles.mh0, styles.mt5, styles.flex1, styles.ph5]} @@ -193,7 +201,7 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { NewTaskPage.displayName = 'NewTaskPage'; -export default withOnyx({ +export default withOnyx({ task: { key: ONYXKEYS.TASK, }, diff --git a/src/pages/tasks/NewTaskTitlePage.tsx b/src/pages/tasks/NewTaskTitlePage.tsx index 4bf6f7bee6f5..0eec7a272a79 100644 --- a/src/pages/tasks/NewTaskTitlePage.tsx +++ b/src/pages/tasks/NewTaskTitlePage.tsx @@ -1,10 +1,11 @@ +import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapperWithRef from '@components/Form/InputWrapper'; -import type {FormOnyxValues} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; @@ -13,17 +14,20 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; +import type {NewTaskNavigatorParamList} from '@libs/Navigation/types'; import * as TaskActions from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/NewTaskForm'; import type {Task} from '@src/types/onyx'; -type NewTaskTitlePageProps = { +type NewTaskTitlePageOnyxProps = { /** Grab the Share title of the Task */ task: OnyxEntry; }; +type NewTaskTitlePageProps = NewTaskTitlePageOnyxProps & StackScreenProps; function NewTaskTitlePage({task}: NewTaskTitlePageProps) { const styles = useThemeStyles(); @@ -31,7 +35,7 @@ function NewTaskTitlePage({task}: NewTaskTitlePageProps) { const {translate} = useLocalize(); - const validate = (values: FormOnyxValues) => { + const validate = (values: FormOnyxValues): FormInputErrors => { const errors = {}; if (!values.taskTitle) { @@ -89,7 +93,7 @@ function NewTaskTitlePage({task}: NewTaskTitlePageProps) { NewTaskTitlePage.displayName = 'NewTaskTitlePage'; -export default withOnyx({ +export default withOnyx({ task: { key: ONYXKEYS.TASK, }, From dee61b16c27832f391d9dc598b071ad8cb26b1ef Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Wed, 6 Mar 2024 12:11:15 +0100 Subject: [PATCH 3/7] change is not empty flag for string --- src/pages/tasks/NewTaskPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/tasks/NewTaskPage.tsx b/src/pages/tasks/NewTaskPage.tsx index 62a513a75265..dc2b0cd77416 100644 --- a/src/pages/tasks/NewTaskPage.tsx +++ b/src/pages/tasks/NewTaskPage.tsx @@ -185,7 +185,7 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { Date: Wed, 6 Mar 2024 12:15:57 +0100 Subject: [PATCH 4/7] update comment for task --- src/pages/tasks/NewTaskDescriptionPage.tsx | 2 +- src/pages/tasks/NewTaskDetailsPage.tsx | 2 +- src/pages/tasks/NewTaskTitlePage.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/tasks/NewTaskDescriptionPage.tsx b/src/pages/tasks/NewTaskDescriptionPage.tsx index 623d13fdda26..a5eb79497707 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.tsx +++ b/src/pages/tasks/NewTaskDescriptionPage.tsx @@ -26,7 +26,7 @@ import INPUT_IDS from '@src/types/form/NewTaskForm'; import type {Task} from '@src/types/onyx'; type NewTaskDescriptionPageOnyxProps = { - /** Grab the Share title of the Task */ + /** Task Creation Data */ task: OnyxEntry; }; diff --git a/src/pages/tasks/NewTaskDetailsPage.tsx b/src/pages/tasks/NewTaskDetailsPage.tsx index f51a8acf0251..97af351920df 100644 --- a/src/pages/tasks/NewTaskDetailsPage.tsx +++ b/src/pages/tasks/NewTaskDetailsPage.tsx @@ -25,7 +25,7 @@ import INPUT_IDS from '@src/types/form/NewTaskForm'; import type {Task} from '@src/types/onyx'; type NewTaskDetailsPageOnyxProps = { - /** Grab the Share title of the Task */ + /** Task Creation Data */ task: OnyxEntry; }; diff --git a/src/pages/tasks/NewTaskTitlePage.tsx b/src/pages/tasks/NewTaskTitlePage.tsx index 0eec7a272a79..582d2a5c6500 100644 --- a/src/pages/tasks/NewTaskTitlePage.tsx +++ b/src/pages/tasks/NewTaskTitlePage.tsx @@ -24,7 +24,7 @@ import INPUT_IDS from '@src/types/form/NewTaskForm'; import type {Task} from '@src/types/onyx'; type NewTaskTitlePageOnyxProps = { - /** Grab the Share title of the Task */ + /** Task Creation Data */ task: OnyxEntry; }; type NewTaskTitlePageProps = NewTaskTitlePageOnyxProps & StackScreenProps; From 9c17b9c2cf81c9c8ebcd920c3d8bd0aa76ce915e Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Wed, 6 Mar 2024 12:48:23 +0100 Subject: [PATCH 5/7] fix set title handler --- src/pages/tasks/NewTaskDetailsPage.tsx | 2 +- src/pages/tasks/NewTaskPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/tasks/NewTaskDetailsPage.tsx b/src/pages/tasks/NewTaskDetailsPage.tsx index 97af351920df..15612e20afd7 100644 --- a/src/pages/tasks/NewTaskDetailsPage.tsx +++ b/src/pages/tasks/NewTaskDetailsPage.tsx @@ -99,7 +99,7 @@ function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { label={translate('task.title')} accessibilityLabel={translate('task.title')} value={taskTitle} - onValueChange={setTaskDescription} + onValueChange={setTaskTitle} autoCorrect={false} /> diff --git a/src/pages/tasks/NewTaskPage.tsx b/src/pages/tasks/NewTaskPage.tsx index dc2b0cd77416..2bfa46af52c8 100644 --- a/src/pages/tasks/NewTaskPage.tsx +++ b/src/pages/tasks/NewTaskPage.tsx @@ -185,7 +185,7 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { Date: Tue, 12 Mar 2024 13:23:28 +0100 Subject: [PATCH 6/7] fix prettier --- src/pages/tasks/NewTaskPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/tasks/NewTaskPage.tsx b/src/pages/tasks/NewTaskPage.tsx index ff57a5d87080..d592f29c415d 100644 --- a/src/pages/tasks/NewTaskPage.tsx +++ b/src/pages/tasks/NewTaskPage.tsx @@ -9,8 +9,8 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MenuItem from '@components/MenuItem'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; -import useLocalize from '@hooks/useLocalize'; import ScrollView from '@components/ScrollView'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import Navigation from '@libs/Navigation/Navigation'; From 4e52920c991d2036d5bd56249f291b7ee32897fd Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 12 Mar 2024 13:52:39 +0100 Subject: [PATCH 7/7] remove redundant optional chaining --- src/pages/tasks/NewTaskPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/tasks/NewTaskPage.tsx b/src/pages/tasks/NewTaskPage.tsx index d592f29c415d..64c46e75c91d 100644 --- a/src/pages/tasks/NewTaskPage.tsx +++ b/src/pages/tasks/NewTaskPage.tsx @@ -98,12 +98,12 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { return; } - if (!task?.title) { + if (!task.title) { setErrorMessage('newTaskPage.pleaseEnterTaskName'); return; } - if (!task?.shareDestination) { + if (!task.shareDestination) { setErrorMessage('newTaskPage.pleaseEnterTaskDestination'); return; }