Skip to content

Commit

Permalink
add delete functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
allroundexperts committed Mar 17, 2024
1 parent c915e7f commit faddd9b
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1847,6 +1847,9 @@ export default {
title: "You haven't created any tags",
subtitle: 'Add a tag to track projects, locations, departments, and more.',
},
deleteTag: 'Delete tag',
deleteTagConfirmation: 'Are you sure that you want to delete this tag?',
deleteFailureMessage: 'An error occurred while deleting the tag, please try again.',
tagRequiredError: 'Tag name is required.',
existingTagError: 'A tag with this name already exists.',
genericFailureMessage: 'An error occurred while updating the tag, please try again.',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1871,6 +1871,9 @@ export default {
title: 'No has creado ninguna etiqueta',
subtitle: 'Añade una etiqueta para realizar el seguimiento de proyectos, ubicaciones, departamentos y otros.',
},
deleteTag: 'Eliminar etiqueta',
deleteTagConfirmation: '¿Estás seguro de que quieres eliminar esta etiqueta?',
deleteFailureMessage: 'Se ha producido un error al intentar eliminar la etiqueta. Por favor, inténtalo más tarde.',
tagRequiredError: 'Lo nombre de la etiqueta es obligatorio.',
existingTagError: 'Ya existe una etiqueta con este nombre.',
genericFailureMessage: 'Se produjo un error al actualizar la etiqueta, inténtelo nuevamente.',
Expand Down
10 changes: 10 additions & 0 deletions src/libs/API/parameters/DeletePolicyTagsParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type DeletePolicyTagsParams = {
policyID: string;
/**
* Stringified JSON object with type of following structure:
* Array<string>
*/
tags: string;
};

