diff --git a/i18n/en.pot b/i18n/en.pot index 05afc787..d9e6d4ee 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2024-03-14T07:46:23.636Z\n" -"PO-Revision-Date: 2024-03-14T07:46:23.636Z\n" +"POT-Creation-Date: 2024-03-18T01:33:26.193Z\n" +"PO-Revision-Date: 2024-03-18T01:33:26.193Z\n" msgid "schemas" msgstr "schemas" @@ -147,12 +147,6 @@ msgstr "An error occurred while loading the items." msgid "{{modelName}} management" msgstr "{{modelName}} management" -msgid "Successfully deleted the {{model}}" -msgstr "Successfully deleted the {{model}}" - -msgid "Failed deleting the {{model}}!" -msgstr "Failed deleting the {{model}}!" - msgid "Metadata access" msgstr "Metadata access" @@ -744,6 +738,15 @@ msgstr "This field requires a unique value, please choose another one" msgid "Required" msgstr "Required" +msgid "Successfully deleted {{modelType}} \"{{displayName}}\"" +msgstr "Successfully deleted {{modelType}} \"{{displayName}}\"" + +msgid "Failed to delete {{modelType}} \"{{displayName}}\"! {{messages}}" +msgstr "Failed to delete {{modelType}} \"{{displayName}}\"! {{messages}}" + +msgid "Failed to delete {{modelType}} \"{{displayName}}\"!" +msgstr "Failed to delete {{modelType}} \"{{displayName}}\"!" + msgid "Custom attributes" msgstr "Custom attributes" diff --git a/src/components/sectionList/SectionListWrapper.tsx b/src/components/sectionList/SectionListWrapper.tsx index a3b77e0d..192f6cfc 100644 --- a/src/components/sectionList/SectionListWrapper.tsx +++ b/src/components/sectionList/SectionListWrapper.tsx @@ -1,5 +1,4 @@ -import { FetchError, useAlert } from '@dhis2/app-runtime' -import i18n from '@dhis2/d2-i18n' +import { FetchError } from '@dhis2/app-runtime' import { SharingDialog } from '@dhis2/ui' import React, { useCallback, useState } from 'react' import { @@ -47,8 +46,8 @@ export const SectionListWrapper = ({ const [sharingDialogId, setSharingDialogId] = useState() const deleteModelMutation = useDeleteModelMutation(schema) const deleteModel = useCallback( - async (id: string) => { - await deleteModelMutation.mutateAsync({ id }) + async ({ id, displayName }: BaseListModel) => { + await deleteModelMutation.mutateAsync({ id, displayName }) refetch() }, [deleteModelMutation, refetch] @@ -113,7 +112,7 @@ export const SectionListWrapper = ({ model={model} onShowDetailsClick={handleDetailsClick} onOpenSharingClick={setSharingDialogId} - onDeleteClick={() => deleteModel(model.id)} + onDeleteClick={() => deleteModel(model)} /> ), [handleDetailsClick, setSharingDialogId, deleteModel] diff --git a/src/components/sectionList/listActions/DefaultListActions.tsx b/src/components/sectionList/listActions/DefaultListActions.tsx index 5fdf32f6..a088a1ce 100644 --- a/src/components/sectionList/listActions/DefaultListActions.tsx +++ b/src/components/sectionList/listActions/DefaultListActions.tsx @@ -1,13 +1,11 @@ import React from 'react' +import { BaseListModel } from '../../../lib' import { canEditModel } from '../../../lib/models/access' -import { BaseIdentifiableObject } from '../../../types/generated' import { ListActions, ActionEdit, ActionMore } from './SectionListActions' -type ModelWithAccess = Pick - type DefaultListActionProps = { - model: ModelWithAccess - onShowDetailsClick: (model: ModelWithAccess) => void + model: BaseListModel + onShowDetailsClick: (model: BaseListModel) => void onOpenSharingClick: (id: string) => void onDeleteClick: () => void } diff --git a/src/lib/models/useDeleteModelMutation.ts b/src/lib/models/useDeleteModelMutation.ts index 36e90847..f0249937 100644 --- a/src/lib/models/useDeleteModelMutation.ts +++ b/src/lib/models/useDeleteModelMutation.ts @@ -5,36 +5,69 @@ import { Schema } from '../useLoadApp' type MutationFnArgs = { id: string + displayName: string + messages?: string[] } export function useDeleteModelMutation(schema: Schema) { + const engine = useDataEngine() const { show: showDeletionSuccess } = useAlert( - i18n.t('Successfully deleted the {{model}}', { - model: schema.singular, - }), + ({ displayName, modelType }) => + i18n.t('Successfully deleted {{modelType}} "{{displayName}}"', { + displayName, + modelType, + }), { success: true } ) + const { show: showDeletionFailure } = useAlert( - i18n.t('Failed deleting the {{model}}!', { - model: schema.singular, - }), + ({ displayName, modelType, messages }) => { + if (messages) { + return i18n.t( + 'Failed to delete {{modelType}} "{{displayName}}"! {{messages}}', + { displayName, modelType, messages: messages.join('; ') } + ) + } + + return i18n.t('Failed to delete {{modelType}} "{{displayName}}"!', { + displayName, + modelType, + }) + }, { success: false } ) - const engine = useDataEngine() - const mutationFn = async (variables: MutationFnArgs) => { - try { - const result = await engine.mutate({ - resource: schema.plural, - id: variables.id, - type: 'delete', - }) - showDeletionSuccess() - return result - } catch (e) { - showDeletionFailure() - } - } + return useMutation({ + mutationFn: (variables: MutationFnArgs) => { + const alertPayload = { + modelType: schema.singular, + displayName: variables.displayName, + } + + return engine + .mutate({ + resource: schema.plural, + id: variables.id, + type: 'delete', + }) + .then((result) => { + showDeletionSuccess(alertPayload) + return result + }) + .catch((e) => { + if (e?.details?.response?.errorReports) { + showDeletionFailure({ + ...alertPayload, + messages: e.details.response.errorReports.map( + ({ message }: { message: string }) => message + ), + }) + } else { + showDeletionFailure(alertPayload) + } - return useMutation({ mutationFn }) + throw e + }) + }, + }) } diff --git a/src/lib/sectionList/fieldFilters.ts b/src/lib/sectionList/fieldFilters.ts index 5e996b00..5c293a3f 100644 --- a/src/lib/sectionList/fieldFilters.ts +++ b/src/lib/sectionList/fieldFilters.ts @@ -1,6 +1,6 @@ import { BaseIdentifiableObject } from '../../types/generated' -export const DEFAULT_FIELD_FILTERS = ['id', 'access'] as const +export const DEFAULT_FIELD_FILTERS = ['id', 'access', 'displayName'] as const export type DefaultFields = (typeof DEFAULT_FIELD_FILTERS)[number] export type BaseListModel = Pick