-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
TaskDescriptionPage.tsx
141 lines (128 loc) · 6.42 KB
/
TaskDescriptionPage.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useRef} from 'react';
import {View} from 'react-native';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import FormProvider from '@components/Form/FormProvider';
import InputWrapper from '@components/Form/InputWrapper';
import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import type {AnimatedTextInputRef} from '@components/RNTextInput';
import ScreenWrapper from '@components/ScreenWrapper';
import TextInput from '@components/TextInput';
import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails';
import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import Parser from '@libs/Parser';
import * as ReportUtils from '@libs/ReportUtils';
import updateMultilineInputRange from '@libs/updateMultilineInputRange';
import withReportOrNotFound from '@pages/home/report/withReportOrNotFound';
import type {WithReportOrNotFoundProps} from '@pages/home/report/withReportOrNotFound';
import variables from '@styles/variables';
import * as Task from '@userActions/Task';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import INPUT_IDS from '@src/types/form/EditTaskForm';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
type TaskDescriptionPageProps = WithReportOrNotFoundProps & WithCurrentUserPersonalDetailsProps;
function TaskDescriptionPage({report, currentUserPersonalDetails}: TaskDescriptionPageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const validate = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_TASK_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.EDIT_TASK_FORM> => {
const errors = {};
const parsedDescription = ReportUtils.getParsedComment(values?.description);
const taskDescriptionLength = ReportUtils.getCommentLength(parsedDescription);
if (values?.description && taskDescriptionLength > CONST.DESCRIPTION_LIMIT) {
ErrorUtils.addErrorMessage(errors, 'description', translate('common.error.characterLimitExceedCounter', {length: taskDescriptionLength, limit: CONST.DESCRIPTION_LIMIT}));
}
return errors;
},
[translate],
);
const submit = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_TASK_FORM>) => {
if (values.description !== Parser.htmlToMarkdown(report?.description ?? '') && !isEmptyObject(report)) {
// Set the description of the report in the store and then call EditTask API
// to update the description of the report on the server
Task.editTask(report, {description: values.description});
}
Navigation.dismissModal(report?.reportID);
},
[report],
);
if (!ReportUtils.isTaskReport(report)) {
Navigation.isNavigationReady().then(() => {
Navigation.dismissModal(report?.reportID);
});
}
const inputRef = useRef<AnimatedTextInputRef | null>(null);
const focusTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const isOpen = ReportUtils.isOpenTaskReport(report);
const canModifyTask = Task.canModifyTask(report, currentUserPersonalDetails.accountID);
const isTaskNonEditable = ReportUtils.isTaskReport(report) && (!canModifyTask || !isOpen);
useFocusEffect(
useCallback(() => {
focusTimeoutRef.current = setTimeout(() => {
if (inputRef.current) {
inputRef.current.focus();
}
return () => {
if (!focusTimeoutRef.current) {
return;
}
clearTimeout(focusTimeoutRef.current);
};
}, CONST.ANIMATED_TRANSITION);
}, []),
);
return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
shouldEnableMaxHeight
testID={TaskDescriptionPage.displayName}
>
<FullPageNotFoundView shouldShow={isTaskNonEditable}>
<HeaderWithBackButton title={translate('task.task')} />
<FormProvider
style={[styles.flexGrow1, styles.ph5]}
formID={ONYXKEYS.FORMS.EDIT_TASK_FORM}
validate={validate}
onSubmit={submit}
submitButtonText={translate('common.save')}
enabledWhenOffline
>
<View style={[styles.mb4]}>
<InputWrapper
InputComponent={TextInput}
role={CONST.ROLE.PRESENTATION}
inputID={INPUT_IDS.DESCRIPTION}
name={INPUT_IDS.DESCRIPTION}
label={translate('newTaskPage.descriptionOptional')}
accessibilityLabel={translate('newTaskPage.descriptionOptional')}
defaultValue={Parser.htmlToMarkdown(report?.description ?? '')}
ref={(element: AnimatedTextInputRef) => {
if (!element) {
return;
}
if (!inputRef.current) {
updateMultilineInputRange(inputRef.current);
}
inputRef.current = element;
}}
autoGrowHeight
maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight}
shouldSubmitForm
isMarkdownEnabled
/>
</View>
</FormProvider>
</FullPageNotFoundView>
</ScreenWrapper>
);
}
TaskDescriptionPage.displayName = 'TaskDescriptionPage';
const ComponentWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(TaskDescriptionPage);
export default withReportOrNotFound()(ComponentWithCurrentUserPersonalDetails);