Skip to content

Commit

Permalink
Merge pull request #329 from dhis2/schemas
Browse files Browse the repository at this point in the history
schemas: implement schemas
  • Loading branch information
Birkbjo authored Jul 4, 2023
2 parents be30d58 + 4026b8f commit 4999068
Show file tree
Hide file tree
Showing 39 changed files with 1,315 additions and 613 deletions.
68 changes: 40 additions & 28 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ 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-23T13:31:53.974Z\n"
"PO-Revision-Date: 2023-05-23T13:31:53.974Z\n"
"POT-Creation-Date: 2023-06-21T21:00:56.973Z\n"
"PO-Revision-Date: 2023-06-21T21:00:56.973Z\n"

msgid "schemas"
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 "Section is not implemented yet"
msgstr "Section is not implemented yet"
Expand Down Expand Up @@ -105,8 +111,8 @@ msgstr "Data set"
msgid "Data sets"
msgstr "Data sets"

msgid "Data set notification"
msgstr "Data set notification"
msgid "Data set notification template"
msgstr "Data set notification template"

msgid "Data set notification templates"
msgstr "Data set notification templates"
Expand Down Expand Up @@ -165,9 +171,6 @@ msgstr "Tracked entity type"
msgid "Tracked entity types"
msgstr "Tracked entity types"

msgid "Programs and Tracker"
msgstr "Programs and Tracker"

msgid "Program"
msgstr "Program"

Expand All @@ -180,11 +183,11 @@ msgstr "Program indicator"
msgid "Program indicators"
msgstr "Program indicators"

msgid "Program indicatorGroup"
msgstr "Program indicatorGroup"
msgid "Program indicator group"
msgstr "Program indicator group"

msgid "Program indicatorGroups"
msgstr "Program indicatorGroups"
msgid "Program indicator groups"
msgstr "Program indicator groups"

msgid "Program rule"
msgstr "Program rule"
Expand All @@ -210,12 +213,6 @@ msgstr "Relationship type"
msgid "Relationship types"
msgstr "Relationship types"

msgid "Validation"
msgstr "Validation"

msgid "Validations"
msgstr "Validations"

msgid "Validation rule"
msgstr "Validation rule"

Expand All @@ -228,15 +225,12 @@ msgstr "Validation rule group"
msgid "Validation rule groups"
msgstr "Validation rule groups"

msgid "Validation notification"
msgstr "Validation notification"
msgid "Validation notification template"
msgstr "Validation notification template"

msgid "Validation notification templates"
msgstr "Validation notification templates"

msgid "Other"
msgstr "Other"

msgid "Constant"
msgstr "Constant"

Expand Down Expand Up @@ -285,18 +279,36 @@ msgstr "Data approval workflow"
msgid "Data approval workflows"
msgstr "Data approval workflows"

msgid "Locale"
msgstr "Locale"

msgid "Locales"
msgstr "Locales"

msgid "SQL view"
msgstr "SQL view"

msgid "SQL views"
msgstr "SQL views"

msgid "Programs and Tracker"
msgstr "Programs and Tracker"

msgid "Programs and Trackers"
msgstr "Programs and Trackers"

msgid "Validation"
msgstr "Validation"

msgid "Validations"
msgstr "Validations"

msgid "Other"
msgstr "Other"

msgid "Others"
msgstr "Others"

msgid "Locale"
msgstr "Locale"

msgid "Locales"
msgstr "Locales"

msgid "Metadata management"
msgstr "Metadata management"

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"typescript": "^5.0.4"
},
"dependencies": {
"@dhis2/app-runtime": "^3.9.3",
"react-router-dom": "^6.11.2"
"@dhis2/app-runtime": "^3.9.4",
"react-router-dom": "^6.11.2",
"zustand": "^4.3.8"
}
}
16 changes: 5 additions & 11 deletions src/app/LoadApp.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { useDataQuery } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import React, { PropsWithChildren } from 'react'
import { Loader } from '../components/loading/Loader'

const query = {
schemas: {
resource: 'schemas',
fields: 'authorities, displayName, name, plural, singular, translatable, properties',
},
}
import { Loader } from '../components'
import { useLoadApp } from '../lib'

