diff --git a/apps/dataset-catalog/components/dataset-form/components/dataset-form-contact-point-section.tsx b/apps/dataset-catalog/components/dataset-form/components/dataset-form-contact-point-section.tsx new file mode 100644 index 000000000..7fe839067 --- /dev/null +++ b/apps/dataset-catalog/components/dataset-form/components/dataset-form-contact-point-section.tsx @@ -0,0 +1,111 @@ +'use client'; +import { Dataset } from '@catalog-frontend/types'; +import { HelpMarkdown, TitleWithTag } from '@catalog-frontend/ui'; +import { localization } from '@catalog-frontend/utils'; +import { Textfield, Box, Checkbox, CheckboxGroup } from '@digdir/designsystemet-react'; +import { Field, useFormikContext } from 'formik'; +import styles from '../dataset-form.module.css'; +import { useState } from 'react'; + +export const ContactPointSection = () => { + const { setFieldValue, values, errors } = useFormikContext(); + const [selectedFields, setSelectedFields] = useState([ + ...(values.contactPoint?.[0].email ? ['email'] : []), + ...(values.contactPoint?.[0].hasTelephone ? ['hasTelephone'] : []), + ...(values.contactPoint?.[0].organizationUnit ? ['organizationUnit'] : []), + ...(values.contactPoint?.[0].hasURL ? ['hasURL'] : []), + ]); + + const contactPointOptions = [ + { value: 'email', label: localization.email }, + { value: 'hasTelephone', label: localization.telephone }, + { value: 'hasURL', label: localization.contactPoint.form }, + { value: 'organizationUnit', label: localization.contactPoint.organizationUnit }, + ]; + + const handleContactChange = (value: string[]) => { + setSelectedFields(value); + contactPointOptions.forEach((option) => { + if (!value.includes(option.value)) { + setFieldValue(`contactPoint.${option.value}`, null); + } + }); + }; + + return ( + + + {localization.datasetForm.heading.contactPoint} + + {localization.datasetForm.helptext.contactPoint} + + + } + tagTitle={localization.tag.required} + /> + } + onChange={handleContactChange} + > + {contactPointOptions.map((option) => ( + + {option.label} + + ))} + + + {selectedFields.includes('email') && ( + + )} + + {selectedFields.includes('hasTelephone') && ( + + )} + {selectedFields.includes('organizationUnit') && ( + + )} + {selectedFields.includes('hasURL') && ( + + )} + + ); +}; diff --git a/apps/dataset-catalog/components/dataset-form/components/dataset-form-content-section.tsx b/apps/dataset-catalog/components/dataset-form/components/dataset-form-content-section.tsx index 7b1a0e3b4..d741beee8 100644 --- a/apps/dataset-catalog/components/dataset-form/components/dataset-form-content-section.tsx +++ b/apps/dataset-catalog/components/dataset-form/components/dataset-form-content-section.tsx @@ -19,24 +19,22 @@ export const ContentSection = () => {
{values.conformsTo && values.conformsTo.map((_, index) => ( - <> -
- remove(index)}> - - - -
- +
+ remove(index)}> + + + +
))} push({ prefLabel: { nb: '' }, uri: '' })}> diff --git a/apps/dataset-catalog/components/dataset-form/components/dataset-form-information-model-section.tsx b/apps/dataset-catalog/components/dataset-form/components/dataset-form-information-model-section.tsx index b1a45fbe1..1570587ad 100644 --- a/apps/dataset-catalog/components/dataset-form/components/dataset-form-information-model-section.tsx +++ b/apps/dataset-catalog/components/dataset-form/components/dataset-form-information-model-section.tsx @@ -96,8 +96,7 @@ export const InformationModelSection = ({ searchEnv }: Props) => {
{values.informationModel && values.informationModel.map((_, index) => ( - <> - +
{ />
- +
))} push('informationModel')}> diff --git a/apps/dataset-catalog/components/dataset-form/dataset-form.module.css b/apps/dataset-catalog/components/dataset-form/dataset-form.module.css index 80c7558cb..55ff11507 100644 --- a/apps/dataset-catalog/components/dataset-form/dataset-form.module.css +++ b/apps/dataset-catalog/components/dataset-form/dataset-form.module.css @@ -42,3 +42,7 @@ .fitContent { width: fit-content; } + +.field { + padding: 0.5rem 0; +} diff --git a/apps/dataset-catalog/components/dataset-form/index.tsx b/apps/dataset-catalog/components/dataset-form/index.tsx index 71b9c9eb0..f28d2d3b5 100644 --- a/apps/dataset-catalog/components/dataset-form/index.tsx +++ b/apps/dataset-catalog/components/dataset-form/index.tsx @@ -22,6 +22,7 @@ import { QualifiedAttributionsSection } from './components/dataset-form-qualifie import { ExampleDataSection } from './components/dataset-form-example-data-section'; import { RelationsSection } from './components/dataset-form-relations-section'; import { DistributionSection } from './components/dataset-from-distribution/dataset-form-distribution-section'; +import { ContactPointSection } from './components/dataset-form-contact-point-section'; type Props = { initialValues: DatasetToBeCreated | Dataset; @@ -226,6 +227,13 @@ export const DatasetForm = ({ openLicenses={openLicenses} /> + + + ); diff --git a/apps/dataset-catalog/components/dataset-form/utils/dataset-initial-values.tsx b/apps/dataset-catalog/components/dataset-form/utils/dataset-initial-values.tsx index 7e3a03acf..b30289016 100644 --- a/apps/dataset-catalog/components/dataset-form/utils/dataset-initial-values.tsx +++ b/apps/dataset-catalog/components/dataset-form/utils/dataset-initial-values.tsx @@ -62,6 +62,7 @@ export const datasetTemplate = (dataset: Dataset): Dataset => { ...dist, accessServiceList: dist.accessService?.map((service) => service.uri) || [], })), + contactPoint: dataset.contactPoint ?? {}, }; }; @@ -119,6 +120,7 @@ export const datasetToBeCreatedTemplate = (): DatasetToBeCreated => { relations: [{ uri: '', prefLabel: { nb: '' } }], inSeries: '', distribution: [], + contactPoint: {}, }; }; diff --git a/apps/dataset-catalog/components/dataset-form/utils/validation-schema.tsx b/apps/dataset-catalog/components/dataset-form/utils/validation-schema.tsx index bf07b754b..a7ed003ba 100644 --- a/apps/dataset-catalog/components/dataset-form/utils/validation-schema.tsx +++ b/apps/dataset-catalog/components/dataset-form/utils/validation-schema.tsx @@ -1,4 +1,4 @@ -import { httpsRegex, localization } from '@catalog-frontend/utils'; +import { httpsRegex, localization, telephoneNumberRegex } from '@catalog-frontend/utils'; import * as Yup from 'yup'; export const datasetValidationSchema = Yup.object().shape({ @@ -64,6 +64,15 @@ export const datasetValidationSchema = Yup.object().shape({ .url(localization.validation.invalidUrl), }), ), + contactPoint: Yup.array().of( + Yup.object().shape({ + hasURL: Yup.string() + .matches(httpsRegex, localization.validation.invalidProtocol) + .url(localization.validation.invalidUrl), + email: Yup.string().email(localization.validation.invalidEmail), + hasTelephone: Yup.string().matches(telephoneNumberRegex, localization.validation.invalidTlf), + }), + ), }); export const distributionSectionSchema = Yup.object().shape({ diff --git a/libs/types/src/lib/dataset.ts b/libs/types/src/lib/dataset.ts index 55fa9cbde..5978fd8ef 100644 --- a/libs/types/src/lib/dataset.ts +++ b/libs/types/src/lib/dataset.ts @@ -43,6 +43,7 @@ export interface DatasetToBeCreated { relations?: UriWithLabel[]; inSeries?: string; distribution?: Distribution[]; + contactPoint: DatasetContactPoint[]; // Arrays of uris used as helper values for Formik. These properties is not part of the db object. losThemeList?: string[]; euThemeList?: string[]; @@ -92,3 +93,9 @@ export interface Distribution { // Arrays of uris used as helper values for Formik. These properties is not part of the db object. accessServiceList?: string[]; } +interface DatasetContactPoint { + email?: string; + hasTelephone?: string; + hasURL?: string; + organizationUnit?: string; +} diff --git a/libs/utils/src/lib/language/dataset.form.nb.ts b/libs/utils/src/lib/language/dataset.form.nb.ts index 5d00890f6..880cc9839 100644 --- a/libs/utils/src/lib/language/dataset.form.nb.ts +++ b/libs/utils/src/lib/language/dataset.form.nb.ts @@ -36,6 +36,8 @@ export const datasetFormNb = { relationsDataset: 'Oppgi relaterte datasett', relationDatasetSeries: 'Oppgi relaterte datasettserier.', relatedResources: 'Oppgi relaterte ressurser.', + contactPoint: + 'Et kontaktpunkt er informasjon om en organisasjon eller enhet som kan kontaktes for spørsmål eller støtte knyttet til datasettet. Minst ett av feltene må fylles ut for å oppfylle kravet til kontaktpunkt.', }, heading: { description: 'Beskrivelse av datasettet', @@ -75,6 +77,7 @@ export const datasetFormNb = { relationDatasetSeries: 'Relasjoner til datasettserier', relatedResources: 'Relaterte ressurser', distribution: 'Distribusjon', + contactPoint: 'Kontaktpunkt', }, accessRight: { public: 'Allmenn tilgang', diff --git a/libs/utils/src/lib/language/nb.ts b/libs/utils/src/lib/language/nb.ts index 9f2f3b221..58ca68153 100644 --- a/libs/utils/src/lib/language/nb.ts +++ b/libs/utils/src/lib/language/nb.ts @@ -120,6 +120,12 @@ export const nb = { county: 'Fylke', }, + contactPoint: { + contactInformation: 'Kontaktinformasjon', + organizationUnit: 'Kontaktpunkt', + form: 'Kontaktskjema', + }, + search: { noHits: 'Ditt søk ga ingen treff', search: 'Søk',