From 3b3b8edaa7409de1e142a71c9801cd9e7303731c Mon Sep 17 00:00:00 2001 From: HendrikThePendric Date: Thu, 23 Jan 2025 12:35:56 +0100 Subject: [PATCH] refactor: encapsulate superset dashboard mutation logic in a hook --- i18n/en.pot | 61 +++--- .../UpdateSupersetEmbeddedDashboard.js | 191 ++++++++---------- .../SupersetEmbeddedDashboardModal.module.css | 8 + ...useSupersetEmbeddedDashboardFieldsState.js | 4 +- .../useSupersetEmbeddedDashboardMutation.js | 107 ++++++++++ 5 files changed, 232 insertions(+), 139 deletions(-) create mode 100644 src/modules/useSupersetEmbeddedDashboardMutation.js diff --git a/i18n/en.pot b/i18n/en.pot index 12146c650..3607cbfeb 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-22T12:28:04.654Z\n" -"PO-Revision-Date: 2025-01-22T12:28:04.655Z\n" +"POT-Creation-Date: 2025-01-23T11:31:37.781Z\n" +"PO-Revision-Date: 2025-01-23T11:31:37.781Z\n" msgid "Untitled dashboard" msgstr "Untitled dashboard" @@ -50,26 +50,36 @@ msgstr "Show chart controls on dashboard items" msgid "Show filters" msgstr "Show filters" -msgid "Could not update dashboard {{name}}" -msgstr "Could not update dashboard {{name}}" - -msgid "Could not delete dashboard {{name}}" -msgstr "Could not delete dashboard {{name}}" +msgid "Delete dashboard" +msgstr "Delete dashboard" -msgid "Edit external dashboard" -msgstr "Edit external dashboard" +msgid "" +"Deleting dashboard \"{{ dashboardName }}\" will remove it for all users. " +"This action cannot be undone. Are you sure you want to permanently delete " +"this dashboard?" +msgstr "" +"Deleting dashboard \"{{ dashboardName }}\" will remove it for all users. " +"This action cannot be undone. Are you sure you want to permanently delete " +"this dashboard?" -msgid "Could not load dashboard details" -msgstr "Could not load dashboard details" +msgid "" +"Note: the source dashboard embedded by this external dashboard will not be " +"deleted." +msgstr "" +"Note: the source dashboard embedded by this external dashboard will not be " +"deleted." -msgid "Update dashboard" -msgstr "Update dashboard" +msgid "Delete" +msgstr "Delete" msgid "Cancel" msgstr "Cancel" -msgid "Delete" -msgstr "Delete" +msgid "Edit external dashboard" +msgstr "Edit external dashboard" + +msgid "Update dashboard" +msgstr "Update dashboard" msgid "New dashboard: choose type" msgstr "New dashboard: choose type" @@ -366,6 +376,15 @@ msgstr "Apps" msgid "Users" msgstr "Users" +msgid "Could not update dashboard {{name}}" +msgstr "Could not update dashboard {{name}}" + +msgid "Could not delete dashboard {{name}}" +msgstr "Could not delete dashboard {{name}}" + +msgid "Could not load dashboard details" +msgstr "Could not load dashboard details" + msgid "" "Failed to save dashboard. You might be offline or not have access to edit " "this dashboard." @@ -414,18 +433,6 @@ msgstr "Exit without saving" msgid "Go to dashboards" msgstr "Go to dashboards" -msgid "Delete dashboard" -msgstr "Delete dashboard" - -msgid "" -"Deleting dashboard \"{{ dashboardName }}\" will remove it for all users. " -"This action cannot be undone. Are you sure you want to permanently delete " -"this dashboard?" -msgstr "" -"Deleting dashboard \"{{ dashboardName }}\" will remove it for all users. " -"This action cannot be undone. Are you sure you want to permanently delete " -"this dashboard?" - msgid "Discard changes" msgstr "Discard changes" diff --git a/src/components/ConfigureSupersetEmbeddedDashboardModal/UpdateSupersetEmbeddedDashboard.js b/src/components/ConfigureSupersetEmbeddedDashboardModal/UpdateSupersetEmbeddedDashboard.js index d444829a2..8782ac0f3 100644 --- a/src/components/ConfigureSupersetEmbeddedDashboardModal/UpdateSupersetEmbeddedDashboard.js +++ b/src/components/ConfigureSupersetEmbeddedDashboardModal/UpdateSupersetEmbeddedDashboard.js @@ -1,4 +1,3 @@ -import { useDataMutation, useDataQuery } from '@dhis2/app-runtime' import i18n from '@dhis2/d2-i18n' import { Button, @@ -11,75 +10,28 @@ import { } from '@dhis2/ui' import cx from 'classnames' import PropTypes from 'prop-types' -import React, { useCallback, useEffect, useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { useHistory } from 'react-router-dom' -import { tFetchDashboards } from '../../actions/dashboards.js' -import { - acClearSelected, - tSetSelectedDashboardById, -} from '../../actions/selected.js' -import { parseSupersetEmbeddedDashboardFieldValues } from '../../modules/parseSupersetEmbeddedDashboardFieldValues.js' +import React, { useEffect } from 'react' import { useSupersetEmbeddedDashboardFieldsState } from '../../modules/useSupersetEmbeddedDashboardFieldsState.js' -import { sGetSelectedId } from '../../reducers/selected.js' +import { useSupersetEmbeddedDashboardMutation } from '../../modules/useSupersetEmbeddedDashboardMutation.js' import styles from './styles/SupersetEmbeddedDashboardModal.module.css' import { SupersetEmbeddedDashboardFields } from './SupersetEmbeddedDashboardFields.js' -const getDashboardQuery = { - dashboard: { - resource: 'dashboards', - id: ({ id }) => id, - params: { - fields: ['name', 'code', 'description', 'access', 'embedded[*]'], - }, - }, -} -const updateDashboardQuery = { - resource: 'dashboards', - type: 'update', - id: ({ id }) => id, - data: ({ values }) => parseSupersetEmbeddedDashboardFieldValues(values), - params: { - skipTranslation: true, - skipSharing: true, - }, -} -const deleteDashboardQuery = { - resource: 'dashboards', - type: 'delete', - id: ({ id }) => id, -} - -const parseErrorText = (error) => - error?.details?.response?.errorReports[0]?.message ?? - i18n.t('An unknown error occurred') - export const UpdateSupersetEmbeddedDashboard = ({ closeModal }) => { - const dispatch = useDispatch() - const history = useHistory() - const id = useSelector(sGetSelectedId) const { - loading: queryLoading, - error: queryError, - data: queryData, - } = useDataQuery(getDashboardQuery, { variables: { id } }) - const dashboard = queryData?.dashboard - const name = dashboard?.name - const [mutationLoading, setMutationLoading] = useState(false) - const handeMutationError = useCallback(() => setMutationLoading(false), []) - const [updateDashboard, { error: updateError }] = useDataMutation( - updateDashboardQuery, - { variables: { id }, onError: handeMutationError } - ) - const [deleteDashboard, { error: deleteError }] = useDataMutation( - deleteDashboardQuery, - { variables: { id }, onError: handeMutationError } - ) - const mutationError = updateError || deleteError - const mutationErrorTitle = updateError - ? i18n.t('Could not update dashboard {{name}}', { name }) - : i18n.t('Could not delete dashboard {{name}}', { name }) - const mutationErrorText = parseErrorText(mutationError) + queryLoading, + queryHasError, + queryErrorTitle, + queryErrorMessage, + mutationLoading, + mutationHasError, + mutationErrorTitle, + mutationErrorText, + dashboard, + showDeleteConfirmDialog, + setShowDeleteConfirmDialog, + handleUpdate, + handleDelete, + } = useSupersetEmbeddedDashboardMutation({ closeModal }) const { hasFieldChanges, isSupersetEmbedIdValid, @@ -87,36 +39,12 @@ export const UpdateSupersetEmbeddedDashboard = ({ closeModal }) => { values, onChange, onSupersetEmbedIdFieldBlur, - resetStateWithNewValues, + resetFieldsStateWithNewValues, } = useSupersetEmbeddedDashboardFieldsState() - const handleSubmit = useCallback( - async (event) => { - event.preventDefault() - setMutationLoading(true) - await updateDashboard({ values }) - await dispatch(tSetSelectedDashboardById(id)) - setMutationLoading(false) - closeModal() - }, - [values, updateDashboard, closeModal, dispatch, id] - ) - const handleDelete = useCallback( - async (_, event) => { - event.preventDefault() - setMutationLoading(true) - await deleteDashboard() - dispatch(acClearSelected()) - await dispatch(tFetchDashboards()) - setMutationLoading(false) - closeModal() - history.push('/') - }, - [deleteDashboard, closeModal, dispatch, history] - ) useEffect(() => { if (dashboard) { - resetStateWithNewValues({ + resetFieldsStateWithNewValues({ title: dashboard.name, code: dashboard.code, description: dashboard.description, @@ -126,31 +54,74 @@ export const UpdateSupersetEmbeddedDashboard = ({ closeModal }) => { showFilters: dashboard.embedded.options.filters.visible, }) } - }, [dashboard, resetStateWithNewValues]) + }, [dashboard, resetFieldsStateWithNewValues]) + + if (showDeleteConfirmDialog) { + return ( + + {i18n.t('Delete dashboard')} + +

+ {i18n.t( + 'Deleting dashboard "{{ dashboardName }}" will remove it for all users. This action cannot be undone. Are you sure you want to permanently delete this dashboard?', + { dashboardName: dashboard.name } + )} +

+

+ {i18n.t( + 'Note: the source dashboard embedded by this external dashboard will not be deleted.', + { nsSeparator: '###' } + )} +

+
+ +
+ + +
+
+
+ ) + } return ( -
+ { + event.preventDefault() + handleUpdate(values) + }} + > {i18n.t('Edit external dashboard', { nsSeparator: '###' })} - {(queryLoading || !!queryError) && ( + {(queryLoading || queryHasError) && (
{queryLoading && } - {queryError && ( - - {parseErrorText(queryError)} + {queryHasError && ( + + {queryErrorMessage} )}
@@ -165,7 +136,7 @@ export const UpdateSupersetEmbeddedDashboard = ({ closeModal }) => { onSupersetEmbedIdFieldBlur={onSupersetEmbedIdFieldBlur} submitting={mutationLoading || queryLoading} /> - {mutationError && ( + {mutationHasError && ( {mutationErrorText} @@ -173,7 +144,7 @@ export const UpdateSupersetEmbeddedDashboard = ({ closeModal }) => {
- {!queryError && ( + {!queryHasError && ( - {!queryError && dashboard?.access?.delete && ( + {!queryHasError && dashboard?.access?.delete && (