Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Create Tag" page #38158

Merged
merged 13 commits into from
Mar 12, 2024
3 changes: 3 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,8 @@ const CONST = {
LOGIN_CHARACTER_LIMIT: 254,
CATEGORY_NAME_LIMIT: 256,

TAG_NAME_LIMIT: 256,

TITLE_CHARACTER_LIMIT: 100,
DESCRIPTION_LIMIT: 500,

Expand Down Expand Up @@ -1741,6 +1743,7 @@ const CONST = {
MAX_64BIT_MIDDLE_PART: 7203685,
MAX_64BIT_RIGHT_PART: 4775807,
INVALID_CATEGORY_NAME: '###',
INVALID_TAG_NAME: '###',
allroundexperts marked this conversation as resolved.
Show resolved Hide resolved

// When generating a random value to fit in 7 digits (for the `middle` or `right` parts above), this is the maximum value to multiply by Math.random().
MAX_INT_FOR_RANDOM_7_DIGIT_VALUE: 10000000,
Expand Down
3 changes: 3 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ const ONYXKEYS = {
WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm',
WORKSPACE_CATEGORY_CREATE_FORM: 'workspaceCategoryCreate',
WORKSPACE_CATEGORY_CREATE_FORM_DRAFT: 'workspaceCategoryCreateDraft',
WORKSPACE_TAG_CREATE_FORM: 'workspaceTagCreate',
WORKSPACE_TAG_CREATE_FORM_DRAFT: 'workspaceTagCreateDraft',
WORKSPACE_SETTINGS_FORM_DRAFT: 'workspaceSettingsFormDraft',
WORKSPACE_DESCRIPTION_FORM: 'workspaceDescriptionForm',
WORKSPACE_DESCRIPTION_FORM_DRAFT: 'workspaceDescriptionFormDraft',
Expand Down Expand Up @@ -416,6 +418,7 @@ type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM]: FormTypes.AddDebitCardForm;
[ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: FormTypes.WorkspaceSettingsForm;
[ONYXKEYS.FORMS.WORKSPACE_CATEGORY_CREATE_FORM]: FormTypes.WorkspaceCategoryCreateForm;
[ONYXKEYS.FORMS.WORKSPACE_TAG_CREATE_FORM]: FormTypes.WorkspaceTagCreateForm;
[ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM]: FormTypes.WorkspaceRateAndUnitForm;
[ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM]: FormTypes.CloseAccountForm;
[ONYXKEYS.FORMS.PROFILE_SETTINGS_FORM]: FormTypes.ProfileSettingsForm;
Expand Down
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,10 @@ const ROUTES = {
route: 'workspace/:policyID/tags',
getRoute: (policyID: string) => `workspace/${policyID}/tags` as const,
},
WORKSPACE_TAG_CREATE: {
route: 'workspace/:policyID/tag/new',
allroundexperts marked this conversation as resolved.
Show resolved Hide resolved
getRoute: (policyID: string) => `workspace/${policyID}/tag/new` as const,
},
WORKSPACE_TAGS_SETTINGS: {
route: 'workspace/:policyID/tags/settings',
getRoute: (policyID: string) => `workspace/${policyID}/tags/settings` as const,
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ const SCREENS = {
TAGS: 'Workspace_Tags',
TAGS_SETTINGS: 'Tags_Settings',
TAGS_EDIT: 'Tags_Edit',
TAG_CREATE: 'Tag_Create',
CURRENCY: 'Workspace_Profile_Currency',
WORKFLOWS: 'Workspace_Workflows',
WORKFLOWS_PAYER: 'Workspace_Workflows_Payer',
Expand Down
4 changes: 4 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1834,11 +1834,15 @@ export default {
requiresTag: 'Members must tag all spend',
customTagName: 'Custom tag name',
enableTag: 'Enable tag',
addTag: 'Add tag',
subtitle: 'Tags add more detailed ways to classify costs.',
emptyTags: {
title: "You haven't created any tags",
subtitle: 'Add a tag to track projects, locations, departments, and more.',
},
tagRequiredError: 'Tag name is required.',
existingTagError: 'A tag with this name already exists.',
invalidTagName: 'Invalid tag name.',
genericFailureMessage: 'An error occurred while updating the tag, please try again.',
},
emptyWorkspace: {
Expand Down
4 changes: 4 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1858,11 +1858,15 @@ export default {
requiresTag: 'Los miembros deben etiquetar todos los gastos',
customTagName: 'Nombre de etiqueta personalizada',
enableTag: 'Habilitar etiqueta',
addTag: 'Añadir etiqueta',
subtitle: 'Las etiquetas añaden formas más detalladas de clasificar los costos.',
emptyTags: {
title: 'No has creado ninguna etiqueta',
subtitle: 'Añade una etiqueta para realizar el seguimiento de proyectos, ubicaciones, departamentos y otros.',
},
tagRequiredError: 'Tag name is required.',
allroundexperts marked this conversation as resolved.
Show resolved Hide resolved
existingTagError: 'A tag with this name already exists.',
allroundexperts marked this conversation as resolved.
Show resolved Hide resolved
invalidTagName: 'Invalid tag name.',
Copy link
Contributor

@ishpaul777 ishpaul777 Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please ask for translation in slack?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, my bad 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still waiting for translations

genericFailureMessage: 'Se produjo un error al actualizar la etiqueta, inténtelo nuevamente.',
},
emptyWorkspace: {
Expand Down
10 changes: 10 additions & 0 deletions src/libs/API/parameters/CreateWorkspaceTagsParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type CreateWorkspaceTagsParams = {
luacmartins marked this conversation as resolved.
Show resolved Hide resolved
policyID: string;
/**
* Stringified JSON object with type of following structure:
* Array<{name: string;}>
*/
tags: string;
};

export default CreateWorkspaceTagsParams;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,4 @@ export type {default as DeclineJoinRequestParams} from './DeclineJoinRequest';
export type {default as JoinPolicyInviteLinkParams} from './JoinPolicyInviteLink';
export type {default as OpenPolicyWorkflowsPageParams} from './OpenPolicyWorkflowsPageParams';
export type {default as OpenPolicyDistanceRatesPageParams} from './OpenPolicyDistanceRatesPageParams';
export type {default as CreateWorkspaceTagsParams} from './CreateWorkspaceTagsParams';
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ const WRITE_COMMANDS = {
CREATE_WORKSPACE_FROM_IOU_PAYMENT: 'CreateWorkspaceFromIOUPayment',
SET_WORKSPACE_CATEGORIES_ENABLED: 'SetWorkspaceCategoriesEnabled',
CREATE_WORKSPACE_CATEGORIES: 'CreateWorkspaceCategories',
CREATE_WORKSPACE_TAG: 'CreatePolicyTag',
SET_WORKSPACE_REQUIRES_CATEGORY: 'SetWorkspaceRequiresCategory',
SET_POLICY_REQUIRES_TAG: 'SetPolicyRequiresTag',
RENAME_POLICY_TAG_LIST: 'RenamePolicyTaglist',
Expand Down Expand Up @@ -283,6 +284,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.SET_WORKSPACE_REQUIRES_CATEGORY]: Parameters.SetWorkspaceRequiresCategoryParams;
[WRITE_COMMANDS.SET_POLICY_REQUIRES_TAG]: Parameters.SetPolicyRequiresTag;
[WRITE_COMMANDS.RENAME_POLICY_TAG_LIST]: Parameters.RenamePolicyTaglist;
[WRITE_COMMANDS.CREATE_WORKSPACE_TAG]: Parameters.CreateWorkspaceTagsParams;
[WRITE_COMMANDS.CREATE_TASK]: Parameters.CreateTaskParams;
[WRITE_COMMANDS.CANCEL_TASK]: Parameters.CancelTaskParams;
[WRITE_COMMANDS.EDIT_TASK_ASSIGNEE]: Parameters.EditTaskAssigneeParams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.CATEGORY_CREATE]: () => require('../../../pages/workspace/categories/CreateCategoryPage').default as React.ComponentType,
[SCREENS.WORKSPACE.TAGS_SETTINGS]: () => require('../../../pages/workspace/tags/WorkspaceTagsSettingsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.TAGS_EDIT]: () => require('../../../pages/workspace/tags/WorkspaceEditTagsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.TAG_CREATE]: () => require('../../../pages/workspace/tags/WorkspaceCreateTagPage').default as React.ComponentType,
[SCREENS.REIMBURSEMENT_ACCOUNT]: () => require('../../../pages/ReimbursementAccount/ReimbursementAccountPage').default as React.ComponentType,
[SCREENS.GET_ASSISTANCE]: () => require('../../../pages/GetAssistancePage').default as React.ComponentType,
[SCREENS.SETTINGS.TWO_FACTOR_AUTH]: () => require('../../../pages/settings/Security/TwoFactorAuth/TwoFactorAuthPage').default as React.ComponentType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial<Record<CentralPaneName, string[]>> =
[SCREENS.WORKSPACE.PROFILE]: [SCREENS.WORKSPACE.NAME, SCREENS.WORKSPACE.CURRENCY, SCREENS.WORKSPACE.DESCRIPTION, SCREENS.WORKSPACE.SHARE],
[SCREENS.WORKSPACE.REIMBURSE]: [SCREENS.WORKSPACE.RATE_AND_UNIT, SCREENS.WORKSPACE.RATE_AND_UNIT_RATE, SCREENS.WORKSPACE.RATE_AND_UNIT_UNIT],
[SCREENS.WORKSPACE.MEMBERS]: [SCREENS.WORKSPACE.INVITE, SCREENS.WORKSPACE.INVITE_MESSAGE, SCREENS.WORKSPACE.MEMBER_DETAILS, SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE_SELECTION],
[SCREENS.WORKSPACE.TAGS]: [SCREENS.WORKSPACE.TAGS_SETTINGS, SCREENS.WORKSPACE.TAGS_EDIT, SCREENS.WORKSPACE.TAG_CREATE],
[SCREENS.WORKSPACE.WORKFLOWS]: [
SCREENS.WORKSPACE.WORKFLOWS_APPROVER,
SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY,
SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET,
SCREENS.WORKSPACE.WORKFLOWS_PAYER,
],
[SCREENS.WORKSPACE.TAGS]: [SCREENS.WORKSPACE.TAGS_SETTINGS, SCREENS.WORKSPACE.TAGS_EDIT],
[SCREENS.WORKSPACE.CATEGORIES]: [SCREENS.WORKSPACE.CATEGORY_CREATE, SCREENS.WORKSPACE.CATEGORY_SETTINGS, SCREENS.WORKSPACE.CATEGORIES_SETTINGS],
};

Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.WORKSPACE.TAGS_EDIT]: {
path: ROUTES.WORKSPACE_EDIT_TAGS.route,
},
[SCREENS.WORKSPACE.TAG_CREATE]: {
path: ROUTES.WORKSPACE_TAG_CREATE.route,
},
[SCREENS.REIMBURSEMENT_ACCOUNT]: {
path: ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.route,
exact: true,
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.CATEGORIES_SETTINGS]: {
policyID: string;
};
[SCREENS.WORKSPACE.TAG_CREATE]: {
policyID: string;
};
[SCREENS.WORKSPACE.TAGS_SETTINGS]: {
policyID: string;
};
Expand Down
54 changes: 54 additions & 0 deletions src/libs/actions/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2746,6 +2746,59 @@ function createPolicyCategory(policyID: string, categoryName: string) {
API.write(WRITE_COMMANDS.CREATE_WORKSPACE_CATEGORIES, parameters, onyxData);
}

function createPolicyTag(policyID: string, tagName: string) {
const onyxData: OnyxData = {
optimisticData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
Tag: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is accurate. A user can rename the tagList name and this request would fail. We need to dynamically update this name. Same goes for the other cases below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea how to get that name? We can have multiple items in a tag list. How would that be handled?

Copy link
Contributor Author

@allroundexperts allroundexperts Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving this discussion over to Slack.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handled!

tags: {
[tagName]: {
name: tagName,
enabled: false,
},
},
errors: null,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
},
},
},
],
successData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
Tag: {
errors: null,
pendingAction: null,
},
},
},
],
failureData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
Tag: {
errors: ErrorUtils.getMicroSecondOnyxError('workspace.tags.genericFailureMessage'),
allroundexperts marked this conversation as resolved.
Show resolved Hide resolved
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for failure scenario shouldn't we remove the tag from the onyx?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we do that. We just show an error and once the user clicks on the x beside the red brick, only then we remove it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the X button is clicked confirming the user read the error the tag should be removed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense.. but i dont see the error appear yet in this pattern do you think that out of scope too?

cc @luacmartins

},
},
],
};

