diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 3c22b0b84b..c4e0dd39e4 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -154,6 +154,9 @@ jobs: node-version: ${{ env.NODE_VERSION }} cache: 'npm' + - name: Create pipeline docker image + run: cd tools && docker build . -f pipelines/Dockerfile -t geonetwork/geonetwork-ui-tools-pipelines:latest + - name: Build the backend run: sudo docker-compose -f support-services/docker-compose.yml up -d init diff --git a/apps/datahub-e2e/src/e2e/datasets.cy.ts b/apps/datahub-e2e/src/e2e/datasets.cy.ts index d90c807231..19f7361e65 100644 --- a/apps/datahub-e2e/src/e2e/datasets.cy.ts +++ b/apps/datahub-e2e/src/e2e/datasets.cy.ts @@ -456,4 +456,40 @@ describe('datasets', () => { }) }) }) + + describe('metadata quality', () => { + describe('metadata quality widget not enabled', () => { + it('should not show quality score sorting', () => { + cy.get('@sortBy').find('button').click() + cy.get('.cdk-overlay-container') + .find('[role=listbox]') + .find('button') + .should('have.length', 3) + }) + }) + + describe('metadata quality widget enabled', () => { + beforeEach(() => { + // this will enable metadata quality widget + cy.intercept('GET', '/assets/configuration/default.toml', { + fixture: 'config-with-metadata-quality.toml', + }) + cy.visit('/search') + }) + + it('should display quality widget', () => { + cy.get('@sortBy').selectDropdownOption('desc,createDate') + cy.get('gn-ui-progress-bar') + .eq(0) + .should('have.attr', 'ng-reflect-value', 87) + }) + + it('should display results sorted by quality score', () => { + cy.get('@sortBy').selectDropdownOption('desc,qualityScore') + cy.get('gn-ui-progress-bar') + .eq(0) + .should('have.attr', 'ng-reflect-value', 100) + }) + }) + }) }) diff --git a/apps/datahub-e2e/src/fixtures/config-with-metadata-quality.toml b/apps/datahub-e2e/src/fixtures/config-with-metadata-quality.toml new file mode 100644 index 0000000000..c1e8e6509f --- /dev/null +++ b/apps/datahub-e2e/src/fixtures/config-with-metadata-quality.toml @@ -0,0 +1,12 @@ +[global] +geonetwork4_api_url = "/geonetwork/srv/api" +proxy_path = "" + +[theme] +primary_color = "#c82850" +secondary_color = "#001638" +main_color = "#212029" # All-purpose text color +background_color = "#fdfbff" + +[metadata-quality] +enabled = true diff --git a/apps/datahub/src/app/home/search/search-page/search-page.component.html b/apps/datahub/src/app/home/search/search-page/search-page.component.html index a34de73590..e809dd3cde 100644 --- a/apps/datahub/src/app/home/search/search-page/search-page.component.html +++ b/apps/datahub/src/app/home/search/search-page/search-page.component.html @@ -1,6 +1,6 @@
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 45fb3d014a..ff4dd1bbb9 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,7 +2,6 @@ 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/model/record' -import { MetadataQualityDisplay } from '@geonetwork-ui/ui/elements' import { MetadataQualityConfig, getMetadataQualityConfig, @@ -15,12 +14,11 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, }) export class SearchPageComponent implements OnInit { - isQualitySortable = false - metadataQualityDisplay = {} as MetadataQualityDisplay + metadataQualityDisplay: boolean constructor( private searchRouter: RouterFacade, - private searchFacade: SearchFacade + public searchFacade: SearchFacade ) {} ngOnInit() { @@ -28,18 +26,7 @@ export class SearchPageComponent implements OnInit { 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, - } + this.metadataQualityDisplay = cfg.ENABLED } onMetadataSelection(metadata: CatalogRecord): void { diff --git a/apps/datahub/src/app/record/record-metadata/record-metadata.component.html b/apps/datahub/src/app/record/record-metadata/record-metadata.component.html index e332f92203..654a2eb8a1 100644 --- a/apps/datahub/src/app/record/record-metadata/record-metadata.component.html +++ b/apps/datahub/src/app/record/record-metadata/record-metadata.component.html @@ -24,13 +24,12 @@
-
+

record.metadata.quality

this.searchService.updateFilters(filters)) } - - get hasMetadataQualityWidget() { - return this.metadataQualityDisplay?.widget === true - } } 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 955e5fd35b..dbe43824ce 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,6 +1,5 @@ import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core' import { MdViewFacade } from '@geonetwork-ui/feature/record' -import { MetadataQualityDisplay } from '@geonetwork-ui/ui/elements' import { MetadataQualityConfig, getMetadataQualityConfig, @@ -13,23 +12,13 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, }) export class RecordPageComponent implements OnDestroy { - metadataQualityDisplay: MetadataQualityDisplay = {} as MetadataQualityDisplay + metadataQualityDisplay: boolean 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, - } + this.metadataQualityDisplay = cfg.ENABLED } ngOnDestroy() { document.documentElement.classList.remove('record-page-active') diff --git a/conf/default.toml b/conf/default.toml index 08e255a813..85aca3f8f6 100644 --- a/conf/default.toml +++ b/conf/default.toml @@ -109,27 +109,6 @@ background_color = "#fdfbff" # 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/feature/search/src/lib/results-list/results-list.container.component.html b/libs/feature/search/src/lib/results-list/results-list.container.component.html index e17fcabf85..45ed9d351b 100644 --- a/libs/feature/search/src/lib/results-list/results-list.container.component.html +++ b/libs/feature/search/src/lib/results-list/results-list.container.component.html @@ -2,12 +2,13 @@ - - {{ icon }} + {{ icon }}

{{ labelKey | translate }}

diff --git a/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.spec.ts b/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.spec.ts index 124ca72ada..444998f088 100644 --- a/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.spec.ts +++ b/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.spec.ts @@ -53,7 +53,7 @@ describe('MetadataQualityInfoComponent', () => { fixture.detectChanges() const iconElement = fixture.debugElement.query(By.css('mat-icon')) - expect(iconElement.nativeElement.innerHTML).toBe('warning_amber') + expect(iconElement.nativeElement.innerHTML).toBe('warning') const textElement = fixture.debugElement.query(By.css('.text')) expect(textElement.nativeElement.innerHTML).toBe( @@ -81,7 +81,7 @@ describe('MetadataQualityInfoComponent', () => { fixture.detectChanges() const iconElement = fixture.debugElement.query(By.css('mat-icon')) - expect(iconElement.nativeElement.innerHTML).toBe('warning_amber') + expect(iconElement.nativeElement.innerHTML).toBe('warning') const textElement = fixture.debugElement.query(By.css('.text')) expect(textElement.nativeElement.innerHTML).toBe( diff --git a/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.ts b/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.ts index 57c75a1bb0..1a0891c2e8 100644 --- a/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.ts +++ b/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.ts @@ -33,7 +33,7 @@ export class MetadataQualityItemComponent implements MetadataQualityItem { @Input() value: boolean get icon() { - return this.value ? 'check' : 'warning_amber' + return this.value ? 'check' : 'warning' } get labelKey() { diff --git a/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html b/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html index f24ab4e8b6..d56a5c1067 100644 --- a/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +++ b/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html @@ -1,5 +1,5 @@
@Input() linkHref: string = null - @Input() metadataQualityDisplay: MetadataQualityDisplay + @Input() metadataQualityDisplay: boolean @Output() mdSelect = new EventEmitter() subscription = new Subscription() abstract: string @@ -51,9 +50,6 @@ export class RecordPreviewComponent implements OnInit, OnDestroy { get organization(): Organization { return this.record.ownerOrganization } - get hasMetadataQualityWidget(): boolean { - return this.metadataQualityDisplay?.widget === true - } constructor(protected elementRef: ElementRef) {} diff --git a/libs/ui/search/src/lib/results-list-item/results-list-item.component.ts b/libs/ui/search/src/lib/results-list-item/results-list-item.component.ts index 4edb676732..c8084239f6 100644 --- a/libs/ui/search/src/lib/results-list-item/results-list-item.component.ts +++ b/libs/ui/search/src/lib/results-list-item/results-list-item.component.ts @@ -14,7 +14,6 @@ import { import { RecordPreviewComponent } from '../record-preview/record-preview.component' import { ResultsLayoutConfigItem } from '../results-list/results-layout.config' import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record' -import { MetadataQualityDisplay } from '@geonetwork-ui/ui/elements' @Component({ selector: 'gn-ui-results-list-item', @@ -26,7 +25,7 @@ export class ResultsListItemComponent implements OnChanges, AfterViewInit { @Input() layoutConfig: ResultsLayoutConfigItem @Input() record: CatalogRecord @Input() favoriteTemplate: TemplateRef<{ $implicit: CatalogRecord }> - @Input() metadataQualityDisplay: MetadataQualityDisplay + @Input() metadataQualityDisplay: boolean @Input() linkHref: string @Output() mdSelect = new EventEmitter() initialized = false diff --git a/libs/ui/search/src/lib/results-list/results-list.component.ts b/libs/ui/search/src/lib/results-list/results-list.component.ts index 0297391f84..fc9fa7e424 100644 --- a/libs/ui/search/src/lib/results-list/results-list.component.ts +++ b/libs/ui/search/src/lib/results-list/results-list.component.ts @@ -3,6 +3,7 @@ import { Component, EventEmitter, Input, + OnInit, Output, TemplateRef, } from '@angular/core' @@ -11,7 +12,6 @@ import { ResultsLayoutConfigItem, } from './results-layout.config' import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record' -import { MetadataQualityDisplay } from '@geonetwork-ui/ui/elements' @Component({ selector: 'gn-ui-results-list', @@ -25,6 +25,6 @@ export class ResultsListComponent { DEFAULT_RESULTS_LAYOUT_CONFIG['CARD'] @Input() favoriteTemplate: TemplateRef<{ $implicit: CatalogRecord }> @Input() recordUrlGetter: (record: CatalogRecord) => string - @Input() metadataQualityDisplay: MetadataQualityDisplay + @Input() metadataQualityDisplay: boolean @Output() mdSelect = new EventEmitter() } diff --git a/libs/util/app-config/src/lib/app-config.ts b/libs/util/app-config/src/lib/app-config.ts index 4c5a89142d..ec86a803ca 100644 --- a/libs/util/app-config/src/lib/app-config.ts +++ b/libs/util/app-config/src/lib/app-config.ts @@ -11,8 +11,8 @@ import { GlobalConfig, LayerConfig, MapConfig, - SearchConfig, MetadataQualityConfig, + SearchConfig, ThemeConfig, } from './model' import { TranslateCompiler, TranslateLoader } from '@ngx-translate/core' @@ -245,20 +245,7 @@ export function loadAppConfig() { parsed, 'metadata-quality', [], - [ - 'enabled', - 'sortable', - 'display_widget_in_detail', - 'display_widget_in_search', - 'display_title', - 'display_description', - 'display_topic', - 'display_keywords', - 'display_legal_constraints', - 'display_contact', - 'display_update_frequency', - 'display_organisation', - ], + ['enabled'], warnings, errors ) @@ -268,22 +255,6 @@ export function loadAppConfig() { : ({ ENABLED: parsedMetadataQualitySection.enabled, SORTABLE: parsedMetadataQualitySection.sortable, - DISPLAY_WIDGET_IN_DETAIL: - parsedMetadataQualitySection.display_widget_in_detail, - DISPLAY_WIDGET_IN_SEARCH: - parsedMetadataQualitySection.display_widget_in_search, - DISPLAY_TITLE: parsedMetadataQualitySection.display_title, - DISPLAY_DESCRIPTION: - parsedMetadataQualitySection.display_description, - DISPLAY_TOPIC: parsedMetadataQualitySection.display_topic, - DISPLAY_KEYWORDS: parsedMetadataQualitySection.display_keywords, - DISPLAY_LEGAL_CONSTRAINTS: - parsedMetadataQualitySection.display_legal_constraints, - DISPLAY_CONTACT: parsedMetadataQualitySection.display_contact, - DISPLAY_UPDATE_FREQUENCY: - parsedMetadataQualitySection.display_update_frequency, - DISPLAY_ORGANISATION: - parsedMetadataQualitySection.display_organisation, } as MetadataQualityConfig) customTranslations = parseTranslationsConfigSection( diff --git a/libs/util/app-config/src/lib/model.ts b/libs/util/app-config/src/lib/model.ts index ba04e7211e..cc7c981dcb 100644 --- a/libs/util/app-config/src/lib/model.ts +++ b/libs/util/app-config/src/lib/model.ts @@ -54,17 +54,6 @@ export interface SearchConfig { export interface MetadataQualityConfig { ENABLED: boolean - SORTABLE: boolean - DISPLAY_WIDGET_IN_DETAIL: boolean - DISPLAY_WIDGET_IN_SEARCH: boolean - DISPLAY_TITLE: boolean - DISPLAY_DESCRIPTION: boolean - DISPLAY_TOPIC: boolean - DISPLAY_KEYWORDS: boolean - DISPLAY_LEGAL_CONSTRAINTS: boolean - DISPLAY_CONTACT: boolean - DISPLAY_UPDATE_FREQUENCY: boolean - DISPLAY_ORGANISATION: boolean } export type CustomTranslations = { [translationKey: string]: string } diff --git a/support-services/docker-compose.yml b/support-services/docker-compose.yml index 340c104943..8ee3b01ff6 100644 --- a/support-services/docker-compose.yml +++ b/support-services/docker-compose.yml @@ -99,6 +99,17 @@ services: ports: - '8080:8080' + init-pipeline: + image: geonetwork/geonetwork-ui-tools-pipelines:latest + environment: + ES_HOST: http://elasticsearch:9200 + RECORDS_INDEX: gn-records + depends_on: + geonetwork: + condition: service_healthy + elasticsearch: + condition: service_healthy + init: image: alpine/curl # only run init if volumes were cleared @@ -110,6 +121,8 @@ services: condition: service_healthy elasticsearch: condition: service_healthy + init-pipeline: + condition: service_completed_successfully healthcheck: test: ['CMD-SHELL', "sh -c '[ -f /done ]'"] interval: 5s diff --git a/support-services/docker-entrypoint.d/02-set-default-pipeline.sh b/support-services/docker-entrypoint.d/02-set-default-pipeline.sh new file mode 100755 index 0000000000..42108454bf --- /dev/null +++ b/support-services/docker-entrypoint.d/02-set-default-pipeline.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +indexConfigDir=/mnt/geonetwork_data/config/index/ + +echo "Setting default pipeline to geonetwork-ui ..." +jq '.settings.index.default_pipeline = "geonetwork-ui"' ${indexConfigDir}records.json > /tmp.json +mv /tmp.json ${indexConfigDir}records.json diff --git a/tools/README.md b/tools/README.md index 3b22f38909..cb8f1da6fb 100644 --- a/tools/README.md +++ b/tools/README.md @@ -18,7 +18,7 @@ offering greater control over the values returned by ElasticSearch and giving an A CLI is provided to let you register or clear GeoNetwork-UI-related pipelines on an ES instance. For example: ```shell -node pipelines/regiser-es-pipelines.js register --host=http://localhost:9200 --records-index=gn-records +node pipelines/register-es-pipelines.js register --host=http://localhost:9200 --records-index=gn-records ``` A docker image can also be built to register the pipelines automatically in a docker environment: