diff --git a/src/app/components/Editor.tsx b/src/app/components/Editor.tsx
index d50f0df..dec45b7 100644
--- a/src/app/components/Editor.tsx
+++ b/src/app/components/Editor.tsx
@@ -1,7 +1,7 @@
import { FieldErrors, FieldPathByValue, FormProvider, Resolver, useForm } from "react-hook-form";
import PubliccodeYmlLanguages from "./PubliccodeYmlLanguages";
-import { Col, Container, notify, Row } from "design-react-kit";
+import { Col, Container, Icon, notify, Row } from "design-react-kit";
import { set } from "lodash";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -44,6 +44,9 @@ import { resetPubliccodeYmlLanguages, setPubliccodeYmlLanguages } from "../store
import yamlSerializer from "../yaml-serializer";
import { removeDuplicate } from "../yaml-upload";
import EditorUsedBy from "./EditorUsedBy";
+import { WarningModal } from "./WarningModal";
+
+const PUBLIC_CODE_EDITOR_WARNINGS = 'PUBLIC_CODE_EDITOR_WARNINGS'
const validatorFn = async (values: PublicCode) => await validator({ publiccode: JSON.stringify(values), baseURL: values.url });
@@ -105,6 +108,20 @@ export default function Editor() {
const [currentPublicodeYmlVersion, setCurrentPubliccodeYmlVersion] = useState('');
const [isYamlModalVisible, setYamlModalVisibility] = useState(false);
const [isPublicCodeImported, setPublicCodeImported] = useState(false);
+ const [isWarningModalVisible, setWarningModalVisibility] = useState(false);
+ const [warnings, setWarnings] = useState<{ key: string; message: string; }[]>([]);
+
+ useEffect(() => {
+ const warnings = localStorage.getItem(PUBLIC_CODE_EDITOR_WARNINGS);
+
+ if (warnings) {
+ setWarnings(JSON.parse(warnings))
+ }
+ }, [])
+
+ useEffect(() => {
+ localStorage.setItem(PUBLIC_CODE_EDITOR_WARNINGS, JSON.stringify(warnings))
+ }, [warnings])
const getNestedValue = (obj: PublicCodeWithDeprecatedFields, path: string) => {
return path.split('.').reduce((acc, key) => (acc as never)?.[key], obj);
@@ -222,6 +239,7 @@ export default function Editor() {
reset({ ...defaultValues });
checkPubliccodeYmlVersion(getValues() as PublicCode);
setPublicCodeImported(false);
+ setWarnings([])
};
const setFormDataAfterImport = async (
@@ -245,17 +263,19 @@ export default function Editor() {
const res = await checkWarnings(values)
- if (res.warnings.size) {
- const body = Array
- .from(res.warnings)
- .reduce((p, [key, { message }]) => p + `${key}: ${message}`, '')
+ setWarnings(Array.from(res.warnings).map(([key, { message }]) => ({ key, message })));
+
+ const numberOfWarnings = res.warnings.size;
- const _1_MINUTE = 60 * 1 * 1000
+ if (numberOfWarnings) {
+ const body = `ci sono ${numberOfWarnings} warnings`
+
+ const _5_SECONDS = 5 * 1 * 1000
notify("Warnings", body, {
dismissable: true,
state: 'warning',
- duration: _1_MINUTE
+ duration: _5_SECONDS
})
}
}
@@ -281,7 +301,16 @@ export default function Editor() {
-
+
+
+ {!!warnings.length &&
+
+ setWarningModalVisibility(true)} />
+
+ }
+
);
diff --git a/src/app/components/EditorFeatures.tsx b/src/app/components/EditorFeatures.tsx
index 921fd59..add0f69 100644
--- a/src/app/components/EditorFeatures.tsx
+++ b/src/app/components/EditorFeatures.tsx
@@ -1,17 +1,22 @@
+import { Button, Icon, Input, InputGroup } from "design-react-kit";
+import { get } from "lodash";
+import { useEffect, useRef, useState } from "react";
import { useController, useFormContext } from "react-hook-form";
-import PublicCode from "../contents/publiccode";
import { useTranslation } from "react-i18next";
-import { get } from "lodash";
-import { useState } from "react";
-import { Button, Icon, Input, InputGroup } from "design-react-kit";
+import PublicCode from "../contents/publiccode";
+import flattenObject from "../flatten-object-to-record";
+import { removeDuplicate } from "../yaml-upload";
interface Props {
lang: string;
}
export default function EditorFeatures({ lang }: Props): JSX.Element {
+ const formFieldName = `description.${lang}.features` as keyof PublicCode;
+
const { control } = useFormContext();
const {
+ field,
field: { onChange, value },
formState: { errors },
} = useController({
@@ -22,21 +27,34 @@ export default function EditorFeatures({ lang }: Props): JSX.Element {
const { t } = useTranslation();
const features: string[] = value ? (value as string[]) : [];
- const [currFeat, setCurrFeat] = useState("");
+ const [current, setCurrent] = useState("");
const label = t(`publiccodeyml.description.features.label`);
const description = t(`publiccodeyml.description.features.description`);
const errorMessage = get(errors, `description.${lang}.features.message`);
- const addFeature = () => {
- onChange([...features, currFeat.trim()]);
- setCurrFeat("");
+ const add = () => {
+ onChange(removeDuplicate([...features, current.trim()]));
+ setCurrent("");
};
- const removeFeature = (feat: string) => {
+ const remove = (feat: string) => {
onChange(features.filter((elem) => elem !== feat));
};
+ const inputRef = useRef(null);
+
+ useEffect(() => {
+ const errorsRecord = flattenObject(errors as Record);
+ const formFieldKeys = Object.keys(errorsRecord);
+ const isFirstError = formFieldKeys && formFieldKeys.length && formFieldKeys[0] === formFieldName
+
+ if (isFirstError) {
+ inputRef.current?.focus()
+ }
+
+ }, [errors, formFieldName, inputRef])
+
return (
@@ -54,7 +72,7 @@ export default function EditorFeatures({ lang }: Props): JSX.Element {