diff --git a/apps/metadata-editor-e2e/src/e2e/edit.cy.ts b/apps/metadata-editor-e2e/src/e2e/edit.cy.ts index 7d37930ba8..c017370cb0 100644 --- a/apps/metadata-editor-e2e/src/e2e/edit.cy.ts +++ b/apps/metadata-editor-e2e/src/e2e/edit.cy.ts @@ -218,6 +218,31 @@ describe('editor form', () => { .eq(1) .as('aboutSection') }) + describe('resource identifier', () => { + it('shows the resource identifier', () => { + cy.get('@aboutSection') + .find('gn-ui-form-field-simple') + .first() + .find('input') + .invoke('val') + .should('eq', 'UWWTD_WASTE_WATER_TREATMENT') + }) + it('edits and saves the resource identifiert', () => { + cy.editor_wrapPreviousDraft() + cy.get('gn-ui-form-field-simple').first().find('input').clear() + cy.get('gn-ui-form-field-simple') + .first() + .find('input') + .type('Test - resource identifier') + cy.editor_publishAndReload() + cy.get('@saveStatus').should('eq', 'record_up_to_date') + cy.get('gn-ui-form-field-simple') + .first() + .find('input') + .invoke('val') + .should('eq', 'Test - resource identifier') + }) + }) describe('resource updated', () => { beforeEach(() => { cy.get('@aboutSection') diff --git a/apps/metadata-editor/src/styles.css b/apps/metadata-editor/src/styles.css index 661c2e2930..aeb3e3a1f6 100644 --- a/apps/metadata-editor/src/styles.css +++ b/apps/metadata-editor/src/styles.css @@ -32,3 +32,7 @@ body { .mat-mdc-button-base { line-height: normal; } + +.input-as-button { + @apply border-2 border-gray-300 hover:border-main bg-transparent hover:text-main py-[11.5px] pl-[14px] pr-2; +} diff --git a/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts b/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts index 76fe1ecd7d..6cfa74924b 100644 --- a/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts +++ b/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts @@ -55,6 +55,7 @@ export class DcatApConverter extends BaseConverter { spatialExtents: readSpatialExtents, keywords: readKeywords, topics: readTopics, + resourceIdentifier: () => undefined, recordUpdated: readRecordUpdated, recordCreated: readRecordCreated, resourceUpdated: readResourceUpdated, @@ -93,6 +94,7 @@ export class DcatApConverter extends BaseConverter { recordUpdated: () => undefined, recordCreated: () => undefined, recordPublished: () => undefined, + resourceIdentifier: () => undefined, resourceUpdated: () => undefined, resourceCreated: () => undefined, resourcePublished: () => undefined, diff --git a/libs/api/metadata-converter/src/lib/fixtures/generic-dataset+geo2france-plu.iso19139.xml b/libs/api/metadata-converter/src/lib/fixtures/generic-dataset+geo2france-plu.iso19139.xml index b48bdadf60..3110a1b7f7 100644 --- a/libs/api/metadata-converter/src/lib/fixtures/generic-dataset+geo2france-plu.iso19139.xml +++ b/libs/api/metadata-converter/src/lib/fixtures/generic-dataset+geo2france-plu.iso19139.xml @@ -45,13 +45,6 @@ A very interesting dataset (un jeu de données très intéressant) - - - - https://www.geoportail-urbanisme.gouv.fr/document/60036_PLU_20220329 - - - @@ -72,6 +65,13 @@ + + + + 2d974612-70b1-4662-a9f4-c43cbe453773 + + + diff --git a/libs/api/metadata-converter/src/lib/fixtures/generic-dataset.iso19115-3.xml b/libs/api/metadata-converter/src/lib/fixtures/generic-dataset.iso19115-3.xml index 27a38de64f..e1f1c250a7 100644 --- a/libs/api/metadata-converter/src/lib/fixtures/generic-dataset.iso19115-3.xml +++ b/libs/api/metadata-converter/src/lib/fixtures/generic-dataset.iso19115-3.xml @@ -146,6 +146,13 @@ + + + + 2d974612-70b1-4662-a9f4-c43cbe453773 + + + diff --git a/libs/api/metadata-converter/src/lib/fixtures/generic-dataset.iso19139.xml b/libs/api/metadata-converter/src/lib/fixtures/generic-dataset.iso19139.xml index 3ef61f6de0..af343e7be2 100644 --- a/libs/api/metadata-converter/src/lib/fixtures/generic-dataset.iso19139.xml +++ b/libs/api/metadata-converter/src/lib/fixtures/generic-dataset.iso19139.xml @@ -73,6 +73,13 @@ + + + + 2d974612-70b1-4662-a9f4-c43cbe453773 + + + diff --git a/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts b/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts index 39bd90b360..024cdd93f6 100644 --- a/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +++ b/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts @@ -70,6 +70,7 @@ export const GENERIC_DATASET_RECORD: DatasetRecord = { recordCreated: new Date('2021-11-15T09:00:00'), recordPublished: new Date('2022-01-01T10:00:00'), recordUpdated: new Date('2022-02-01T15:12:00'), + resourceIdentifier: '2d974612-70b1-4662-a9f4-c43cbe453773', resourceCreated: new Date('2022-09-01T14:18:19'), resourceUpdated: new Date('2022-12-04T15:12:00'), title: 'A very interesting dataset (un jeu de données très intéressant)', diff --git a/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts b/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts index 6b20e5a56f..156741f698 100644 --- a/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +++ b/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts @@ -146,4 +146,6 @@ Ce lot de données produit en 2019, a été numérisé à partir du PCI Vecteur defaultLanguage: 'fr', otherLanguages: [], translations: {}, + resourceIdentifier: + 'https://www.geoportail-urbanisme.gouv.fr/document/60036_PLU_20220329', } diff --git a/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts b/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts index 72450d8f85..afb3cbc13b 100644 --- a/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +++ b/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts @@ -68,6 +68,7 @@ export const GEOCAT_CH_DATASET_RECORD: DatasetRecord = { abstract: `Perimeter der Alpenkonvention in der Schweiz. Die Alpenkonvention ist ein völkerrechtlicher Vertrag zwischen den acht Alpenländern Deutschland, Frankreich, Italien, Liechtenstein, Monaco, Österreich, Schweiz, Slowenien sowie der Europäischen Union. Das Ziel des Übereinkommens ist der Schutz der Alpen durch eine sektorübergreifende, ganzheitliche und nachhaltige Politik.`, overviews: [], topics: ['planningCadastre', 'planningCadastre_Planning'], + resourceIdentifier: 'ch.are.alpenkonvention', keywords: [ { thesaurus: { diff --git a/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts b/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts index 546b13116f..c2d76808e4 100644 --- a/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +++ b/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts @@ -71,6 +71,7 @@ Toutes ces données sont reprises dans BDR.`, recordCreated: new Date('2019-04-02T12:34:35'), recordUpdated: new Date('2022-06-16T05:01:21'), resourceCreated: new Date('2002-01-01'), + resourceIdentifier: '2d974612-70b1-4662-a9f4-c43cbe453773', resourceUpdated: new Date('2022-06-16'), resourcePublished: new Date('2022-06-16'), onlineResources: [ @@ -644,6 +645,7 @@ export const METAWAL_SERVICE_RECORD: ServiceRecord = { }, recordCreated: new Date('2019-04-02T12:31:58'), recordUpdated: new Date('2022-02-09T11:31:06.766Z'), + resourceIdentifier: '6d2b6fdb-f1ea-4d48-8697-a0c05512f1dc', resourcePublished: new Date('2016-12-01'), securityConstraints: [], title: diff --git a/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts b/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts index 4a7d1b474e..bf3f6e0e51 100644 --- a/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +++ b/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts @@ -34,6 +34,7 @@ import { readOwnerOrganization, readRecordUpdated, readResourceCreated, + readResourceIdentifier, readResourcePublished, readResourceUpdated, readSecurityConstraints, @@ -61,6 +62,7 @@ import { writeOtherConstraints, writeRecordUpdated, writeResourceCreated, + writeResourceIdentifier, writeResourcePublished, writeResourceUpdated, writeSecurityConstraints, @@ -85,6 +87,7 @@ export class Iso19139Converter extends BaseConverter { recordUpdated: readRecordUpdated, recordCreated: () => undefined, // not supported in ISO19139 recordPublished: () => undefined, // not supported in ISO19139 + resourceIdentifier: readResourceIdentifier, resourceUpdated: readResourceUpdated, resourceCreated: readResourceCreated, resourcePublished: readResourcePublished, @@ -124,6 +127,7 @@ export class Iso19139Converter extends BaseConverter { recordUpdated: writeRecordUpdated, recordCreated: () => undefined, // not supported in ISO19139 recordPublished: () => undefined, // not supported in ISO19139 + resourceIdentifier: writeResourceIdentifier, resourceUpdated: writeResourceUpdated, resourceCreated: writeResourceCreated, resourcePublished: writeResourcePublished, @@ -232,6 +236,7 @@ export class Iso19139Converter extends BaseConverter { const onlineResources = this.readers['onlineResources'](rootEl, tr) const otherLanguages = this.readers['otherLanguages'](rootEl, tr) const defaultLanguage = this.readers['defaultLanguage'](rootEl, tr) + const resourceIdentifier = this.readers['resourceIdentifier'](rootEl, tr) if (kind === 'dataset') { const status = this.readers['status'](rootEl, tr) @@ -246,6 +251,7 @@ export class Iso19139Converter extends BaseConverter { return this.afterRecordRead({ uniqueIdentifier, + ...(resourceIdentifier && { resourceIdentifier }), kind, otherLanguages, defaultLanguage, @@ -280,6 +286,7 @@ export class Iso19139Converter extends BaseConverter { } else { return this.afterRecordRead({ uniqueIdentifier, + ...(resourceIdentifier && { resourceIdentifier }), kind, otherLanguages, defaultLanguage, @@ -370,6 +377,8 @@ export class Iso19139Converter extends BaseConverter { this.writers['otherConstraints'](record, rootEl) fieldChanged('onlineResources') && this.writers['onlineResources'](record, rootEl) + fieldChanged('resourceIdentifier') && + this.writers['resourceIdentifier'](record, rootEl) if (record.kind === 'dataset') { fieldChanged('status') && this.writers['status'](record, rootEl) diff --git a/libs/api/metadata-converter/src/lib/iso19139/read-parts.spec.ts b/libs/api/metadata-converter/src/lib/iso19139/read-parts.spec.ts index f33351c880..5580e7390b 100644 --- a/libs/api/metadata-converter/src/lib/iso19139/read-parts.spec.ts +++ b/libs/api/metadata-converter/src/lib/iso19139/read-parts.spec.ts @@ -19,6 +19,7 @@ import { readContacts, readOnlineResources, readOwnerOrganization, + readResourceIdentifier, readSpatialExtents, readTemporalExtents, } from './read-parts' diff --git a/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts b/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts index e1838d9043..4e88f74581 100644 --- a/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +++ b/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts @@ -1124,3 +1124,17 @@ export function readDefaultLanguage(rootEl: XmlElement): LanguageCode { map((lang) => (lang ? LANG_3_TO_2_MAPPER[lang.toLowerCase()] : null)) )(rootEl) } + +export function readResourceIdentifier(rootEl: XmlElement): string { + return pipe( + findIdentification(), + findNestedElement( + 'gmd:citation', + 'gmd:CI_Citation', + 'gmd:identifier', + 'gmd:MD_Identifier', + 'gmd:code' + ), + extractCharacterString() + )(rootEl) +} diff --git a/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts b/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts index bf87b7ba18..b41c13e5c1 100644 --- a/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +++ b/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts @@ -1463,3 +1463,20 @@ export function writeDefaultLanguage( writeAttribute('codeListValue', lang3) )(rootEl) } + +export function writeResourceIdentifier( + record: DatasetRecord, + rootEl: XmlElement +) { + pipe( + findOrCreateIdentification(), + findNestedChildOrCreate('gmd:citation', 'gmd:CI_Citation'), + removeChildrenByName('gmd:identifier'), + record.resourceIdentifier + ? pipe( + createNestedChild('gmd:identifier', 'gmd:MD_Identifier', 'gmd:code'), + writeCharacterString(record.resourceIdentifier) + ) + : noop + )(rootEl) +} diff --git a/libs/common/domain/src/lib/model/record/metadata.model.ts b/libs/common/domain/src/lib/model/record/metadata.model.ts index 1a4403b439..249ef189ec 100644 --- a/libs/common/domain/src/lib/model/record/metadata.model.ts +++ b/libs/common/domain/src/lib/model/record/metadata.model.ts @@ -104,6 +104,7 @@ export interface BaseRecord { updateFrequency?: UpdateFrequency // information related to the resource (dataset, service) + resourceIdentifier?: string contactsForResource: Array resourceCreated?: Date resourcePublished?: Date diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html index 833e5f015e..e7ad7f8d41 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html +++ b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html @@ -5,6 +5,7 @@ [choices]="licenceOptions" [selected]="selectedLicence" (selectValue)="handleLicenceSelection($event)" + [extraBtnClass]="'input-as-button gn-ui-text-input'" > diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.html b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.html index 587ff5eeb9..c9275759a4 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.html +++ b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.html @@ -1,29 +1,8 @@ - diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.spec.ts b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.spec.ts index bcb0f8b7c7..68d785a46e 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.spec.ts +++ b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.spec.ts @@ -1,7 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing' import { FormFieldSimpleComponent } from './form-field-simple.component' -import { FormControl } from '@angular/forms' describe('FormFieldSimpleComponent', () => { let component: FormFieldSimpleComponent @@ -14,7 +13,6 @@ describe('FormFieldSimpleComponent', () => { fixture = TestBed.createComponent(FormFieldSimpleComponent) component = fixture.componentInstance - component.control = new FormControl() fixture.detectChanges() }) diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.ts b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.ts index e09b00ef0a..59a5cc0162 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.ts +++ b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.ts @@ -6,6 +6,7 @@ import { Input, Output, } from '@angular/core' +import { FormsModule } from '@angular/forms' @Component({ selector: 'gn-ui-form-field-simple', @@ -13,35 +14,14 @@ import { styleUrls: ['./form-field-simple.component.css'], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [CommonModule], + imports: [CommonModule, FormsModule], }) export class FormFieldSimpleComponent { - @Input() type: 'date' | 'url' | 'text' | 'number' | 'list' | 'toggle' + @Input() type: 'text' | 'number' @Input() readonly = false @Input() invalid = false @Input() placeholder = '' - @Input() options?: { label: string; value: unknown }[] @Input() value: unknown @Output() valueChange: EventEmitter = new EventEmitter() - - get inputType() { - switch (this.type) { - case 'url': - case 'text': - return 'text' - case 'date': - return 'datetime-local' - case 'number': - return 'number' - case 'toggle': - return 'checkbox' - default: - return '' - } - } - - get isSelect() { - return this.type === 'list' - } } diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html index 9d784ff973..d7802bd204 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +++ b/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html @@ -11,6 +11,7 @@ [selected]="selectedFrequency" (selectValue)="onSelectFrequencyValue($event)" [disabled]="!planned" + [extraBtnClass]="'input-as-button gn-ui-text-input'" > diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html b/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html index 60344f8c67..dc579cb070 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +++ b/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html @@ -62,6 +62,13 @@ (valueChange)="valueChange.emit($event)" > + + +