Skip to content

Commit

Permalink
fix: scorecard form
Browse files Browse the repository at this point in the history
Fixed issues with additional labels input field
  • Loading branch information
nnkogift committed Sep 6, 2024
1 parent 3dba94e commit 92de400
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useFieldArray } from "react-hook-form";
import { Button, Field, InputField } from "@dhis2/ui";
import i18n from "@dhis2/d2-i18n";
import { RHFTextInputField } from "@hisptz/dhis2-ui";
import { useState } from "react";
import { IconAdd24, IconDelete24 } from "@dhis2/ui-icons";


export function AdditionalLabelsField() {
const [addFieldValue, setAddFieldValue] = useState<string | undefined>();
const { fields, append, remove } = useFieldArray({
name: "additionalLabels"
});

const onAdd = () => {
if (addFieldValue) {
append(addFieldValue as string);
setAddFieldValue(undefined);
}
};

return (
<Field label={i18n.t("Additional labels")}>
<div style={{ gap: 24 }} className="column">
<div style={{ gap: 8 }} className="column">
{
fields.map((field, i) => {
return (
<div key={field.id} style={{ gap: 8 }} className="row align-items-center">
<div style={{ flex: 1 }}>
<RHFTextInputField name={`additionalLabels.${i}`} />
</div>
<Button onClick={() => remove(i)} icon={<IconDelete24 />}>{i18n.t("Delete")}</Button>
</div>
);
})
}
</div>
<div style={{ gap: 8 }} className="row align-items-end">
<div style={{ flex: 1 }}>
<InputField label={i18n.t("Add new label")} value={addFieldValue} onChange={({ value }: { value?: string }) => setAddFieldValue(value)} />
</div>
<Button onClick={onAdd} disabled={!addFieldValue} icon={<IconAdd24 />}>{i18n.t("Add")}</Button>
</div>
</div>
</Field>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "../../../ScorecardManagement.module.css";
import { PeriodSelector } from "./PeriodSelector";
import LegendDefinitionFormField from "./LegendDefinitionFormField";
import { PeriodTypeSelector } from "./PeriodTypeSelector";
import { AdditionalLabelsField } from "./AdditionalLabelsField";

export default function GeneralForm() {

Expand Down Expand Up @@ -50,17 +51,7 @@ export default function GeneralForm() {
<LegendDefinitionFormField />
</div>
<div className="col-sm-6 col-xl-4 additional-labels-settings">
<RHFCustomInput
addable
deletable
name="additionalLabels"
valueType="MULTIPLE_FIELDS"
label={i18n.t("Additional Labels (Tags)")}
multipleField={{
name: "label",
valueType: "TEXT"
}}
/>
<AdditionalLabelsField />
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
import { generateLegendDefaults, getScorecardSummary } from "@scorecard/shared";
import { cloneDeep, find, isEmpty, set } from "lodash";
import { LegendDefinition, ScorecardDataGroup, ScorecardDataHolder, ScorecardDataSource, SpecificTarget } from "@hisptz/dhis2-analytics";

export function resetLegends(groups: any, legendDefinitions: any) {
export function resetLegends(groups: ScorecardDataGroup[], legendDefinitions: LegendDefinition[]) {
const newGroups = cloneDeep(groups);
if (newGroups) {
newGroups?.forEach((group: any) => {
group?.dataHolders?.forEach((dataHolder: any) => {
dataHolder?.dataSources?.forEach((dataSource: any) => {
group?.dataHolders?.forEach((dataHolder: ScorecardDataHolder) => {
dataHolder?.dataSources?.forEach((dataSource: ScorecardDataSource) => {
set(
dataSource,
"legends",
generateLegendDefaults(
getNonDefaultLegendDefinitions(legendDefinitions),
),
dataSource.weight,
dataSource.highIsGood
)
);
if (!isEmpty(dataSource.specificTargets)) {
dataSource.specificTargets.forEach(
(specificTarget: any) => {
(specificTarget: SpecificTarget) => {
set(
specificTarget,
"legends",
generateLegendDefaults(
getNonDefaultLegendDefinitions(
legendDefinitions,
legendDefinitions
),
),
dataSource.weight,
dataSource.highIsGood
)
);
},
}
);
}
});
Expand All @@ -39,15 +44,7 @@ export function resetLegends(groups: any, legendDefinitions: any) {
export function getNonDefaultLegendDefinitions(legendDefinitions: any) {
return (
legendDefinitions?.filter(
(legendDefinition: any) => !legendDefinition.isDefault,
) ?? []
);
}

export function getDefaultLegendDefinitions(legendDefinitions: any) {
return (
legendDefinitions?.filter(
(legendDefinition: any) => legendDefinition.isDefault,
(legendDefinition: any) => !legendDefinition.isDefault
) ?? []
);
}
Expand Down
62 changes: 61 additions & 1 deletion packages/app/src/modules/ScorecardManagement/hooks/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { useDataQuery } from "@dhis2/app-runtime";
import { useGetScorecardSharingSettings } from "../../ScorecardList/hooks/authority";
import { useEffect, useState } from "react";
import { useFormSchema } from "./schema";
import { uid } from "@hisptz/dhis2-utils";
import i18n from "@dhis2/d2-i18n";

const query: any = {
scorecard: {
Expand All @@ -15,6 +17,64 @@ const query: any = {
}
};

const defaultValue: Partial<ScorecardConfig> = {
id: uid(),
legendDefinitions: [
{
color: "#D3D3D3",
name: i18n.t("N/A"),
isDefault: true,
id: "N/A"
},
{
color: "#FFFFFF",
name: i18n.t("No Data"),
isDefault: true,
id: "No Data"
},
{
id: uid(),
color: "#008000",
name: i18n.t("Target Reached/ On Track")
},
{
id: uid(),
color: "#FFFF00",
name: i18n.t("Progress, but more effort required")
},
{
id: uid(),
color: "#FF0000",
name: i18n.t("Not on track")
}
],
options: {
averageDisplayType: "ALL",
legend: true,
title: true,
itemNumber: true,
emptyRows: true,
showHierarchy: false,
averageColumn: false,
averageRow: false,
highlightedIndicators: false,
arrows: false,
showDataInRows: false
},
orgUnitSelection: {
levels: [],
groups: [],
orgUnits: [],
userSubX2Unit: false,
userSubUnit: false,
userOrgUnit: false
},
highlightedIndicators: [],
dataSelection: {
dataGroups: []
}
};


export default function useScorecardFormMetadata() {
const { id } = useParams<{ id: string }>();
Expand All @@ -34,7 +94,7 @@ export default function useScorecardFormMetadata() {
const scorecardDefaultValues = await refetch() as { scorecard: ScorecardConfig };
return scorecardDefaultValues.scorecard;
}
return {} as ScorecardConfig;
return defaultValue as ScorecardConfig;
},
mode: "onSubmit",
reValidateMode: "onSubmit",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ export function useFormSchema() {
const engine = useDataEngine();
return scorecardConfigSchema.extend({
title: z.string({ required_error: i18n.t("Title is required") }).min(4, i18n.t("Title must have at least 4 characters")).refine(async (value) => {
console.log(value);
const titleExists = await titleDoesNotExist(engine, id, value);
return !titleExists || i18n.t(
`A scorecard with the title '{{value}}' already exists. Please select another title`,
{ value }
);
}),
additionalLabels: z.array(z.string()).optional(),
subtitle: z.string().optional(),
customHeader: z.string().optional(),
description: z.string().optional()
Expand Down
3 changes: 2 additions & 1 deletion packages/shared/src/models/base.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import produce from "immer";
import { cloneDeep, defaultsDeep } from "lodash";
import { ScorecardOptions } from "./index";

export default class DataModel {
constructor(attributes = {}) {
Expand All @@ -20,7 +21,7 @@ export default class DataModel {
}

static setObject(object: any, values: any = {}) {
const updatedObject = cloneDeep(object);
const updatedObject =new ScorecardOptions cloneDeep(object);
for (const key of Object.keys(values)) {
updatedObject[key] = values[key];
}
Expand Down

0 comments on commit 92de400

Please sign in to comment.