Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fixed validation issue in maintenance form fields #363

Merged
merged 7 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions src/app/components/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PubliccodeYmlLanguages from "./PubliccodeYmlLanguages";

import { Col, Container, notify, Row } from "design-react-kit";
import { set } from "lodash";
import { useCallback, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import YAML from "yaml";
import licenses from "../../generated/licenses.json";
Expand Down Expand Up @@ -104,6 +104,7 @@ export default function Editor() {
const configCountrySections = countrySection.parse(DEFAULT_COUNTRY_SECTIONS);
const [currentPublicodeYmlVersion, setCurrentPubliccodeYmlVersion] = useState('');
const [isYamlModalVisible, setYamlModalVisibility] = useState(false);
const [isPublicCodeImported, setPublicCodeImported] = useState(false);

const getNestedValue = (obj: PublicCodeWithDeprecatedFields, path: string) => {
return path.split('.').reduce((acc, key) => (acc as never)?.[key], obj);
Expand Down Expand Up @@ -140,6 +141,8 @@ export default function Editor() {
const methods = useForm<PublicCode | PublicCodeWithDeprecatedFields>({
defaultValues,
resolver,
mode: 'onTouched',
reValidateMode: 'onChange'
});
const { getValues, handleSubmit, watch, setValue, reset } = methods;

Expand Down Expand Up @@ -167,6 +170,33 @@ export default function Editor() {
storage: window?.localStorage, // default window.sessionStorage
exclude: [],
});

const resetMaintenance = useCallback((value: Partial<PublicCode>) => {
const maintenanceType = (value as PublicCode).maintenance.type;

if (maintenanceType === "none") {
setValue('maintenance.contacts', [])
setValue('maintenance.contractors', [])
}

if (maintenanceType === "community" || maintenanceType === "internal") {
setValue('maintenance.contractors', [])
}

if (maintenanceType === "contract") {
setValue('maintenance.contacts', [])
}
}, [setValue])

useEffect(() => {
const subscription = watch((value, { name }) => {
if (name === 'maintenance.type') {
resetMaintenance(value as PublicCode);
}
}
)
return () => subscription.unsubscribe()
}, [watch, resetMaintenance])
//#endregion

//#region form action handlers
Expand All @@ -191,6 +221,7 @@ export default function Editor() {
dispatch(resetPubliccodeYmlLanguages());
reset({ ...defaultValues });
checkPubliccodeYmlVersion(getValues() as PublicCode);
setPublicCodeImported(false);
};

const setFormDataAfterImport = async (
Expand All @@ -210,6 +241,8 @@ export default function Editor() {

checkPubliccodeYmlVersion(publicCode);

setPublicCodeImported(true);

const res = await checkWarnings(values)

if (res.warnings.size) {
Expand Down Expand Up @@ -252,7 +285,7 @@ export default function Editor() {
<div className='mt-3'></div>
<FormProvider {...methods}>
<form>
{currentPublicodeYmlVersion &&
{isPublicCodeImported && currentPublicodeYmlVersion &&
<Row xs="1" md="1">
<Col>
<EditorSelect<"publiccodeYmlVersion">
Expand Down Expand Up @@ -455,7 +488,7 @@ export default function Editor() {
loadFileYaml={(file) => loadFileYamlHandler(file)}
trigger={() => submitHandler()}
languages={languages}
yamlLoaded
yamlLoaded={isPublicCodeImported}
/>
<InfoBox />
<YamlModal
Expand Down
124 changes: 63 additions & 61 deletions src/app/components/EditorContacts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,68 +29,70 @@ export default function EditorContacts(): JSX.Element {
return (
<fieldset>
<legend>{t(`publiccodeyml.${fieldName}.label`)}</legend>
{field.value?.length === 0 ? null : (
<Table responsive>
<caption><small>{t(`publiccodeyml.${fieldName}.affiliation.description`)}</small></caption>
<thead>
<tr>
<th className="align-top">#</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.name.label`)} *
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.email.label`)}
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.phone.label`)}
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.affiliation.label`)}
</th>
<th></th>
</tr>
</thead>
<tbody>
{fields.map(({ id }, index) => (
<tr key={id}>
<th scope="row">{index + 1}</th>
{subfields.map((subfield) => {
const { ref, ...reg } = register(
`${fieldName}.${index}.${subfield}`
);

return (
<td key={subfield}>
<Input
{...reg}
innerRef={ref}
valid={
get(errors, `${fieldName}.${index}.${subfield}`) &&
false
}
validationText={get(
errors,
`${fieldName}.${index}.${subfield}.message`
)}
/>
</td>
);
})}
<td>
<Button
color="link"
icon
onClick={() => remove(index)}
size="xs"
>
<Icon icon="it-delete" size="sm" title="Remove feature" />
</Button>
</td>
{field.value?.length === 0
? (<p><small>Nessun contatto presente</small></p>)
: (
<Table responsive>
<caption><small>{t(`publiccodeyml.${fieldName}.affiliation.description`)}</small></caption>
<thead>
<tr>
<th className="align-top">#</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.name.label`)} *
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.email.label`)}
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.phone.label`)}
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.affiliation.label`)}
</th>
<th></th>
</tr>
))}
</tbody>
</Table>
)}
</thead>
<tbody>
{fields.map(({ id }, index) => (
<tr key={id}>
<th scope="row">{index + 1}</th>
{subfields.map((subfield) => {
const { ref, ...reg } = register(
`${fieldName}.${index}.${subfield}`
);

return (
<td key={subfield}>
<Input
{...reg}
innerRef={ref}
valid={
get(errors, `${fieldName}.${index}.${subfield}`) &&
false
}
validationText={get(
errors,
`${fieldName}.${index}.${subfield}.message`
)}
/>
</td>
);
})}
<td>
<Button
color="link"
icon
onClick={() => remove(index)}
size="xs"
>
<Icon icon="it-delete" size="sm" title="Remove feature" />
</Button>
</td>
</tr>
))}
</tbody>
</Table>
)}
<Button
color="primary"
onClick={() =>
Expand Down
120 changes: 61 additions & 59 deletions src/app/components/EditorContractors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,66 +29,68 @@ export default function EditorContractors(): JSX.Element {
return (
<fieldset>
<legend>{t(`publiccodeyml.${fieldName}.label`)}</legend>
{field.value?.length === 0 ? null : (
<Table responsive>
<thead>
<tr>
<th className="align-top">#</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.name.label`)} *
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.until.label`)} *
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.email.label`)}
</th>
<th>{t(`publiccodeyml.${fieldName}.website.label`)}</th>
<th></th>
</tr>
</thead>
<tbody>
{fields.map(({ id }, index) => (
<tr key={id}>
<th scope="row">{index + 1}</th>
{subfields.map((subfield) => {
const { ref, ...reg } = register(
`${fieldName}.${index}.${subfield}`
);

return (
<td key={subfield}>
<Input
{...reg}
innerRef={ref}
type={subfield === "until" ? "date" : "text"}
valid={
get(errors, `${fieldName}.${index}.${subfield}`) &&
false
}
validationText={get(
errors,
`${fieldName}.${index}.${subfield}.message`
)}
/>
</td>
);
})}
<td>
<Button
color="link"
icon
onClick={() => remove(index)}
size="xs"
>
<Icon icon="it-delete" size="sm" title="Remove feature" />
</Button>
</td>
{field.value?.length === 0
? (<p><small>Nessun riferimento presente</small></p>)
: (
<Table responsive>
<thead>
<tr>
<th className="align-top">#</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.name.label`)} *
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.until.label`)} *
</th>
<th className="align-top">
{t(`publiccodeyml.${fieldName}.email.label`)}
</th>
<th>{t(`publiccodeyml.${fieldName}.website.label`)}</th>
<th></th>
</tr>
))}
</tbody>
</Table>
)}
</thead>
<tbody>
{fields.map(({ id }, index) => (
<tr key={id}>
<th scope="row">{index + 1}</th>
{subfields.map((subfield) => {
const { ref, ...reg } = register(
`${fieldName}.${index}.${subfield}`
);

return (
<td key={subfield}>
<Input
{...reg}
innerRef={ref}
type={subfield === "until" ? "date" : "text"}
valid={
get(errors, `${fieldName}.${index}.${subfield}`) &&
false
}
validationText={get(
errors,
`${fieldName}.${index}.${subfield}.message`
)}
/>
</td>
);
})}
<td>
<Button
color="link"
icon
onClick={() => remove(index)}
size="xs"
>
<Icon icon="it-delete" size="sm" title="Remove feature" />
</Button>
</td>
</tr>
))}
</tbody>
</Table>
)}
<Button
color="primary"
onClick={() => append({ name: "", until: "", email: "", website: "" })}
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/EditorScreenshots.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function EditorScreenshots({ lang }: Props): JSX.Element {

const label = t(`publiccodeyml.description.screenshots.label`);
const description = t(`publiccodeyml.description.screenshots.description`);

const errorMessages = control.getFieldState(`description.${lang}.screenshots`).error as unknown as FieldError[]

const add = () => {
Expand All @@ -44,7 +44,7 @@ export default function EditorScreenshots({ lang }: Props): JSX.Element {
<label
className="active"
htmlFor={`description.${lang}.screenshots`}
>{`${label} *`}</label>
>{`${label}`}</label>
<ul className="list-group list-group-flush">
{screenshots.map((screenshot, index) => (
<li
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/EditorUsedBy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function EditorUsedBy(): JSX.Element {
<label
className="active"
htmlFor={`usedby`}
>{`${label} *`}</label>
>{`${label}`}</label>
<ul className="list-group list-group-flush">
{usedBy.map((feat) => (
<li
Expand Down
10 changes: 9 additions & 1 deletion src/app/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,16 @@ export const validator = async (
baseURL = ''
}: ValidatorParams): Promise<Result> => {
if (!IsPublicCodeYmlValid) throw new Error("Validator not ready");

let url = ''
try {
url = new URL(baseURL).href
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (_: unknown) {
console.warn('invalid URL')
}

const res = await IsPublicCodeYmlValid(publiccode, branch, baseURL);
const res = await IsPublicCodeYmlValid(publiccode, branch, url);

const {
publicCode,
Expand Down
Loading