Skip to content

Commit

Permalink
feat: add tema section to dataset form (#832)
Browse files Browse the repository at this point in the history
  • Loading branch information
hegeaal authored and jeffreiffers committed Dec 5, 2024
1 parent d1e6564 commit 854e43d
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 2 deletions.
57 changes: 57 additions & 0 deletions apps/dataset-catalog/app/context/themes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use client';
import { getLosThemes, getDataThemes } from '@catalog-frontend/data-access';
import { LosTheme, DataTheme } from '@catalog-frontend/types';
import React, { createContext, useEffect, useState, ReactNode } from 'react';

type ThemesContextType = {
losThemes: LosTheme[];
dataThemes: DataTheme[];
loading: boolean;
error: string | null;
};

const ThemesContext = createContext<ThemesContextType | undefined>(undefined);

export const ThemesProvider = ({ children }: { children: ReactNode }) => {
const [losThemes, setLosThemes] = useState<LosTheme[]>([]);
const [dataThemes, setDataThemes] = useState<DataTheme[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);

useEffect(() => {
const fetchThemes = async () => {
setLoading(true);
try {
const [los, data] = await Promise.all([getLosThemes(), getDataThemes()]);
const losThemesData = await los.json();
const dataThemesData = await data.json();

setLosThemes(losThemesData.losNodes.flat());
setDataThemes(dataThemesData.dataThemes);
} catch (err) {
console.error(`Failed to fetch reference-data, ${err}`);
} finally {
setLoading(false);
}
};

fetchThemes();
}, []);

const value = {
losThemes,
dataThemes,
loading,
error,
};

return <ThemesContext.Provider value={value}>{children}</ThemesContext.Provider>;
};

export const useThemes = () => {
const context = React.useContext(ThemesContext);
if (context === undefined) {
throw new Error('useThemes must be used within a ThemesProvider');
}
return context;
};
1 change: 1 addition & 0 deletions apps/dataset-catalog/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Layout, NextAuthProvider, ReactQueryClientProvider } from '@catalog-frontend/ui';
import { localization } from '@catalog-frontend/utils';
import { Metadata } from 'next';
import { ThemesProvider } from './context/themes';

