From 4423fbdbc62f144e8eb79fee0f5843d95cd780b6 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Thu, 28 Dec 2023 20:20:41 +0000 Subject: [PATCH 01/14] copy TaskPreview --- .../ReportActionItem/TaskPreview.tsx | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/components/ReportActionItem/TaskPreview.tsx diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx new file mode 100644 index 000000000000..a7728045f407 --- /dev/null +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -0,0 +1,164 @@ +import lodashGet from 'lodash/get'; +import PropTypes from 'prop-types'; +import React from 'react'; +import {View} from 'react-native'; +import {withOnyx} from 'react-native-onyx'; +import _ from 'underscore'; +import Checkbox from '@components/Checkbox'; +import Icon from '@components/Icon'; +import * as Expensicons from '@components/Icon/Expensicons'; +import {usePersonalDetails} from '@components/OnyxProvider'; +import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; +import refPropTypes from '@components/refPropTypes'; +import RenderHTML from '@components/RenderHTML'; +import {showContextMenuForReport} from '@components/ShowContextMenuContext'; +import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps, withCurrentUserPersonalDetailsPropTypes} from '@components/withCurrentUserPersonalDetails'; +import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useThemeStyles from '@hooks/useThemeStyles'; +import compose from '@libs/compose'; +import ControlSelection from '@libs/ControlSelection'; +import * as DeviceCapabilities from '@libs/DeviceCapabilities'; +import getButtonState from '@libs/getButtonState'; +import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; +import Navigation from '@libs/Navigation/Navigation'; +import * as ReportUtils from '@libs/ReportUtils'; +import * as TaskUtils from '@libs/TaskUtils'; +import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; +import * as Session from '@userActions/Session'; +import * as Task from '@userActions/Task'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; + +const propTypes = { + /** The ID of the associated taskReport */ + taskReportID: PropTypes.string.isRequired, + + /** Whether the task preview is hovered so we can modify its style */ + isHovered: PropTypes.bool, + + /** The linked reportAction */ + action: PropTypes.shape(reportActionPropTypes).isRequired, + + /* Onyx Props */ + + taskReport: PropTypes.shape({ + /** Title of the task */ + reportName: PropTypes.string, + + /** AccountID of the manager in this iou report */ + managerID: PropTypes.number, + + /** AccountID of the creator of this iou report */ + ownerAccountID: PropTypes.number, + }), + + /** The policy of root parent report */ + rootParentReportpolicy: PropTypes.shape({ + /** The role of current user */ + role: PropTypes.string, + }), + + /** The chat report associated with taskReport */ + chatReportID: PropTypes.string.isRequired, + + /** Popover context menu anchor, used for showing context menu */ + contextMenuAnchor: refPropTypes, + + /** Callback for updating context menu active state, used for showing context menu */ + checkIfContextMenuActive: PropTypes.func, + + /* Onyx Props */ + ...withLocalizePropTypes, + + ...withCurrentUserPersonalDetailsPropTypes, +}; + +const defaultProps = { + ...withCurrentUserPersonalDetailsDefaultProps, + taskReport: {}, + rootParentReportpolicy: {}, + isHovered: false, +}; + +function TaskPreview(props) { + const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); + const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; + // The reportAction might not contain details regarding the taskReport + // Only the direct parent reportAction will contain details about the taskReport + // Other linked reportActions will only contain the taskReportID and we will grab the details from there + const isTaskCompleted = !_.isEmpty(props.taskReport) + ? props.taskReport.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.taskReport.statusNum === CONST.REPORT.STATUS.APPROVED + : props.action.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.action.childStatusNum === CONST.REPORT.STATUS.APPROVED; + const taskTitle = _.escape(TaskUtils.getTaskTitle(props.taskReportID, props.action.childReportName)); + const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(props.taskReport) || props.action.childManagerAccountID; + const assigneeLogin = lodashGet(personalDetails, [taskAssigneeAccountID, 'login'], ''); + const assigneeDisplayName = lodashGet(personalDetails, [taskAssigneeAccountID, 'displayName'], ''); + const taskAssignee = assigneeDisplayName || LocalePhoneNumber.formatPhoneNumber(assigneeLogin); + const htmlForTaskPreview = + taskAssignee && taskAssigneeAccountID !== 0 + ? `@${taskAssignee} ${taskTitle}` + : `${taskTitle}`; + const isDeletedParentAction = ReportUtils.isCanceledTaskReport(props.taskReport, props.action); + + if (isDeletedParentAction) { + return ${props.translate('parentReportAction.deletedTask')}`} />; + } + + return ( + + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(props.taskReportID))} + onPressIn={() => DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} + onPressOut={() => ControlSelection.unblock()} + onLongPress={(event) => showContextMenuForReport(event, props.contextMenuAnchor, props.chatReportID, props.action, props.checkIfContextMenuActive)} + style={[styles.flexRow, styles.justifyContentBetween]} + role={CONST.ROLE.BUTTON} + accessibilityLabel={props.translate('task.task')} + > + + { + if (isTaskCompleted) { + Task.reopenTask(props.taskReport); + } else { + Task.completeTask(props.taskReport); + } + })} + accessibilityLabel={props.translate('task.task')} + /> + + + + + + ); +} + +TaskPreview.propTypes = propTypes; +TaskPreview.defaultProps = defaultProps; +TaskPreview.displayName = 'TaskPreview'; + +export default compose( + withLocalize, + withCurrentUserPersonalDetails, + withOnyx({ + taskReport: { + key: ({taskReportID}) => `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, + initialValue: {}, + }, + rootParentReportpolicy: { + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID || '0'}`, + selector: (policy) => _.pick(policy, ['role']), + }, + }), +)(TaskPreview); From d35f4b41203f219e15e058701ca1ae7d937c72bd Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Fri, 29 Dec 2023 00:44:51 +0000 Subject: [PATCH 02/14] policy Id unused error --- .../ReportActionItem/TaskPreview.js | 164 ------------------ .../ReportActionItem/TaskPreview.tsx | 117 +++++-------- 2 files changed, 46 insertions(+), 235 deletions(-) delete mode 100644 src/components/ReportActionItem/TaskPreview.js diff --git a/src/components/ReportActionItem/TaskPreview.js b/src/components/ReportActionItem/TaskPreview.js deleted file mode 100644 index a7728045f407..000000000000 --- a/src/components/ReportActionItem/TaskPreview.js +++ /dev/null @@ -1,164 +0,0 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; -import React from 'react'; -import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; -import Checkbox from '@components/Checkbox'; -import Icon from '@components/Icon'; -import * as Expensicons from '@components/Icon/Expensicons'; -import {usePersonalDetails} from '@components/OnyxProvider'; -import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; -import refPropTypes from '@components/refPropTypes'; -import RenderHTML from '@components/RenderHTML'; -import {showContextMenuForReport} from '@components/ShowContextMenuContext'; -import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps, withCurrentUserPersonalDetailsPropTypes} from '@components/withCurrentUserPersonalDetails'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; -import useStyleUtils from '@hooks/useStyleUtils'; -import useThemeStyles from '@hooks/useThemeStyles'; -import compose from '@libs/compose'; -import ControlSelection from '@libs/ControlSelection'; -import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import getButtonState from '@libs/getButtonState'; -import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; -import Navigation from '@libs/Navigation/Navigation'; -import * as ReportUtils from '@libs/ReportUtils'; -import * as TaskUtils from '@libs/TaskUtils'; -import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; -import * as Session from '@userActions/Session'; -import * as Task from '@userActions/Task'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; - -const propTypes = { - /** The ID of the associated taskReport */ - taskReportID: PropTypes.string.isRequired, - - /** Whether the task preview is hovered so we can modify its style */ - isHovered: PropTypes.bool, - - /** The linked reportAction */ - action: PropTypes.shape(reportActionPropTypes).isRequired, - - /* Onyx Props */ - - taskReport: PropTypes.shape({ - /** Title of the task */ - reportName: PropTypes.string, - - /** AccountID of the manager in this iou report */ - managerID: PropTypes.number, - - /** AccountID of the creator of this iou report */ - ownerAccountID: PropTypes.number, - }), - - /** The policy of root parent report */ - rootParentReportpolicy: PropTypes.shape({ - /** The role of current user */ - role: PropTypes.string, - }), - - /** The chat report associated with taskReport */ - chatReportID: PropTypes.string.isRequired, - - /** Popover context menu anchor, used for showing context menu */ - contextMenuAnchor: refPropTypes, - - /** Callback for updating context menu active state, used for showing context menu */ - checkIfContextMenuActive: PropTypes.func, - - /* Onyx Props */ - ...withLocalizePropTypes, - - ...withCurrentUserPersonalDetailsPropTypes, -}; - -const defaultProps = { - ...withCurrentUserPersonalDetailsDefaultProps, - taskReport: {}, - rootParentReportpolicy: {}, - isHovered: false, -}; - -function TaskPreview(props) { - const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); - const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; - // The reportAction might not contain details regarding the taskReport - // Only the direct parent reportAction will contain details about the taskReport - // Other linked reportActions will only contain the taskReportID and we will grab the details from there - const isTaskCompleted = !_.isEmpty(props.taskReport) - ? props.taskReport.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.taskReport.statusNum === CONST.REPORT.STATUS.APPROVED - : props.action.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.action.childStatusNum === CONST.REPORT.STATUS.APPROVED; - const taskTitle = _.escape(TaskUtils.getTaskTitle(props.taskReportID, props.action.childReportName)); - const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(props.taskReport) || props.action.childManagerAccountID; - const assigneeLogin = lodashGet(personalDetails, [taskAssigneeAccountID, 'login'], ''); - const assigneeDisplayName = lodashGet(personalDetails, [taskAssigneeAccountID, 'displayName'], ''); - const taskAssignee = assigneeDisplayName || LocalePhoneNumber.formatPhoneNumber(assigneeLogin); - const htmlForTaskPreview = - taskAssignee && taskAssigneeAccountID !== 0 - ? `@${taskAssignee} ${taskTitle}` - : `${taskTitle}`; - const isDeletedParentAction = ReportUtils.isCanceledTaskReport(props.taskReport, props.action); - - if (isDeletedParentAction) { - return ${props.translate('parentReportAction.deletedTask')}`} />; - } - - return ( - - Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(props.taskReportID))} - onPressIn={() => DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} - onPressOut={() => ControlSelection.unblock()} - onLongPress={(event) => showContextMenuForReport(event, props.contextMenuAnchor, props.chatReportID, props.action, props.checkIfContextMenuActive)} - style={[styles.flexRow, styles.justifyContentBetween]} - role={CONST.ROLE.BUTTON} - accessibilityLabel={props.translate('task.task')} - > - - { - if (isTaskCompleted) { - Task.reopenTask(props.taskReport); - } else { - Task.completeTask(props.taskReport); - } - })} - accessibilityLabel={props.translate('task.task')} - /> - - - - - - ); -} - -TaskPreview.propTypes = propTypes; -TaskPreview.defaultProps = defaultProps; -TaskPreview.displayName = 'TaskPreview'; - -export default compose( - withLocalize, - withCurrentUserPersonalDetails, - withOnyx({ - taskReport: { - key: ({taskReportID}) => `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, - initialValue: {}, - }, - rootParentReportpolicy: { - key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID || '0'}`, - selector: (policy) => _.pick(policy, ['role']), - }, - }), -)(TaskPreview); diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index a7728045f407..eda7d4f20429 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -1,19 +1,15 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; +import {OnyxEntry, withOnyx} from 'react-native-onyx'; import Checkbox from '@components/Checkbox'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import {usePersonalDetails} from '@components/OnyxProvider'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; -import refPropTypes from '@components/refPropTypes'; import RenderHTML from '@components/RenderHTML'; import {showContextMenuForReport} from '@components/ShowContextMenuContext'; -import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps, withCurrentUserPersonalDetailsPropTypes} from '@components/withCurrentUserPersonalDetails'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import withCurrentUserPersonalDetails, {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; +import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; @@ -24,78 +20,61 @@ import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import * as TaskUtils from '@libs/TaskUtils'; -import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import * as Session from '@userActions/Session'; import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type {Policy, Report, ReportAction} from '@src/types/onyx'; +import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; -const propTypes = { - /** The ID of the associated taskReport */ - taskReportID: PropTypes.string.isRequired, - - /** Whether the task preview is hovered so we can modify its style */ - isHovered: PropTypes.bool, - - /** The linked reportAction */ - action: PropTypes.shape(reportActionPropTypes).isRequired, - +type TaskPreviewOnyxProps = { /* Onyx Props */ - taskReport: PropTypes.shape({ - /** Title of the task */ - reportName: PropTypes.string, - - /** AccountID of the manager in this iou report */ - managerID: PropTypes.number, - - /** AccountID of the creator of this iou report */ - ownerAccountID: PropTypes.number, - }), + taskReport: OnyxEntry; /** The policy of root parent report */ - rootParentReportpolicy: PropTypes.shape({ - /** The role of current user */ - role: PropTypes.string, - }), + rootParentReportpolicy: OnyxEntry | null>; +}; - /** The chat report associated with taskReport */ - chatReportID: PropTypes.string.isRequired, +type TaskPreviewProps = WithCurrentUserPersonalDetailsProps & + TaskPreviewOnyxProps & { + /** The ID of the associated policy */ + policyID: string; + /** The ID of the associated taskReport */ + taskReportID: string; - /** Popover context menu anchor, used for showing context menu */ - contextMenuAnchor: refPropTypes, + /** Whether the task preview is hovered so we can modify its style */ + isHovered: boolean; - /** Callback for updating context menu active state, used for showing context menu */ - checkIfContextMenuActive: PropTypes.func, + /** The linked reportAction */ + action: OnyxEntry; - /* Onyx Props */ - ...withLocalizePropTypes, + /** The chat report associated with taskReport */ + chatReportID: string; - ...withCurrentUserPersonalDetailsPropTypes, -}; + /** Popover context menu anchor, used for showing context menu */ + contextMenuAnchor: Element; -const defaultProps = { - ...withCurrentUserPersonalDetailsDefaultProps, - taskReport: {}, - rootParentReportpolicy: {}, - isHovered: false, -}; + /** Callback for updating context menu active state, used for showing context menu */ + checkIfContextMenuActive: () => void; + }; -function TaskPreview(props) { +function TaskPreview(props: TaskPreviewProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; + const {translate} = useLocalize(); // The reportAction might not contain details regarding the taskReport // Only the direct parent reportAction will contain details about the taskReport // Other linked reportActions will only contain the taskReportID and we will grab the details from there - const isTaskCompleted = !_.isEmpty(props.taskReport) - ? props.taskReport.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.taskReport.statusNum === CONST.REPORT.STATUS.APPROVED - : props.action.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.action.childStatusNum === CONST.REPORT.STATUS.APPROVED; - const taskTitle = _.escape(TaskUtils.getTaskTitle(props.taskReportID, props.action.childReportName)); - const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(props.taskReport) || props.action.childManagerAccountID; - const assigneeLogin = lodashGet(personalDetails, [taskAssigneeAccountID, 'login'], ''); - const assigneeDisplayName = lodashGet(personalDetails, [taskAssigneeAccountID, 'displayName'], ''); + const isTaskCompleted = isNotEmptyObject(props.taskReport) + ? props.taskReport?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.taskReport.statusNum === CONST.REPORT.STATUS.APPROVED + : props.action?.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.action?.childStatusNum === CONST.REPORT.STATUS.APPROVED; + const taskTitle = _.escape(TaskUtils.getTaskTitle(props.taskReportID, props.action?.childReportName ?? '')); + const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(props.taskReport ?? {}) ?? props.action?.childManagerAccountID ?? ''; + const assigneeLogin = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.login ?? '' : ''; + const assigneeDisplayName = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.displayName ?? '' : ''; const taskAssignee = assigneeDisplayName || LocalePhoneNumber.formatPhoneNumber(assigneeLogin); const htmlForTaskPreview = taskAssignee && taskAssigneeAccountID !== 0 @@ -104,7 +83,7 @@ function TaskPreview(props) { const isDeletedParentAction = ReportUtils.isCanceledTaskReport(props.taskReport, props.action); if (isDeletedParentAction) { - return ${props.translate('parentReportAction.deletedTask')}`} />; + return ${translate('parentReportAction.deletedTask')}`} />; } return ( @@ -113,25 +92,25 @@ function TaskPreview(props) { onPress={() => Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(props.taskReportID))} onPressIn={() => DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} onPressOut={() => ControlSelection.unblock()} - onLongPress={(event) => showContextMenuForReport(event, props.contextMenuAnchor, props.chatReportID, props.action, props.checkIfContextMenuActive)} + onLongPress={(event) => showContextMenuForReport(event, props.contextMenuAnchor, props.chatReportID, props.action ?? {}, props.checkIfContextMenuActive)} style={[styles.flexRow, styles.justifyContentBetween]} role={CONST.ROLE.BUTTON} - accessibilityLabel={props.translate('task.task')} + accessibilityLabel={translate('task.task')} > { if (isTaskCompleted) { - Task.reopenTask(props.taskReport); + Task.reopenTask(props.taskReport ?? {}); } else { - Task.completeTask(props.taskReport); + Task.completeTask(props.taskReport ?? {}); } })} - accessibilityLabel={props.translate('task.task')} + accessibilityLabel={translate('task.task')} /> @@ -144,21 +123,17 @@ function TaskPreview(props) { ); } -TaskPreview.propTypes = propTypes; -TaskPreview.defaultProps = defaultProps; TaskPreview.displayName = 'TaskPreview'; export default compose( - withLocalize, - withCurrentUserPersonalDetails, - withOnyx({ + withOnyx({ taskReport: { key: ({taskReportID}) => `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, - initialValue: {}, }, rootParentReportpolicy: { - key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID || '0'}`, - selector: (policy) => _.pick(policy, ['role']), + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID ?? '0'}`, + selector: (policy: Policy | null) => _.pick(policy, ['role']), }, }), + withCurrentUserPersonalDetails, )(TaskPreview); From 3057c00631c869210a856764ef480f9ca21d8f8a Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Fri, 29 Dec 2023 13:10:43 +0000 Subject: [PATCH 03/14] fix policyId unused lint error --- src/components/ReportActionItem/TaskPreview.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index eda7d4f20429..b740d381ca76 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -34,12 +34,13 @@ type TaskPreviewOnyxProps = { taskReport: OnyxEntry; /** The policy of root parent report */ - rootParentReportpolicy: OnyxEntry | null>; + rootParentReportpolicy: OnyxEntry<{role: string}>; }; type TaskPreviewProps = WithCurrentUserPersonalDetailsProps & TaskPreviewOnyxProps & { /** The ID of the associated policy */ + // eslint-disable-next-line policyID: string; /** The ID of the associated taskReport */ taskReportID: string; @@ -71,7 +72,7 @@ function TaskPreview(props: TaskPreviewProps) { const isTaskCompleted = isNotEmptyObject(props.taskReport) ? props.taskReport?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.taskReport.statusNum === CONST.REPORT.STATUS.APPROVED : props.action?.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.action?.childStatusNum === CONST.REPORT.STATUS.APPROVED; - const taskTitle = _.escape(TaskUtils.getTaskTitle(props.taskReportID, props.action?.childReportName ?? '')); + const taskTitle = escape(TaskUtils.getTaskTitle(props.taskReportID, props.action?.childReportName ?? '')); const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(props.taskReport ?? {}) ?? props.action?.childManagerAccountID ?? ''; const assigneeLogin = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.login ?? '' : ''; const assigneeDisplayName = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.displayName ?? '' : ''; @@ -102,7 +103,9 @@ function TaskPreview(props: TaskPreviewProps) { style={[styles.mr2]} containerStyle={[styles.taskCheckbox]} isChecked={isTaskCompleted} - disabled={!Task.canModifyTask(props.taskReport ?? {}, props.currentUserPersonalDetails.accountID, props.rootParentReportpolicy?.role ?? '')} + disabled={ + !Task.canModifyTask(props.taskReport ?? {}, props.currentUserPersonalDetails.accountID, props.rootParentReportpolicy ? props.rootParentReportpolicy.role : '') + } onPress={Session.checkIfActionIsAllowed(() => { if (isTaskCompleted) { Task.reopenTask(props.taskReport ?? {}); @@ -132,7 +135,7 @@ export default compose( }, rootParentReportpolicy: { key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID ?? '0'}`, - selector: (policy: Policy | null) => _.pick(policy, ['role']), + selector: (policy: Policy | null) => ({role: policy?.role ?? ''}), }, }), withCurrentUserPersonalDetails, From 20a2eedc4d0975ce4b9bf3279d7c16bb7eb81f87 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Tue, 2 Jan 2024 19:23:34 +0000 Subject: [PATCH 04/14] replace escape to htmlEncode --- src/components/ReportActionItem/TaskPreview.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index b740d381ca76..3f65964018f5 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -1,3 +1,4 @@ +import Str from 'expensify-common/lib/str'; import React from 'react'; import {View} from 'react-native'; import {OnyxEntry, withOnyx} from 'react-native-onyx'; @@ -72,7 +73,7 @@ function TaskPreview(props: TaskPreviewProps) { const isTaskCompleted = isNotEmptyObject(props.taskReport) ? props.taskReport?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.taskReport.statusNum === CONST.REPORT.STATUS.APPROVED : props.action?.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.action?.childStatusNum === CONST.REPORT.STATUS.APPROVED; - const taskTitle = escape(TaskUtils.getTaskTitle(props.taskReportID, props.action?.childReportName ?? '')); + const taskTitle = Str.htmlEncode(TaskUtils.getTaskTitle(props.taskReportID, props.action?.childReportName ?? '')); const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(props.taskReport ?? {}) ?? props.action?.childManagerAccountID ?? ''; const assigneeLogin = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.login ?? '' : ''; const assigneeDisplayName = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.displayName ?? '' : ''; From 580eb89b9c0300d3bcf0843331a9e9d7fa5c3f59 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Wed, 3 Jan 2024 12:39:00 +0000 Subject: [PATCH 05/14] add PolicyRole type and destrcuture props --- .../ReportActionItem/TaskPreview.tsx | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 3f65964018f5..88956a9d25a0 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -29,13 +29,17 @@ import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction} from '@src/types/onyx'; import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; +type PolicyRole = { + role: string +}; + type TaskPreviewOnyxProps = { /* Onyx Props */ taskReport: OnyxEntry; /** The policy of root parent report */ - rootParentReportpolicy: OnyxEntry<{role: string}>; + rootParentReportpolicy: OnyxEntry; }; type TaskPreviewProps = WithCurrentUserPersonalDetailsProps & @@ -62,7 +66,7 @@ type TaskPreviewProps = WithCurrentUserPersonalDetailsProps & checkIfContextMenuActive: () => void; }; -function TaskPreview(props: TaskPreviewProps) { +function TaskPreview({taskReport, taskReportID, action, contextMenuAnchor, chatReportID, checkIfContextMenuActive, isHovered, currentUserPersonalDetails, rootParentReportpolicy}: TaskPreviewProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; @@ -70,11 +74,11 @@ function TaskPreview(props: TaskPreviewProps) { // The reportAction might not contain details regarding the taskReport // Only the direct parent reportAction will contain details about the taskReport // Other linked reportActions will only contain the taskReportID and we will grab the details from there - const isTaskCompleted = isNotEmptyObject(props.taskReport) - ? props.taskReport?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.taskReport.statusNum === CONST.REPORT.STATUS.APPROVED - : props.action?.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.action?.childStatusNum === CONST.REPORT.STATUS.APPROVED; - const taskTitle = Str.htmlEncode(TaskUtils.getTaskTitle(props.taskReportID, props.action?.childReportName ?? '')); - const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(props.taskReport ?? {}) ?? props.action?.childManagerAccountID ?? ''; + const isTaskCompleted = isNotEmptyObject(taskReport) + ? taskReport?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && taskReport.statusNum === CONST.REPORT.STATUS.APPROVED + : action?.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && action?.childStatusNum === CONST.REPORT.STATUS.APPROVED; + const taskTitle = Str.htmlEncode(TaskUtils.getTaskTitle(taskReportID, action?.childReportName ?? '')); + const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(taskReport ?? {}) ?? action?.childManagerAccountID ?? ''; const assigneeLogin = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.login ?? '' : ''; const assigneeDisplayName = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.displayName ?? '' : ''; const taskAssignee = assigneeDisplayName || LocalePhoneNumber.formatPhoneNumber(assigneeLogin); @@ -82,7 +86,7 @@ function TaskPreview(props: TaskPreviewProps) { taskAssignee && taskAssigneeAccountID !== 0 ? `@${taskAssignee} ${taskTitle}` : `${taskTitle}`; - const isDeletedParentAction = ReportUtils.isCanceledTaskReport(props.taskReport, props.action); + const isDeletedParentAction = ReportUtils.isCanceledTaskReport(taskReport, action); if (isDeletedParentAction) { return ${translate('parentReportAction.deletedTask')}`} />; @@ -91,10 +95,10 @@ function TaskPreview(props: TaskPreviewProps) { return ( Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(props.taskReportID))} + onPress={() => Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(taskReportID))} onPressIn={() => DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} onPressOut={() => ControlSelection.unblock()} - onLongPress={(event) => showContextMenuForReport(event, props.contextMenuAnchor, props.chatReportID, props.action ?? {}, props.checkIfContextMenuActive)} + onLongPress={(event) => showContextMenuForReport(event, contextMenuAnchor, chatReportID, action ?? {}, checkIfContextMenuActive)} style={[styles.flexRow, styles.justifyContentBetween]} role={CONST.ROLE.BUTTON} accessibilityLabel={translate('task.task')} @@ -105,13 +109,13 @@ function TaskPreview(props: TaskPreviewProps) { containerStyle={[styles.taskCheckbox]} isChecked={isTaskCompleted} disabled={ - !Task.canModifyTask(props.taskReport ?? {}, props.currentUserPersonalDetails.accountID, props.rootParentReportpolicy ? props.rootParentReportpolicy.role : '') + !Task.canModifyTask(taskReport ?? {}, currentUserPersonalDetails.accountID, rootParentReportpolicy ? rootParentReportpolicy.role : '') } onPress={Session.checkIfActionIsAllowed(() => { if (isTaskCompleted) { - Task.reopenTask(props.taskReport ?? {}); + Task.reopenTask(taskReport ?? {}); } else { - Task.completeTask(props.taskReport ?? {}); + Task.completeTask(taskReport ?? {}); } })} accessibilityLabel={translate('task.task')} @@ -120,7 +124,7 @@ function TaskPreview(props: TaskPreviewProps) { From 6c7f1df51a97a62f9f118b7f93727841872829a2 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Wed, 3 Jan 2024 12:42:07 +0000 Subject: [PATCH 06/14] fix lint error --- .../ReportActionItem/TaskPreview.tsx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 88956a9d25a0..4b9ee8e5c7b6 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -30,7 +30,7 @@ import type {Policy, Report, ReportAction} from '@src/types/onyx'; import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; type PolicyRole = { - role: string + role: string; }; type TaskPreviewOnyxProps = { @@ -66,7 +66,17 @@ type TaskPreviewProps = WithCurrentUserPersonalDetailsProps & checkIfContextMenuActive: () => void; }; -function TaskPreview({taskReport, taskReportID, action, contextMenuAnchor, chatReportID, checkIfContextMenuActive, isHovered, currentUserPersonalDetails, rootParentReportpolicy}: TaskPreviewProps) { +function TaskPreview({ + taskReport, + taskReportID, + action, + contextMenuAnchor, + chatReportID, + checkIfContextMenuActive, + isHovered, + currentUserPersonalDetails, + rootParentReportpolicy, +}: TaskPreviewProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; @@ -108,9 +118,7 @@ function TaskPreview({taskReport, taskReportID, action, contextMenuAnchor, chatR style={[styles.mr2]} containerStyle={[styles.taskCheckbox]} isChecked={isTaskCompleted} - disabled={ - !Task.canModifyTask(taskReport ?? {}, currentUserPersonalDetails.accountID, rootParentReportpolicy ? rootParentReportpolicy.role : '') - } + disabled={!Task.canModifyTask(taskReport ?? {}, currentUserPersonalDetails.accountID, rootParentReportpolicy ? rootParentReportpolicy.role : '')} onPress={Session.checkIfActionIsAllowed(() => { if (isTaskCompleted) { Task.reopenTask(taskReport ?? {}); From 4e80d27522ee758a8e33441a6a8b2ba751d6a635 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Wed, 3 Jan 2024 15:53:22 +0000 Subject: [PATCH 07/14] update the code by suggestion --- src/components/ReportActionItem/TaskPreview.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 4b9ee8e5c7b6..f8a2d4c9fbc4 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -89,8 +89,8 @@ function TaskPreview({ : action?.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && action?.childStatusNum === CONST.REPORT.STATUS.APPROVED; const taskTitle = Str.htmlEncode(TaskUtils.getTaskTitle(taskReportID, action?.childReportName ?? '')); const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(taskReport ?? {}) ?? action?.childManagerAccountID ?? ''; - const assigneeLogin = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.login ?? '' : ''; - const assigneeDisplayName = taskAssigneeAccountID ? personalDetails[taskAssigneeAccountID]?.displayName ?? '' : ''; + const assigneeLogin = personalDetails[taskAssigneeAccountID]?.login ?? ''; + const assigneeDisplayName = personalDetails[taskAssigneeAccountID]?.displayName ?? ''; const taskAssignee = assigneeDisplayName || LocalePhoneNumber.formatPhoneNumber(assigneeLogin); const htmlForTaskPreview = taskAssignee && taskAssigneeAccountID !== 0 From dcf28b93e4f2733b9e8d92e948ca4d092f45a393 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Fri, 5 Jan 2024 14:18:36 +0000 Subject: [PATCH 08/14] remove compose --- src/components/ReportActionItem/TaskPreview.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index f8a2d4c9fbc4..1a678eb14a74 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -141,7 +141,7 @@ function TaskPreview({ TaskPreview.displayName = 'TaskPreview'; -export default compose( +export default withCurrentUserPersonalDetails( withOnyx({ taskReport: { key: ({taskReportID}) => `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, @@ -150,6 +150,5 @@ export default compose( key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID ?? '0'}`, selector: (policy: Policy | null) => ({role: policy?.role ?? ''}), }, - }), - withCurrentUserPersonalDetails, -)(TaskPreview); + })(TaskPreview), +); From 3e46f69eff74eee114a995c6811db98bb862fa3f Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Fri, 5 Jan 2024 14:23:41 +0000 Subject: [PATCH 09/14] apply suggestion --- src/components/ReportActionItem/TaskPreview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 1a678eb14a74..566b8c6f7bdc 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -118,7 +118,7 @@ function TaskPreview({ style={[styles.mr2]} containerStyle={[styles.taskCheckbox]} isChecked={isTaskCompleted} - disabled={!Task.canModifyTask(taskReport ?? {}, currentUserPersonalDetails.accountID, rootParentReportpolicy ? rootParentReportpolicy.role : '')} + disabled={!Task.canModifyTask(taskReport ?? {}, currentUserPersonalDetails.accountID, rootParentReportpolicy?.role ?? '')} onPress={Session.checkIfActionIsAllowed(() => { if (isTaskCompleted) { Task.reopenTask(taskReport ?? {}); From b125365d02e938d38211c118ffb6af8f40b486c2 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Fri, 5 Jan 2024 15:19:29 +0000 Subject: [PATCH 10/14] add a commnet for props --- src/components/ReportActionItem/TaskPreview.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 566b8c6f7bdc..04834f03f4fe 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -30,12 +30,14 @@ import type {Policy, Report, ReportAction} from '@src/types/onyx'; import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; type PolicyRole = { + /** The role of current user */ role: string; }; type TaskPreviewOnyxProps = { /* Onyx Props */ + /* current report of TaskPreview */ taskReport: OnyxEntry; /** The policy of root parent report */ From b8913f20b2f7286c73246cc569f3a50ca284e534 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Fri, 5 Jan 2024 15:27:21 +0000 Subject: [PATCH 11/14] limit eslint-disable --- src/components/ReportActionItem/TaskPreview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 04834f03f4fe..69273fa9437f 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -47,7 +47,7 @@ type TaskPreviewOnyxProps = { type TaskPreviewProps = WithCurrentUserPersonalDetailsProps & TaskPreviewOnyxProps & { /** The ID of the associated policy */ - // eslint-disable-next-line + // eslint-disable-next-line react/no-unused-prop-types policyID: string; /** The ID of the associated taskReport */ taskReportID: string; From b1ddad925761ac143484bc4f8a3078ba6444c947 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Fri, 5 Jan 2024 16:22:37 +0000 Subject: [PATCH 12/14] add default value for isHovered --- src/components/ReportActionItem/TaskPreview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 69273fa9437f..64aabb179384 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -75,9 +75,9 @@ function TaskPreview({ contextMenuAnchor, chatReportID, checkIfContextMenuActive, - isHovered, currentUserPersonalDetails, rootParentReportpolicy, + isHovered = false, }: TaskPreviewProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); From 3b87005ff52a6067bcdb331a60b9fdfa960c6a81 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Fri, 5 Jan 2024 16:27:45 +0000 Subject: [PATCH 13/14] use isEmptyObject instead of isNotEmptyObject --- src/components/ReportActionItem/TaskPreview.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 64aabb179384..0a8258b9ec6e 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -13,7 +13,6 @@ import withCurrentUserPersonalDetails, {WithCurrentUserPersonalDetailsProps} fro import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; -import compose from '@libs/compose'; import ControlSelection from '@libs/ControlSelection'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import getButtonState from '@libs/getButtonState'; @@ -27,7 +26,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction} from '@src/types/onyx'; -import {isNotEmptyObject} from '@src/types/utils/EmptyObject'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; type PolicyRole = { /** The role of current user */ @@ -86,7 +85,7 @@ function TaskPreview({ // The reportAction might not contain details regarding the taskReport // Only the direct parent reportAction will contain details about the taskReport // Other linked reportActions will only contain the taskReportID and we will grab the details from there - const isTaskCompleted = isNotEmptyObject(taskReport) + const isTaskCompleted = !isEmptyObject(taskReport) ? taskReport?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && taskReport.statusNum === CONST.REPORT.STATUS.APPROVED : action?.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && action?.childStatusNum === CONST.REPORT.STATUS.APPROVED; const taskTitle = Str.htmlEncode(TaskUtils.getTaskTitle(taskReportID, action?.childReportName ?? '')); From 825b702b68775f04814d9f14200f9cfac920b7d4 Mon Sep 17 00:00:00 2001 From: unicorndev-727 Date: Wed, 10 Jan 2024 20:15:35 +0000 Subject: [PATCH 14/14] fix lint error --- src/components/ReportActionItem/TaskPreview.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/ReportActionItem/TaskPreview.tsx b/src/components/ReportActionItem/TaskPreview.tsx index 0a8258b9ec6e..fbc58a381318 100644 --- a/src/components/ReportActionItem/TaskPreview.tsx +++ b/src/components/ReportActionItem/TaskPreview.tsx @@ -1,7 +1,8 @@ import Str from 'expensify-common/lib/str'; import React from 'react'; import {View} from 'react-native'; -import {OnyxEntry, withOnyx} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import Checkbox from '@components/Checkbox'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -9,7 +10,8 @@ import {usePersonalDetails} from '@components/OnyxProvider'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import RenderHTML from '@components/RenderHTML'; import {showContextMenuForReport} from '@components/ShowContextMenuContext'; -import withCurrentUserPersonalDetails, {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; +import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; +import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles';