diff --git a/i18n/en.pot b/i18n/en.pot index b09280b2..09ac97a0 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-08-07T13:59:56.557Z\n" -"PO-Revision-Date: 2025-08-07T13:59:56.557Z\n" +"POT-Creation-Date: 2025-09-18T05:58:00.550Z\n" +"PO-Revision-Date: 2025-09-18T05:58:00.550Z\n" msgid "Events - Create/update" msgstr "" @@ -740,6 +740,12 @@ msgstr "" msgid "JSON Response" msgstr "" +msgid "Select organisation unit to populate data" +msgstr "" + +msgid "Select available organisation units to include in the template" +msgstr "" + msgid "Template" msgstr "" @@ -749,6 +755,9 @@ msgstr "" msgid "Select template to export..." msgstr "" +msgid "" +msgstr "" + msgid "Start period" msgstr "" @@ -758,49 +767,48 @@ msgstr "" msgid "Organisation units" msgstr "" -msgid "Select organisation unit to populate data" -msgstr "" - -msgid "Select available organisation units to include in the template" +msgid "User does not have any capture organisations units" msgstr "" -msgid "User does not have any capture organisations units" +msgid "Populate" msgstr "" -msgid "Advanced template properties" +msgid "Populate template with data" msgstr "" -msgid "Language" +msgid "Also filter TEI and relationships by their enrollment date" msgstr "" -msgid "Split data entry tabs by section" +msgid "TEI and relationships enrollment by organisation unit type" msgstr "" -msgid "Theme" +msgid "Current user organisation units (data capture)" msgstr "" -msgid "" +msgid "Selected organisation units with their descendants" msgstr "" -msgid "Populate template with data" +msgid "Only selected organisation units" msgstr "" -msgid "Also filter TEI and relationships by their enrollment date" +msgid "Include relationships" msgstr "" -msgid "TEI and relationships enrollment by organisation unit type" +msgid "" +"Creates a tab for each available TEI relationship type, showing their " +"contents. Click here to learn more about the relationship model." msgstr "" -msgid "Current user organisation units (data capture)" +msgid "Advanced template properties" msgstr "" -msgid "Selected organisation units with their descendants" +msgid "Language" msgstr "" -msgid "Only selected organisation units" +msgid "Theme" msgstr "" -msgid "Include relationships" +msgid "Split data entry tabs by section" msgstr "" msgid "Use metadata codes (organisation units, data elements and options)" diff --git a/i18n/es.po b/i18n/es.po index d929bf27..ab30a0d1 100644 --- a/i18n/es.po +++ b/i18n/es.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Bulk Load\n" -"POT-Creation-Date: 2025-08-07T13:59:56.557Z\n" +"POT-Creation-Date: 2025-09-18T05:58:00.550Z\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -773,6 +773,12 @@ msgstr "Mensajes" msgid "JSON Response" msgstr "Respuesta JSON" +msgid "Select organisation unit to populate data" +msgstr "Seleccione la unidad de organización para rellenar los datos" + +msgid "Select available organisation units to include in the template" +msgstr "Seleccione las unidades organizativas para añadir a la plantilla" + msgid "Template" msgstr "Plantilla" @@ -782,6 +788,9 @@ msgstr "Modelo de Datos" msgid "Select template to export..." msgstr "Seleccione plantilla para exportar..." +msgid "" +msgstr "" + msgid "Start period" msgstr "Periodo inicial" @@ -791,29 +800,12 @@ msgstr "Periodo final" msgid "Organisation units" msgstr "Unidades Organizativas" -msgid "Select organisation unit to populate data" -msgstr "Seleccione la unidad de organización para rellenar los datos" - -msgid "Select available organisation units to include in the template" -msgstr "Seleccione las unidades organizativas para añadir a la plantilla" - msgid "User does not have any capture organisations units" msgstr "El usuario no tiene unidades organizativas asociadas" -msgid "Advanced template properties" -msgstr "Propiedades avanzadas de la plantilla" - -msgid "Language" -msgstr "Idioma" - -msgid "Split data entry tabs by section" -msgstr "" - -msgid "Theme" -msgstr "Tema" - -msgid "" -msgstr "" +#, fuzzy +msgid "Populate" +msgstr "Plantilla" msgid "Populate template with data" msgstr "Rellenar la plantilla con datos" @@ -836,6 +828,23 @@ msgstr "" msgid "Include relationships" msgstr "" +msgid "" +"Creates a tab for each available TEI relationship type, showing their " +"contents. Click here to learn more about the relationship model." +msgstr "" + +msgid "Advanced template properties" +msgstr "Propiedades avanzadas de la plantilla" + +msgid "Language" +msgstr "Idioma" + +msgid "Theme" +msgstr "Tema" + +msgid "Split data entry tabs by section" +msgstr "" + msgid "Use metadata codes (organisation units, data elements and options)" msgstr "" diff --git a/i18n/fr.po b/i18n/fr.po index 615c166f..48ba19a8 100644 --- a/i18n/fr.po +++ b/i18n/fr.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Bulk Load App\n" -"POT-Creation-Date: 2025-08-07T13:59:56.557Z\n" +"POT-Creation-Date: 2025-09-18T05:58:00.550Z\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -793,6 +793,12 @@ msgstr "" msgid "JSON Response" msgstr "" +msgid "Select organisation unit to populate data" +msgstr "" + +msgid "Select available organisation units to include in the template" +msgstr "Sélectionnez les unités d'organisation à inclure dans le modèle" + msgid "Template" msgstr "Modèle" @@ -802,6 +808,9 @@ msgstr "Modèle de données" msgid "Select template to export..." msgstr "Sélectionnez le modèle à exporter ..." +msgid "" +msgstr "" + msgid "Start period" msgstr "Période de début" @@ -811,31 +820,14 @@ msgstr "Période de fin" msgid "Organisation units" msgstr "Unités d'organisation" -msgid "Select organisation unit to populate data" -msgstr "" - -msgid "Select available organisation units to include in the template" -msgstr "Sélectionnez les unités d'organisation à inclure dans le modèle" - msgid "User does not have any capture organisations units" msgstr "" "L'utilisateur n'a pas accès à aucune unité d'organisation por la saisie de " "données" -msgid "Advanced template properties" -msgstr "Propriétés avancées du modèle" - -msgid "Language" -msgstr "Langue" - -msgid "Split data entry tabs by section" -msgstr "" - -msgid "Theme" -msgstr "Thème" - -msgid "" -msgstr "" +#, fuzzy +msgid "Populate" +msgstr "Modèle" msgid "Populate template with data" msgstr "Remplir le modèle avec des données" @@ -858,6 +850,23 @@ msgstr "" msgid "Include relationships" msgstr "" +msgid "" +"Creates a tab for each available TEI relationship type, showing their " +"contents. Click here to learn more about the relationship model." +msgstr "" + +msgid "Advanced template properties" +msgstr "Propriétés avancées du modèle" + +msgid "Language" +msgstr "Langue" + +msgid "Theme" +msgstr "Thème" + +msgid "Split data entry tabs by section" +msgstr "" + msgid "Use metadata codes (organisation units, data elements and options)" msgstr "" diff --git a/i18n/pt.po b/i18n/pt.po index 0f43d6c6..435d61e2 100644 --- a/i18n/pt.po +++ b/i18n/pt.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Bulk Load\n" -"POT-Creation-Date: 2025-08-07T13:59:56.557Z\n" +"POT-Creation-Date: 2025-09-18T05:58:00.550Z\n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -828,6 +828,12 @@ msgstr "Mensagens" msgid "JSON Response" msgstr "Resposta do JSON" +msgid "Select organisation unit to populate data" +msgstr "Selecione a unidade da organização para preencher os dados" + +msgid "Select available organisation units to include in the template" +msgstr "Selecione as unidades organizacionais para incluir na planilha" + msgid "Template" msgstr "Modelo" @@ -837,6 +843,9 @@ msgstr "Modelo de dados" msgid "Select template to export..." msgstr "Selecione o planilha para exportar ..." +msgid "" +msgstr "" + msgid "Start period" msgstr "Período inicial" @@ -846,29 +855,12 @@ msgstr "Período final" msgid "Organisation units" msgstr "Unidades organizacionais" -msgid "Select organisation unit to populate data" -msgstr "Selecione a unidade da organização para preencher os dados" - -msgid "Select available organisation units to include in the template" -msgstr "Selecione as unidades organizacionais para incluir na planilha" - msgid "User does not have any capture organisations units" msgstr "O usuário não tem accesso a nenhuma unidade organizacional" -msgid "Advanced template properties" -msgstr "Propriedades avançadas da planilha" - -msgid "Language" -msgstr "Língua" - -msgid "Split data entry tabs by section" -msgstr "" - -msgid "Theme" -msgstr "Tema" - -msgid "" -msgstr "" +#, fuzzy +msgid "Populate" +msgstr "Modelo" msgid "Populate template with data" msgstr "Preencher a planilha com dados" @@ -891,6 +883,23 @@ msgstr "" msgid "Include relationships" msgstr "" +msgid "" +"Creates a tab for each available TEI relationship type, showing their " +"contents. Click here to learn more about the relationship model." +msgstr "" + +msgid "Advanced template properties" +msgstr "Propriedades avançadas da planilha" + +msgid "Language" +msgstr "Língua" + +msgid "Theme" +msgstr "Tema" + +msgid "Split data entry tabs by section" +msgstr "" + msgid "Use metadata codes (organisation units, data elements and options)" msgstr "" diff --git a/i18n/ru.po b/i18n/ru.po index 9faabce0..fe4e4827 100644 --- a/i18n/ru.po +++ b/i18n/ru.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Bulk Load\n" -"POT-Creation-Date: 2025-08-07T13:59:56.557Z\n" +"POT-Creation-Date: 2025-09-18T05:58:00.550Z\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -830,6 +830,12 @@ msgstr "Сообщения" msgid "JSON Response" msgstr "Ответ JSON" +msgid "Select organisation unit to populate data" +msgstr "Выберите организационную единицу для заполнения данных" + +msgid "Select available organisation units to include in the template" +msgstr "Выберите доступные подразделения организации для включения в шаблон" + msgid "Template" msgstr "Шаблон" @@ -839,6 +845,9 @@ msgstr "Модель данных" msgid "Select template to export..." msgstr "Выберите шаблон для экспорта..." +msgid "" +msgstr "<Нет значения>" + msgid "Start period" msgstr "Начальный период" @@ -848,29 +857,12 @@ msgstr "Конечный период" msgid "Organisation units" msgstr "Организационные единицы" -msgid "Select organisation unit to populate data" -msgstr "Выберите организационную единицу для заполнения данных" - -msgid "Select available organisation units to include in the template" -msgstr "Выберите доступные подразделения организации для включения в шаблон" - msgid "User does not have any capture organisations units" msgstr "У пользователя нет подразделений организаций захвата" -msgid "Advanced template properties" -msgstr "Расширенные свойства шаблона" - -msgid "Language" -msgstr "Язык" - -msgid "Split data entry tabs by section" -msgstr "" - -msgid "Theme" -msgstr "Тема" - -msgid "" -msgstr "<Нет значения>" +#, fuzzy +msgid "Populate" +msgstr "Шаблон" msgid "Populate template with data" msgstr "Заполнение шаблона данными" @@ -893,6 +885,23 @@ msgstr "" msgid "Include relationships" msgstr "" +msgid "" +"Creates a tab for each available TEI relationship type, showing their " +"contents. Click here to learn more about the relationship model." +msgstr "" + +msgid "Advanced template properties" +msgstr "Расширенные свойства шаблона" + +msgid "Language" +msgstr "Язык" + +msgid "Theme" +msgstr "Тема" + +msgid "Split data entry tabs by section" +msgstr "" + msgid "Use metadata codes (organisation units, data elements and options)" msgstr "" diff --git a/src/test/mocks/server.ts b/src/test/mocks/server.ts index a9c93187..1136f7ef 100644 --- a/src/test/mocks/server.ts +++ b/src/test/mocks/server.ts @@ -53,7 +53,7 @@ export function initializeMockServer() { // Organisation unit Global mock.onGet("/organisationUnits", { params: { - fields: "children,displayName,id,level,path", + fields: "children,displayName,id,level,path,shortName", paging: false, filter: ["id:in:[H8RixfF8ugH]"], }, diff --git a/src/webapp/components/collapsible-section/Section.tsx b/src/webapp/components/collapsible-section/Section.tsx new file mode 100644 index 00000000..65ac2299 --- /dev/null +++ b/src/webapp/components/collapsible-section/Section.tsx @@ -0,0 +1,98 @@ +import { Icon, IconButton, makeStyles, Paper } from "@material-ui/core"; +import React from "react"; +import { buildClassName } from "../../utils/reactHelpers"; + +type IconPosition = "left" | "right"; +type ArrowStyle = "up_down" | "right_left" | "down_right"; + +interface SectionProps { + isOpen?: boolean; + setOpen?: (open: boolean) => void; + children: React.ReactNode; + title: React.ReactNode; + collapsible?: boolean; + elevation?: number; + iconPos?: IconPosition; + classProps?: { + sectionPaper?: string; + sectionHeader?: string; + sectionContent?: string; + }; + arrowStyle?: ArrowStyle; +} + +export const Section = (props: SectionProps) => { + const { + children, + title, + collapsible, + isOpen = true, + setOpen = () => {}, + elevation = 1, + iconPos = "right", + classProps = {}, + arrowStyle = "up_down", + } = props; + const classes = useStyles(); + const leftIcon = iconPos === "left" ? classes.leftIcon : null; + const toggle = () => setOpen(!isOpen); + + return ( + +
+ {collapsible && leftIcon && } + {title} + {collapsible && !leftIcon && } +
+
+ {children} +
+
+ ); +}; + +interface CollapsibleToggleProps { + isOpen: boolean; + arrowStyle: ArrowStyle; +} + +const CollapsibleToggle = (props: CollapsibleToggleProps) => { + const { isOpen, arrowStyle } = props; + const classes = useStyles(); + const [open, close] = arrowStyle.split("_"); + + return ( + + {isOpen ? `keyboard_arrow_${open}` : `keyboard_arrow_${close}`} + + ); +}; + +const useStyles = makeStyles({ + header: { + margin: 0, + padding: "1em", + paddingLeft: 0, + display: "flex", + justifyContent: "space-between", + alignItems: "center", + borderBottom: "solid 1px #e8edf2", + cursor: "pointer", + }, + noBorder: { border: "none" }, + leftIcon: { + justifyContent: "normal", + gap: 10, + }, + paper: { padding: "1em", paddingTop: "0.5em", marginBottom: "1em" }, + button: { padding: 0 }, + hidden: { display: "none" }, +}); diff --git a/src/webapp/components/template-selector/LabelHelp.tsx b/src/webapp/components/template-selector/LabelHelp.tsx new file mode 100644 index 00000000..e0cb08b6 --- /dev/null +++ b/src/webapp/components/template-selector/LabelHelp.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { makeStyles, Tooltip } from "@material-ui/core"; +import HelpOutlineIcon from "@material-ui/icons/HelpOutline"; + +type LabelHelpProps = { + helpText: string; + label: React.ReactNode; + onClick?: () => void; +}; + +export const LabelHelp = (props: LabelHelpProps) => { + const { helpText, label, onClick } = props; + const classes = useStyles(); + return ( +
+ {label} + + + +
+ ); +}; + +const useStyles = makeStyles({ + root: { display: "flex", alignItems: "center" }, + tooltip: { marginLeft: 10, color: "#000000DE" }, +}); diff --git a/src/webapp/components/template-selector/TemplateSelector.tsx b/src/webapp/components/template-selector/TemplateSelector.tsx index 58c18177..d51dc1aa 100644 --- a/src/webapp/components/template-selector/TemplateSelector.tsx +++ b/src/webapp/components/template-selector/TemplateSelector.tsx @@ -1,6 +1,6 @@ import { Id } from "@eyeseetea/d2-api"; import { DatePicker, OrgUnitsSelector } from "@eyeseetea/d2-ui-components"; -import { Checkbox, FormControlLabel, makeStyles } from "@material-ui/core"; +import { Checkbox, FormControlLabel, makeStyles, Typography } from "@material-ui/core"; import _ from "lodash"; import moment from "moment"; import React, { useCallback, useEffect, useMemo, useState } from "react"; @@ -15,6 +15,8 @@ import { useAppContext } from "../../contexts/app-context"; import Settings from "../../logic/settings"; import { orgUnitListParams } from "../../utils/template"; import { Select, SelectOption } from "../select/Select"; +import { Section } from "../collapsible-section/Section"; +import { LabelHelp } from "./LabelHelp"; type DataSource = Record; @@ -69,13 +71,13 @@ export const TemplateSelector = ({ const [selectedOrgUnits, setSelectedOrgUnits] = useState([]); const [datePickerFormat, setDatePickerFormat] = useState(); const [userHasReadAccess, setUserHasReadAccess] = useState(false); - const [filterOrgUnits, setFilterOrgUnits] = useState(false); + const [filterOrgUnits, setFilterOrgUnits] = useState(true); const [selectedModel, setSelectedModel] = useState(""); const [state, setState] = useState>( { startDate: moment().add("-1", "year").startOf("year"), endDate: moment().add("-1", "year").endOf("year"), - relationshipsOuFilter: "CAPTURE", + relationshipsOuFilter: "SELECTED", populate: false, downloadRelationships: true, filterTEIEnrollmentDate: false, @@ -89,6 +91,7 @@ export const TemplateSelector = ({ dataFilterOptions: {}, } ); + const [showAdvancedOptions, setShowAdvancedOptions] = useState(false); const dataSets = dataSource?.dataSets; const { templateId, id } = state; @@ -160,12 +163,12 @@ export const TemplateSelector = ({ useEffect(() => { const { type, id, templateId, templateType, ...rest } = state; if (type && id && templateId && templateType) { - const orgUnits = filterOrgUnits ? cleanOrgUnitPaths(selectedOrgUnits) : []; + const orgUnits = cleanOrgUnitPaths(selectedOrgUnits); onChange({ type, id, orgUnits, templateId, templateType, ...rest }); } else { onChange(null); } - }, [state, selectedOrgUnits, filterOrgUnits, orgUnitTreeFilter, onChange]); + }, [state, selectedOrgUnits, orgUnitTreeFilter, onChange]); const themeOptions = dataSource ? modelToSelectOption(themes) : []; @@ -231,7 +234,7 @@ export const TemplateSelector = ({ : undefined, }, })); - setFilterOrgUnits(false); + clearPopulateDates(); setSelectedOrgUnits([]); } @@ -300,11 +303,7 @@ export const TemplateSelector = ({ setState(state => ({ ...state, filterTEIEnrollmentDate })); }; - const onFilterOrgUnitsChange = (_event: React.ChangeEvent, filterOrgUnits: boolean) => { - const isCustomProgram = state.templateType === "custom" && state.type !== "dataSets"; - const populate = isCustomProgram && filterOrgUnits; - setState(state => ({ ...state, populate })); - clearPopulateDates(); + const onFilterOrgUnitsChange = (filterOrgUnits: boolean) => { setFilterOrgUnits(filterOrgUnits); }; @@ -312,109 +311,139 @@ export const TemplateSelector = ({ setState(state => ({ ...state, language: value })); }; + const openTeiRelationshipHelp = () => { + window.open( + "https://docs.dhis2.org/en/use/user-guides/dhis-core-version-master/understanding-the-data-model/relationship-model.html", + "_blank" + ); + }; + + const orgUnitHelpText = + state.templateType === "custom" + ? i18n.t("Select organisation unit to populate data") + : i18n.t("Select available organisation units to include in the template"); + const isCustomDataSet = state.templateType === "custom" && state.type === "dataSets"; const isMultipleSelection = !isCustomDataSet; const showPopulate = !(state.templateType === "custom" && !settings.showPopulateInCustomForms); const selected = state.id && state.templateId ? getOptionValue({ id: state.id, templateId: state.templateId }) : ""; const hasDataFilter = Boolean(state.dataFilterOptions.teiFilter?.filters.length); + const subSectionClasses = useMemo(() => { + return { sectionHeader: classes.subSectionHeader, sectionPaper: classes.subSection }; + }, [classes]); + return ( <> -

{i18n.t("Template")}

- -
- {models.length > 1 && ( +
{i18n.t("Template")}} classProps={classes}> +
+ {models.length > 1 && ( +
+
- )} -
- ")} - /> -
- )} - - {state.type === "dataSets" && state.templateType === "custom" && showPopulate && ( - onCustomFormDateChange(date)} - maxDate={state.endDate} - views={datePickerFormat?.views} - format={datePickerFormat?.format ?? "DD/MM/YYYY"} - InputLabelProps={{ style: { color: "#494949" } }} - /> - )} - {state.type === "dataSets" && (showPopulate || state.showPeriod) && ( -
-
- onStartDateChange("startDate", date, true)} - maxDate={state.endDate} - views={datePickerFormat?.views} - format={datePickerFormat?.format ?? "DD/MM/YYYY"} - InputLabelProps={{ style: { color: "#494949" } }} - /> -
+ {hasDataFilter && state.dataFilterOptions.teiFilter && (
- onEndDateChange("endDate", date, true)} - minDate={state.startDate} - views={datePickerFormat?.views} - format={datePickerFormat?.format ?? "DD/MM/YYYY"} - InputLabelProps={{ style: { color: "#494949" } }} + -
-
- )} - - {isDataSet && state.templateType !== "custom" && ( - - } - label={i18n.t("Split data entry tabs by section")} - /> - )} + )} +
+ )} + - {themeOptions.length > 0 && ( -
-
- + onRelationshipsOuFilterChange(value as RelationshipOrgUnitFilter) + } + options={[ + { + label: i18n.t("Current user organisation units (data capture)"), + value: "CAPTURE", + }, + { + label: i18n.t("Selected organisation units with their descendants"), + value: "DESCENDANTS", + }, + { label: i18n.t("Only selected organisation units"), value: "SELECTED" }, + ]} /> - } - label={i18n.t("Also filter TEI and relationships by their enrollment date")} - /> +
+
+ +
+ + } + label={ + + } + /> +
)} + + )} +
{i18n.t("Advanced template properties")}} + classProps={classes} + isOpen={showAdvancedOptions} + setOpen={setShowAdvancedOptions} + collapsible={true} + > + {availableLanguages.length > 0 && (state.templateType !== "custom" || state.showLanguage) && (
- onStartDateChange("populateStartDate", date)} - minDate={ - state.type === "dataSets" - ? state.startDate?.startOf(datePickerFormat?.unit ?? "day") - : undefined - } - maxDate={moment.min( - _.compact([state.type === "dataSets" && state.endDate, state.populateEndDate]) - )} - views={datePickerFormat?.views} - format={datePickerFormat?.format ?? "DD/MM/YYYY"} - InputLabelProps={{ style: { color: "#494949" } }} - /> -
- -
- onEndDateChange("populateEndDate", date)} - minDate={moment.max( - _.compact([state.type === "dataSets" && state.startDate, state.populateStartDate]) - )} - maxDate={ - state.type === "dataSets" - ? state.endDate?.endOf(datePickerFormat?.unit ?? "day") - : undefined - } - views={datePickerFormat?.views} - format={datePickerFormat?.format ?? "DD/MM/YYYY"} - InputLabelProps={{ style: { color: "#494949" } }} + - onRelationshipsOuFilterChange(value as RelationshipOrgUnitFilter) - } - options={[ - { - label: i18n.t("Current user organisation units (data capture)"), - value: "CAPTURE", - }, - { - label: i18n.t("Selected organisation units with their descendants"), - value: "DESCENDANTS", - }, - { label: i18n.t("Only selected organisation units"), value: "SELECTED" }, - ]} + placeholder={i18n.t("Theme")} + onChange={onThemeChange} + options={themeOptions} + allowEmpty={true} + emptyLabel={i18n.t("")} + value={state.theme ?? ""} />
+ )} + {isDataSet && state.templateType !== "custom" && ( + + } + label={i18n.t("Split data entry tabs by section")} + /> + )} + + {state.type && (
- } - label={i18n.t("Include relationships")} + control={} + label={i18n.t("Use metadata codes (organisation units, data elements and options)")} />
- - )} - - {state.type && ( -
- } - label={i18n.t("Use metadata codes (organisation units, data elements and options)")} - /> -
- )} + )} +
); }; @@ -621,7 +674,12 @@ const useStyles = makeStyles({ justifyContent: "space-around", marginRight: "1em", }, - title: { marginBottom: 0 }, + title: { margin: 0, padding: 0, display: "flex", alignItems: "center" }, + formHeader: { marginTop: 0 }, + subSection: { padding: 0, margin: 0, background: "#fbfcfd" }, + subSectionTitle: { marginBottom: 0 }, + subSectionHeader: { borderBottom: "none" }, + sectionPaper: { background: "#fbfcfd" }, select: { flexBasis: "100%", margin: "0.5em", marginLeft: 0, marginTop: "1em" }, checkbox: { marginTop: "1em" }, orgUnitSelector: { marginTop: "1em", marginBottom: "2em" }, @@ -632,6 +690,7 @@ const useStyles = makeStyles({ alignItems: "center", justifyContent: "center", }, + orgUnitCount: { marginLeft: "3px" }, }); function modelToSelectOption(array: T[]) { diff --git a/src/webapp/utils/reactHelpers.ts b/src/webapp/utils/reactHelpers.ts new file mode 100644 index 00000000..7e80c4f7 --- /dev/null +++ b/src/webapp/utils/reactHelpers.ts @@ -0,0 +1,5 @@ +import _ from "lodash"; + +export function buildClassName(classNames: (string | null | undefined)[]): string { + return _.compact(classNames).join(" "); +}