export default DeletePolicyTagsParams;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,4 @@ export type {default as EnablePolicyTaxesParams} from './EnablePolicyTaxesParams
export type {default as OpenPolicyMoreFeaturesPageParams} from './OpenPolicyMoreFeaturesPageParams';
export type {default as CreatePolicyDistanceRateParams} from './CreatePolicyDistanceRateParams';
export type {default as CreatePolicyTagsParams} from './CreatePolicyTagsParams';
export type {default as DeletePolicyTagsParams} from './DeletePolicyTagsParams';
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ const WRITE_COMMANDS = {
DELETE_WORKSPACE_CATEGORIES: 'DeleteWorkspaceCategories',
SET_POLICY_REQUIRES_TAG: 'SetPolicyRequiresTag',
RENAME_POLICY_TAG_LIST: 'RenamePolicyTaglist',
DELETE_POLICY_TAGS: 'Policy_IndependentTaglist_Tags_Remove',
CREATE_TASK: 'CreateTask',
CANCEL_TASK: 'CancelTask',
EDIT_TASK_ASSIGNEE: 'EditTaskAssignee',
Expand Down Expand Up @@ -294,6 +295,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.RENAME_POLICY_TAG_LIST]: Parameters.RenamePolicyTaglist;
[WRITE_COMMANDS.CREATE_POLICY_TAG]: Parameters.CreatePolicyTagsParams;
[WRITE_COMMANDS.SET_POLICY_TAGS_ENABLED]: Parameters.SetPolicyTagsEnabled;
[WRITE_COMMANDS.DELETE_POLICY_TAGS]: Parameters.DeletePolicyTagsParams;
[WRITE_COMMANDS.CREATE_TASK]: Parameters.CreateTaskParams;
[WRITE_COMMANDS.CANCEL_TASK]: Parameters.CancelTaskParams;
[WRITE_COMMANDS.EDIT_TASK_ASSIGNEE]: Parameters.EditTaskAssigneeParams;
Expand Down
74 changes: 69 additions & 5 deletions src/libs/actions/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import type {
PolicyCategories,
PolicyCategory,
PolicyMember,
PolicyTag,
PolicyTagList,
PolicyTags,
RecentlyUsedCategories,
Expand All @@ -79,7 +80,7 @@ import type {
ReportAction,
Transaction,
} from '@src/types/onyx';
import type {Errors, PendingAction} from '@src/types/onyx/OnyxCommon';
import type {Errors, OnyxValueWithOfflineFeedback, PendingAction} from '@src/types/onyx/OnyxCommon';
import type {OriginalMessageJoinPolicyChangeLog} from '@src/types/onyx/OriginalMessage';
import type {Attributes, CustomUnit, Rate, Unit} from '@src/types/onyx/Policy';
import type {OnyxData} from '@src/types/onyx/Request';
Expand Down Expand Up @@ -2841,15 +2842,15 @@ function renamePolicyCategory(policyID: string, policyCategory: {oldName: string
}

function createPolicyTag(policyID: string, tagName: string) {
const tagListName = Object.keys(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})[0];
const policyTag = PolicyUtils.getTagLists(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})?.[0] ?? {};

const onyxData: OnyxData = {
optimisticData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[tagListName]: {
[policyTag.name]: {
tags: {
[tagName]: {
name: tagName,
Expand All @@ -2867,7 +2868,7 @@ function createPolicyTag(policyID: string, tagName: string) {
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[tagListName]: {
[policyTag.name]: {
tags: {
[tagName]: {
errors: null,
Expand All @@ -2883,7 +2884,7 @@ function createPolicyTag(policyID: string, tagName: string) {
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[tagListName]: {
[policyTag.name]: {
tags: {
[tagName]: {
errors: ErrorUtils.getMicroSecondOnyxError('workspace.tags.genericFailureMessage'),
Expand Down Expand Up @@ -2989,6 +2990,68 @@ function setWorkspaceTagEnabled(policyID: string, tagsToUpdate: Record<string, {
API.write(WRITE_COMMANDS.SET_POLICY_TAGS_ENABLED, parameters, onyxData);
}

function deletePolicyTags(policyID: string, tagsToDelete: string[]) {
const policyTag = PolicyUtils.getTagLists(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})?.[0] ?? {};

const onyxData: OnyxData = {
optimisticData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[policyTag.name]: {
tags: {
...tagsToDelete.reduce<Record<string, Partial<OnyxValueWithOfflineFeedback<PolicyTag>>>>((acc, tagName) => {
acc[tagName] = {pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE};
return acc;
}, {}),
},
},
},
},
],
successData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[policyTag.name]: {
tags: {
...tagsToDelete.reduce<Record<string, null | Partial<OnyxValueWithOfflineFeedback<PolicyTag>>>>((acc, tagName) => {
acc[tagName] = null;
return acc;
}, {}),
},
},
},
},
],
failureData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[policyTag.name]: {
tags: {
...tagsToDelete.reduce<Record<string, Partial<OnyxValueWithOfflineFeedback<PolicyTag>>>>((acc, tagName) => {
acc[tagName] = {pendingAction: null, errors: ErrorUtils.getMicroSecondOnyxError('workspace.tags.deleteFailureMessage')};
return acc;
}, {}),
},
},
},
},
],
};

const parameters = {
policyID,
tags: JSON.stringify(tagsToDelete),
};

API.write(WRITE_COMMANDS.DELETE_POLICY_TAGS, parameters, onyxData);
}

function clearPolicyTagErrors(policyID: string, tagName: string) {
const tagListName = Object.keys(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})[0];
const tag = allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`]?.[tagListName].tags?.[tagName];
Expand Down Expand Up @@ -3908,5 +3971,6 @@ export {
clearPolicyTagErrors,
clearWorkspaceReimbursementErrors,
deleteWorkspaceCategories,
deletePolicyTags,
setWorkspaceTagEnabled,
};
39 changes: 38 additions & 1 deletion src/pages/workspace/tags/TagSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ import React, {useMemo} from 'react';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import ConfirmModal from '@components/ConfirmModal';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import {Trashcan} from '@components/Icon/Expensicons';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ScreenWrapper from '@components/ScreenWrapper';
import Switch from '@components/Switch';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import {setWorkspaceTagEnabled} from '@libs/actions/Policy';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
import type {SettingsNavigatorParamList} from '@navigation/types';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
Expand All @@ -35,12 +39,22 @@ function TagSettingsPage({route, policyTags}: TagSettingsPageProps) {
const {translate} = useLocalize();
const policyTag = useMemo(() => PolicyUtils.getTagList(policyTags, 0), [policyTags]);

const {windowWidth} = useWindowDimensions();

const [isDeleteTagModalOpen, setIsDeleteTagModalOpen] = React.useState(false);

const currentPolicyTag = policyTag.tags[decodeURIComponent(route.params.tagName)];

if (!currentPolicyTag) {
return <NotFoundPage />;
}

const deleteTagAndHideModal = () => {
Policy.deletePolicyTags(route.params.policyID, [currentPolicyTag.name]);
setIsDeleteTagModalOpen(false);
Navigation.goBack();
};

const updateWorkspaceTagEnabled = (value: boolean) => {
setWorkspaceTagEnabled(route.params.policyID, {[currentPolicyTag.name]: {name: currentPolicyTag.name, enabled: value}});
};
Expand All @@ -53,7 +67,30 @@ function TagSettingsPage({route, policyTags}: TagSettingsPageProps) {
style={[styles.defaultModalContainer]}
testID={TagSettingsPage.displayName}
>
<HeaderWithBackButton title={route.params.tagName} />
<HeaderWithBackButton
title={route.params.tagName}
shouldShowThreeDotsButton
shouldSetModalVisibility={false}
threeDotsAnchorPosition={styles.threeDotsPopoverOffset(windowWidth)}
threeDotsMenuItems={[
{
icon: Trashcan,
text: translate('workspace.tags.deleteTag'),
onSelected: () => setIsDeleteTagModalOpen(true),
},
]}
/>
<ConfirmModal
title={translate('workspace.tags.deleteTag')}
isVisible={isDeleteTagModalOpen}
onConfirm={deleteTagAndHideModal}
onCancel={() => setIsDeleteTagModalOpen(false)}
shouldSetModalVisibility={false}
prompt={translate('workspace.tags.deleteTagConfirmation')}
confirmText={translate('common.delete')}
cancelText={translate('common.cancel')}
danger
/>
<View style={styles.flexGrow1}>
<OfflineWithFeedback
errors={ErrorUtils.getLatestErrorMessageField(currentPolicyTag)}
Expand Down

0 comments on commit faddd9b

Please sign in to comment.