diff --git a/packages/app/i18n/en.pot b/packages/app/i18n/en.pot index f76f183b..4f9ddbed 100644 --- a/packages/app/i18n/en.pot +++ b/packages/app/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: 2024-09-06T07:09:21.611Z\n" -"PO-Revision-Date: 2024-09-06T07:09:21.611Z\n" +"POT-Creation-Date: 2024-09-06T09:01:38.368Z\n" +"PO-Revision-Date: 2024-09-06T09:01:38.368Z\n" msgid "Could not determine scorecard's access" msgstr "Could not determine scorecard's access" @@ -267,17 +267,26 @@ msgstr "Additional Labels (Tags)" msgid "Legend Definitions" msgstr "Legend Definitions" +msgid "Select" +msgstr "Select" + +msgid "Select default period(s)" +msgstr "Select default period(s)" + msgid "Default period" msgstr "Default period" msgid "Selected" msgstr "Selected" -msgid "Select default period" -msgstr "Select default period" +msgid "{{buttonLabel}} default period" +msgstr "{{buttonLabel}} default period" + +msgid "Allowed period type" +msgstr "Allowed period type" -msgid "Period type is required" -msgstr "Period type is required" +msgid "The period selector will only show periods of this type" +msgstr "The period selector will only show periods of this type" msgid "Fixed Periods" msgstr "Fixed Periods" @@ -291,6 +300,12 @@ msgstr "Highlighted Indicators" msgid "Add Highlighted Indicator" msgstr "Add Highlighted Indicator" +msgid "You need to fix issues on this step before moving to another step" +msgstr "You need to fix issues on this step before moving to another step" + +msgid "Form contains errors. Please fix them to continue." +msgstr "Form contains errors. Please fix them to continue." + msgid "Saving" msgstr "Saving" @@ -462,9 +477,6 @@ msgstr "Confirm scorecard selection" msgid "Are you sure you want to select this scorecard for this dashboard?" msgstr "Are you sure you want to select this scorecard for this dashboard?" -msgid "Select" -msgstr "Select" - msgid "Search" msgstr "Search" diff --git a/packages/app/package.json b/packages/app/package.json index 60a4c2a3..bac61b0f 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -19,7 +19,7 @@ "@dhis2/cypress-commands": "^9.0.2", "@dhis2/cypress-plugins": "^9.0.2", "@dhis2/d2-i18n": "^1.1.0", - "@hookform/devtools": "^4.0.2", + "@hookform/devtools": "^4.3.1", "@types/cypress": "^1.1.3", "@types/node": "^20.14.11", "@types/react": "^18.3.3", diff --git a/packages/app/src/locales/en/translations.json b/packages/app/src/locales/en/translations.json index 58b6bbe1..d1f449a5 100644 --- a/packages/app/src/locales/en/translations.json +++ b/packages/app/src/locales/en/translations.json @@ -84,14 +84,19 @@ "Custom Header": "Custom Header", "Additional Labels (Tags)": "Additional Labels (Tags)", "Legend Definitions": "Legend Definitions", + "Select": "Select", + "Select default period(s)": "Select default period(s)", "Default period": "Default period", "Selected": "Selected", - "Select default period": "Select default period", - "Period type is required": "Period type is required", + "{{buttonLabel}} default period": "{{buttonLabel}} default period", + "Allowed period type": "Allowed period type", + "The period selector will only show periods of this type": "The period selector will only show periods of this type", "Fixed Periods": "Fixed Periods", "Relative Periods": "Relative Periods", "Highlighted Indicators": "Highlighted Indicators", "Add Highlighted Indicator": "Add Highlighted Indicator", + "You need to fix issues on this step before moving to another step": "You need to fix issues on this step before moving to another step", + "Form contains errors. Please fix them to continue.": "Form contains errors. Please fix them to continue.", "Saving": "Saving", "Save and exit": "Save and exit", "Save and continue": "Save and continue", @@ -143,7 +148,6 @@ "Create a new scorecard in the scorecard app to see it here.": "Create a new scorecard in the scorecard app to see it here.", "Confirm scorecard selection": "Confirm scorecard selection", "Are you sure you want to select this scorecard for this dashboard?": "Are you sure you want to select this scorecard for this dashboard?", - "Select": "Select", "Search": "Search", "Preparing widgets migration...": "Preparing widgets migration...", "Migrating scorecards widgets": "Migrating scorecards widgets" diff --git a/packages/app/src/modules/ScorecardManagement/components/General/components/GeneralForm.tsx b/packages/app/src/modules/ScorecardManagement/components/General/components/GeneralForm.tsx index 7088cb8d..726ee578 100644 --- a/packages/app/src/modules/ScorecardManagement/components/General/components/GeneralForm.tsx +++ b/packages/app/src/modules/ScorecardManagement/components/General/components/GeneralForm.tsx @@ -1,17 +1,12 @@ -import { useDataEngine } from "@dhis2/app-runtime"; import i18n from "@dhis2/d2-i18n"; import { RHFDHIS2FormField as RHFCustomInput, RHFTextInputField } from "@hisptz/dhis2-ui"; import React from "react"; -import { useParams } from "react-router-dom"; import "../../../ScorecardManagement.module.css"; -import { titleDoesNotExist } from "../utils/utils"; import { PeriodSelector } from "./PeriodSelector"; import LegendDefinitionFormField from "./LegendDefinitionFormField"; import { PeriodTypeSelector } from "./PeriodTypeSelector"; export default function GeneralForm() { - const { id } = useParams(); - const engine = useDataEngine(); return (
{ - return ( - (await titleDoesNotExist(engine, id, value)) || - i18n.t( - `A scorecard with the title '{{value}}' already exists. Please select another title`, - { value } - ) - ); - } - }} />
- +
diff --git a/packages/app/src/modules/ScorecardManagement/hooks/meta.ts b/packages/app/src/modules/ScorecardManagement/hooks/meta.ts index 104ccbcc..218cde75 100644 --- a/packages/app/src/modules/ScorecardManagement/hooks/meta.ts +++ b/packages/app/src/modules/ScorecardManagement/hooks/meta.ts @@ -1,11 +1,11 @@ -import { DATASTORE_NAMESPACE, ScorecardConfig, scorecardConfigSchema } from "@scorecard/shared"; +import { DATASTORE_NAMESPACE, ScorecardConfig } from "@scorecard/shared"; import { useForm } from "react-hook-form"; import { useParams } from "react-router-dom"; import { zodResolver } from "@hookform/resolvers/zod"; import { useDataQuery } from "@dhis2/app-runtime"; import { useGetScorecardSharingSettings } from "../../ScorecardList/hooks/authority"; import { useEffect, useState } from "react"; - +import { useFormSchema } from "./schema"; const query: any = { scorecard: { @@ -25,6 +25,7 @@ export default function useScorecardFormMetadata() { }, lazy: true }); + const schema = useFormSchema(); const getAccess = useGetScorecardSharingSettings(); const form = useForm({ shouldFocusError: true, @@ -35,8 +36,9 @@ export default function useScorecardFormMetadata() { } return {} as ScorecardConfig; }, - reValidateMode: "onChange", - resolver: zodResolver(scorecardConfigSchema) + mode: "onSubmit", + reValidateMode: "onSubmit", + resolver: zodResolver(schema) }); async function getScorecardAccess() { diff --git a/packages/app/src/modules/ScorecardManagement/hooks/schema.ts b/packages/app/src/modules/ScorecardManagement/hooks/schema.ts new file mode 100644 index 00000000..c86bdc09 --- /dev/null +++ b/packages/app/src/modules/ScorecardManagement/hooks/schema.ts @@ -0,0 +1,25 @@ +import { scorecardConfigSchema } from "@scorecard/shared"; +import { z } from "zod"; +import i18n from "@dhis2/d2-i18n"; +import { titleDoesNotExist } from "../components/General/utils/utils"; +import { useParams } from "react-router-dom"; +import { useDataEngine } from "@dhis2/app-runtime"; + + +export function useFormSchema() { + const { id } = useParams(); + 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 } + ); + }), + subtitle: z.string().optional(), + customHeader: z.string().optional(), + description: z.string().optional() + }); +} diff --git a/packages/app/src/modules/ScorecardManagement/index.tsx b/packages/app/src/modules/ScorecardManagement/index.tsx index cc750e05..d7c15318 100644 --- a/packages/app/src/modules/ScorecardManagement/index.tsx +++ b/packages/app/src/modules/ScorecardManagement/index.tsx @@ -6,6 +6,7 @@ import { ManagementTabBar } from "./components/ManagementTabBar"; import { Outlet } from "react-router-dom"; import { TabHeader } from "./components/TabHeader"; import { NavigationButtons, StepNavigationButtons } from "./components/NavigationButtons"; +import { DevTool } from "@hookform/devtools"; export default function ScoreCardManagement() { const { form, access } = useScorecardFormMetadata(); @@ -37,6 +38,7 @@ export default function ScoreCardManagement() {
+ ); } diff --git a/yarn.lock b/yarn.lock index 8e27a747..4431cb7d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3075,7 +3075,7 @@ dependencies: luxon "^3.4.4" -"@hookform/devtools@^4.0.2": +"@hookform/devtools@^4.3.1": version "4.3.1" resolved "https://registry.yarnpkg.com/@hookform/devtools/-/devtools-4.3.1.tgz#5df1b77ea12b4f1c220da3d2dba737f81cbb12bc" integrity sha512-CrWxEoHQZaOXJZVQ8KBgOuAa8p2LI8M0DAN5GTRTmdCieRwFVjVDEmuTAVazWVRRkpEQSgSt3KYp7VmmqXdEnw==