diff --git a/server/data-source/couchdb-dataset.mjs b/server/data-source/couchdb-dataset.mjs index 4de05e6..ab991ca 100644 --- a/server/data-source/couchdb-dataset.mjs +++ b/server/data-source/couchdb-dataset.mjs @@ -1,6 +1,6 @@ import { getId, getTypes, getEntityByIri, getString, getStrings, getResource, getResources, getPlainStrings, getPlainString, getEntityByType, getValue } from "./shared/jsonld.mjs"; import { selectForLanguages } from "./shared/couchdb-response.mjs"; -import { DCTERMS, DCAT, VCARD, SKOS, SGOV, EUA, ADMS, FOAF, OWL, NKOD, PU, SPDX } from "./shared/vocabulary.mjs"; +import { DCTERMS, DCAT, VCARD, SKOS, SGOV, EUA, ADMS, FOAF, OWL, NKOD, PU, SPDX , EUROPE} from "./shared/vocabulary.mjs"; export function createCouchDbDataset(couchDbConnector) { return { @@ -72,6 +72,7 @@ function jsonldToDataset(jsonld, iri) { loadDatasetTemporal(jsonld, entity, result); loadDatasetOptional(entity, result); loadDatasetNationalCatalog(jsonld, entity, result); + loadDatasetHighValueDatasets(entity, result); return result; } @@ -121,6 +122,8 @@ function createEmptyDataset(iri) { "isFromVdf": false, "isCodelist": false, "vdfOriginator": null, + "applicableLegislation": [], + "hvdCategory": [], } } @@ -230,11 +233,16 @@ function loadDatasetNationalCatalog(jsonld, entity, dataset) { const types = getTypes(entity); dataset.isFromForm = types.includes(NKOD.SourceForm); dataset.isFromCatalog = types.includes(NKOD.SourceLkod); - dataset.isFromVDF = types.includes(NKOD.Vdf); + dataset.isFromVdf = types.includes(NKOD.Vdf); dataset.isCodelist = types.includes(NKOD.CodeList); dataset.vdfOriginator = getResource(entity, NKOD.originator); } +function loadDatasetHighValueDatasets(entity, dataset) { + dataset.applicableLegislation = getResources(entity, EUROPE.applicableLegislation); + dataset.hvdCategory = getResources(entity, EUROPE.hvdCategory); +} + function jsonldToDistribution(jsonld, iri) { const entity = getEntityByIri(jsonld, iri); if (entity === null) { @@ -263,6 +271,7 @@ function jsonldToDistribution(jsonld, iri) { "compressFormat": getResource(entity, DCAT.compressFormat), "type": "Distribution", "legal": loadDistributionLegal(jsonld, entity), + "applicableLegislation": getResources(entity, EUROPE.applicableLegislation), }; const accessServiceIri = getResource(entity, DCAT.accessService); @@ -304,6 +313,7 @@ function loadDistributionDataService(jsonld, iri) { "endpointDescription": getResource(entity, DCAT.endpointDescription), "endpointURL": getResource(entity, DCAT.endpointURL), "conformsTo": getResources(entity, DCTERMS.conformsTo), + "applicableLegislation": getResources(entity, EUROPE.applicableLegislation), } } @@ -314,6 +324,7 @@ function createEmptyDataService() { "endpointDescription": null, "endpointURL": null, "conformsTo": [], + "applicableLegislation": [], }; } diff --git a/server/data-source/shared/vocabulary.mjs b/server/data-source/shared/vocabulary.mjs index e4fad1e..f9cbf36 100644 --- a/server/data-source/shared/vocabulary.mjs +++ b/server/data-source/shared/vocabulary.mjs @@ -201,3 +201,10 @@ export const LP = { export const SGOV = { "ObjectType": "https://slovník.gov.cz/základní/pojem/typ-objektu", }; + +const EUROPE_PREFIX = "http://data.europa.eu/r5r/"; + +export const EUROPE = { + "applicableLegislation": EUROPE_PREFIX + "applicableLegislation", + "hvdCategory": EUROPE_PREFIX + "hvdCategory", +}; diff --git a/server/data-source/solr-dataset.mjs b/server/data-source/solr-dataset.mjs index 509018f..e04caec 100644 --- a/server/data-source/solr-dataset.mjs +++ b/server/data-source/solr-dataset.mjs @@ -57,7 +57,9 @@ function buildDatasetsQuery(language, query) { sort, sortDirection, offset, - limit + limit, + hvdCategory, + applicableLegislation, } = query; const fq = [ ...prepareFieldQuery("publisher", publisher), @@ -66,6 +68,8 @@ function buildDatasetsQuery(language, query) { ...prepareFieldQuery("file_type", format), ...prepareFieldQuery("data_service_type", dataServiceType), ...prepareFieldQuery("is_part_of", isPartOf), + ...prepareFieldQuery("hvd_category", hvdCategory), + ...prepareFieldQuery("applicable_legislation", applicableLegislation), ]; if (temporalStart !== null) { fq.push(`temporal_start:[* TO ${temporalStart}T00:00:00Z]`); @@ -86,6 +90,7 @@ function buildDatasetsQuery(language, query) { "data_service_type", "publisher", "theme", + "hvd_category", ], "fl": [ "iri", @@ -94,6 +99,7 @@ function buildDatasetsQuery(language, query) { "description_cs", "description_en", "file_type", + "applicable_legislation", ], "fq": fq, "sort": prepareSort(language, sort, sortDirection), @@ -116,6 +122,7 @@ function parseDatasetsResponse(languages, response) { "title": selectLanguage(document, "title_", languages), "description": selectLanguage(document, "description_", languages), "file_type": document["file_type"] ?? [], + "applicable_legislation": document["applicable_legislation"] ?? [], })); const facet_fields = response["facet_counts"]["facet_fields"]; @@ -125,6 +132,7 @@ function parseDatasetsResponse(languages, response) { "dataServiceType": parseFacet(facet_fields["data_service_type"]), "publisher": parseFacet(facet_fields["publisher"]), "theme": parseFacet(facet_fields["theme"]), + "hvdCategory": parseFacet(facet_fields["hvd_category"]), }; return { diff --git a/server/http/dataset-detail/dataset-detail-cs.html b/server/http/dataset-detail/dataset-detail-cs.html index 95fcf8f..5cf9f0e 100644 --- a/server/http/dataset-detail/dataset-detail-cs.html +++ b/server/http/dataset-detail/dataset-detail-cs.html @@ -1,44 +1,64 @@ - + + {{> head }} - {{dataset.heading.title}} - Národní katalog otevřených dat (NKOD) + + {{#with navigation}} {{> navigation }} {{/with}} {{#with dataset}} - + {{#with heading}} -

{{title}}

- - - - - - {{/with}} - {{#with publisher}} - -

{{label}}

-
- {{/with}} -
-

- {{breaklines description}} -

+

{{title}}

+ + + + + + {{/with}} + {{#with publisher}} + +

{{label}}

+
+
+ {{/with}} + {{#if applicableLegislationVisible}} +
+ {{#each applicableLegislation}} + {{#if chip}}{{chip.label}}{{/if}} + {{/each}} + + +
    + {{#each applicableLegislation}} +
  • + {{#if chip}}{{chip.label}}{{/if}} + {{label}} +
  • + {{/each}} +
+
+
+ {{/if}} +
{{#each keywords}} - + {{label}} {{/each}}
-
+

+ {{breaklines description}} +

{{#if themesVisible}} @@ -121,7 +141,7 @@

{{label}}

{{#each documentation}}
Zobrazit dokumentaci - +
{{/each}} @@ -142,7 +162,7 @@

{{label}}

{{#each conformsTo}}
{{label}} - +
{{/each}} @@ -161,6 +181,22 @@

{{label}}

{{/if}} + {{#if hvdCategoryVisible}} +
+
Kategorie HVD
+ {{#each hvdCategory}} +
+ + {{label}} + +   + + + +
+ {{/each}} +
+ {{/if}}
{{#if parentDataset}} @@ -174,31 +210,50 @@

{{label}}

{{/with}} {{#with distributions}} {{#if visible}} - +

Distribuce datové sady

-
- + {{#each items}} -
+

{{title}}

{{format}}

-
+ {{#if applicableLegislationVisible}} +
+ {{#each applicableLegislation}} + {{#if chip}}{{chip.label}}{{/if}} + {{/each}} + + +
    + {{#each applicableLegislation}} +
  • + {{#if chip}}{{chip.label}}{{/if}} + {{label}} +
  • + {{/each}} +
+
+
+ {{/if}} +
{{#if missingLegal}} -
+
Podmínky užití distribuce nejsou specifikovány
{{/if}} {{#if dcatApLegal}} -
+ {{/if}} {{#if dcatApCzLegal}}{{#with dcatApCzLegal}} -
-
Podmínky užití distribuce
+
+
+
Podmínky užití distribuce
+
  • {{#with authorship}} @@ -264,14 +319,16 @@
    Podmínky užití distribuce {{/with}}{{/if}} {{#if distribution}}{{#with distribution}} -
    -
    Soubor ke stažení
    +
    +
    +
    Soubor ke stažení
    +
      {{#if downloadArrayVisible}}
    • {{#each downloadArray}} Stáhnout - + {{/each}}
    • {{/if}} @@ -279,7 +336,7 @@
      Soubor ke stažení
    • {{#each schemaArray}} Schéma - + {{/each}}
    • {{/if}} @@ -289,26 +346,68 @@
      Soubor ke stažení
      - +
    Typ média
  • - - + {{#if compressFormat}} +
  • +
    + {{compressFormat.label}} + + + +
    + Formát komprese +
  • + {{/if}} + {{#if packageFormat}} +
  • +
    + {{packageFormat.label}} + + + +
    + Formát balíčku +
  • + {{/if}}
{{/with}}{{/if}} {{#if dataService}}{{#with dataService}} -
-
Datová služba
+
+
+
+ Datová služba +
+ {{#if applicableLegislationVisible}} +
+ {{#each applicableLegislation}} + {{#if chip}}{{chip.label}}{{/if}} + {{/each}} + + +
    + {{#each applicableLegislation}} +
  • + {{#if chip}}{{chip.label}}{{/if}} + {{label}} +
  • + {{/each}} +
+
+
+ {{/if}} +
Typ média {{/if}} - - + {{#if compressFormat}} +
  • +
    + {{compressFormat.label}} + + + +
    + Formát komprese +
  • + {{/if}} + {{#if packageFormat}} +
  • +
    + {{packageFormat.label}} + + + +
    + Formát balíčku +
  • + {{/if}}
    {{/with}}{{/if}} @@ -363,12 +482,12 @@
    Datová služba
    {{/with}} {{#with datasetSeries}} {{#if visible}} - +

    Datové sady této datové série


    -
    +
    {{#each items}} -
    +

    {{title}}

    @@ -386,12 +505,12 @@

    {{title}}

    {{/with}} {{#with applications}} {{#if visible}} - +

    Aplikace využívající tuto datovou sadu


    -
    +
    {{#each items}} -
    +

    {{title}}

    @@ -407,7 +526,8 @@

    {{title}}

    {{#with footer}} {{> footer }} {{/with}} - + + diff --git a/server/http/dataset-detail/dataset-detail-model.mjs b/server/http/dataset-detail/dataset-detail-model.mjs index ff29359..2028b16 100644 --- a/server/http/dataset-detail/dataset-detail-model.mjs +++ b/server/http/dataset-detail/dataset-detail-model.mjs @@ -21,7 +21,7 @@ export async function prepareData(services, languages, query) { }; } - prepareDataset(dataset); + prepareDatasetInPlace(dataset); const distributions = prepareDistributions(dataset); const resourcesToAddLabelsTo = [ @@ -33,11 +33,14 @@ export async function prepareData(services, languages, query) { dataset.frequency, ...dataset.spatial, ...distributions.items.map(item => item.format), + ...dataset.hvdCategory, ]; const resourcesToAddLabelsToWithNoDefault = [ ...dataset.conformsTo, ...distributions.items.map(item => item.mediaType), + ...distributions.items.map(item => item.compressFormat), + ...distributions.items.map(item => item.packageFormat), ]; await services.label.addLabelToResources(languages, resourcesToAddLabelsTo); @@ -53,10 +56,11 @@ export async function prepareData(services, languages, query) { }; }; -function prepareDataset(dataset) { +function prepareDatasetInPlace(dataset) { dataset.themes = dataset.themes.map(iri => ({ iri })); dataset.euroVocThemes = dataset.euroVocThemes.map(iri => ({ iri })); dataset.semanticThemes = dataset.semanticThemes.map(iri => ({ iri })); + dataset.hvdCategory = dataset.hvdCategory.map(iri => ({ iri })); dataset.accessRights = dataset.accessRights.map(iri => ({ iri })); if (dataset.frequency !== null) { @@ -66,7 +70,7 @@ function prepareDataset(dataset) { "iri": dataset.publisher, }; dataset.spatial = dataset.spatial.map(iri => ({ iri })); - dataset.conformsTo = dataset.conformsTo.map(iri => ({iri})); + dataset.conformsTo = dataset.conformsTo.map(iri => ({ iri })); } function prepareDistributions(dataset) { @@ -79,8 +83,11 @@ function prepareDistributions(dataset) { for (const distribution of distributions.items) { distribution.format = { "iri": distribution.format }; distribution.mediaType = distribution.mediaType === null - ? null - : { "iri": distribution.mediaType }; + ? null : { "iri": distribution.mediaType }; + distribution.compressFormat = distribution.compressFormat === null + ? null : { "iri": distribution.compressFormat }; + distribution.packageFormat = distribution.packageFormat === null + ? null : { "iri": distribution.packageFormat }; } return distributions; } @@ -117,3 +124,4 @@ async function fetchDatasetSeries(services, languages, datasetIri) { })), } } + diff --git a/server/http/dataset-detail/dataset-detail-view-html.mjs b/server/http/dataset-detail/dataset-detail-view-html.mjs index 169c70f..4830302 100644 --- a/server/http/dataset-detail/dataset-detail-view-html.mjs +++ b/server/http/dataset-detail/dataset-detail-view-html.mjs @@ -127,6 +127,10 @@ const PERSONAL_DATA_MAP = { }), } +const LEGISLATION_HVD = "http://data.europa.eu/eli/reg_impl/2023/138/oj"; + +const LEGISLATION_DYNAMIC_DATA = "https://www.e-sbirka.cz/eli/cz/sb/1999/106/2024-01-01/dokument/norma/cast_1/par_3a/odst_6"; + export function renderHtml(services, languages, query, data, reply) { if (data == null) { services.http.handleNotFound(services, reply); @@ -138,7 +142,8 @@ export function renderHtml(services, languages, query, data, reply) { const template = services.template.view(ROUTE.DATASET_DETAIL); reply .code(200) - .header("Content-Type", "text/html; charset=utf-8").send(template(templateData)); + .header("Content-Type", "text/html; charset=utf-8") + .send(template(templateData)); } export function prepareTemplateData(configuration, translation, navigation, languages, query, data) { @@ -232,6 +237,15 @@ function prepareDataset(configuration, translation, navigation, { dataset }) { }), "label": dataset.parentDataset.title, }, + // + "hvdCategoryVisible": dataset.hvdCategory.length > 0, + "hvdCategory": dataset.hvdCategory.map(item => ({ + "iri": item.iri, + "href": datasetListNavigation.linkFromServer({ "hvdCategory": [item.iri] }), + "label": item.label, + })), + "applicableLegislationVisible": dataset.applicableLegislation.length > 0, + "applicableLegislation": prepareApplicableLegislation(dataset.applicableLegislation), }; } @@ -359,6 +373,41 @@ function prepareContactPoints(contactPoints) { })); } +function prepareApplicableLegislation(applicableLegislation) { + const result = applicableLegislation.map(url => ({ + url: url, + label: url, + chip: createChipForApplicableLegislation(url), + })); + result.sort((left, right) => { + if (left.chip !== null && right.chip === null) { + return -1; + } + if (left.chip === null && right.chip ==! null) { + return 1; + } + return left.url.localeCompare(right.url, 'en'); + }); + return result; +} + +function createChipForApplicableLegislation(url) { + switch (url) { + case LEGISLATION_HVD: + return { + variant: "error", + label: "HVD", + }; + case LEGISLATION_DYNAMIC_DATA: + return { + variant: "warning", + label: "Dynamická", + }; + default: + return null; + } +} + function prepareDistributions(configuration, translation, navigation, query, data) { if (data.distributions.items.length === 0) { return { @@ -381,6 +430,10 @@ function prepareDistributions(configuration, translation, navigation, query, dat "iri": item.iri, "title": item.title, "format": item.format?.label ?? null, + // We have one on level of a distribution, another on a level of data service. + "applicableLegislationVisible": item.applicableLegislation.length > 0, + "applicableLegislation": prepareApplicableLegislation(item.applicableLegislation), + // ...prepareLegal(translation, item), ...prepareDistribution(item), ...prepareDataService(configuration, item, item.dataService) @@ -506,6 +559,8 @@ function prepareDataService(configuration, distribution, dataService) { "mediaType": mediaType, "compressFormat": distribution.compressFormat, "packageFormat": distribution.packageFormat, + "applicableLegislationVisible": dataService.applicableLegislation.length > 0, + "applicableLegislation": prepareApplicableLegislation(dataService.applicableLegislation), }, }; } @@ -561,6 +616,6 @@ function prepareDatasetMetadata({ dataset, distributions }) { "@type": "DataDownload", "contentUrl": distribution.downloadURL?.[0] ?? distribution.accessURL, "encodingFormat": distribution.format.label, - })), + })), } } diff --git a/server/http/dataset-list/dataset-list-cs.html b/server/http/dataset-list/dataset-list-cs.html index 1be96f9..d012846 100644 --- a/server/http/dataset-list/dataset-list-cs.html +++ b/server/http/dataset-list/dataset-list-cs.html @@ -3,17 +3,19 @@ {{> head }} - Datové sady - Národní katalog otevřených dat (NKOD) + + + {{#with navigation}} {{> navigation }} {{/with}} - + {{#each facets}} {{>facet}} {{/each}} @@ -32,19 +34,19 @@

    Rozšířené vyhledávání