From 473a36751c738889a1704c8974ba1e0acfb07c09 Mon Sep 17 00:00:00 2001 From: Diana Nanyanzi Date: Thu, 5 Dec 2024 06:07:51 +0300 Subject: [PATCH] feat: add alerts --- i18n/en.pot | 89 +++++++++++++++++++++++-- src/components/create/Toolbar.tsx | 15 ++++- src/components/edit/Edit.tsx | 20 ++++-- src/components/keys/keysTable.tsx | 35 ++++++++-- src/components/namespaces/LinksList.tsx | 33 +++++++-- src/hooks/useCustomAlert.tsx | 14 ++++ 6 files changed, 178 insertions(+), 28 deletions(-) create mode 100644 src/hooks/useCustomAlert.tsx diff --git a/i18n/en.pot b/i18n/en.pot index 7bcb03d..f3cc6aa 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,18 +5,90 @@ 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-12-03T15:46:13.768Z\n" -"PO-Revision-Date: 2024-12-03T15:46:13.769Z\n" +"POT-Creation-Date: 2024-12-05T03:27:06.316Z\n" +"PO-Revision-Date: 2024-12-05T03:27:06.317Z\n" + +msgid "View keys" +msgstr "View keys" + +msgid "Click a namespace to view its keys" +msgstr "Click a namespace to view its keys" + +msgid "Add New Key" +msgstr "Add New Key" + +msgid "Add New Namespace" +msgstr "Add New Namespace" + +msgid "Namespace" +msgstr "Namespace" + +msgid "Key" +msgstr "Key" + +msgid "Cancel" +msgstr "Cancel" + +msgid "Add Key" +msgstr "Add Key" + +msgid "Add Namespace" +msgstr "Add Namespace" + +msgid "Key created successfully" +msgstr "Key created successfully" + +msgid "There was an error creating the key" +msgstr "There was an error creating the key" msgid "Add new namespace" msgstr "Add new namespace" -msgid "ERROR" -msgstr "ERROR" +msgid "New namespace" +msgstr "New namespace" + +msgid "Add new key" +msgstr "Add new key" + +msgid "New key" +msgstr "New key" + +msgid "Delete" +msgstr "Delete" + +msgid "Failed to fetch key values!" +msgstr "Failed to fetch key values!" + +msgid "Key successfully updated" +msgstr "Key successfully updated" + +msgid "There was an error updating the key" +msgstr "There was an error updating the key" + +msgid "Loading" +msgstr "Loading" + +msgid "Save changes" +msgstr "Save changes" + +msgid "Key deleted successfully" +msgstr "Key deleted successfully" + +msgid "There was an error deleting the key" +msgstr "There was an error deleting the key" + +msgid "There was an error while deleting the key" +msgstr "There was an error while deleting the key" + +msgid "Error fetching namespaces" +msgstr "Error fetching namespaces" msgid "Namespaces" msgstr "Namespaces" +msgid "This will delete all the keys in this namespace" +msgstr "This will delete all the keys in this namespace" + msgid "DataStore" msgstr "DataStore" @@ -26,8 +98,11 @@ msgstr "User DataStore" msgid "Search" msgstr "Search" -msgid "Namespace" -msgstr "Namespace" - msgid "An error has occurred" msgstr "An error has occurred" + +msgid "Back" +msgstr "Back" + +msgid "Back to DataStore" +msgstr "Back to DataStore" diff --git a/src/components/create/Toolbar.tsx b/src/components/create/Toolbar.tsx index 318e680..172b5f6 100644 --- a/src/components/create/Toolbar.tsx +++ b/src/components/create/Toolbar.tsx @@ -3,18 +3,20 @@ import { Button, Divider } from '@dhis2/ui' import React, { useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' import classes from '../../App.module.css' +import useCustomAlert from '../../hooks/useCustomAlert' import i18n from '../../locales' import CreateModal from './CreateModal' const Toolbar = () => { const { store, namespace } = useParams() + const engine = useDataEngine() + const navigate = useNavigate() const [addNewNamespace, setAddNewNamespace] = useState(false) const [addNewKey, setAddNewKey] = useState(false) const [values, setValues] = useState({}) - const engine = useDataEngine() - const navigate = useNavigate() + const { showSuccess, showError } = useCustomAlert() const handleAddNamespaceOrKey = async (values: { namespace?: string @@ -41,10 +43,17 @@ const Toolbar = () => { } else if (addNewKey) { url = `${store}/edit/${namespace}/${values?.key}` } + const message = i18n.t('Key created successfully') + showSuccess(message) navigate(url) - setValues({}) }, + onError: () => { + const message = i18n.t( + 'There was an error creating the key' + ) + showError(message) + }, } ) closeModal() diff --git a/src/components/edit/Edit.tsx b/src/components/edit/Edit.tsx index a1b051a..59f0928 100644 --- a/src/components/edit/Edit.tsx +++ b/src/components/edit/Edit.tsx @@ -2,6 +2,7 @@ import { useDataMutation, useDataQuery } from '@dhis2/app-runtime' import { Button } from '@dhis2-ui/button' import React, { useEffect, useState } from 'react' import { useParams } from 'react-router-dom' +import useCustomAlert from '../../hooks/useCustomAlert' import i18n from '../../locales' import Editor from './Editor' @@ -23,6 +24,7 @@ const keyValuesQuery = ({ store }: { store: string }) => ({ const Edit = () => { const { key, namespace, store } = useParams() + const { showSuccess, showError } = useCustomAlert() const { data, @@ -33,22 +35,28 @@ const Edit = () => { key, namespace, }, + onError: () => { + const message = i18n.t('Failed to fetch key values!') + showError(message) + }, }) const [value, setValue] = useState( JSON.stringify(data?.results, null, 4) || '' ) - const saveChanges = () => { - // todo: show alert - console.log('show success alert') - } - const [updateKey, { loading }] = useDataMutation( // @ts-expect-error("") modifyKeyMutation({ store }), { - onComplete: saveChanges, + onComplete: () => { + const message = i18n.t('Key successfully updated') + showSuccess(message) + }, + onError: () => { + const message = i18n.t('There was an error updating the key') + showError(message) + }, } ) diff --git a/src/components/keys/keysTable.tsx b/src/components/keys/keysTable.tsx index b29ddc6..6cde81e 100644 --- a/src/components/keys/keysTable.tsx +++ b/src/components/keys/keysTable.tsx @@ -10,6 +10,7 @@ import { import React, { useEffect, useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' import classes from '../../App.module.css' +import useCustomAlert from '../../hooks/useCustomAlert' import i18n from '../../locales' import DeleteButton from '../delete/DeleteButton' import DeleteModal from '../delete/DeleteModal' @@ -30,8 +31,9 @@ const KeysTable = () => { const { store, namespace } = useParams() const navigate = useNavigate() const engine = useDataEngine() + const { showError, showSuccess } = useCustomAlert() - const { data, loading, refetch } = useDataQuery( + const { data, loading, refetch, error } = useDataQuery( fetchNamespaceQuery({ store }), { variables: { @@ -49,11 +51,28 @@ const KeysTable = () => { }, [namespace]) const handleDeleteAction = async (key) => { - await engine.mutate({ - type: 'delete', - resource: `${store}/${namespace}`, - id: key, - }) + await engine.mutate( + { + type: 'delete', + resource: `${store}/${namespace}`, + id: key, + }, + { + onComplete: () => { + const message = i18n.t('Key deleted successfully') + showSuccess(message) + }, + onError: (error) => { + const message = i18n.t( + 'There was an error deleting the key', + { + error: error.message, + } + ) + showError(message) + }, + } + ) setOpenModal(false) if (deleteNamespace) { @@ -67,6 +86,10 @@ const KeysTable = () => { return } + if (error) { + return
Error: {error.message}
+ } + return (
{data && ( diff --git a/src/components/namespaces/LinksList.tsx b/src/components/namespaces/LinksList.tsx index 4048952..c866f20 100644 --- a/src/components/namespaces/LinksList.tsx +++ b/src/components/namespaces/LinksList.tsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import React, { useEffect, useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' import classes from '../../App.module.css' +import useCustomAlert from '../../hooks/useCustomAlert' import i18n from '../../locales' import DeleteModal from '../delete/DeleteModal' import CenteredLoader from '../Loader' @@ -14,13 +15,33 @@ function LinksList({ data, error, loading, refetchList }) { const [selectedNamespace, setSelectedNamespace] = useState('') const engine = useDataEngine() const navigate = useNavigate() + const { showError, showSuccess } = useCustomAlert() const handleDeleteAction = async (selectedNamespace) => { - await engine.mutate({ - type: 'delete', - resource: `${store}/${selectedNamespace}`, - id: key, - }) + await engine.mutate( + { + type: 'delete', + resource: `${store}/${selectedNamespace}`, + id: key, + }, + { + onComplete: () => { + const message = i18n.t('Key deleted successfully', { + key, + }) + showSuccess(message) + }, + onError: (error) => { + const message = i18n.t( + 'There was an error while deleting the key', + { + error: error.message, + } + ) + showError(message) + }, + } + ) setOpenModal(false) refetchList() @@ -33,7 +54,7 @@ function LinksList({ data, error, loading, refetchList }) { return (
- {error && {i18n.t('ERROR')}} + {error && {i18n.t('Error fetching namespaces')}} {loading && } {data && ( <> diff --git a/src/hooks/useCustomAlert.tsx b/src/hooks/useCustomAlert.tsx new file mode 100644 index 0000000..56b3c9d --- /dev/null +++ b/src/hooks/useCustomAlert.tsx @@ -0,0 +1,14 @@ +import { useAlert } from '@dhis2/app-service-alerts' + +const useCustomAlert = () => { + const { show } = useAlert( + ({ message }) => message, + ({ isError }) => (isError ? { critical: true } : { success: true }) + ) + return { + showSuccess: (message) => show({ message }), + showError: (message) => show({ message, isError: true }), + } +} + +export default useCustomAlert