Skip to content

Commit

Permalink
Feat/ha/add geografi section to dataset form (#865)
Browse files Browse the repository at this point in the history
  • Loading branch information
hegeaal authored Oct 29, 2024
1 parent f555d6e commit df5f0ab
Show file tree
Hide file tree
Showing 22 changed files with 1,001 additions and 18 deletions.
4 changes: 4 additions & 0 deletions apps/dataset-catalog/app/actions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export async function createDataset(values: DatasetToBeCreated, catalogId: strin
],
keyword: values?.keywordList ? transformToLocalizedStrings(values?.keywordList) : '',
concepts: values?.conceptList ? convertListToListOfObjects(values.conceptList, 'uri') : [],
spatial: values?.spatialList ? convertListToListOfObjects(values.spatialList, 'uri') : [],
language: values.languageList ? convertListToListOfObjects(values.languageList, 'uri') : [],
};
const datasetNoEmptyValues = removeEmptyValues(newDataset);

Expand Down Expand Up @@ -103,6 +105,8 @@ export async function updateDataset(catalogId: string, initialDataset: Dataset,
],
keyword: values?.keywordList ? transformToLocalizedStrings(values?.keywordList) : '',
concepts: values?.conceptList ? convertListToListOfObjects(values.conceptList, 'uri') : [],
spatial: values?.spatialList ? convertListToListOfObjects(values.spatialList, 'uri') : [],
language: values.languageList ? convertListToListOfObjects(values.languageList, 'uri') : [],
});

