From 55b84b30b0ad8cffdc9318f390fca878a48a0ec3 Mon Sep 17 00:00:00 2001 From: Milagros Date: Wed, 12 Jul 2023 00:45:56 +0200 Subject: [PATCH 1/5] feat: create workflow context --- src/workflow-context/WorkflowContext.js | 8 +++ src/workflow-context/WorkflowProvider.js | 69 ++++++++++++++++++++++ src/workflow-context/index.js | 3 + src/workflow-context/useWorkflowContext.js | 4 ++ 4 files changed, 84 insertions(+) create mode 100644 src/workflow-context/WorkflowContext.js create mode 100644 src/workflow-context/WorkflowProvider.js create mode 100644 src/workflow-context/index.js create mode 100644 src/workflow-context/useWorkflowContext.js diff --git a/src/workflow-context/WorkflowContext.js b/src/workflow-context/WorkflowContext.js new file mode 100644 index 00000000..dfce8bbd --- /dev/null +++ b/src/workflow-context/WorkflowContext.js @@ -0,0 +1,8 @@ +import { createContext } from 'react' + +const WorkflowContext = createContext({ + programs: [], + dataSets: [], +}) + +export { WorkflowContext } diff --git a/src/workflow-context/WorkflowProvider.js b/src/workflow-context/WorkflowProvider.js new file mode 100644 index 00000000..6bf50c6e --- /dev/null +++ b/src/workflow-context/WorkflowProvider.js @@ -0,0 +1,69 @@ +import { useAlert, useDataQuery } from '@dhis2/app-runtime' +import i18n from '@dhis2/d2-i18n' +import { CircularLoader, ComponentCover } from '@dhis2/ui' +import PropTypes from 'prop-types' +import React from 'react' +import { WorkflowContext } from './WorkflowContext' + +const query = { + programs: { + resource: 'programs', + params: { + fields: [ + 'id', + 'name', + 'programType', + 'categoryCombo[id,name]', + 'access', + ], + paging: 'false', + }, + }, + dataSets: { + resource: 'dataSets', + params: { + fields: [ + 'id', + 'name', + 'periodType', + 'categoryCombo[id,name]', + 'access', + ], + paging: 'false', + }, + }, +} + +const WorkflowProvider = ({ children }) => { + const { fetching, error, data, called } = useDataQuery(query) + const { show } = useAlert(i18n.t('Failed to get data'), { critical: true }) + + if (fetching || !called) { + return ( + + + + ) + } + + if (error) { + return <>{show()} + } + + const programs = data?.programs?.programs + const dataSets = data?.dataSets?.dataSets + + const providerValue = { programs, dataSets } + + return ( + + {children} + + ) +} + +WorkflowProvider.propTypes = { + children: PropTypes.node.isRequired, +} + +export { WorkflowProvider } diff --git a/src/workflow-context/index.js b/src/workflow-context/index.js new file mode 100644 index 00000000..42be2e9c --- /dev/null +++ b/src/workflow-context/index.js @@ -0,0 +1,3 @@ +export * from './useWorkflowContext' +export * from './WorkflowContext' +export * from './WorkflowProvider' diff --git a/src/workflow-context/useWorkflowContext.js b/src/workflow-context/useWorkflowContext.js new file mode 100644 index 00000000..c42d5c4e --- /dev/null +++ b/src/workflow-context/useWorkflowContext.js @@ -0,0 +1,4 @@ +import { useContext } from 'react' +import { WorkflowContext } from './WorkflowContext' + +export const useWorkflowContext = () => useContext(WorkflowContext) From c4c83deb5f2525895474935d188a6c98a8dedf88 Mon Sep 17 00:00:00 2001 From: Milagros Date: Thu, 13 Jul 2023 18:27:38 +0200 Subject: [PATCH 2/5] feat: add workflow --- src/pages/AppLayout.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pages/AppLayout.js b/src/pages/AppLayout.js index 9e0f10fd..ef088913 100644 --- a/src/pages/AppLayout.js +++ b/src/pages/AppLayout.js @@ -5,6 +5,7 @@ import { AuthWall } from '../auth' import Router from '../components/Router' import SideBar from '../components/sidebar/Sidebar' import styles from '../styles/Layout.module.css' +import { WorkflowProvider } from '../workflow-context' const AppLayout = () => ( @@ -15,7 +16,9 @@ const AppLayout = () => (
- + + +
From f1aa790f1c932ed2780450eed57de34db0bdf054 Mon Sep 17 00:00:00 2001 From: Milagros Date: Thu, 13 Jul 2023 18:43:14 +0200 Subject: [PATCH 3/5] feat: use program and dataset data from context --- .../analyticVisualization/SelectDataset.js | 5 ++--- .../analyticVisualization/SelectProgram.js | 5 ++--- src/pages/Analytics/Dataset/DatasetAnalyticList.js | 4 ++-- src/pages/Analytics/Program/ProgramAnalyticsList.js | 4 ++-- .../Appearance/Datasets/DatasetSpecificSettings.js | 12 ++++++++---- .../Datasets/DatasetSpecificSettings.js | 12 ++++++++---- .../Programs/ProgramSpecificSettings.js | 12 ++++++++---- src/utils/utils/filterListByAccess.js | 7 +++++++ src/utils/utils/index.js | 1 + 9 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 src/utils/utils/filterListByAccess.js diff --git a/src/components/analyticVisualization/SelectDataset.js b/src/components/analyticVisualization/SelectDataset.js index bd7a2e4a..a86beeed 100644 --- a/src/components/analyticVisualization/SelectDataset.js +++ b/src/components/analyticVisualization/SelectDataset.js @@ -1,11 +1,11 @@ import i18n from '@dhis2/d2-i18n' import PropTypes from 'prop-types' import React from 'react' -import { useReadDatasetQuery } from '../../pages/Analytics/Dataset/DatasetVisualizationQuery' +import { useWorkflowContext } from '../../workflow-context' import { SelectField } from '../field' export const SelectDataset = ({ settings, onChange }) => { - const { datasetList, loading } = useReadDatasetQuery() + const { dataSets: datasetList } = useWorkflowContext() const options = datasetList || [] const handleChange = (e) => { @@ -26,7 +26,6 @@ export const SelectDataset = ({ settings, onChange }) => { selected={settings.dataset || ''} onChange={handleChange} options={options} - loading={loading} /> ) } diff --git a/src/components/analyticVisualization/SelectProgram.js b/src/components/analyticVisualization/SelectProgram.js index 46633ae0..4104054d 100644 --- a/src/components/analyticVisualization/SelectProgram.js +++ b/src/components/analyticVisualization/SelectProgram.js @@ -1,11 +1,11 @@ import i18n from '@dhis2/d2-i18n' import PropTypes from 'prop-types' import React from 'react' -import { useReadProgramQuery } from '../../pages/Analytics/Program/ProgramVisualizationQueries' +import { useWorkflowContext } from '../../workflow-context' import { SelectField } from '../field' export const SelectProgram = ({ settings, onChange }) => { - const { programList, loading } = useReadProgramQuery() + const { programs: programList } = useWorkflowContext() const options = programList || [] const handleChange = (e) => { @@ -25,7 +25,6 @@ export const SelectProgram = ({ settings, onChange }) => { label={i18n.t('Program')} selected={settings.program || ''} onChange={handleChange} - loading={loading} options={options} /> ) diff --git a/src/pages/Analytics/Dataset/DatasetAnalyticList.js b/src/pages/Analytics/Dataset/DatasetAnalyticList.js index 47a192db..3393c3e4 100644 --- a/src/pages/Analytics/Dataset/DatasetAnalyticList.js +++ b/src/pages/Analytics/Dataset/DatasetAnalyticList.js @@ -6,9 +6,9 @@ import PropTypes from 'prop-types' import React, { useEffect, useState } from 'react' import { DatasetTable } from '../../../components/analyticVisualization' import { NoticeError } from '../../../components/noticeAlert' +import { useWorkflowContext } from '../../../workflow-context' import { getVisualizationIdList } from '../helper' import { useVisualizations } from '../VisualizationQuery' -import { useReadDatasetQuery } from './DatasetVisualizationQuery' import { prepareRows, rowsToDataStore } from './helper' import NewDatasetVisualization from './NewDatasetVisualization' @@ -22,7 +22,7 @@ const DatasetAnalyticList = ({ error, visualizations: visualizationAPI, } = useVisualizations(getVisualizationIdList(visualizations)) - const { datasetList } = useReadDatasetQuery() + const { dataSets: datasetList } = useWorkflowContext() const [rows, setRows] = useState() const [initialRows, setInitialRows] = useState() const [groups, setGroups] = useState() diff --git a/src/pages/Analytics/Program/ProgramAnalyticsList.js b/src/pages/Analytics/Program/ProgramAnalyticsList.js index 85e40950..0cc9dc8d 100644 --- a/src/pages/Analytics/Program/ProgramAnalyticsList.js +++ b/src/pages/Analytics/Program/ProgramAnalyticsList.js @@ -6,11 +6,11 @@ import PropTypes from 'prop-types' import React, { useEffect, useState } from 'react' import { ProgramTable } from '../../../components/analyticVisualization' import { NoticeError } from '../../../components/noticeAlert' +import { useWorkflowContext } from '../../../workflow-context' import { getVisualizationIdList } from '../helper' import { useVisualizations } from '../VisualizationQuery' import { prepareRows, rowsToDataStore } from './helper' import NewProgramVisualization from './NewProgramVisualization' -import { useReadProgramQuery } from './ProgramVisualizationQueries' const ProgramAnalyticsList = ({ visualizations, @@ -22,7 +22,7 @@ const ProgramAnalyticsList = ({ error, visualizations: visualizationAPI, } = useVisualizations(getVisualizationIdList(visualizations)) - const { programList } = useReadProgramQuery() + const { programs: programList } = useWorkflowContext() const [rows, setRows] = useState() const [initialRows, setInitialRows] = useState() const [groups, setGroups] = useState() diff --git a/src/pages/Appearance/Datasets/DatasetSpecificSettings.js b/src/pages/Appearance/Datasets/DatasetSpecificSettings.js index 2568f2d2..dac78e23 100644 --- a/src/pages/Appearance/Datasets/DatasetSpecificSettings.js +++ b/src/pages/Appearance/Datasets/DatasetSpecificSettings.js @@ -4,14 +4,18 @@ import keyBy from 'lodash/keyBy' import PropTypes from 'prop-types' import React, { useEffect, useState } from 'react' import PageSubtitle from '../../../components/page/PageSubtitle' -import { filterUnusedElements } from '../../../utils/utils' -import { useReadDataset } from './datasetQuery' +import { + filterListByDataWriteAccess, + filterUnusedElements, +} from '../../../utils/utils' +import { useWorkflowContext } from '../../../workflow-context' import { prepareSpecificSettingsList } from './helper' import NewDatasetSettings from './NewDatasetSettings' import SpecificTableAction from './SpecificTableAction' const DatasetSpecificSettings = ({ onChange, specificSettings, disabled }) => { - const { datasetList } = useReadDataset() + const { dataSets } = useWorkflowContext() + const datasetList = filterListByDataWriteAccess(dataSets) const [initialRows, setInitialRows] = useState() const [rows, setRows] = useState() const [listName, setListName] = useState() @@ -28,7 +32,7 @@ const DatasetSpecificSettings = ({ onChange, specificSettings, disabled }) => { setListName(filterUnusedElements(datasetList, updated)) setLoad(true) } - }, [specificSettings, datasetList]) + }, [specificSettings]) useEffect(() => { if (rows && !isEqual(rows, initialRows)) { diff --git a/src/pages/Synchronization/Datasets/DatasetSpecificSettings.js b/src/pages/Synchronization/Datasets/DatasetSpecificSettings.js index 40152a37..9bc7f087 100644 --- a/src/pages/Synchronization/Datasets/DatasetSpecificSettings.js +++ b/src/pages/Synchronization/Datasets/DatasetSpecificSettings.js @@ -4,8 +4,11 @@ import keyBy from 'lodash/keyBy' import PropTypes from 'prop-types' import React, { useEffect, useState } from 'react' import PageHeader from '../../../components/page/PageHeader' -import { filterUnusedElements } from '../../../utils/utils' -import { useReadDataset } from './datasetQueries' +import { + filterListByReadAccess, + filterUnusedElements, +} from '../../../utils/utils' +import { useWorkflowContext } from '../../../workflow-context' import { prepareSpecificSettingsList } from './helper' import NewDatasetSpecific from './NewDatasetSpecific' import SpecificTableAction from './SpecificTableAction' @@ -15,8 +18,9 @@ const DatasetSpecificSettings = ({ handleSpecificSettings, disabled, }) => { - const { datasetList } = useReadDataset() + const { dataSets } = useWorkflowContext() const [rows, setRows] = useState() + const datasetList = filterListByReadAccess(dataSets) const [initialRows, setInitialRows] = useState() const [listName, setListName] = useState() const [loadSpecific, setLoad] = useState(false) @@ -32,7 +36,7 @@ const DatasetSpecificSettings = ({ setListName(filterUnusedElements(datasetList, rowList)) setLoad(true) } - }, [specificSettings, datasetList]) + }, [specificSettings]) useEffect(() => { if (rows && initialRows && !isEqual(rows, initialRows)) { diff --git a/src/pages/Synchronization/Programs/ProgramSpecificSettings.js b/src/pages/Synchronization/Programs/ProgramSpecificSettings.js index ff3aeacc..b14d87b4 100644 --- a/src/pages/Synchronization/Programs/ProgramSpecificSettings.js +++ b/src/pages/Synchronization/Programs/ProgramSpecificSettings.js @@ -4,10 +4,13 @@ import keyBy from 'lodash/keyBy' import PropTypes from 'prop-types' import React, { useEffect, useState } from 'react' import PageHeader from '../../../components/page/PageHeader' -import { filterUnusedElements } from '../../../utils/utils' +import { + filterListByReadAccess, + filterUnusedElements, +} from '../../../utils/utils' +import { useWorkflowContext } from '../../../workflow-context' import { prepareSpecificSettingsList } from './helper' import NewProgramSpecific from './NewProgramSpecific' -import { useReadProgram } from './programQueries' import SpecificTableAction from './SpecificTableAction' const ProgramSpecificSettings = ({ @@ -15,7 +18,8 @@ const ProgramSpecificSettings = ({ changeSpecificSettings, disabled, }) => { - const { programList } = useReadProgram() + const { programs } = useWorkflowContext() + const programList = filterListByReadAccess(programs) const [rows, setRows] = useState() const [initialRows, setInitialRows] = useState() const [listName, setListName] = useState() @@ -32,7 +36,7 @@ const ProgramSpecificSettings = ({ setListName(filterUnusedElements(programList, rowList)) setLoad(true) } - }, [specificSettings, programList]) + }, [specificSettings]) useEffect(() => { if (rows && initialRows && !isEqual(rows, initialRows)) { diff --git a/src/utils/utils/filterListByAccess.js b/src/utils/utils/filterListByAccess.js new file mode 100644 index 00000000..689e8255 --- /dev/null +++ b/src/utils/utils/filterListByAccess.js @@ -0,0 +1,7 @@ +import filter from 'lodash/filter' + +export const filterListByReadAccess = (list) => + filter(list, { access: { read: true } }) + +export const filterListByDataWriteAccess = (list) => + filter(list, { access: { data: { write: true } } }) diff --git a/src/utils/utils/index.js b/src/utils/utils/index.js index 36c0a68e..7dd4a7e3 100644 --- a/src/utils/utils/index.js +++ b/src/utils/utils/index.js @@ -1,3 +1,4 @@ +export * from './filterListByAccess' export * from './filterUnusedElements' export * from './findProgramNameById' export * from './formatList' From a33dfb37e8117342507ea15f9beaeae41d3cadce Mon Sep 17 00:00:00 2001 From: Milagros Date: Thu, 13 Jul 2023 22:28:42 +0200 Subject: [PATCH 4/5] feat: delete unused program and dataset queries --- .../Dataset/DatasetVisualizationQuery.js | 25 ------------------ .../Program/ProgramVisualizationQueries.js | 21 --------------- src/pages/Appearance/Datasets/datasetQuery.js | 25 ------------------ .../Datasets/datasetQueries.js | 26 ------------------- .../Programs/programQueries.js | 25 ------------------ 5 files changed, 122 deletions(-) delete mode 100644 src/pages/Analytics/Dataset/DatasetVisualizationQuery.js delete mode 100644 src/pages/Analytics/Program/ProgramVisualizationQueries.js delete mode 100644 src/pages/Appearance/Datasets/datasetQuery.js delete mode 100644 src/pages/Synchronization/Datasets/datasetQueries.js delete mode 100644 src/pages/Synchronization/Programs/programQueries.js diff --git a/src/pages/Analytics/Dataset/DatasetVisualizationQuery.js b/src/pages/Analytics/Dataset/DatasetVisualizationQuery.js deleted file mode 100644 index 6c0cb8bc..00000000 --- a/src/pages/Analytics/Dataset/DatasetVisualizationQuery.js +++ /dev/null @@ -1,25 +0,0 @@ -import { useDataQuery } from '@dhis2/app-runtime' - -const datasetsQuery = { - dataset: { - resource: 'dataSets', - params: { - fields: ['id', 'name'], - paging: 'false', - }, - }, -} - -/** - * Query to get data set list - * */ - -export const useReadDatasetQuery = () => { - const { loading, data, error } = useDataQuery(datasetsQuery) - - return { - loading, - error, - datasetList: data && data.dataset.dataSets, - } -} diff --git a/src/pages/Analytics/Program/ProgramVisualizationQueries.js b/src/pages/Analytics/Program/ProgramVisualizationQueries.js deleted file mode 100644 index 389e877d..00000000 --- a/src/pages/Analytics/Program/ProgramVisualizationQueries.js +++ /dev/null @@ -1,21 +0,0 @@ -import { useDataQuery } from '@dhis2/app-runtime' - -const programsQuery = { - programs: { - resource: 'programs', - params: { - fields: ['id', 'name'], - paging: 'false', - }, - }, -} - -export const useReadProgramQuery = () => { - const { loading, data, error } = useDataQuery(programsQuery) - - return { - loading, - error, - programList: data && data.programs.programs, - } -} diff --git a/src/pages/Appearance/Datasets/datasetQuery.js b/src/pages/Appearance/Datasets/datasetQuery.js deleted file mode 100644 index 07c8aa7f..00000000 --- a/src/pages/Appearance/Datasets/datasetQuery.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Query to get the list of Programs the user has access - * */ -import { useDataQuery } from '@dhis2/app-runtime' - -const getDatasetsQuery = { - dataset: { - resource: 'dataSets', - params: { - fields: ['id', 'name', 'periodType', 'categoryCombo[id,name]'], - filter: 'access.data.write:eq:true', - paging: 'false', - }, - }, -} - -export const useReadDataset = () => { - const { loading, error, data } = useDataQuery(getDatasetsQuery) - - return { - loading, - error, - datasetList: data && data.dataset.dataSets, - } -} diff --git a/src/pages/Synchronization/Datasets/datasetQueries.js b/src/pages/Synchronization/Datasets/datasetQueries.js deleted file mode 100644 index a9717885..00000000 --- a/src/pages/Synchronization/Datasets/datasetQueries.js +++ /dev/null @@ -1,26 +0,0 @@ -import { useDataQuery } from '@dhis2/app-runtime' - -/** - * Query to get the list of Dataset the user has access - * */ - -export const getDatasetQuery = { - dataset: { - resource: 'dataSets', - params: { - fields: ['id', 'name', 'periodType'], - filter: 'access.read:eq:true', - paging: 'false', - }, - }, -} - -export const useReadDataset = () => { - const { loading, error, data } = useDataQuery(getDatasetQuery) - - return { - loading, - error, - datasetList: data && data.dataset.dataSets, - } -} diff --git a/src/pages/Synchronization/Programs/programQueries.js b/src/pages/Synchronization/Programs/programQueries.js deleted file mode 100644 index 62bb36fb..00000000 --- a/src/pages/Synchronization/Programs/programQueries.js +++ /dev/null @@ -1,25 +0,0 @@ -import { useDataQuery } from '@dhis2/app-runtime' -/** - * Query to get the list of Programs the user has access - * */ - -export const getProgramsQuery = { - programs: { - resource: 'programs', - params: { - fields: ['id', 'name', 'programType'], - filter: 'access.read:eq:true', - paging: 'false', - }, - }, -} - -export const useReadProgram = () => { - const { loading, error, data } = useDataQuery(getProgramsQuery) - - return { - loadProgram: loading, - errorProgram: error, - programList: data && data.programs.programs, - } -} From 475d3017553dfdec4c7e8965d3db0ca88249f5bd Mon Sep 17 00:00:00 2001 From: Milagros Date: Thu, 13 Jul 2023 22:33:38 +0200 Subject: [PATCH 5/5] feat: regenerate en.pot --- i18n/en.pot | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/i18n/en.pot b/i18n/en.pot index c4bf2007..22db0414 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: 2023-05-29T16:48:00.591Z\n" -"PO-Revision-Date: 2023-05-29T16:48:00.591Z\n" +"POT-Creation-Date: 2023-07-05T09:36:08.695Z\n" +"PO-Revision-Date: 2023-07-05T09:36:08.695Z\n" msgid "" "The initial configuration of the app has been completed and it is now ready " @@ -974,3 +974,6 @@ msgstr "Check the amount of data a user would sync to their device." msgid "User" msgstr "User" + +msgid "Failed to get data" +msgstr "Failed to get data"