Skip to content

Commit

Permalink
Merge pull request #274 from EyeSeeTea/development
Browse files Browse the repository at this point in the history
Release 3.18.1
  • Loading branch information
adrianq authored Apr 29, 2022
2 parents a121bc5 + 21e0f7c commit 27f8027
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 61 deletions.
7 changes: 5 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -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: 2022-04-20T12:30:37.694Z\n"
"PO-Revision-Date: 2022-04-20T12:30:37.694Z\n"
"POT-Creation-Date: 2022-04-29T09:28:31.324Z\n"
"PO-Revision-Date: 2022-04-29T09:28:31.324Z\n"

msgid "Data values - Create/update"
msgstr ""
Expand Down Expand Up @@ -383,6 +383,9 @@ msgstr ""
msgid "Ok"
msgstr ""

msgid "Search by name/code"
msgstr ""

msgid "Create template"
msgstr ""

Expand Down
5 changes: 4 additions & 1 deletion i18n/es.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Bulk Load\n"
"POT-Creation-Date: 2022-04-20T12:30:37.694Z\n"
"POT-Creation-Date: 2022-04-29T09:28:31.324Z\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand Down Expand Up @@ -410,6 +410,9 @@ msgstr "Borrar"
msgid "Ok"
msgstr "Ok"

msgid "Search by name/code"
msgstr ""

msgid "Create template"
msgstr "Crear plantilla"

Expand Down
5 changes: 4 additions & 1 deletion i18n/fr.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Bulk Load App\n"
"POT-Creation-Date: 2022-04-20T12:30:37.694Z\n"
"POT-Creation-Date: 2022-04-29T09:28:31.324Z\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand Down Expand Up @@ -407,6 +407,9 @@ msgstr "Supprimer"
msgid "Ok"
msgstr "D'accord"

msgid "Search by name/code"
msgstr ""

#, fuzzy
msgid "Create template"
msgstr "Créer un thème"
Expand Down
5 changes: 4 additions & 1 deletion i18n/pt.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Bulk Load\n"
"POT-Creation-Date: 2022-04-20T12:30:37.694Z\n"
"POT-Creation-Date: 2022-04-29T09:28:31.324Z\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand Down Expand Up @@ -428,6 +428,9 @@ msgstr "Excluir"
msgid "Ok"
msgstr "Ok"

msgid "Search by name/code"
msgstr ""

#, fuzzy
msgid "Create template"
msgstr "Criar tema"
Expand Down
5 changes: 4 additions & 1 deletion i18n/ru.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Bulk Load\n"
"POT-Creation-Date: 2022-04-20T12:30:37.694Z\n"
"POT-Creation-Date: 2022-04-29T09:28:31.324Z\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand Down Expand Up @@ -430,6 +430,9 @@ msgstr "Удалить"
msgid "Ok"
msgstr "Хорошо"

msgid "Search by name/code"
msgstr ""

#, fuzzy
msgid "Create template"
msgstr "Создать тему"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "bulk-load",
"description": "Bulk importing made easy",
"version": "3.18.0",
"version": "3.18.1",
"license": "GPL-3.0",
"author": "EyeSeeTea team",
"homepage": ".",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useAppContext } from "../../contexts/app-context";
import { modelToSelectOption } from "../../utils/refs";
import { Select } from "../select/Select";
import { SettingsFieldsProps } from "./SettingsFields";
import { useDataForms } from "./settings.hooks";
import { useDataFormsSelector } from "../../hooks/useDataForms";