const parameters = {
policyID,
tags: JSON.stringify([{name: tagName}]),
};

API.write(WRITE_COMMANDS.CREATE_WORKSPACE_TAG, parameters, onyxData);
luacmartins marked this conversation as resolved.
Show resolved Hide resolved
}

function setWorkspaceRequiresCategory(policyID: string, requiresCategory: boolean) {
const onyxData: OnyxData = {
optimisticData: [
Expand Down Expand Up @@ -3453,5 +3506,6 @@ export {
enablePolicyTaxes,
enablePolicyWorkflows,
openPolicyDistanceRatesPage,
createPolicyTag,
clearWorkspaceReimbursementErrors,
};
4 changes: 3 additions & 1 deletion src/pages/workspace/categories/CreateCategoryPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {FormInputErrors, 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';
Expand All @@ -34,6 +35,7 @@ type CreateCategoryPageProps = WorkspaceCreateCategoryPageOnyxProps & StackScree
function CreateCategoryPage({route, policyCategories}: CreateCategoryPageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {inputCallbackRef} = useAutoFocusInput();

const validate = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.WORKSPACE_CATEGORY_CREATE_FORM>) => {
Expand Down Expand Up @@ -92,7 +94,7 @@ function CreateCategoryPage({route, policyCategories}: CreateCategoryPageProps)
accessibilityLabel={translate('common.name')}
inputID={INPUT_IDS.CATEGORY_NAME}
role={CONST.ROLE.PRESENTATION}
autoFocus
ref={inputCallbackRef}
/>
</FormProvider>
</ScreenWrapper>
Expand Down
112 changes: 112 additions & 0 deletions src/pages/workspace/tags/WorkspaceCreateTagPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback} from 'react';
import {Keyboard} 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 {FormInputErrors, 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 ValidationUtils from '@libs/ValidationUtils';
import type {SettingsNavigatorParamList} from '@navigation/types';
import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper';
import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper';
import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';
import INPUT_IDS from '@src/types/form/WorkspaceTagCreateForm';
import type {PolicyTagList} from '@src/types/onyx';

type WorkspaceCreateTagPageOnyxProps = {
/** All policy tags */
policyTags: OnyxEntry<PolicyTagList>;
};

type CreateTagPageProps = WorkspaceCreateTagPageOnyxProps & StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.TAG_CREATE>;

function CreateTagPage({route, policyTags}: CreateTagPageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {inputCallbackRef} = useAutoFocusInput();

const validate = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.WORKSPACE_TAG_CREATE_FORM>) => {
const errors: FormInputErrors<typeof ONYXKEYS.FORMS.WORKSPACE_TAG_CREATE_FORM> = {};
const tagName = values.tagName.trim();

if (!ValidationUtils.isRequiredFulfilled(tagName)) {
errors.tagName = 'workspace.tags.tagRequiredError';
} else if (policyTags?.Tag?.tags?.[tagName]) {
errors.tagName = 'workspace.tags.existingTagError';
} else if (tagName === CONST.INVALID_TAG_NAME) {
errors.tagName = 'workspace.tags.invalidTagName';
allroundexperts marked this conversation as resolved.
Show resolved Hide resolved
} else if ([...tagName].length > CONST.TAG_NAME_LIMIT) {
// Uses the spread syntax to count the number of Unicode code points instead of the number of UTF-16 code units.
ErrorUtils.addErrorMessage(errors, 'tagName', ['common.error.characterLimitExceedCounter', {length: [...tagName].length, limit: CONST.TAG_NAME_LIMIT}]);
}

return errors;
},
[policyTags],
);

const createTag = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.WORKSPACE_TAG_CREATE_FORM>) => {
Policy.createPolicyTag(route.params.policyID, values.tagName.trim());
Keyboard.dismiss();
Navigation.goBack();
},
[route.params.policyID],
);

return (
<AdminPolicyAccessOrNotFoundWrapper policyID={route.params.policyID}>
<PaidPolicyAccessOrNotFoundWrapper policyID={route.params.policyID}>
<ScreenWrapper
mountiny marked this conversation as resolved.
Show resolved Hide resolved
includeSafeAreaPaddingBottom={false}
style={[styles.defaultModalContainer]}
testID={CreateTagPage.displayName}
>
allroundexperts marked this conversation as resolved.
Show resolved Hide resolved
<HeaderWithBackButton
title={translate('workspace.tags.addTag')}
onBackButtonPress={Navigation.goBack}
/>
<FormProvider
formID={ONYXKEYS.FORMS.WORKSPACE_TAG_CREATE_FORM}
onSubmit={createTag}
submitButtonText={translate('common.save')}
validate={validate}
style={[styles.mh5, styles.flex1]}
enabledWhenOffline
>
<InputWrapper
InputComponent={TextInput}
maxLength={CONST.TAG_NAME_LIMIT}
label={translate('common.name')}
accessibilityLabel={translate('common.name')}
inputID={INPUT_IDS.TAG_NAME}
role={CONST.ROLE.PRESENTATION}
ref={inputCallbackRef}
/>
</FormProvider>
</ScreenWrapper>
</PaidPolicyAccessOrNotFoundWrapper>
</AdminPolicyAccessOrNotFoundWrapper>
);
}

CreateTagPage.displayName = 'CreateTagPage';

export default withOnyx<CreateTagPageProps, WorkspaceCreateTagPageOnyxProps>({
policyTags: {
key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${route?.params?.policyID}`,
},
})(CreateTagPage);
Loading
Loading