export const LoadApp = ({ children }: PropsWithChildren) => {
const queryResponse = useDataQuery(query)
const queryResponse = useLoadApp()
return (
<Loader queryResponse={queryResponse} label="schemas">
<Loader queryResponse={queryResponse} label={i18n.t('schemas')}>
{children}
</Loader>
)
Expand Down
17 changes: 17 additions & 0 deletions src/app/routes/CheckAuthorityForSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import i18n from '@dhis2/d2-i18n'
import React from 'react'
import { Outlet } from 'react-router-dom'
import { useSectionHandle } from '../../lib'
import { useIsSectionAuthorizedPredicate } from '../../lib/sections'

export const CheckAuthorityForSection = () => {
const section = useSectionHandle()
const isSectionAllowed = useIsSectionAuthorizedPredicate()

if (section && !isSectionAllowed(section)) {
throw new Error(
i18n.t('You do not have the authority to view this page.')
)
}
return <Outlet />
}
6 changes: 5 additions & 1 deletion src/app/routes/LegacyAppRedirect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import i18n from '@dhis2/d2-i18n'
import { NoticeBox, Button } from '@dhis2/ui'
import React from 'react'
import { useParams, Params } from 'react-router-dom'
import { Section, SECTIONS_MAP } from '../../constants'
import { isOverviewSection, Section, SECTIONS_MAP } from '../../constants'

const legacyPath = '/dhis-web-maintenance/index.html#/'

Expand All @@ -28,6 +28,10 @@ const getLegacySectionPath = (
id = isNew ? 'add' : params?.id || ''
}

if (isOverviewSection(section)) {
const legacySection = legacySectionMap[section.name] ?? section.name
return `list/${legacySection}Section`
}
const legacySection =
legacySectionMap[section.parentSectionKey] ?? section.parentSectionKey

Expand Down
86 changes: 52 additions & 34 deletions src/app/routes/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ import {
RouteObject,
useParams,
} from 'react-router-dom'
import { SECTIONS_MAP, Section } from '../../constants'
import { isModuleNotFoundError } from '../../lib'
import { isValidUid } from '../../models'
import {
SECTIONS_MAP,
SCHEMA_SECTIONS,
Section,
SchemaSection,
OVERVIEW_SECTIONS,
} from '../../constants'
import { isValidUid, isModuleNotFoundError } from '../../lib'
import { OverviewSection } from '../../types'
import { Layout } from '../layout'
import { CheckAuthorityForSection } from './CheckAuthorityForSection'
import { DefaultErrorRoute } from './DefaultErrorRoute'
import { LegacyAppRedirect } from './LegacyAppRedirect'
import { getSectionPath, routePaths } from './routePaths'
Expand All @@ -23,12 +30,21 @@ import { getSectionPath, routePaths } from './routePaths'
// Overviews are small, and the AllOverview would load all the other overviews anyway,
// so it's propbably better to load them all at once
function createOverviewLazyRouteFunction(
componentName: keyof typeof import('../../pages/overview/')
componentName: string, //keyof typeof import('../../pages/overview/'),
section?: OverviewSection
): LazyRouteFunction<RouteObject> {
return async () => {
const routeComponent = await import(`../../pages/overview/`)
const name = componentName as keyof typeof routeComponent
const Component = routeComponent[name]
if (!Component && section) {
return {
element: <LegacyAppRedirect section={section} />,
}
}

return {
Component: routeComponent[componentName],
Component: routeComponent[name],
}
}
}
Expand Down Expand Up @@ -69,34 +85,31 @@ const VerifyModelId = () => {
return <Outlet />
}

const sectionsNoEditRoute = new Set<Section>([SECTIONS_MAP.locale])
const sectionsNoNewRoute = new Set<Section>([SECTIONS_MAP.categoryOptionCombo])
const sectionsNoNewRoute = new Set<SchemaSection>([
SECTIONS_MAP.categoryOptionCombo,
])

const sectionRoutes = Object.values(SECTIONS_MAP).map((section) => (
const schemaSectionRoutes = Object.values(SCHEMA_SECTIONS).map((section) => (
<Route
key={section.namePlural}
path={getSectionPath(section)}
handle={{ section }}
>
<Route index lazy={createSectionLazyRouteFunction(section, 'List')} />
{!sectionsNoNewRoute.has(section) && (
<Route
path={routePaths.sectionNew}
lazy={createSectionLazyRouteFunction(section, 'New')}
handle={{
hideSidebar: true,
}}
/>
)}

{!sectionsNoEditRoute.has(section) && (
<Route handle={{ hideSidebar: true }}>
{!sectionsNoNewRoute.has(section) && (
<Route
path={routePaths.sectionNew}
lazy={createSectionLazyRouteFunction(section, 'New')}
/>
)}
<Route path=":id" element={<VerifyModelId />}>
<Route
index
lazy={createSectionLazyRouteFunction(section, 'Edit')}
></Route>
</Route>
)}
</Route>
</Route>
))

Expand All @@ -106,21 +119,26 @@ const routes = createRoutesFromElements(
path="/"
element={<Navigate to={routePaths.overviewRoot} replace />}
/>
<Route path={routePaths.overviewRoot}>
<Route
index
lazy={createOverviewLazyRouteFunction('AllOverview')}
/>
<Route
path={getSectionPath(SECTIONS_MAP.dataElement)}
lazy={createOverviewLazyRouteFunction('DataElements')}
/>
<Route
path={getSectionPath(SECTIONS_MAP.category)}
lazy={createOverviewLazyRouteFunction('Categories')}
/>
<Route element={<CheckAuthorityForSection />}>
<Route path={routePaths.overviewRoot}>
<Route
index
lazy={createOverviewLazyRouteFunction('AllOverview')}
/>
{Object.values(OVERVIEW_SECTIONS).map((section) => (
<Route
key={section.name}
path={getSectionPath(section)}
lazy={createOverviewLazyRouteFunction(
section.componentName,
section
)}
handle={{ section }}
/>
))}
</Route>
{schemaSectionRoutes}
</Route>
{sectionRoutes}
</Route>
)

Expand Down
4 changes: 2 additions & 2 deletions src/app/routes/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { useMatches } from 'react-router-dom'
import type { Section } from '../../constants/sections'
import type { SchemaSection } from '../../constants/sections'

// utility type to type a match with a handle-property returned from useMatches
// since handle is unknown, we need to cast it to the correct type
Expand All @@ -10,7 +10,7 @@ type MatchWithHandle<THandle> = ReturnType<typeof useMatches>[number] & {
// common type for possible handle-properties used in Route
export type RouteHandle = {
hideSidebar?: boolean
section?: Section
section?: SchemaSection
}

export type MatchRouteHandle = MatchWithHandle<RouteHandle>
Loading

0 comments on commit 4999068

Please sign in to comment.