const diff = compare(initialDataset, updatedDataset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
getDatasetTypes,
getDataThemes,
getFrequencies,
getLanguages,
getLosThemes,
getOrganization,
getProvenanceStatements,
Expand All @@ -17,6 +18,7 @@ import {
export default async function EditDatasetPage({ params }: Params) {
const { catalogId, datasetId } = params;
const searchEnv = process.env.FDK_SEARCH_SERVICE_BASE_URI ?? '';
const referenceDataEnv = process.env.FDK_BASE_URI ?? '';
const dataset = await getDatasetById(catalogId, datasetId);
const organization: Organization = await getOrganization(catalogId).then((res) => res.json());

Expand All @@ -26,12 +28,14 @@ export default async function EditDatasetPage({ params }: Params) {
datasetTypesResponse,
provenanceStatementsResponse,
frequenciesResponse,
languagesResponse,
] = await Promise.all([
getLosThemes().then((res) => res.json()),
getDataThemes().then((res) => res.json()),
getDatasetTypes().then((res) => res.json()),
getProvenanceStatements().then((res) => res.json()),
getFrequencies().then((res) => res.json()),
getLanguages().then((res) => res.json()),
]);

const referenceData = {
Expand All @@ -40,6 +44,7 @@ export default async function EditDatasetPage({ params }: Params) {
datasetTypes: datasetTypesResponse.datasetTypes,
provenanceStatements: provenanceStatementsResponse.provenanceStatements,
frequencies: frequenciesResponse.frequencies,
languages: languagesResponse.linguisticSystems,
};

const breadcrumbList = [
Expand Down Expand Up @@ -69,6 +74,7 @@ export default async function EditDatasetPage({ params }: Params) {
initialValues={dataset}
submitType={'update'}
searchEnv={searchEnv}
referenceDataEnv={referenceDataEnv}
referenceData={referenceData}
></DatasetForm>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getDatasetTypes,
getDataThemes,
getFrequencies,
getLanguages,
getLosThemes,
getOrganization,
getProvenanceStatements,
Expand All @@ -18,19 +19,22 @@ export default async function NewDatasetPage({ params }: Params) {
const { catalogId } = params;
const organization: Organization = await getOrganization(catalogId).then((res) => res.json());
const searchEnv = process.env.FDK_SEARCH_SERVICE_BASE_URI ?? '';
const referenceDataEnv = process.env.FDK_BASE_URI ?? '';

const [
losThemesResponse,
dataThemesResponse,
datasetTypesResponse,
provenanceStatementsResponse,
frequenciesResponse,
languageResponse
] = await Promise.all([
getLosThemes().then((res) => res.json()),
getDataThemes().then((res) => res.json()),
getDatasetTypes().then((res) => res.json()),
getProvenanceStatements().then((res) => res.json()),
getFrequencies().then((res) => res.json()),
getLanguages().then((res) => res.json())
]);

const referenceData = {
Expand All @@ -39,6 +43,7 @@ export default async function NewDatasetPage({ params }: Params) {
datasetTypes: datasetTypesResponse.datasetTypes,
provenanceStatements: provenanceStatementsResponse.provenanceStatements,
frequencies: frequenciesResponse.frequencies,
languages: languageResponse.linguisticSystems
};

const breadcrumbList = [
Expand All @@ -65,6 +70,7 @@ export default async function NewDatasetPage({ params }: Params) {
submitType={'create'}
referenceData={referenceData}
searchEnv={searchEnv}
referenceDataEnv={referenceDataEnv}
></DatasetForm>
</div>
</>
Expand Down
24 changes: 13 additions & 11 deletions apps/dataset-catalog/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Layout, NextAuthProvider } from '@catalog-frontend/ui';
import { Layout, NextAuthProvider, ReactQueryClientProvider } from '@catalog-frontend/ui';
import { localization } from '@catalog-frontend/utils';
import { Metadata } from 'next';

Expand All @@ -12,16 +12,18 @@ const RootLayout = ({ children }: { children: React.ReactNode }) => {
<html lang={localization.getLanguage()}>
<body>
<NextAuthProvider>
<Layout
catalogAdminUrl={process.env.CATALOG_ADMIN_BASE_URI}
fdkRegistrationBaseUrl={`${process.env.CATALOG_PORTAL_BASE_URI}/catalogs`}
adminGuiBaseUrl={process.env.ADMIN_GUI_BASE_URI}
fdkCommunityBaseUrl={process.env.FDK_COMMUNITY_BASE_URI}
fdkBaseUrl={process.env.FDK_BASE_URI}
catalogTitle={localization.catalogType.service}
>
{children}
</Layout>
<ReactQueryClientProvider>
<Layout
catalogAdminUrl={process.env.CATALOG_ADMIN_BASE_URI}
fdkRegistrationBaseUrl={`${process.env.CATALOG_PORTAL_BASE_URI}/catalogs`}
adminGuiBaseUrl={process.env.ADMIN_GUI_BASE_URI}
fdkCommunityBaseUrl={process.env.FDK_COMMUNITY_BASE_URI}
fdkBaseUrl={process.env.FDK_BASE_URI}
catalogTitle={localization.catalogType.service}
>
{children}
</Layout>
</ReactQueryClientProvider>
</NextAuthProvider>
</body>
</html>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export const ConceptSection = ({ searchEnv }: Props) => {
multiple
value={values.conceptList}
placeholder={localization.datasetForm.helptext.searchConcept}
filter={() => true} // Deactivate filter, handled by backend
>
{suggestions.map((suggestion) => (
<Combobox.Option
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
'use client';
import { AddButton, DeleteButton, FormContainer, TitleWithTag } from '@catalog-frontend/ui';
import { getTranslateText, localization } from '@catalog-frontend/utils';
import { Checkbox, Combobox, Heading, Textfield } from '@digdir/designsystemet-react';
import { useCallback, useState } from 'react';
import { useSearchAdministrativeUnits, useSearchAdministrativeUnitsByUri } from '../../hooks/useReferenceDataSearch';
import { Field, FieldArray, useFormikContext } from 'formik';
import { Dataset, ReferenceDataCode } from '@catalog-frontend/types';
import { debounce, sortBy } from 'lodash';
import styles from './dataset-form.module.css';

interface Props {
envVariable: string;
languages: ReferenceDataCode[];
}

export const GeographySection = ({ envVariable, languages }: Props) => {
const [searchTerm, setSearchTerm] = useState<string>('');
const { values, setFieldValue } = useFormikContext<Dataset>();
const langNOR = languages.filter((lang) => lang.code === 'NOR')[0];

const { data: searchHits, isLoading: isSearching } = useSearchAdministrativeUnits(searchTerm, envVariable);
const { data: selectedValues, isLoading: isLoadingselectedValues } = useSearchAdministrativeUnitsByUri(
values?.spatialList,
envVariable,
);

const debouncedSetSearchTerm = debounce((term: string) => {
setSearchTerm(term);
}, 300);

const handleSearchChange = useCallback((input: any) => {
debouncedSetSearchTerm(input.target.value);
}, []);

const getLocationType = (uri: string): string => {
if (uri.includes('kommune')) return localization.spatial.municipality;
if (uri.includes('fylke')) return localization.spatial.country;
if (uri.includes('nasjon')) return localization.spatial.country;
return '';
};
const customLanguageOrder = [
'http://publications.europa.eu/resource/authority/language/NOB',
'http://publications.europa.eu/resource/authority/language/NNO',
'http://publications.europa.eu/resource/authority/language/ENG',
'http://publications.europa.eu/resource/authority/language/SMI',
];

const sortedLanguages = sortBy(languages, (item) => {
return customLanguageOrder.indexOf(item.uri);
});

const comboboxOptions = [
// Combines selectedValues and searchHits, and add uri's for values not found in selectedValues
...new Map(
[
...(selectedValues ?? []),
...(searchHits ?? []),
...(values.spatialList ?? []).map((uri) => ({
uri,
label:
(selectedValues?.find((item) => item.uri === uri) || searchHits?.find((item) => item.uri === uri))?.label ??
null,
})),
].map((spatial) => [spatial.uri, spatial]),
).values(),
];

return (
<div>
<Heading
size='sm'
spacing
>
{localization.datasetForm.heading.geography}
</Heading>
<FormContainer>
<FormContainer.Header
title={localization.datasetForm.heading.spatial}
subtitle={localization.datasetForm.helptext.spatial}
/>
{!isLoadingselectedValues && (
<Combobox
loading={isSearching}
onChange={handleSearchChange}
placeholder={`${localization.search.search}...`}
virtual
multiple
onValueChange={(selectedValues) => setFieldValue('spatialList', selectedValues)}
value={values.spatialList || []}
filter={() => true} // Deactivates filter. Filtering is handled in the backend.
>
<Combobox.Empty>
{searchTerm.length < 2
? localization.datasetForm.validation.searchString
: `${localization.search.noHits}...`}
</Combobox.Empty>
{comboboxOptions.map((location) => (
<Combobox.Option
value={location.uri}
key={location.uri}
description={getLocationType(location.uri)}
>
{location.label ? getTranslateText(location.label) : location.uri}
</Combobox.Option>
))}
</Combobox>
)}
<FormContainer.Header
title={localization.datasetForm.heading.temporal}
subtitle={localization.datasetForm.helptext.temporal}
/>
<FieldArray
name='temporal'
render={({ remove, push }) => (
<div>
{values.temporal &&
values.temporal.map((_, index) => (
<div
className={styles.date}
key={index}
>
<Field
as={Textfield}
label={
<TitleWithTag
title={localization.from}
tagColor='info'
tagTitle={localization.tag.recommended}
/>
}
type='date'
name={`temporal.${index}.startDate`}
/>
<Field
as={Textfield}
label={
<TitleWithTag
title={localization.to}
tagColor='info'
tagTitle={localization.tag.recommended}
/>
}
type='date'
name={`temporal.${index}.endDate`}
/>
<DeleteButton onClick={() => remove(index)} />
</div>
))}
<div className={styles.fitContent}>
<AddButton onClick={() => push({ startDate: '', endDate: '' })}>
{localization.datasetForm.button.addDate}
</AddButton>
</div>
</div>
)}
/>
<FormContainer.Header
title={localization.datasetForm.heading.releaseDate}
subtitle={localization.datasetForm.helptext.releaseDate}
/>
<Field
className={styles.date}
as={Textfield}
type='date'
name='issued'
/>
<FormContainer.Header
title={localization.datasetForm.heading.language}
subtitle={localization.datasetForm.helptext.language}
/>
<Checkbox.Group
legend={`${localization.choose}...`}
onChange={(values) => setFieldValue('languageList', values)}
value={values.languageList}
>
{values.languageList && values.languageList.includes('NOR') && (
<Checkbox
key={langNOR.uri}
value={langNOR.uri}
>
{getTranslateText(langNOR.label)}
</Checkbox>
)}
{sortedLanguages
.filter((lang) => lang.code !== 'NOR')
.map((lang) => (
<Checkbox
key={lang.uri}
value={lang.uri}
>
{getTranslateText(lang.label)}
</Checkbox>
))}
</Checkbox.Group>
</FormContainer>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,15 @@
grid-template-columns: 20% 55% 20%;
gap: 2.5%;
}

.date {
display: grid;
grid-template-columns: 40% 40% 10%;
gap: 3%;
align-items: flex-end;
padding-bottom: 2rem;
}

.fitContent {
width: fit-content;
}
Loading

0 comments on commit df5f0ab

Please sign in to comment.