From 26867e5f15a37cd98deaa900916b70e075f913f7 Mon Sep 17 00:00:00 2001 From: Diana Nanyanzi Date: Wed, 11 Dec 2024 03:13:51 +0300 Subject: [PATCH] chore: restructure directory - Remove redundant ui files - organise component files - correct imports --- i18n/en.pot | 88 +++------ src/App.module.css | 113 ------------ src/App.tsx | 4 +- src/components/EmptyArea.tsx | 20 --- src/components/Error.tsx | 74 -------- src/components/{panel => }/Panel.module.css | 61 +------ src/components/create/CreateModal.tsx | 80 --------- src/components/create/Toolbar.tsx | 112 ------------ src/components/delete/DeleteButton.tsx | 21 --- src/components/delete/DeleteModal.tsx | 36 ---- src/components/edit/Edit.tsx | 120 ------------- src/components/edit/Editor.tsx | 22 --- .../{panel => }/empty/EmptyArea.tsx | 4 +- .../{panel => }/empty/EmptyEditor.tsx | 6 +- .../{panel => }/error/ErrorComponent.tsx | 4 +- .../{panel => }/error/ErrorPanel.tsx | 2 +- src/components/keys/Keys.tsx | 10 -- src/components/keys/keysTable.tsx | 169 ------------------ .../{panel => }/modals/CreateModal.tsx | 20 +-- src/components/namespaces/LinksList.tsx | 107 ----------- .../{panel => panels}/EditPanel.tsx | 20 ++- .../{panel => panels}/KeysPanel.tsx | 10 +- .../{panel => panels}/NamespacesPanel.tsx | 12 +- src/components/sidebar/DataStoreSelect.tsx | 32 ---- src/components/sidebar/SidebarNavLink.tsx | 36 ---- src/components/sidebar/searchField.tsx | 18 -- src/components/sidebar/sidebar.tsx | 92 ---------- .../{panel => }/sidepanel/CreateButton.tsx | 11 +- .../sidepanel/DataStoreControl.tsx | 4 +- src/components/{ => sidepanel}/Loader.tsx | 0 .../{panel => sidepanel}/PanelEditor.tsx | 0 .../{panel => sidepanel}/PanelHeader.tsx | 2 +- .../{panel => }/sidepanel/PanelLink.tsx | 6 +- .../{panel => }/sidepanel/PanelLinksList.tsx | 6 +- .../{panel => }/sidepanel/SearchField.tsx | 2 +- .../{panel => }/sidepanel/SidePanel.tsx | 76 ++++---- src/hooks/useCustomAlert.tsx | 2 +- .../routes/Main.tsx => routes/MainLayout.tsx} | 8 +- .../panel => }/routes/PanelRouter.tsx | 14 +- .../panel => }/routes/ThreePanelLayout.tsx | 6 +- src/routes/layout.tsx | 25 --- src/routes/router.tsx | 40 ----- 42 files changed, 150 insertions(+), 1345 deletions(-) delete mode 100644 src/App.module.css delete mode 100644 src/components/EmptyArea.tsx delete mode 100644 src/components/Error.tsx rename src/components/{panel => }/Panel.module.css (58%) delete mode 100644 src/components/create/CreateModal.tsx delete mode 100644 src/components/create/Toolbar.tsx delete mode 100644 src/components/delete/DeleteButton.tsx delete mode 100644 src/components/delete/DeleteModal.tsx delete mode 100644 src/components/edit/Edit.tsx delete mode 100644 src/components/edit/Editor.tsx rename src/components/{panel => }/empty/EmptyArea.tsx (90%) rename src/components/{panel => }/empty/EmptyEditor.tsx (77%) rename src/components/{panel => }/error/ErrorComponent.tsx (95%) rename src/components/{panel => }/error/ErrorPanel.tsx (89%) delete mode 100644 src/components/keys/Keys.tsx delete mode 100644 src/components/keys/keysTable.tsx rename src/components/{panel => }/modals/CreateModal.tsx (86%) delete mode 100644 src/components/namespaces/LinksList.tsx rename src/components/{panel => panels}/EditPanel.tsx (86%) rename src/components/{panel => panels}/KeysPanel.tsx (93%) rename src/components/{panel => panels}/NamespacesPanel.tsx (90%) delete mode 100644 src/components/sidebar/DataStoreSelect.tsx delete mode 100644 src/components/sidebar/SidebarNavLink.tsx delete mode 100644 src/components/sidebar/searchField.tsx delete mode 100644 src/components/sidebar/sidebar.tsx rename src/components/{panel => }/sidepanel/CreateButton.tsx (68%) rename src/components/{panel => }/sidepanel/DataStoreControl.tsx (87%) rename src/components/{ => sidepanel}/Loader.tsx (100%) rename src/components/{panel => sidepanel}/PanelEditor.tsx (100%) rename src/components/{panel => sidepanel}/PanelHeader.tsx (83%) rename src/components/{panel => }/sidepanel/PanelLink.tsx (90%) rename src/components/{panel => }/sidepanel/PanelLinksList.tsx (92%) rename src/components/{panel => }/sidepanel/SearchField.tsx (89%) rename src/components/{panel => }/sidepanel/SidePanel.tsx (61%) rename src/{components/panel/routes/Main.tsx => routes/MainLayout.tsx} (57%) rename src/{components/panel => }/routes/PanelRouter.tsx (78%) rename src/{components/panel => }/routes/ThreePanelLayout.tsx (71%) delete mode 100644 src/routes/layout.tsx delete mode 100644 src/routes/router.tsx diff --git a/i18n/en.pot b/i18n/en.pot index d09fdc0..a46ec1f 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-12-06T20:56:19.444Z\n" -"PO-Revision-Date: 2024-12-06T20:56:19.445Z\n" +"POT-Creation-Date: 2024-12-11T00:48:22.223Z\n" +"PO-Revision-Date: 2024-12-11T00:48:22.223Z\n" msgid "View keys" msgstr "View keys" @@ -14,14 +14,14 @@ msgstr "View keys" msgid "Click a namespace to view its keys" msgstr "Click a namespace to view its keys" +msgid "Select a namespace and key to edit its values" +msgstr "Select a namespace and key to edit its values" + msgid "An error occurred" msgstr "An error occurred" -msgid "Add New Key" -msgstr "Add New Key" - -msgid "Add New Namespace" -msgstr "Add New Namespace" +msgid "Error" +msgstr "Error" msgid "Namespace" msgstr "Namespace" @@ -32,33 +32,6 @@ 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 "New namespace" -msgstr "New namespace" - -msgid "Add new key" -msgstr "Add new key" - -msgid "New key" -msgstr "New key" - -msgid "Delete" -msgstr "Delete" - msgid "Key successfully updated" msgstr "Key successfully updated" @@ -71,38 +44,35 @@ 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 "create" +msgstr "create" -msgid "There was an error while deleting the key" -msgstr "There was an error while deleting the key" +msgid "DataStore" +msgstr "DataStore" -msgid "Error fetching namespaces" -msgstr "Error fetching namespaces" +msgid "UserDataStore" +msgstr "UserDataStore" -msgid "Namespaces" -msgstr "Namespaces" +msgid "Search" +msgstr "Search" -msgid "This will delete all the keys in this namespace" -msgstr "This will delete all the keys in this namespace" +msgid "Key created successfully" +msgstr "Key created successfully" -msgid "Select a namespace and key to edit its values" -msgstr "Select a namespace and key to edit its values" +msgid "Add New Namespace" +msgstr "Add New Namespace" -msgid "Error" -msgstr "Error" +msgid "Add New Key" +msgstr "Add New Key" -msgid "New" -msgstr "New" +msgid "Add Namespace" +msgstr "Add Namespace" -msgid "DataStore" -msgstr "DataStore" +msgid "Add Key" +msgstr "Add Key" -msgid "User DataStore" -msgstr "User DataStore" +msgid "New namespace" +msgstr "New namespace" -msgid "Search" -msgstr "Search" +msgid "New key" +msgstr "New key" diff --git a/src/App.module.css b/src/App.module.css deleted file mode 100644 index 97f1344..0000000 --- a/src/App.module.css +++ /dev/null @@ -1,113 +0,0 @@ -.container { - width: 100%; - height: 100%; - display: flex; - flex-direction: row; - font-size: 1rem; -} - -.top { - margin-top: 0.5em; -} - -.bottom { - margin-bottom: 0.5em; -} - -/* sidebar */ -.sidebar { - width: 20%; - margin: 0.1em; -} - -.sidebarContent { - padding: 0.3em; - width: 20%; -} - -.sidebarList h4 { - padding: 0; - margin: 0.5em; -} - -.sidebarList ul { - margin: 0; - padding: 0; -} - -.select { - height: 70px; - padding: 0; - margin: 0; -} - -/* main area */ - -.main { - width: 80%; - margin: 0.1em; -} - -/* --- keys */ - -.keysTable { - margin-top: 10px; - padding: 0.2em; -} - -/* nav link */ - -/* sourced and adapted from https://github.com/dhis2/design-specs/blob/b65e6518dcc7c16733379cd80688e67a422fc742/src/components/sidenav.css#L73 (-> 104) */ -.navLink { - display: grid; - grid-template-columns: 2.5fr 0.5fr; -} - -.navLink button { - border: 0; -} - -.navLink a { - display: block; - min-height: 36px; - padding: 10px; - /* background: var(--colors-grey100); */ - text-decoration: none; - color: var(--colors-grey900); - font-size: 15px; - display: flex; - align-items: center; -} -.navLink:hover, -.navLink a:hover { - background: var(--colors-grey300); -} -.navLink:focus, -.navLink a:focus { - outline: 2px solid white; - background: var(--colors-grey200); - outline-offset: -2px; -} - -.navLink a.active, -.navLink :global(.active) { - font-weight: 500; - background: var(--colors-grey200); - box-shadow: inset 6px 0px 0px 0px var(--colors-grey500); -} -.navLink.active:hover { - background: var(--colors-grey300); -} - -/* Toolbar */ -.toolbar { - margin-top: 5px; - height: 70px; - display: flex; - flex-direction: row; -} - -.toolbar button { - align-self: center; - margin: 0 0 0 15px; -} diff --git a/src/App.tsx b/src/App.tsx index b3c9254..91dd082 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,13 +1,11 @@ import React, { FC } from 'react' import { RouterProvider } from 'react-router-dom' import AppWrapper from './components/AppWrapper' -import { threePanelRouter } from './components/panel/routes/PanelRouter' -// import { router } from './routes/Router' +import { threePanelRouter } from './routes/PanelRouter' const App: FC = () => { return ( - {/* */} ) diff --git a/src/components/EmptyArea.tsx b/src/components/EmptyArea.tsx deleted file mode 100644 index aaf7687..0000000 --- a/src/components/EmptyArea.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { Center, NoticeBox } from '@dhis2/ui' -import React from 'react' -import { useParams } from 'react-router-dom' -import i18n from '../locales' - -const EmptyArea = () => { - const { store, namespace } = useParams() - return ( - <> - {store && !namespace && ( -
- - {i18n.t('Click a namespace to view its keys')} - -
- )} - - ) -} -export default EmptyArea diff --git a/src/components/Error.tsx b/src/components/Error.tsx deleted file mode 100644 index 4f6883e..0000000 --- a/src/components/Error.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { Card, Center, NoticeBox } from '@dhis2/ui' -import React from 'react' -import { Link, isRouteErrorResponse, useRouteError } from 'react-router-dom' -import i18n from '../locales' - -interface Error { - status?: number - statusText?: string - internal?: boolean - data?: string - message?: string -} - -type PassedErrorProps = { - err?: { - httpStatus?: string - httpStatusCode?: number - status?: string - message?: string - errorCode?: string - } -} - -export default function Error({ err }: PassedErrorProps) { - const error: Error = useRouteError() - - return ( -
- -
- - {isRouteErrorResponse(error) ? ( - <> -

- - {error.status} {error.statusText}{' '} - - - {error.data} -

- Back to datastore - - ) : ( -

- - {error.status} {error.statusText}{' '} - - {error?.message && ( - - {error.message} - )} -

- )} - {err && ( -

- - {err.httpStatusCode} {err.httpStatus}{' '} - - {err?.message && - {err.message}} -

- )} -
-
-
-
- ) -} diff --git a/src/components/panel/Panel.module.css b/src/components/Panel.module.css similarity index 58% rename from src/components/panel/Panel.module.css rename to src/components/Panel.module.css index 47dbef8..05d03f1 100644 --- a/src/components/panel/Panel.module.css +++ b/src/components/Panel.module.css @@ -1,11 +1,5 @@ .container { - /* width: 100%; */ - /* height: 100vh; */ box-sizing: border-box; - /* height: 100%; */ - /* display: flex; */ - /* flex-direction: row; */ - /* font-size: 1rem; */ display: grid; grid-template-columns: 296px auto; border: 1px solid var(--colors-grey300); @@ -25,19 +19,11 @@ .sidebar { border-right: 1px solid var(--colors-grey400); - /* background: yellow; */ - /* margin-top: 0.5em */ - /* padding: 0.5em; */ - /* width: 290px; */ - /* margin: 0.1em; */ } .sidebarContent { padding: 0.5em; margin-top: 0.2em; - /* margin: 0; */ - /* padding: 0.3em; */ - /* width: 20%; */ } .createButton { @@ -50,31 +36,12 @@ border: none; } -.top { - /* margin-top: 0.5em; */ -} - -.bottom { - /* margin-bottom: 0.5em; */ -} - -.sidebarList h4 { - /* padding: 0; */ - /* margin: 0.5em; */ -} - .sidebarList ul { margin: 0; padding: 0; list-style-type: none; } -.select { - /* height: 70px; */ - /* padding: 0; */ - /* margin: 0; */ -} - /* main area */ .main { @@ -82,44 +49,30 @@ grid-template-columns: 296px auto; } -/* --- keys */ - -.keysTable { - /* margin-top: 10px; */ - /* padding: 0.2em; */ -} - /* nav link */ /* sourced and adapted from https://github.com/dhis2/design-specs/blob/b65e6518dcc7c16733379cd80688e67a422fc742/src/components/sidenav.css#L73 (-> 104) */ .navLink { width: 100%; - /* display: grid; */ - /* grid-template-rows: 1fr 2fr 1fr; */ - /* background-color: aliceblue; */ - /* border: 1px solid red; */ - /* height: 50px; */ + display: grid; + grid-template-columns: 2fr auto; min-height: 36px; border-radius: 10px; } .navLink button { - /* border: 0; */ + border: 0; + background-color: transparent; } .navLink a { - /* display: block; */ - /* min-height: 36px; */ - padding: 5px; - /* background: var(--colors-grey100); */ + padding: 10px 5px; text-decoration: none; color: var(--colors-grey900); font-size: 15px; display: grid; - grid-template-columns: 25px auto 30px; + grid-template-columns: 25px auto; border-radius: 10px; - /* display: flex; */ - /* align-items: center; */ } .navLink a button { @@ -139,9 +92,7 @@ .navLink a.active, .navLink :global(.active) { - /* font-weight: 500; */ background: var(--colors-teal050); - /* box-shadow: inset 6px 0px 0px 0px var(--colors-grey500); */ } .navLink.active:hover { background: var(--colors-teal050); diff --git a/src/components/create/CreateModal.tsx b/src/components/create/CreateModal.tsx deleted file mode 100644 index dc12481..0000000 --- a/src/components/create/CreateModal.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { - Modal, - ModalTitle, - ModalContent, - ModalActions, - Button, - ButtonStrip, - InputField, -} from '@dhis2/ui' -import PropTypes from 'prop-types' -import React from 'react' -import i18n from '../../locales' - -const CreateModal = ({ - addNewKey, - addNewNamespace, - createFn, - values, - setValues, - closeModal, -}) => { - return ( - - - {addNewKey && i18n.t('Add New Key')} - {addNewNamespace && i18n.t('Add New Namespace')} - - - {addNewNamespace && ( - { - setValues({ - ...values, - ['namespace']: value, - }) - }} - /> - )} - { - setValues({ - ...values, - ['key']: value, - }) - }} - /> - - - - - - - - - ) -} - -CreateModal.propTypes = { - addNewKey: PropTypes.bool, - addNewNamespace: PropTypes.bool, - closeModal: PropTypes.func, - createFn: PropTypes.func, - setValues: PropTypes.func, - values: PropTypes.object, -} - -export default CreateModal diff --git a/src/components/create/Toolbar.tsx b/src/components/create/Toolbar.tsx deleted file mode 100644 index 172b5f6..0000000 --- a/src/components/create/Toolbar.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { useDataEngine } from '@dhis2/app-service-data' -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 { showSuccess, showError } = useCustomAlert() - - const handleAddNamespaceOrKey = async (values: { - namespace?: string - key?: unknown - }) => { - let resource = '' - if (addNewNamespace) { - resource = `${store}/${values?.namespace}/${values?.key}` - } else if (addNewKey) { - resource = `${store}/${namespace}/${values?.key}` - } - - await engine.mutate( - { - type: 'create', - resource, - data: () => ({}), - }, - { - onComplete: () => { - let url = '' - if (addNewNamespace) { - url = `${store}/edit/${values?.namespace}/${values?.key}` - } 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() - } - - const closeModal = () => { - setAddNewKey(false) - setAddNewNamespace(false) - } - - return ( - <> - {store && ( - <> -
- - {namespace && ( - - )} -
- - - )} - {(addNewKey || addNewNamespace) && ( - - )} - - ) -} - -export default Toolbar diff --git a/src/components/delete/DeleteButton.tsx b/src/components/delete/DeleteButton.tsx deleted file mode 100644 index a2fe5e6..0000000 --- a/src/components/delete/DeleteButton.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Button } from '@dhis2-ui/button' -import PropTypes from 'prop-types' -import React from 'react' -import i18n from '../../locales' - -export default function DeleteButton({ openModal }) { - return ( - - ) -} - -DeleteButton.propTypes = { - openModal: PropTypes.func, -} diff --git a/src/components/delete/DeleteModal.tsx b/src/components/delete/DeleteModal.tsx deleted file mode 100644 index 14ef64c..0000000 --- a/src/components/delete/DeleteModal.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { - Modal, - ModalContent, - ModalActions, - Button, - ButtonStrip, -} from '@dhis2/ui' -import PropTypes from 'prop-types' -import React from 'react' -import i18n from '../../locales' - -const DeleteModal = ({ children, deleteFn, closeModal }) => { - return ( - - {children} - - - - - - - - ) -} - -DeleteModal.propTypes = { - children: PropTypes.node, - closeModal: PropTypes.func, - deleteFn: PropTypes.func, -} - -export default DeleteModal diff --git a/src/components/edit/Edit.tsx b/src/components/edit/Edit.tsx deleted file mode 100644 index 3591c9c..0000000 --- a/src/components/edit/Edit.tsx +++ /dev/null @@ -1,120 +0,0 @@ -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 Error from '../Error' -import Editor from './Editor' - -const modifyKeyMutation = ({ store }) => ({ - type: 'update' as const, - resource: `${store}`, - id: ({ key, namespace }: { key: string; namespace: string }) => - `${namespace}/${key}`, - data: ({ value }) => JSON.parse(value), -}) - -const keyValuesQuery = ({ store }: { store: string }) => ({ - results: { - resource: `${store}`, - id: ({ key, namespace }: { key: string; namespace: string }) => - `${namespace}/${key}`, - }, -}) - -const Edit = () => { - const { key, namespace, store } = useParams() - const { showSuccess, showError } = useCustomAlert() - - const { - data, - loading: queryLoading, - error, - refetch, - } = useDataQuery(keyValuesQuery({ store }), { - variables: { - key, - namespace, - }, - }) - - const [value, setValue] = useState( - JSON.stringify(data?.results, null, 4) || '' - ) - - const [updateKey, { loading }] = useDataMutation( - // @ts-expect-error("") - modifyKeyMutation({ store }), - { - onComplete: () => { - const message = i18n.t('Key successfully updated') - showSuccess(message) - }, - onError: () => { - const message = i18n.t('There was an error updating the key') - showError(message) - }, - } - ) - - const handleEditorChange = (value) => { - setValue(value) - } - - useEffect(() => { - setValue(JSON.stringify(data?.results, null, 4)) - }, [data]) - - useEffect(() => { - refetch({ key, namespace }) - }, [key, namespace, store, refetch]) - - if (error) { - // throw new Response(error.message, { - // status: error.details.httpStatusCode, - // statusText: error.details.httpStatus, - // }) - return - } - - const loadingText = i18n.t('Loading') - - return ( -
- -
- -
-
- ) -} - -export default Edit diff --git a/src/components/edit/Editor.tsx b/src/components/edit/Editor.tsx deleted file mode 100644 index fa6ea01..0000000 --- a/src/components/edit/Editor.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { json } from '@codemirror/lang-json' -import CodeMirror from '@uiw/react-codemirror' -import PropTypes from 'prop-types' -import React from 'react' - -const Editor = ({ value, handleChange }) => { - return ( - - ) -} - -Editor.propTypes = { - handleChange: PropTypes.func, - value: PropTypes.string, -} - -export default Editor diff --git a/src/components/panel/empty/EmptyArea.tsx b/src/components/empty/EmptyArea.tsx similarity index 90% rename from src/components/panel/empty/EmptyArea.tsx rename to src/components/empty/EmptyArea.tsx index ad6c706..d00f736 100644 --- a/src/components/panel/empty/EmptyArea.tsx +++ b/src/components/empty/EmptyArea.tsx @@ -1,9 +1,9 @@ import { NoticeBox } from '@dhis2/ui' import React from 'react' import { useParams } from 'react-router-dom' -import i18n from '../../../locales' +import i18n from '../../locales' import classes from '../Panel.module.css' -import { PanelHeader } from '../PanelHeader' +import { PanelHeader } from '../sidepanel/PanelHeader' import EmptyPanelEditor from './EmptyEditor' const EmptyArea = () => { diff --git a/src/components/panel/empty/EmptyEditor.tsx b/src/components/empty/EmptyEditor.tsx similarity index 77% rename from src/components/panel/empty/EmptyEditor.tsx rename to src/components/empty/EmptyEditor.tsx index b3774ae..a189b36 100644 --- a/src/components/panel/empty/EmptyEditor.tsx +++ b/src/components/empty/EmptyEditor.tsx @@ -1,7 +1,7 @@ import React from 'react' -import i18n from '../../../locales' -import PanelEditor from '../PanelEditor' -import { PanelHeader } from '../PanelHeader' +import i18n from '../../locales' +import PanelEditor from '../sidepanel/PanelEditor' +import { PanelHeader } from '../sidepanel/PanelHeader' export default function EmptyEditor({ placeholder }: { placeholder?: string }) { const defaultMessage = i18n.t( diff --git a/src/components/panel/error/ErrorComponent.tsx b/src/components/error/ErrorComponent.tsx similarity index 95% rename from src/components/panel/error/ErrorComponent.tsx rename to src/components/error/ErrorComponent.tsx index babec59..4c5d42d 100644 --- a/src/components/panel/error/ErrorComponent.tsx +++ b/src/components/error/ErrorComponent.tsx @@ -1,9 +1,9 @@ import { NoticeBox } from '@dhis2/ui' import React from 'react' import { Link, isRouteErrorResponse, useRouteError } from 'react-router-dom' -import i18n from '../../../locales' +import i18n from '../../locales' import classes from '../Panel.module.css' -import { PanelHeader } from '../PanelHeader' +import { PanelHeader } from '../sidepanel/PanelHeader' interface Error { status?: number diff --git a/src/components/panel/error/ErrorPanel.tsx b/src/components/error/ErrorPanel.tsx similarity index 89% rename from src/components/panel/error/ErrorPanel.tsx rename to src/components/error/ErrorPanel.tsx index 6d2ee20..7e29525 100644 --- a/src/components/panel/error/ErrorPanel.tsx +++ b/src/components/error/ErrorPanel.tsx @@ -1,5 +1,5 @@ import React from 'react' -import i18n from '../../../locales' +import i18n from '../../locales' import EmptyPanelEditor from '../empty/EmptyEditor' import ErrorComponent from './ErrorComponent' diff --git a/src/components/keys/Keys.tsx b/src/components/keys/Keys.tsx deleted file mode 100644 index 1eaa45c..0000000 --- a/src/components/keys/Keys.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import KeysTable from './KeysTable' - -export default function Keys() { - return ( -
- -
- ) -} diff --git a/src/components/keys/keysTable.tsx b/src/components/keys/keysTable.tsx deleted file mode 100644 index f0d049b..0000000 --- a/src/components/keys/keysTable.tsx +++ /dev/null @@ -1,169 +0,0 @@ -import { useDataEngine, useDataQuery } from '@dhis2/app-runtime' -import { - DataTable, - DataTableCell, - DataTableColumnHeader, - DataTableRow, - TableBody, - TableHead, -} from '@dhis2/ui' -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' -import Error from '../Error' -import CenteredLoader from '../Loader' - -interface QueryResults { - results: [] -} - -const fetchNamespaceQuery = ({ store }) => ({ - results: { - resource: `${store}`, - id: ({ id }) => id, - }, -}) - -const KeysTable = () => { - const { store, namespace } = useParams() - const navigate = useNavigate() - const engine = useDataEngine() - const { showError, showSuccess } = useCustomAlert() - - const { data, loading, refetch, error } = useDataQuery( - fetchNamespaceQuery({ store }), - { - variables: { - id: namespace, - }, - } - ) - - const [deleteNamespace, setDeleteNamespace] = useState(false) - const [selectedKey, setSelectedKey] = useState('') - const [openModal, setOpenModal] = useState(false) - - useEffect(() => { - refetch({ id: namespace }) - }, [namespace, refetch]) - - const handleDeleteAction = async (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) { - navigate(`/${store}`) - } else { - refetch({ id: namespace }) - } - } - - if (loading) { - return - } - - if (error) { - // throw new Response(error.message, { - // status: error.details.httpStatusCode, - // statusText: error.details.httpStatus, - // }) - return - } - - return ( -
- {data && ( - - - - Keys - - Actions - - - - - {data?.results?.length && ( - <> - {data.results.map((key, index) => { - const handleClick = () => { - const url = `/${store}/edit/${namespace}/${key}` - navigate(url) - } - return ( - - - {key} - - - { - setOpenModal(true) - setDeleteNamespace( - data?.results - ?.length < 2 - ) - setSelectedKey(key) - }} - /> - - - ) - })} - - )} - - - )} - {openModal && ( - handleDeleteAction(selectedKey)} - closeModal={() => setOpenModal(false)} - > -

- {i18n.t( - `Are you sure you want to delete '${selectedKey}' in ${namespace}?` - )} -

- {deleteNamespace && ( -

- {i18n.t( - `This will also delete the namespace '${namespace}'` - )} -

- )} -
- )} -
- ) -} - -export default KeysTable diff --git a/src/components/panel/modals/CreateModal.tsx b/src/components/modals/CreateModal.tsx similarity index 86% rename from src/components/panel/modals/CreateModal.tsx rename to src/components/modals/CreateModal.tsx index f908fb2..acff421 100644 --- a/src/components/panel/modals/CreateModal.tsx +++ b/src/components/modals/CreateModal.tsx @@ -8,16 +8,16 @@ import { InputField, } from '@dhis2/ui' import React from 'react' -import i18n from '../../../locales' +import i18n from '../../locales' import { CreateFieldValues } from '../sidepanel/SidePanel' type CreateModalProps = { - createFn: (values) => void, - values: CreateFieldValues, - setValues: (values) => void, - closeModal: () => void, - title: string, - type: string, + createFn: (values) => void + values: CreateFieldValues + setValues: (values) => void + closeModal: () => void + title: string + type: string buttonLabel: string } @@ -28,13 +28,11 @@ const CreateModal = ({ closeModal, title, type, - buttonLabel + buttonLabel, }: CreateModalProps) => { return ( - - {title} - + {title} {type === 'namespace' && ( { - 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() - navigate(`${store}`) - } - - useEffect(() => { - refetchList() - }, [store, namespace, key, refetchList]) - - return ( -
- {error && {i18n.t('Error fetching namespaces')}} - {loading && } - {data && ( - <> -

{i18n.t('Namespaces')}

-
    - {data.results.map((namespace: string, index) => { - return ( - { - setOpenModal(true) - setSelectedNamespace(namespace) - }} - /> - ) - })} -
- - )} - {openModal && ( - handleDeleteAction(selectedNamespace)} - closeModal={() => setOpenModal(false)} - > -

- {i18n.t( - `Are you sure you want to delete '${namespace}'?` - )} -

-

- {i18n.t( - `This will delete all the keys in this namespace` - )} -

-
- )} -
- ) -} - -LinksList.propTypes = { - data: PropTypes.object, - error: PropTypes.any, - loading: PropTypes.any, - refetchList: PropTypes.func, -} - -export default LinksList diff --git a/src/components/panel/EditPanel.tsx b/src/components/panels/EditPanel.tsx similarity index 86% rename from src/components/panel/EditPanel.tsx rename to src/components/panels/EditPanel.tsx index f2a30c7..741ee0d 100644 --- a/src/components/panel/EditPanel.tsx +++ b/src/components/panels/EditPanel.tsx @@ -4,9 +4,9 @@ import React, { useEffect, useState } from 'react' import { useParams } from 'react-router-dom' import useCustomAlert from '../../hooks/useCustomAlert' import i18n from '../../locales' -import Error from '../Error' -import PanelEditor from './PanelEditor' -import { PanelHeader } from './PanelHeader' +import ErrorComponent from '../error/ErrorComponent' +import PanelEditor from '../sidepanel/PanelEditor' +import { PanelHeader } from '../sidepanel/PanelHeader' const modifyKeyMutation = ({ store }) => ({ type: 'update' as const, @@ -24,9 +24,10 @@ const keyValuesQuery = ({ store }: { store: string }) => ({ }, }) -const PanelEdit = () => { +const EditPanel = () => { const { key, namespace, store } = useParams() const { showSuccess, showError } = useCustomAlert() + // const [ updateError, setUpdateError ] = useState(null) const { data, @@ -44,7 +45,7 @@ const PanelEdit = () => { 'Select a namespace and key to edit its values' ) - const [updateKey, { loading }] = useDataMutation( + const [updateKey, { loading: mutationLoading }] = useDataMutation( // @ts-expect-error("") modifyKeyMutation({ store }), { @@ -61,9 +62,11 @@ const PanelEdit = () => { const handleEditorChange = (value) => { setValue(value) + // setUpdateError(null) } const handleUpdate = async () => { + // setUpdateError(null) try { await updateKey({ key, @@ -71,6 +74,7 @@ const PanelEdit = () => { value, }) } catch (error) { + // setUpdateError(error.message) const message = i18n.t('There was an error updating the key') showError(message) } @@ -85,7 +89,7 @@ const PanelEdit = () => { }, [key, namespace, store, refetch]) if (error) { - return + return } const loadingText = `${i18n.t('Loading')}...` @@ -118,7 +122,7 @@ const PanelEdit = () => { title="Save" primary small - loading={loading} + loading={mutationLoading} > {i18n.t('Save changes')} @@ -132,4 +136,4 @@ const PanelEdit = () => { ) } -export default PanelEdit +export default EditPanel diff --git a/src/components/panel/KeysPanel.tsx b/src/components/panels/KeysPanel.tsx similarity index 93% rename from src/components/panel/KeysPanel.tsx rename to src/components/panels/KeysPanel.tsx index 01387a2..726e5f9 100644 --- a/src/components/panel/KeysPanel.tsx +++ b/src/components/panels/KeysPanel.tsx @@ -1,8 +1,8 @@ -import { useDataQuery } from '@dhis2/app-service-data' +import { useDataQuery } from '@dhis2/app-runtime' import React, { useEffect } from 'react' import { useParams } from 'react-router-dom' -import { PanelHeader } from './PanelHeader' -import SidebarPanel from './sidepanel/SidePanel' +import { PanelHeader } from '../sidepanel/PanelHeader' +import SidePanel from '../sidepanel/SidePanel' interface QueryResults { results: [] @@ -44,7 +44,7 @@ const KeysPanel = () => { }, [store]) return ( - { }, [store]) return ( - { }, [store]) return ( - { }, [store]) return ( - { - return ( -
- - - - -
- ) -} - -DataStoreSelect.propTypes = { - handleChange: PropTypes.func, - option: PropTypes.string, -} - -export default DataStoreSelect diff --git a/src/components/sidebar/SidebarNavLink.tsx b/src/components/sidebar/SidebarNavLink.tsx deleted file mode 100644 index 10e2a83..0000000 --- a/src/components/sidebar/SidebarNavLink.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Button } from '@dhis2/ui' -import { IconDelete16 } from '@dhis2/ui-icons' -import PropTypes from 'prop-types' -import React from 'react' -import { NavLink } from 'react-router-dom' -import classes from '../../App.module.css' - -const SidebarNavLink = ({ to, label, handleDeleteModal }) => { - return ( -
  • - - isActive ? 'active' : isPending ? 'pending' : '' - } - > - {label} - -
  • - ) -} - -SidebarNavLink.propTypes = { - handleDeleteModal: PropTypes.func, - label: PropTypes.string, - to: PropTypes.string, -} - -export default SidebarNavLink diff --git a/src/components/sidebar/searchField.tsx b/src/components/sidebar/searchField.tsx deleted file mode 100644 index c2a0cf4..0000000 --- a/src/components/sidebar/searchField.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { InputField } from '@dhis2/ui' -import React from 'react' -import classes from '../../App.module.css' -import i18n from '../../locales' - -const SearchField = () => { - return ( -
    - -
    - ) -} - -export default SearchField diff --git a/src/components/sidebar/sidebar.tsx b/src/components/sidebar/sidebar.tsx deleted file mode 100644 index 9487089..0000000 --- a/src/components/sidebar/sidebar.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { useDataQuery } from '@dhis2/app-service-data' -import { Card, Divider } from '@dhis2/ui' -import React, { useEffect, useState } from 'react' -import { useNavigate, useParams } from 'react-router-dom' -import classes from '../../App.module.css' -import LinksList from '../namespaces/LinksList' -import DataStoreSelect from './DataStoreSelect' -// import SearchField from './SearchField' - -interface QueryResults { - results: [] -} - -const userDataStoreQuery = { - results: { - resource: 'userDataStore', - }, -} - -const dataStoreQuery = { - results: { - resource: 'dataStore', - }, -} - -const Sidebar = () => { - const navigate = useNavigate() - const { store } = useParams() - const [option, setOption] = useState(store || '') - - const { - error: dataStoreQueryError, - loading: dataStoreQueryLoading, - data: dataStoreQueryData, - refetch: refetchDataStore, - } = useDataQuery(dataStoreQuery) - - const { - error: userDataStoreQueryError, - loading: userDataStoreQueryLoading, - data: userDataStoreQueryData, - refetch: refetchUserDataStore, - } = useDataQuery(userDataStoreQuery) - - useEffect(() => { - const storeOptions = ['dataStore', 'userDataStore'] - if (!storeOptions.includes(store)) { - navigate('/dataStore') - } else { - setOption(store) - } - }, [store, navigate]) - - const handleDataStoreSelect = ({ selected }) => { - setOption(selected) - navigate(`/${selected}`) - } - return ( - -
    - -
    - - {store && ( - <> - {/* */} - {store === 'userDataStore' && ( - - )} - {store === 'dataStore' && ( - - )} - - )} -
    - ) -} - -export default Sidebar diff --git a/src/components/panel/sidepanel/CreateButton.tsx b/src/components/sidepanel/CreateButton.tsx similarity index 68% rename from src/components/panel/sidepanel/CreateButton.tsx rename to src/components/sidepanel/CreateButton.tsx index 67cf2e9..071bfd3 100644 --- a/src/components/panel/sidepanel/CreateButton.tsx +++ b/src/components/sidepanel/CreateButton.tsx @@ -1,16 +1,21 @@ import { Button } from '@dhis2/ui' import { IconAdd16 } from '@dhis2/ui-icons' import React from 'react' -import i18n from '../../../locales' +import i18n from '../../locales' import classes from '../Panel.module.css' -const CreateButton = ({ label, handleClick }) => { +type CreateButtonProps = { + label: string + handleClick: () => void +} + +const CreateButton = ({ label, handleClick }: CreateButtonProps) => { return (