From 2cadcf65de4bb5d60e9c304ebddee04effb87978 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Fri, 13 Oct 2023 14:36:51 +0200 Subject: [PATCH 1/9] [TS migration] Migrate 'withPolicy.js' HOC to TypeScript --- .eslintrc.js | 2 +- src/libs/getComponentDisplayName.ts | 2 +- .../{withPolicy.js => withPolicy.tsx} | 87 ++++++++----------- 3 files changed, 40 insertions(+), 51 deletions(-) rename src/pages/workspace/{withPolicy.js => withPolicy.tsx} (58%) diff --git a/.eslintrc.js b/.eslintrc.js index 75a74ed371c4..83e9479ce0c4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -116,7 +116,7 @@ module.exports = { }, { selector: ['parameter', 'method'], - format: ['camelCase'], + format: ['camelCase', 'PascalCase'], }, ], '@typescript-eslint/ban-types': [ diff --git a/src/libs/getComponentDisplayName.ts b/src/libs/getComponentDisplayName.ts index fd1bbcaea521..0bf52d543a84 100644 --- a/src/libs/getComponentDisplayName.ts +++ b/src/libs/getComponentDisplayName.ts @@ -1,6 +1,6 @@ import {ComponentType} from 'react'; /** Returns the display name of a component */ -export default function getComponentDisplayName(component: ComponentType): string { +export default function getComponentDisplayName(component: ComponentType): string { return component.displayName ?? component.name ?? 'Component'; } diff --git a/src/pages/workspace/withPolicy.js b/src/pages/workspace/withPolicy.tsx similarity index 58% rename from src/pages/workspace/withPolicy.js rename to src/pages/workspace/withPolicy.tsx index b1659ea2b7a6..94731b2dc650 100644 --- a/src/pages/workspace/withPolicy.js +++ b/src/pages/workspace/withPolicy.tsx @@ -1,21 +1,22 @@ -import _ from 'underscore'; -import lodashGet from 'lodash/get'; -import React from 'react'; +import React, {ComponentType, ForwardedRef, RefAttributes, forwardRef} from 'react'; import PropTypes from 'prop-types'; -import {withOnyx} from 'react-native-onyx'; +import {OnyxEntry, withOnyx} from 'react-native-onyx'; import {useNavigationState} from '@react-navigation/native'; import CONST from '../../CONST'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; import * as Policy from '../../libs/actions/Policy'; import ONYXKEYS from '../../ONYXKEYS'; import policyMemberPropType from '../policyMemberPropType'; +import * as OnyxTypes from '../../types/onyx'; -/** - * @param {Object} route - * @returns {String} - */ -function getPolicyIDFromRoute(route) { - return lodashGet(route, 'params.policyID', ''); +type PolicyRoute = { + params?: { + policyID: string; + }; +}; + +function getPolicyIDFromRoute(route: PolicyRoute): string { + return route?.params?.policyID ?? 'N/A'; } const policyPropTypes = { @@ -28,10 +29,10 @@ const policyPropTypes = { name: PropTypes.string, /** The current user's role in the policy */ - role: PropTypes.oneOf(_.values(CONST.POLICY.ROLE)), + role: PropTypes.oneOf(Object.values(CONST.POLICY.ROLE)), /** The policy type */ - type: PropTypes.oneOf(_.values(CONST.POLICY.TYPE)), + type: PropTypes.oneOf(Object.values(CONST.POLICY.TYPE)), /** The email of the policy owner */ owner: PropTypes.string, @@ -61,66 +62,54 @@ const policyPropTypes = { policyMembers: PropTypes.objectOf(policyMemberPropType), }; -const policyDefaultProps = { - policy: {}, +const policyDefaultProps: WithPolicyOnyxProps = { + policy: {} as OnyxTypes.Policy, policyMembers: {}, }; +type WithPolicyOnyxProps = { + policy: OnyxEntry; + policyMembers: OnyxEntry; +}; + +type WithPolicyProps = WithPolicyOnyxProps & { + route: PolicyRoute; +}; /* * HOC for connecting a policy in Onyx corresponding to the policyID in route params */ -export default function (WrappedComponent) { - const propTypes = { - /** The HOC takes an optional ref as a prop and passes it as a ref to the wrapped component. - * That way, if a ref is passed to a component wrapped in the HOC, the ref is a reference to the wrapped component, not the HOC. */ - forwardedRef: PropTypes.func, - - ...policyPropTypes, - }; - - const defaultProps = { - forwardedRef: () => {}, - - ...policyDefaultProps, - }; - - function WithPolicy(props) { - const currentRoute = _.last(useNavigationState((state) => state.routes || [])); - const policyID = getPolicyIDFromRoute(currentRoute); - - if (_.isString(policyID) && !_.isEmpty(policyID)) { +export default function withPolicy( + WrappedComponent: ComponentType>, +): React.ComponentType> { + function WithPolicy(props: TProps, ref: ForwardedRef) { + const routes = useNavigationState((state) => state.routes || []); + const currentRoute = routes?.[routes.length - 1]; + const policyID = getPolicyIDFromRoute(currentRoute as PolicyRoute); + + if (typeof policyID === 'string' && policyID.length > 0) { Policy.updateLastAccessedWorkspace(policyID); } - const rest = _.omit(props, ['forwardedRef']); return ( ); } - WithPolicy.propTypes = propTypes; - WithPolicy.defaultProps = defaultProps; + WithPolicy.defaultProps = policyDefaultProps; WithPolicy.displayName = `withPolicy(${getComponentDisplayName(WrappedComponent)})`; - const withPolicy = React.forwardRef((props, ref) => ( - - )); - - return withOnyx({ + + return withOnyx({ policy: { key: (props) => `${ONYXKEYS.COLLECTION.POLICY}${getPolicyIDFromRoute(props.route)}`, }, policyMembers: { key: (props) => `${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${getPolicyIDFromRoute(props.route)}`, }, - })(withPolicy); + })(forwardRef(WithPolicy)); } export {policyPropTypes, policyDefaultProps}; From 9b074dd4a52930ba1acffed0adeedc0832a84a6c Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Thu, 19 Oct 2023 10:34:23 +0200 Subject: [PATCH 2/9] Add new onyx values --- src/ONYXKEYS.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index ad8b60700e39..c761b540bc22 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -382,9 +382,11 @@ type OnyxValues = { // Collections [ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download; [ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy; + [ONYXKEYS.COLLECTION.POLICY_DRAFTS]: OnyxTypes.Policy; [ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: OnyxTypes.PolicyCategory; [ONYXKEYS.COLLECTION.POLICY_TAGS]: OnyxTypes.PolicyTag; [ONYXKEYS.COLLECTION.POLICY_MEMBERS]: OnyxTypes.PolicyMember; + [ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS]: OnyxTypes.PolicyMember; [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES]: OnyxTypes.RecentlyUsedCategories; [ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyMember; [ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT]: Record; From 7ae4259e4167e62ee71ea30ea2a70dcf633cddb7 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Thu, 19 Oct 2023 17:35:05 +0200 Subject: [PATCH 3/9] Adjust the code after review --- src/pages/workspace/withPolicy.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index f168061f5fea..23473ec726dc 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -62,13 +62,6 @@ const policyPropTypes = { policyMembers: PropTypes.objectOf(policyMemberPropType), }; -const policyDefaultProps: WithPolicyOnyxProps = { - policy: {} as OnyxTypes.Policy, - policyMembers: {}, - policyDraft: {} as OnyxTypes.Policy, - policyMembersDraft: {}, -}; - type WithPolicyOnyxProps = { policy: OnyxEntry; policyMembers: OnyxEntry; @@ -79,6 +72,14 @@ type WithPolicyOnyxProps = { type WithPolicyProps = WithPolicyOnyxProps & { route: PolicyRoute; }; + +const policyDefaultProps: WithPolicyOnyxProps = { + policy: {} as OnyxTypes.Policy, + policyMembers: {}, + policyDraft: {} as OnyxTypes.Policy, + policyMembersDraft: {}, +}; + /* * HOC for connecting a policy in Onyx corresponding to the policyID in route params */ @@ -90,7 +91,7 @@ export default function withPolicy( const currentRoute = routes?.[routes.length - 1]; const policyID = getPolicyIDFromRoute(currentRoute as PolicyRoute); - if (typeof policyID === 'string' && policyID.length > 0) { + if (policyID.length > 0) { Policy.updateLastAccessedWorkspace(policyID); } From 7ffe27e996defa5cfce388dbcec6f5c19935bf3a Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Thu, 19 Oct 2023 18:45:19 +0200 Subject: [PATCH 4/9] Fix forwardRef error --- src/pages/workspace/withPolicy.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index 23473ec726dc..2e55230a0a33 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -104,7 +104,6 @@ export default function withPolicy( ); } - WithPolicy.defaultProps = policyDefaultProps; WithPolicy.displayName = `withPolicy(${getComponentDisplayName(WrappedComponent)})`; return withOnyx, WithPolicyOnyxProps>({ From 7058006baf3696aa5a0b19e6e0c7dd1c6b78786b Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Fri, 20 Oct 2023 14:26:38 +0200 Subject: [PATCH 5/9] Improve PolicyRoute type --- src/pages/workspace/withPolicy.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index 2e55230a0a33..7bb9db9ad8e0 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -1,7 +1,7 @@ import React, {ComponentType, ForwardedRef, RefAttributes, forwardRef} from 'react'; import PropTypes from 'prop-types'; import {OnyxEntry, withOnyx} from 'react-native-onyx'; -import {useNavigationState} from '@react-navigation/native'; +import {RouteProp, useNavigationState} from '@react-navigation/native'; import CONST from '../../CONST'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; import * as Policy from '../../libs/actions/Policy'; @@ -9,11 +9,7 @@ import ONYXKEYS from '../../ONYXKEYS'; import policyMemberPropType from '../policyMemberPropType'; import * as OnyxTypes from '../../types/onyx'; -type PolicyRoute = { - params?: { - policyID: string; - }; -}; +type PolicyRoute = RouteProp<{params: {policyID: string}}>; function getPolicyIDFromRoute(route: PolicyRoute): string { return route?.params?.policyID ?? ''; From 97e36fb6f232a4c874b55154fac4f109e834e76c Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 25 Oct 2023 14:57:18 +0200 Subject: [PATCH 6/9] Adjust after review --- src/pages/workspace/withPolicy.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index 7bb9db9ad8e0..166da98a9c73 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -84,7 +84,7 @@ export default function withPolicy( ): React.ComponentType> { function WithPolicy(props: TProps, ref: ForwardedRef) { const routes = useNavigationState((state) => state.routes || []); - const currentRoute = routes?.[routes.length - 1]; + const currentRoute = routes?.at(-1); const policyID = getPolicyIDFromRoute(currentRoute as PolicyRoute); if (policyID.length > 0) { From 81b8730950cc8f03f58ddd86ba6935b67d1e17b4 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Fri, 27 Oct 2023 11:41:54 +0200 Subject: [PATCH 7/9] Change display name --- src/pages/workspace/withPolicy.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index 166da98a9c73..c0108f27e413 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -79,9 +79,7 @@ const policyDefaultProps: WithPolicyOnyxProps = { /* * HOC for connecting a policy in Onyx corresponding to the policyID in route params */ -export default function withPolicy( - WrappedComponent: ComponentType>, -): React.ComponentType> { +export default function (WrappedComponent: ComponentType>): React.ComponentType> { function WithPolicy(props: TProps, ref: ForwardedRef) { const routes = useNavigationState((state) => state.routes || []); const currentRoute = routes?.at(-1); @@ -100,7 +98,7 @@ export default function withPolicy( ); } - WithPolicy.displayName = `withPolicy(${getComponentDisplayName(WrappedComponent)})`; + WithPolicy.displayName = `WithPolicy`; return withOnyx, WithPolicyOnyxProps>({ policy: { From f5672e02c617292253c339ec8b23e2ae33acae74 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Fri, 27 Oct 2023 11:42:12 +0200 Subject: [PATCH 8/9] Remove getComponentDisplayName --- src/pages/workspace/withPolicy.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index c0108f27e413..45e91c2c9b15 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {OnyxEntry, withOnyx} from 'react-native-onyx'; import {RouteProp, useNavigationState} from '@react-navigation/native'; import CONST from '../../CONST'; -import getComponentDisplayName from '../../libs/getComponentDisplayName'; import * as Policy from '../../libs/actions/Policy'; import ONYXKEYS from '../../ONYXKEYS'; import policyMemberPropType from '../policyMemberPropType'; From 2cbc764626c70470fb15e5330f0d47886c17df16 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Mon, 30 Oct 2023 10:05:15 +0100 Subject: [PATCH 9/9] Fix imports --- src/pages/workspace/withPolicy.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index 0cf7e6936526..8db093ec24d0 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -1,13 +1,12 @@ -import * as OnyxTypes from '../../types/onyx'; import {RouteProp, useNavigationState} from '@react-navigation/native'; import PropTypes from 'prop-types'; -import React, {ComponentType, ForwardedRef, RefAttributes, forwardRef} from 'react'; +import React, {ComponentType, ForwardedRef, forwardRef, RefAttributes} from 'react'; import {OnyxEntry, withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; import policyMemberPropType from '@pages/policyMemberPropType'; import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import * as OnyxTypes from '@src/types/onyx'; type PolicyRoute = RouteProp<{params: {policyID: string}}>;