-
+
diff --git a/apps/datahub/src/app/home/search/search-page/search-page.component.ts b/apps/datahub/src/app/home/search/search-page/search-page.component.ts
index 76fb7f142d..24f77cbfd0 100644
--- a/apps/datahub/src/app/home/search/search-page/search-page.component.ts
+++ b/apps/datahub/src/app/home/search/search-page/search-page.component.ts
@@ -2,6 +2,11 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'
import { RouterFacade } from '@geonetwork-ui/feature/router'
import { SearchFacade } from '@geonetwork-ui/feature/search'
import { CatalogRecord } from '@geonetwork-ui/common/domain/record'
+import { MetadataQualityDisplay } from '@geonetwork-ui/ui/elements'
+import {
+ MetadataQualityConfig,
+ getMetadataQualityConfig,
+} from '@geonetwork-ui/util/app-config'
@Component({
selector: 'datahub-search-page',
@@ -10,6 +15,9 @@ import { CatalogRecord } from '@geonetwork-ui/common/domain/record'
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SearchPageComponent implements OnInit {
+ isQualitySortable = false
+ metadataQualityDisplay = {} as MetadataQualityDisplay
+
constructor(
private searchRouter: RouterFacade,
private searchFacade: SearchFacade
@@ -17,6 +25,21 @@ export class SearchPageComponent implements OnInit {
ngOnInit() {
this.searchFacade.setResultsLayout('ROW')
+
+ const cfg: MetadataQualityConfig =
+ getMetadataQualityConfig() || ({} as MetadataQualityConfig)
+ this.isQualitySortable = cfg.SORTABLE === true
+ this.metadataQualityDisplay = {
+ widget: cfg.ENABLED && cfg.DISPLAY_WIDGET_IN_SEARCH !== false,
+ title: cfg.DISPLAY_TITLE,
+ description: cfg.DISPLAY_DESCRIPTION,
+ contact: cfg.DISPLAY_CONTACT,
+ keywords: cfg.DISPLAY_KEYWORDS,
+ legalConstraints: cfg.DISPLAY_LEGAL_CONSTRAINTS,
+ topic: cfg.DISPLAY_TOPIC,
+ updateFrequency: cfg.DISPLAY_UPDATE_FREQUENCY,
+ organisation: cfg.DISPLAY_ORGANISATION,
+ }
}
onMetadataSelection(metadata: CatalogRecord): void {
diff --git a/apps/datahub/src/app/record/record-page/record-page.component.html b/apps/datahub/src/app/record/record-page/record-page.component.html
index 6454073fae..a4b8388ae1 100644
--- a/apps/datahub/src/app/record/record-page/record-page.component.html
+++ b/apps/datahub/src/app/record/record-page/record-page.component.html
@@ -2,5 +2,7 @@
-
+
diff --git a/apps/datahub/src/app/record/record-page/record-page.component.ts b/apps/datahub/src/app/record/record-page/record-page.component.ts
index 29db0c9715..955e5fd35b 100644
--- a/apps/datahub/src/app/record/record-page/record-page.component.ts
+++ b/apps/datahub/src/app/record/record-page/record-page.component.ts
@@ -1,5 +1,10 @@
import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core'
import { MdViewFacade } from '@geonetwork-ui/feature/record'
+import { MetadataQualityDisplay } from '@geonetwork-ui/ui/elements'
+import {
+ MetadataQualityConfig,
+ getMetadataQualityConfig,
+} from '@geonetwork-ui/util/app-config'
@Component({
selector: 'datahub-record-page',
@@ -8,8 +13,23 @@ import { MdViewFacade } from '@geonetwork-ui/feature/record'
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RecordPageComponent implements OnDestroy {
+ metadataQualityDisplay: MetadataQualityDisplay = {} as MetadataQualityDisplay
+
constructor(public mdViewFacade: MdViewFacade) {
document.documentElement.classList.add('record-page-active')
+ const cfg: MetadataQualityConfig =
+ getMetadataQualityConfig() || ({} as MetadataQualityConfig)
+ this.metadataQualityDisplay = {
+ widget: cfg.ENABLED && cfg.DISPLAY_WIDGET_IN_DETAIL !== false,
+ title: cfg.DISPLAY_TITLE,
+ description: cfg.DISPLAY_DESCRIPTION,
+ contact: cfg.DISPLAY_CONTACT,
+ keywords: cfg.DISPLAY_KEYWORDS,
+ legalConstraints: cfg.DISPLAY_LEGAL_CONSTRAINTS,
+ topic: cfg.DISPLAY_TOPIC,
+ updateFrequency: cfg.DISPLAY_UPDATE_FREQUENCY,
+ organisation: cfg.DISPLAY_ORGANISATION,
+ }
}
ngOnDestroy() {
document.documentElement.classList.remove('record-page-active')
diff --git a/apps/webcomponents/src/assets/i18n/en.json b/apps/webcomponents/src/assets/i18n/en.json
index ddc1c8a84a..4375eb8625 100644
--- a/apps/webcomponents/src/assets/i18n/en.json
+++ b/apps/webcomponents/src/assets/i18n/en.json
@@ -22,6 +22,7 @@
"results.sortBy.dateStamp": "Most recent",
"results.sortBy.popularity": "Popularity",
"results.sortBy.relevancy": "Relevancy",
+ "results.sortBy.qualityScore": "Quality score",
"search.field.any.placeholder": "Search datasets, services and maps ...",
"search.field.sortBy": "Sort by",
"search.loading": "Loading ..."
diff --git a/conf/default.toml b/conf/default.toml
index 44903cbe7f..6dbf06558b 100644
--- a/conf/default.toml
+++ b/conf/default.toml
@@ -95,6 +95,36 @@ background_color = "#fdfbff"
# Search presets will be advertised to the user along the main search field.
+
+### METADATA QUALITY SETTINGS
+
+# This section contains settings used for fine-tuning the metadata quality experience
+[metadata-quality]
+# By default the widget is not activated to enable it, just add this parameter.
+# enabled = true
+# If u want to use metadata quality widget this configuration is required
+
+# if you add an indexed field to calculate the qualityScore, the datahub search allow you to sort on this field with this parameter
+# sortable = true
+
+# by default the widget appears in 2 locations in the search list and in the detail page
+# allow you to hide the widget in detail
+# display_widget_in_detail = false
+# allow you to hide the widget in search list
+# display_widget_in_search = false
+# If you want see the widget in the two locations, don't fill theses configurations
+
+# By default the window popup all fields to view if they are filled or not but you can hide some
+# display_title = false
+# display_description = false
+# display_topic = false
+# display_keywords = false
+# display_legal_constraints = false
+# display_contact = false
+# display_update_frequency = false
+# display_organisation = false
+# If you want see all fields, don't fill theses configurations
+
### MAP SETTINGS
# The map section allows to customize how maps are configured.
diff --git a/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts b/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts
index 428feae900..cbd1e2d35e 100644
--- a/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts
+++ b/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts
@@ -53,6 +53,10 @@ export class Gn4FieldMapper {
const landingPage = getAsUrl(this.metadataUrlService.getUrl(uuid))
return { ...output, uniqueIdentifier: uuid, landingPage }
},
+ qualityScore: (output, source) => ({
+ ...output,
+ qualityScore: selectField(source, 'qualityScore'),
+ }),
resourceTitleObject: (output, source) => ({
...output,
title: selectFallback(
@@ -83,6 +87,12 @@ export class Gn4FieldMapper {
],
}
},
+ cl_topic: (output, source) => ({
+ ...output,
+ topic: getAsArray(
+ selectField
(source, 'cl_topic')
+ ).map((topic) => selectTranslatedValue(topic, this.lang3)),
+ }),
cl_status: (output, source) => ({
...output,
status: getStatusFromStatusCode(
@@ -249,6 +259,18 @@ export class Gn4FieldMapper {
...output,
...(fieldName.endsWith('UseLimitationObject')
? {
+ legalConstraints:
+ fieldName === 'MD_LegalConstraintsUseLimitationObject'
+ ? [
+ ...(output.legalConstraints || []),
+ ...selectField(
+ source,
+ fieldName
+ ).map((source: SourceWithUnknownProps) =>
+ selectTranslatedValue(source, this.lang3)
+ ),
+ ]
+ : output.legalConstraints || [],
useLimitations: [
...(output.useLimitations || []),
...selectField(source, fieldName).map(
diff --git a/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.spec.ts b/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.spec.ts
index ca8015d7ed..93b1d5c6b7 100644
--- a/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.spec.ts
+++ b/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.spec.ts
@@ -611,6 +611,7 @@ describe('Gn4MetadataMapper', () => {
landingPage: new URL(
'http://my.catalog.org/metadata/cf5048f6-5bbf-4e44-ba74-e6f429af51ea'
),
+ legalConstraints: ["Restriction légale d'utilisation à préciser"],
licenses: [
{
link: new URL(
@@ -637,6 +638,7 @@ describe('Gn4MetadataMapper', () => {
status: 'under_development',
themes: ['Installations de suivi environnemental'],
title: 'Surval - Données par paramètre',
+ topic: ['Océans'],
uniqueIdentifier: 'cf5048f6-5bbf-4e44-ba74-e6f429af51ea',
updateFrequency: {
per: 'day',
diff --git a/libs/api/repository/src/lib/gn4/elasticsearch/constant.ts b/libs/api/repository/src/lib/gn4/elasticsearch/constant.ts
index bff735b7d4..f3faeb88a3 100644
--- a/libs/api/repository/src/lib/gn4/elasticsearch/constant.ts
+++ b/libs/api/repository/src/lib/gn4/elasticsearch/constant.ts
@@ -11,7 +11,14 @@ export const ES_SOURCE_SUMMARY = [
'linkProtocol',
'contactForResource.organisation',
'contact.organisation',
+ 'contact.email',
'userSavedCount',
+ 'updateFrequency',
+ 'cl_topic',
+ 'cl_maintenanceAndUpdateFrequency',
+ 'tag',
+ 'MD_LegalConstraintsUseLimitationObject',
+ 'qualityScore'
]
export const ES_QUERY_STRING_FIELDS = [
diff --git a/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.spec.ts b/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.spec.ts
index 4dbe744ef7..b21a496d54 100644
--- a/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.spec.ts
+++ b/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.spec.ts
@@ -434,7 +434,14 @@ describe('ElasticsearchService', () => {
'linkProtocol',
'contactForResource.organisation',
'contact.organisation',
+ 'contact.email',
'userSavedCount',
+ "updateFrequency",
+ "cl_topic",
+ "cl_maintenanceAndUpdateFrequency",
+ "tag",
+ "MD_LegalConstraintsUseLimitationObject",
+ "qualityScore",
],
query: {
bool: {
diff --git a/libs/common/domain/src/lib/record/metadata.model.ts b/libs/common/domain/src/lib/record/metadata.model.ts
index a1b74566c4..8778094e86 100644
--- a/libs/common/domain/src/lib/record/metadata.model.ts
+++ b/libs/common/domain/src/lib/record/metadata.model.ts
@@ -58,10 +58,14 @@ export interface BaseRecord {
keywords: Array // TODO: handle thesaurus and id
accessConstraints: Array
useLimitations: Array
+ legalConstraints?: Array
licenses: Array
overviews: Array
extras?: Record
landingPage?: URL
+ topic?: Array
+ updateFrequency?: UpdateFrequency
+ qualityScore?: number
// to add: iso19139.topicCategory
// to add: canonical url
@@ -136,7 +140,6 @@ export interface DatasetRecord extends BaseRecord {
kind: 'dataset'
contactsForResource: Array
status: RecordStatus
- updateFrequency: UpdateFrequency
datasetCreated?: Date
datasetUpdated?: Date
lineage: string // Explanation of the origin of this record (e.g: how, why)"
diff --git a/libs/common/domain/src/lib/search/sort-by.model.ts b/libs/common/domain/src/lib/search/sort-by.model.ts
index 86dfded722..bb860ab8e9 100644
--- a/libs/common/domain/src/lib/search/sort-by.model.ts
+++ b/libs/common/domain/src/lib/search/sort-by.model.ts
@@ -4,4 +4,5 @@ export const SortByEnum: Record = {
CREATE_DATE: ['desc', 'createDate'],
POPULARITY: ['desc', 'userSavedCount'],
RELEVANCY: ['desc', '_score'],
+ QUALITY_SCORE: ['desc', 'qualityScore'],
}
diff --git a/libs/feature/record/src/lib/record-metadata/record-metadata.component.html b/libs/feature/record/src/lib/record-metadata/record-metadata.component.html
index 094cb1cf2a..39a654b0fb 100644
--- a/libs/feature/record/src/lib/record-metadata/record-metadata.component.html
+++ b/libs/feature/record/src/lib/record-metadata/record-metadata.component.html
@@ -24,6 +24,15 @@