diff --git a/i18n/en.pot b/i18n/en.pot index e4dd84f5..f5550a04 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: 2025-01-22T08:07:55.176Z\n" -"PO-Revision-Date: 2025-01-22T08:07:55.176Z\n" +"POT-Creation-Date: 2025-01-23T10:27:25.765Z\n" +"PO-Revision-Date: 2025-01-23T10:27:25.765Z\n" msgid "schemas" msgstr "schemas" @@ -14,6 +14,9 @@ msgstr "schemas" msgid "You do not have the authority to view this page." msgstr "You do not have the authority to view this page." +msgid "You are missing the required authority ({{authority}}) to view this page." +msgstr "You are missing the required authority ({{authority}}) to view this page." + msgid "Section is not implemented yet" msgstr "Section is not implemented yet" @@ -36,6 +39,9 @@ msgstr "The page you are looking for does not exist." msgid "New {{modelName}}" msgstr "New {{modelName}}" +msgid "Merge {{modelName}}" +msgstr "Merge {{modelName}}" + msgid "Edit {{modelName}}" msgstr "Edit {{modelName}}" @@ -51,9 +57,24 @@ msgstr "Overview" msgid "Search menu items" msgstr "Search menu items" +msgid "All" +msgstr "All" + +msgid "Positive" +msgstr "Positive" + +msgid "Negative" +msgstr "Negative" + +msgid "Outline" +msgstr "Outline" + msgid "Search icons" msgstr "Search icons" +msgid "No icons match the search." +msgstr "No icons match the search." + msgid "Select" msgstr "Select" @@ -63,15 +84,15 @@ msgstr "Remove icon" msgid "Cancel" msgstr "Cancel" -msgid "Retry" -msgstr "Retry" - -msgid "All" -msgstr "All" +msgid "Clear all" +msgstr "Clear all" msgid "Filter options" msgstr "Filter options" +msgid "Retry" +msgstr "Retry" + msgid "Save and close" msgstr "Save and close" @@ -135,6 +156,32 @@ msgstr "Failed to load {{label}}" msgid "Failed to load" msgstr "Failed to load" +msgid "Merging cannot be undone" +msgstr "Merging cannot be undone" + +msgid "Confirmation code does not match" +msgstr "Confirmation code does not match" + +msgid "Merge" +msgstr "Merge" + +msgid "Merging {{count}} {{model}}..." +msgid_plural "Merging {{count}} {{model}}..." +msgstr[0] "Merging {{count}} {{model}}..." +msgstr[1] "Merging {{count}} {{model}}..." + +msgid "Merging..." +msgstr "Merging..." + +msgid "Merge complete" +msgstr "Merge complete" + +msgid "Back to list" +msgstr "Back to list" + +msgid "At least one source is required" +msgstr "At least one source is required" + msgid "Aggregation level(s)" msgstr "Aggregation level(s)" @@ -411,6 +458,9 @@ msgstr "Manage View" msgid "{{number}} selected" msgstr "{{number}} selected" +msgid "Merge..." +msgstr "Merge..." + msgid "Deselect all" msgstr "Deselect all" @@ -1158,6 +1208,60 @@ msgstr "Form name should not exceed 230 characters" msgid "End date should be after start date" msgstr "End date should be after start date" +msgid "" +"The merge operation will merge the source category options into\n" +" the target category options. One or many source category " +"options\n" +" can be specified" +msgstr "" +"The merge operation will merge the source category options into\n" +" the target category options. One or many source category " +"options\n" +" can be specified" + +msgid "" +"Only one target should be specified. The merge operation will\n" +" transfer all of the category options metadata associations " +"to the\n" +" source category option over to the target category option." +msgstr "" +"Only one target should be specified. The merge operation will\n" +" transfer all of the category options metadata associations " +"to the\n" +" source category option over to the target category option." + +msgid "Category options to be merged (source)" +msgstr "Category options to be merged (source)" + +msgid "Select category options to merge" +msgstr "Select category options to merge" + +msgid "Category options to merge into (target)" +msgstr "Category options to merge into (target)" + +msgid "Select category options to merge into" +msgstr "Select category options to merge into" + +msgid "Merge settings" +msgstr "Merge settings" + +msgid "" +"What should happen to the source category options after the merge is " +"complete?" +msgstr "" +"What should happen to the source category options after the merge is " +"complete?" + +msgid "Keep {{ count }} source category options" +msgid_plural "Keep {{ count }} source category options" +msgstr[0] "Keep {{ count }} source category options" +msgstr[1] "Keep {{ count }} source category options" + +msgid "Delete {{ count }} source category options" +msgid_plural "Delete {{ count }} source category options" +msgstr[0] "Delete {{ count }} source category options" +msgstr[1] "Delete {{ count }} source category options" + msgid "Custom attributes" msgstr "Custom attributes" @@ -1355,9 +1459,73 @@ msgstr "Form" msgid "Advanced" msgstr "Advanced" +msgid "Configure indicator type merge" +msgstr "Configure indicator type merge" + +msgid "The indicator types merge operation is complete." +msgstr "The indicator types merge operation is complete." + +msgid "All selected indicator types were merged successfully." +msgstr "All selected indicator types were merged successfully." + msgid "Set up the basic information for this Indicator Type." msgstr "Set up the basic information for this Indicator Type." +msgid "" +"The merge operation will merge the source indicator types into\n" +" the target indicator type. One or many source indicator " +"types\n" +" can be specified" +msgstr "" +"The merge operation will merge the source indicator types into\n" +" the target indicator type. One or many source indicator " +"types\n" +" can be specified" + +msgid "" +"Only one target should be specified. The merge operation will\n" +" transfer all of the indicator metadata associations to the\n" +" source indicator types over to the target indicator type." +msgstr "" +"Only one target should be specified. The merge operation will\n" +" transfer all of the indicator metadata associations to the\n" +" source indicator types over to the target indicator type." + +msgid "Indicator types to be merged (source)" +msgstr "Indicator types to be merged (source)" + +msgid "Select indicator types to merge" +msgstr "Select indicator types to merge" + +msgid "Indicator type to merge into (target)" +msgstr "Indicator type to merge into (target)" + +msgid "Select indicator type to merge into" +msgstr "Select indicator type to merge into" + +msgid "" +"What should happen to the source indicator types after the merge is " +"complete?" +msgstr "" +"What should happen to the source indicator types after the merge is " +"complete?" + +msgid "Keep {{ count }} source indicator types" +msgid_plural "Keep {{ count }} source indicator types" +msgstr[0] "Keep {{ count }} source indicator types" +msgstr[1] "Keep {{ count }} source indicator types" + +msgid "Delete {{ count }} source indicator types" +msgid_plural "Delete {{ count }} source indicator types" +msgstr[0] "Delete {{ count }} source indicator types" +msgstr[1] "Delete {{ count }} source indicator types" + +msgid "Conflicting factors" +msgstr "Conflicting factors" + +msgid "It is not recommended to merge indicator types with different factors." +msgstr "It is not recommended to merge indicator types with different factors." + msgid "Set up the basic information for this organisational unit group set." msgstr "Set up the basic information for this organisational unit group set." diff --git a/src/components/SearchableMultiSelect/SearchableMultiSelect.module.css b/src/components/SearchableMultiSelect/SearchableMultiSelect.module.css index e691512c..a0da7b40 100644 --- a/src/components/SearchableMultiSelect/SearchableMultiSelect.module.css +++ b/src/components/SearchableMultiSelect/SearchableMultiSelect.module.css @@ -48,6 +48,7 @@ padding: var(--spacers-dp16); box-shadow: 0 0 4px rgba(0, 0, 0, 0.4); background: var(--colors-white); + z-index: 1; } .searchInput { diff --git a/src/lib/sections/mergableSections.ts b/src/lib/sections/mergableSections.ts index 1a26e856..250cc670 100644 --- a/src/lib/sections/mergableSections.ts +++ b/src/lib/sections/mergableSections.ts @@ -6,6 +6,7 @@ import { hasAuthority, useCurrentUserAuthorities } from '../user' const sectionAuthorityMap = new Map([ [SECTIONS_MAP.indicator, 'F_INDICATOR_MERGE'], [SECTIONS_MAP.indicatorType, 'F_INDICATOR_TYPE_MERGE'], + [SECTIONS_MAP.categoryOption, 'F_CATEGORY_OPTION_MERGE'], ]) export const getMergeAuthority = ( diff --git a/src/pages/categoryOptions/Merge.tsx b/src/pages/categoryOptions/Merge.tsx new file mode 100644 index 00000000..399681a9 --- /dev/null +++ b/src/pages/categoryOptions/Merge.tsx @@ -0,0 +1,92 @@ +import { useDataEngine } from '@dhis2/app-runtime' +import i18n from '@dhis2/d2-i18n' +import React, { useMemo } from 'react' +import { Form } from 'react-final-form' +import { + DefaultMergeFormContents, + MergeComplete, + StyledMergeForm, + Title, +} from '../../components/merge' +import { getDefaults, useLocationWithState } from '../../lib' +import { createFormError } from '../../lib/form/createFormError' +import { + CategoryOptionMergeFormValues, + mergeFormSchema, + validate, +} from './merge/categoryOptionMergeSchema' +import { CategoryOptionMergeFormFields } from './merge/CategoryOptionMergeFormFields' + +export const Component = () => { + const location = useLocationWithState<{ selectedModels: Set }>() + + const dataEngine = useDataEngine() + const initialValues = useMemo(() => { + const defaults = { + ...getDefaults(mergeFormSchema), + target: undefined, + sources: Array.from(location.state?.selectedModels || []).map( + (id) => ({ + id, + }) + ), + } + return defaults + }, [location.state?.selectedModels]) + + const onSubmit = async (values: CategoryOptionMergeFormValues) => { + try { + const data = mergeFormSchema.parse(values) + await dataEngine.mutate({ + resource: 'categoryOptions/merge', + type: 'create', + data, + }) + return undefined + } catch (e) { + console.error(e) + return createFormError(e) + } + } + + return ( +
+ {({ handleSubmit }) => ( + + + {i18n.t('Configure category options merge')} + + } + mergeCompleteElement={ + +

+ {i18n.t( + 'The category options merge operation is complete.' + )} +

+

+ {i18n.t( + 'All selected category options were merged successfully.' + )} +

+
+ } + > + +
+
+ )} +
+ ) +}