export interface ModuleTemplateDialogProps extends SettingsFieldsProps {
title: string;
Expand All @@ -25,7 +25,7 @@ export function DataFormTemplateAssignDialog(props: ModuleTemplateDialogProps):

const [templates, setTemplates] = useState<NamedRef[]>([]);

const dataForms = useDataForms();
const dataForms = useDataFormsSelector();
const selectedDataForm = dataForms.selected;

useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions src/webapp/components/settings/TemplateEditDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import i18n from "../../../locales";
import { Select } from "../select/Select";
import { CustomTemplate } from "../../../domain/entities/Template";
import React from "react";
import { useDataForms } from "./settings.hooks";
import { useDataFormsSelector } from "../../hooks/useDataForms";
import {
TemplateView as ViewModel,
TemplateViewActions as ViewModelActions,
Expand Down Expand Up @@ -102,7 +102,7 @@ const EditDialog: React.FC<CustomTemplateEditDialogProps2> = React.memo(props =>

const translations = React.useMemo(() => ViewModelActions.getTranslations(), []);
const snackbar = useSnackbar();
const dataForms = useDataForms({
const dataForms = useDataFormsSelector({
type: template.dataFormType || undefined,
initialSelectionId: template.dataFormId || undefined,
});
Expand Down
147 changes: 114 additions & 33 deletions src/webapp/components/settings/TemplateListTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import {
ConfirmationDialog,
ObjectsTable,
PaginationOptions,
SearchBox,
TableAction,
TableColumn,
TableSelection,
TableState,
useLoading,
useSnackbar,
} from "@eyeseetea/d2-ui-components";
import { Button, Icon } from "@material-ui/core";
import { Button, Icon, makeStyles } from "@material-ui/core";
import _ from "lodash";
import moment from "moment";

Expand All @@ -25,7 +26,8 @@ import { FormMode, CustomTemplateEditDialog } from "./TemplateEditDialog";
import { downloadFile } from "../../utils/download";
import { DataForm, DataFormType, dataFormTypes, getTranslations } from "../../../domain/entities/DataForm";
import { fromBase64, xlsxMimeType } from "../../../utils/files";
import { useDataForms } from "./settings.hooks";
import { useDataForms } from "../../hooks/useDataForms";
import { Select, SelectProps } from "../select/Select";

interface WarningDialog {
title?: string;
Expand Down Expand Up @@ -62,9 +64,14 @@ export default function TemplateListTable(props: TemplateListTableProps) {
const [warningDialog, setWarningDialog] = useState<WarningDialog | null>(null);

const dataForms = useDataForms();
const dataFormsById = React.useMemo(() => _.keyBy(dataForms.objects, df => df.id), [dataForms.objects]);
const dataFormsById = React.useMemo(() => _.keyBy(dataForms, df => df.id), [dataForms]);

const rows = buildCustomTemplateRow(dataFormsById, customTemplates);
const allRows = React.useMemo(() => {
return buildCustomTemplateRow(dataFormsById, customTemplates);
}, [dataFormsById, customTemplates]);

const { rows, searchText, search, dataFormTypeOptions, dataFormType, setDataFormTypeFromOption } =
useFilters(allRows);

const newTemplate = () => {
setCustomTemplateEdit({ type: "new" });
Expand Down Expand Up @@ -212,6 +219,8 @@ export default function TemplateListTable(props: TemplateListTableProps) {
setSettingsState({ type: "closed" });
}, []);

const classes = useStyles();

return (
<React.Fragment>
{warningDialog && (
Expand Down Expand Up @@ -254,9 +263,31 @@ export default function TemplateListTable(props: TemplateListTableProps) {
onChange={onTableChange}
paginationOptions={paginationOptions}
filterComponents={
<Button variant="contained" color="primary" onClick={newTemplate} disableElevation>
{i18n.t("Create template")}
</Button>
<React.Fragment key="filters">
<SearchBox
key="objects-table-search-box"
className={classes.searchBox}
value={searchText}
hintText={i18n.t("Search by name/code")}
onChange={search}
/>
<div className={classes.dataFormSelect}>
<Select
placeholder={i18n.t("Data Form Type")}
options={dataFormTypeOptions}
onChange={setDataFormTypeFromOption}
value={dataFormType}
allowEmpty
emptyLabel={i18n.t("All")}
/>
</div>

<div className={classes.createTemplateButton}>
<Button variant="contained" color="primary" onClick={newTemplate} disableElevation>
{i18n.t("Create template")}
</Button>
</div>
</React.Fragment>
}
/>
</React.Fragment>
Expand All @@ -267,42 +298,51 @@ function buildCustomTemplateRow(
dataFormsById: _.Dictionary<DataForm>,
customTemplates: CustomTemplate[]
): TemplateRow[] {
return _(customTemplates)
.flatMap(({ id, name, description, created, lastUpdated, dataFormId, dataFormType }) => {
const dataFormId_ = dataFormId.type === "value" ? dataFormId.id : undefined;
const dataFormType_ = dataFormType.type === "value" ? dataFormType.id : undefined;
if (!dataFormId_) return [];
if (!(dataFormType_ && isValueInUnionType(dataFormType_, dataFormTypes))) return [];
const dataFormName = dataFormsById[dataFormId_]?.name || name;

const customRow: TemplateRow = {
type: "custom",
id,
name,
description,
created: created ? `${created.user.username} (${formatDate(created.timestamp)})` : "-",
lastUpdated: lastUpdated ? `${lastUpdated.user.username} (${formatDate(lastUpdated.timestamp)})` : "-",
dataFormId: dataFormId_,
dataFormType: dataFormType_,
dataFormName,
};
const customTemplatesByDataFormId = _(customTemplates)
.keyBy(template => (template.dataFormId.type === "value" ? template.dataFormId.id : ""))
.value();

const rows = _(dataFormsById)
.flatMap((dataForm, dataFormId) => {
const customTemplate = customTemplatesByDataFormId[dataFormId];

const customRow: TemplateRow | undefined = customTemplate
? {
type: "custom",
id: customTemplate.id,
name: customTemplate.name,
description: customTemplate.description,
created: customTemplate.created
? `${customTemplate.created.user.username} (${formatDate(customTemplate.created.timestamp)})`
: "-",
lastUpdated: customTemplate.lastUpdated
? `${customTemplate.lastUpdated.user.username} (${formatDate(
customTemplate.lastUpdated.timestamp
)})`
: "-",
dataFormId: dataForm.id,
dataFormType: dataForm.type,
dataFormName: dataForm.name,
}
: undefined;

const autogeneratedRow: TemplateRow = {
...customRow,
name: dataFormName,
id: dataFormId_,
type: "autogenerated",
name: dataForm.name,
id: dataForm.id,
description: "",
created: "",
lastUpdated: "",
dataFormId: dataFormId_,
dataFormType: dataFormType_,
dataFormName,
dataFormId: dataForm.id,
dataFormType: dataForm.type,
dataFormName: dataForm.name,
};

return [customRow, autogeneratedRow];
return _.compact([customRow, autogeneratedRow]);
})
.value();

return rows;
}

function formatDate(timestamp: string): string {
Expand All @@ -313,3 +353,44 @@ const paginationOptions: PaginationOptions = {
pageSizeOptions: [10, 20],
pageSizeInitialValue: 10,
};

const useStyles = makeStyles({
createTemplateButton: { marginLeft: 20 },
dataFormSelect: { width: 150, marginLeft: 20, marginTop: -9 },
searchBox: { maxWidth: "500px", width: "30%", marginLeft: 20 },
});

function useFilters(allRows: TemplateRow[]) {
const [searchText, search] = React.useState("");

const dataFormTypeOptions = React.useMemo(() => {
return [
{ value: "dataSets", label: i18n.t("Data Set") },
{ value: "programs", label: i18n.t("Event Program") },
{ value: "trackerPrograms", label: i18n.t("Tracker Program") },
];
}, []);

const [dataFormType, setDataFormType] = React.useState<DataFormType>();

const setDataFormTypeFromOption = React.useCallback<SelectProps["onChange"]>(option => {
if (!option.value) {
setDataFormType(undefined);
} else if (isValueInUnionType(option.value, dataFormTypes)) {
setDataFormType(option.value);
}
}, []);

const rowsByText = React.useMemo(() => {
const text = searchText.toLowerCase().trim();
return text
? allRows.filter(row => row.id.toLowerCase().includes(text) || row.name.toLowerCase().includes(text))
: allRows;
}, [allRows, searchText]);

const rows = React.useMemo(() => {
return dataFormType ? rowsByText.filter(row => row.dataFormType === dataFormType) : rowsByText;
}, [dataFormType, rowsByText]);

return { rows, searchText, search, dataFormTypeOptions, dataFormType, setDataFormTypeFromOption };
}
Loading

0 comments on commit 27f8027

Please sign in to comment.