export const metadata: Metadata = {
title: localization.catalogType.dataset,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { Dataset, Option } from '@catalog-frontend/types';
import { FormContainer, TitleWithTag } from '@catalog-frontend/ui';
import { useThemes } from '../../app/context/themes/index';
import { Combobox, Spinner } from '@digdir/designsystemet-react';
import { getTranslateText, localization } from '@catalog-frontend/utils';
import { Field, FormikErrors, useFormikContext } from 'formik';
import styles from './dataset-form.module.css';

export const TemaSection = () => {
const { losThemes, dataThemes, loading } = useThemes();
const { setFieldValue, values, errors } = useFormikContext<Dataset>();

const getNameFromLosPath = (path: string): string | string[] => {
const obj = losThemes?.find((obj) => obj.losPaths.includes(path));
return obj ? getTranslateText(obj.name) : [];
};

const getParentNames = (inputPaths: string[]): string => {
const results: string[] = [];

inputPaths.forEach((path) => {
const parts = path.split('/').slice(0, -1);
const parentPath = parts.slice(0, -1).join('/');
const childPath = parts.join('/');

const parentName = getNameFromLosPath(parentPath);
const childName = getNameFromLosPath(childPath);

const formattedResult = `${parentName} - ${childName}`;
results.push(formattedResult);
});

return `${localization.datasetForm.helptext.parentTheme}: ${results.join('; ')}`;
};

const containsFilter = (inputValue: string, option: Option): boolean => {
return option.label.toLowerCase().includes(inputValue.toLowerCase());
};

return (
<FormContainer>
<FormContainer.Header
title={localization.datasetForm.heading.losTheme}
subtitle={localization.datasetForm.helptext.theme}
/>
<>
<div className={styles.combobox}>
<TitleWithTag
title={localization.datasetForm.fieldLabel.losTheme}
tagTitle={localization.tag.recommended}
tagColor='info'
/>
{loading ? (
<div className={styles.spinner}>
<Spinner title={`${localization.loading}...`} />
</div>
) : (
<Field
as={Combobox}
name='losThemeList'
value={values.losThemeList}
multiple
virtual
filter={containsFilter}
placeholder={`${localization.search.search}...`}
onValueChange={(values: string[]) => setFieldValue('losThemeList', values)}
>
<Combobox.Empty>{localization.search.noHits}</Combobox.Empty>
{losThemes?.map((theme) => (
<Combobox.Option
key={theme.uri}
value={theme.uri}
description={getParentNames(theme.losPaths)}
>
{getTranslateText(theme.name)}
</Combobox.Option>
))}
</Field>
)}
</div>
</>
<FormContainer.Header
title={localization.datasetForm.heading.euTheme}
subtitle={localization.datasetForm.helptext.theme}
/>
<>
<div className={styles.combobox}>
<TitleWithTag
title={localization.datasetForm.fieldLabel.euTheme}
tagTitle={localization.tag.required}
/>
{loading ? (
<div className={styles.spinner}>
<Spinner title={`${localization.loading}...`} />
</div>
) : (
<Field
as={Combobox}
multiple
filter={containsFilter}
placeholder={`${localization.search.search}...`}
error={errors.euThemeList}
value={values.euThemeList}
onValueChange={(values: string[]) => setFieldValue('euThemeList', values)}
>
<Combobox.Empty>{localization.search.noHits}</Combobox.Empty>
{dataThemes &&
dataThemes.map((eutheme) => (
<Combobox.Option
key={eutheme.uri}
value={eutheme.uri}
>
{getTranslateText(eutheme.label)}
</Combobox.Option>
))}
</Field>
)}
</div>
</>
</FormContainer>
);
};

export default TemaSection;
4 changes: 2 additions & 2 deletions libs/data-access/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export * from './lib/catalog-history/api';
export * from './lib/concept/api';
export * from './lib/organization/api';
export * from './lib/reference-data/api';
export * from './lib/reference-data/generated/graphql';
export * as ReferenceDataGraphql from './lib/reference-data/generated/graphql';
export * from './lib/search/api';
export * from './lib/code-list/api';
export * from './lib/users/api';
Expand All @@ -17,6 +17,6 @@ export * from './lib/statuses/api';
export * from './lib/datasets/api';
export * from './lib/data-service/api';
export * from './lib/records-of-processing-activities/api';
export * from './lib/strapi/generated/graphql';
export * as StrapiGraphql from './lib/strapi/generated/graphql';
export * from './lib/strapi/service-messages';
export * from './lib/enhetsregisteret';
19 changes: 19 additions & 0 deletions libs/data-access/src/lib/themes/api/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const getLosThemes = async () => {
const resource = `https://staging.fellesdatakatalog.digdir.no/reference-data/los/themes-and-words`; //env-variabel kommer i neste PR
const options = {
headers: {
'Content-Type': 'application/json',
},
};
return await fetch(resource, options);
};

export const getDataThemes = async () => {
const resource = `https://staging.fellesdatakatalog.digdir.no/reference-data/eu/data-themes`; //env-variabel kommer i neste PR
const options = {
headers: {
'Content-Type': 'application/json',
},
};
return await fetch(resource, options);
};
24 changes: 24 additions & 0 deletions libs/types/src/lib/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { UriWIthLabel } from './dataset';
import { LocalizedStrings } from './localization';

export interface LosTheme {
children?: null;
parents?: string[];
isTheme?: boolean;
losPaths: string[];
name?: LocalizedStrings;
definition?: null;
uri: string;
synonyms?: string[];
relatedTerms?: null;
theme?: boolean;
internalId: null;
}

export interface DataTheme {
uri: string;
code?: string;
label: LocalizedStrings;
startUse?: string;
conceptSchema?: UriWIthLabel;
}

0 comments on commit 854e43d

Please sign in to comment.