From 1000d4a8e7d99097136cbd858a2cee184c521ec3 Mon Sep 17 00:00:00 2001 From: Romuald Caplier Date: Wed, 10 Jul 2024 17:03:12 +0200 Subject: [PATCH] feat(metadata-editor): organize fields into pages and sections. --- .../breadcrumbs/page-selector.component.css | 0 .../breadcrumbs/page-selector.component.html | 39 +++ .../page-selector.component.spec.ts | 26 ++ .../breadcrumbs/page-selector.component.ts | 30 +++ .../top-toolbar/top-toolbar.component.html | 2 +- .../src/app/edit/edit-page.component.html | 45 +++- .../src/app/edit/edit-page.component.spec.ts | 12 +- .../src/app/edit/edit-page.component.ts | 44 +++- .../src/app/pipes/filter.pipe.ts | 11 - apps/metadata-editor/tsconfig.json | 6 +- libs/feature/editor/src/index.ts | 1 + .../editor/src/lib/+state/editor.reducer.ts | 4 +- .../src/lib/+state/editor.selectors.spec.ts | 78 +++--- .../editor/src/lib/+state/editor.selectors.ts | 19 +- .../form-field/form-field.component.html | 18 +- .../form-field/form-field.component.spec.ts | 1 - .../form-field/form-field.component.ts | 3 +- .../form-field/form-field.model.ts | 43 ---- .../record-form/form-field/index.ts | 1 - .../record-form/record-form.component.html | 54 +++- .../record-form/record-form.component.spec.ts | 5 +- .../record-form/record-form.component.ts | 28 ++- .../editor/src/lib/expressions.spec.ts | 11 +- libs/feature/editor/src/lib/expressions.ts | 2 +- libs/feature/editor/src/lib/fields.config.ts | 236 +++++++++++++----- .../src/lib/fixtures/editor.fixtures.ts | 158 ++++++++++++ libs/feature/editor/src/lib/fixtures/index.ts | 1 + .../src/lib/models/editor-config.model.ts | 55 ++++ .../editor/src/lib/models/fields.model.ts | 29 --- libs/feature/editor/src/lib/models/index.ts | 1 + .../editor/src/lib/services/editor.service.ts | 12 +- libs/feature/editor/tsconfig.json | 6 +- libs/feature/editor/tsconfig.lib.json | 10 +- libs/util/shared/tsconfig.lib.json | 6 +- translations/de.json | 28 +++ translations/en.json | 28 +++ translations/es.json | 28 +++ translations/fr.json | 28 +++ translations/it.json | 28 +++ translations/nl.json | 28 +++ translations/pt.json | 28 +++ translations/sk.json | 28 +++ 42 files changed, 936 insertions(+), 285 deletions(-) create mode 100644 apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.css create mode 100644 apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.html create mode 100644 apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.spec.ts create mode 100644 apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.ts delete mode 100644 apps/metadata-editor/src/app/pipes/filter.pipe.ts delete mode 100644 libs/feature/editor/src/lib/components/record-form/form-field/form-field.model.ts create mode 100644 libs/feature/editor/src/lib/fixtures/editor.fixtures.ts create mode 100644 libs/feature/editor/src/lib/fixtures/index.ts create mode 100644 libs/feature/editor/src/lib/models/editor-config.model.ts delete mode 100644 libs/feature/editor/src/lib/models/fields.model.ts diff --git a/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.css b/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.html b/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.html new file mode 100644 index 0000000000..b38938f323 --- /dev/null +++ b/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.html @@ -0,0 +1,39 @@ +
+ +
+
+ +
+ {{ index }} +
+
+ {{ page.labelKey }} +
+
+
+
+
+
+
+
+
diff --git a/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.spec.ts b/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.spec.ts new file mode 100644 index 0000000000..0e6f756aed --- /dev/null +++ b/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.spec.ts @@ -0,0 +1,26 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { TranslateModule } from '@ngx-translate/core' +import { PageSelectorComponent } from './page-selector.component' +import { EDITOR_CONFIG } from '@geonetwork-ui/feature/editor' + +describe('BreadcrumbsComponent', () => { + let component: PageSelectorComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + providers: [], + }).compileComponents() + + fixture = TestBed.createComponent(PageSelectorComponent) + component = fixture.componentInstance + component.pages = EDITOR_CONFIG().pages + component.selectedPage = 0 + fixture.detectChanges() + }) + + it('should create', () => { + expect(component).toBeTruthy() + }) +}) diff --git a/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.ts b/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.ts new file mode 100644 index 0000000000..7b3c3df71c --- /dev/null +++ b/apps/metadata-editor/src/app/edit/components/breadcrumbs/page-selector.component.ts @@ -0,0 +1,30 @@ +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + Input, + Output, +} from '@angular/core' +import { CommonModule } from '@angular/common' +import { ButtonComponent } from '@geonetwork-ui/ui/inputs' +import { TranslateModule } from '@ngx-translate/core' +import { EditorFieldPage } from '@geonetwork-ui/feature/editor' + +@Component({ + selector: 'md-editor-page-selector', + standalone: true, + imports: [CommonModule, ButtonComponent, TranslateModule], + templateUrl: './page-selector.component.html', + styleUrls: ['./page-selector.component.css'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PageSelectorComponent { + @Input() selectedPage = 0 + @Input() pages: EditorFieldPage[] + + @Output() selectedPageChange = new EventEmitter() + + pageSectionClickHandler(index: number) { + this.selectedPageChange.emit(index) + } +} diff --git a/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.html b/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.html index aab1948240..89cd41f9d4 100644 --- a/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.html +++ b/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.html @@ -1,4 +1,4 @@ -
+
side_navigation diff --git a/apps/metadata-editor/src/app/edit/edit-page.component.html b/apps/metadata-editor/src/app/edit/edit-page.component.html index 9fc5cfabfe..d93d4aab53 100644 --- a/apps/metadata-editor/src/app/edit/edit-page.component.html +++ b/apps/metadata-editor/src/app/edit/edit-page.component.html @@ -1,11 +1,38 @@ -
-
- -
-
-
- + +
+
+ + +
+
+
+ +
+ +
+
+ + {{ + selectedPage === 0 + ? ('editor.record.form.bottomButtons.comeBackLater' | translate) + : ('editor.record.form.bottomButtons.previous' | translate) + }} + + editor.record.form.bottomButtons.next
-
-
+ diff --git a/apps/metadata-editor/src/app/edit/edit-page.component.spec.ts b/apps/metadata-editor/src/app/edit/edit-page.component.spec.ts index 401d9541ce..36fc290d2d 100644 --- a/apps/metadata-editor/src/app/edit/edit-page.component.spec.ts +++ b/apps/metadata-editor/src/app/edit/edit-page.component.spec.ts @@ -1,12 +1,14 @@ import { ComponentFixture, TestBed } from '@angular/core/testing' import { EditPageComponent } from './edit-page.component' import { ActivatedRoute, Router } from '@angular/router' -import { EditorFacade } from '@geonetwork-ui/feature/editor' +import { EDITOR_CONFIG, EditorFacade } from '@geonetwork-ui/feature/editor' import { NO_ERRORS_SCHEMA } from '@angular/core' import { DATASET_RECORDS } from '@geonetwork-ui/common/fixtures' import { BehaviorSubject, Subject } from 'rxjs' import { NotificationsService } from '@geonetwork-ui/feature/notifications' import { TranslateModule } from '@ngx-translate/core' +import { FindPipe } from '../pipes/filter.pipe' +import { PageSelectorComponent } from './components/breadcrumbs/page-selector.component' const getRoute = () => ({ snapshot: { @@ -25,6 +27,7 @@ class RouterMock { class EditorFacadeMock { record$ = new BehaviorSubject(DATASET_RECORDS[0]) + recordFields$ = new BehaviorSubject(EDITOR_CONFIG()) openRecord = jest.fn() saveError$ = new Subject() saveSuccess$ = new Subject() @@ -42,7 +45,12 @@ describe('EditPageComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [EditPageComponent, TranslateModule.forRoot()], + imports: [ + EditPageComponent, + TranslateModule.forRoot(), + FindPipe, + PageSelectorComponent, + ], schemas: [NO_ERRORS_SCHEMA], providers: [ { diff --git a/apps/metadata-editor/src/app/edit/edit-page.component.ts b/apps/metadata-editor/src/app/edit/edit-page.component.ts index 7327286a2c..8586f05362 100644 --- a/apps/metadata-editor/src/app/edit/edit-page.component.ts +++ b/apps/metadata-editor/src/app/edit/edit-page.component.ts @@ -3,6 +3,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { EditorFacade, + EditorFieldPage, RecordFormComponent, } from '@geonetwork-ui/feature/editor' import { ButtonComponent } from '@geonetwork-ui/ui/inputs' @@ -13,8 +14,14 @@ import { NotificationsContainerComponent, NotificationsService, } from '@geonetwork-ui/feature/notifications' -import { TranslateService } from '@ngx-translate/core' +import { TranslateModule, TranslateService } from '@ngx-translate/core' import { filter, Subscription, take } from 'rxjs' +import { PageSelectorComponent } from './components/breadcrumbs/page-selector.component' +import { marker } from '@biesbjerg/ngx-translate-extract-marker' + +marker('editor.record.form.bottomButtons.comeBackLater') +marker('editor.record.form.bottomButtons.previous') +marker('editor.record.form.bottomButtons.next') @Component({ selector: 'md-editor-edit', @@ -29,18 +36,30 @@ import { filter, Subscription, take } from 'rxjs' PublishButtonComponent, TopToolbarComponent, NotificationsContainerComponent, + PageSelectorComponent, + TranslateModule, ], }) export class EditPageComponent implements OnInit, OnDestroy { subscription = new Subscription() + fields$ = this.facade.recordFields$ + totalPages = 0 + selectedPage = 0 + constructor( private route: ActivatedRoute, private facade: EditorFacade, private notificationsService: NotificationsService, private translateService: TranslateService, private router: Router - ) {} + ) { + this.subscription.add( + this.fields$.subscribe((fields) => { + this.totalPages = fields.pages.length + }) + ) + } ngOnInit(): void { const [currentRecord, currentRecordSource, currentRecordAlreadySaved] = @@ -109,4 +128,25 @@ export class EditPageComponent implements OnInit, OnDestroy { ngOnDestroy() { this.subscription.unsubscribe() } + + getSelectedPageFields(pages: EditorFieldPage[]) { + return pages[this.selectedPage] + } + + previousPageButtonHandler() { + if (this.selectedPage === 0) { + this.router.navigate(['catalog', 'search']) + } else { + this.selectedPage-- + } + } + + nextPageButtonHandler() { + if (this.selectedPage === this.totalPages - 1) return + this.selectedPage++ + } + + selectedPageChange(index: number) { + this.selectedPage = index + } } diff --git a/apps/metadata-editor/src/app/pipes/filter.pipe.ts b/apps/metadata-editor/src/app/pipes/filter.pipe.ts deleted file mode 100644 index 4cbff21914..0000000000 --- a/apps/metadata-editor/src/app/pipes/filter.pipe.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' - -@Pipe({ - name: 'filter', - standalone: true, -}) -export class FilterPipe implements PipeTransform { - transform(array: any[], index: number): any { - return array.find((item) => item.index === index) - } -} diff --git a/apps/metadata-editor/tsconfig.json b/apps/metadata-editor/tsconfig.json index d2c6daf3e1..54f2b40f0e 100644 --- a/apps/metadata-editor/tsconfig.json +++ b/apps/metadata-editor/tsconfig.json @@ -19,11 +19,7 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "target": "es2020", - "lib": [ - "dom", - "es2020", - "dom.iterable" - ], + "lib": ["dom", "es2020", "dom.iterable"], "downlevelIteration": true }, "angularCompilerOptions": { diff --git a/libs/feature/editor/src/index.ts b/libs/feature/editor/src/index.ts index 5e6dd85211..c95afdefd4 100644 --- a/libs/feature/editor/src/index.ts +++ b/libs/feature/editor/src/index.ts @@ -9,3 +9,4 @@ export * from './lib/components/record-form/record-form.component' export * from './lib/components/wizard/wizard.component' export * from './lib/components/wizard-field/wizard-field.component' export * from './lib/components/wizard-summarize/wizard-summarize.component' +export * from './lib/fixtures' diff --git a/libs/feature/editor/src/lib/+state/editor.reducer.ts b/libs/feature/editor/src/lib/+state/editor.reducer.ts index 425e3d0c41..506f3436fb 100644 --- a/libs/feature/editor/src/lib/+state/editor.reducer.ts +++ b/libs/feature/editor/src/lib/+state/editor.reducer.ts @@ -2,7 +2,7 @@ import { Action, createReducer, on } from '@ngrx/store' import * as EditorActions from './editor.actions' import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record' import { SaveRecordError } from './editor.models' -import { EditorFieldsConfig } from '../models/fields.model' +import { EditorConfig } from '../models' import { DEFAULT_FIELDS } from '../fields.config' export const EDITOR_FEATURE_KEY = 'editor' @@ -22,7 +22,7 @@ export interface EditorState { saving: boolean saveError: SaveRecordError | null changedSinceSave: boolean - fieldsConfig: EditorFieldsConfig + fieldsConfig: EditorConfig } export interface EditorPartialState { diff --git a/libs/feature/editor/src/lib/+state/editor.selectors.spec.ts b/libs/feature/editor/src/lib/+state/editor.selectors.spec.ts index 0d61773f97..e3ee07bfd9 100644 --- a/libs/feature/editor/src/lib/+state/editor.selectors.spec.ts +++ b/libs/feature/editor/src/lib/+state/editor.selectors.spec.ts @@ -58,45 +58,26 @@ describe('Editor Selectors', () => { describe('selectRecordFields', () => { it('should return the config and value for each field', () => { const result = EditorSelectors.selectRecordFields(state) - expect(result).toEqual([ - { - config: DEFAULT_FIELDS[0], - value: DATASET_RECORDS[0].title, - }, - { - config: DEFAULT_FIELDS[1], - value: DATASET_RECORDS[0].abstract, - }, - { - config: DEFAULT_FIELDS[2], - value: DATASET_RECORDS[0].uniqueIdentifier, - }, - { - config: DEFAULT_FIELDS[3], - value: DATASET_RECORDS[0].recordUpdated, - }, - { - config: DEFAULT_FIELDS[4], - value: DATASET_RECORDS[0].licenses, - }, - { - config: DEFAULT_FIELDS[5], - value: DATASET_RECORDS[0].resourceUpdated, - }, - { - config: DEFAULT_FIELDS[6], - value: DATASET_RECORDS[0].updateFrequency, - }, - { - config: DEFAULT_FIELDS[7], - value: DATASET_RECORDS[0].temporalExtents, - }, - { - config: DEFAULT_FIELDS[8], - value: DATASET_RECORDS[0].keywords, - }, - ]) + + const actualSections = result.pages.map((page) => page.sections).flat() + + const expectedSections = DEFAULT_FIELDS.pages + .map((page) => page.sections) + .flat() + + expect(actualSections).toEqual(expectedSections) + + const actualFields = actualSections + .map((section) => section.fields) + .flat() + + const expectedFields = expectedSections + .map((section) => section.fields) + .flat() + + expect(actualFields).toEqual(expectedFields) }) + it('should not coerce falsy values to null', () => { const result = EditorSelectors.selectRecordFields({ ...state, @@ -109,14 +90,19 @@ describe('Editor Selectors', () => { }, }, }) - expect(result).toContainEqual({ - config: DEFAULT_FIELDS[0], - value: '', - }) - expect(result).toContainEqual({ - config: DEFAULT_FIELDS[1], - value: '', - }) + + const resultFields = result.pages + .flatMap((page) => page.sections) + .flatMap((section) => section.fields) + + const abstractField = resultFields.find( + (field) => field.model === 'abstract' + ) + + const titleField = resultFields.find((field) => field.model === 'title') + + expect(abstractField.value).toEqual('') + expect(titleField.value).toEqual('') }) }) }) diff --git a/libs/feature/editor/src/lib/+state/editor.selectors.ts b/libs/feature/editor/src/lib/+state/editor.selectors.ts index e9a601da80..3661ace5f1 100644 --- a/libs/feature/editor/src/lib/+state/editor.selectors.ts +++ b/libs/feature/editor/src/lib/+state/editor.selectors.ts @@ -41,9 +41,18 @@ export const selectRecordFieldsConfig = createSelector( export const selectRecordFields = createSelector( selectEditorState, - (state: EditorState) => - state.fieldsConfig.map((fieldConfig) => ({ - config: fieldConfig, - value: state.record?.[fieldConfig.model] ?? null, - })) + (state: EditorState) => { + const fieldsConfig = state.fieldsConfig + fieldsConfig.pages.forEach((page) => { + page.sections.forEach((section) => { + section.fields.forEach((field) => { + if (state.record) { + field.value = state.record[field.model] + } + }) + }) + }) + + return fieldsConfig + } ) 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 98f8503d27..ec1b774a7b 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 @@ -4,8 +4,8 @@ @@ -15,14 +15,14 @@
-

{{ formControl.value }} -

+ help @@ -41,14 +41,14 @@ diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.spec.ts b/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.spec.ts index aa81387dba..6337d1d9b3 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.spec.ts +++ b/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.spec.ts @@ -23,7 +23,6 @@ describe('FormFieldComponent', () => { fixture = TestBed.createComponent(FormFieldComponent) component = fixture.componentInstance component.config = { - type: 'text', labelKey: 'my.label', } }) diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts b/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts index 5077db478e..44621437a5 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +++ b/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts @@ -25,10 +25,10 @@ import { FormFieldObjectComponent } from './form-field-object/form-field-object. import { FormFieldRichComponent } from './form-field-rich/form-field-rich.component' import { FormFieldSimpleComponent } from './form-field-simple/form-field-simple.component' import { FormFieldSpatialExtentComponent } from './form-field-spatial-extent/form-field-spatial-extent.component' -import { FormFieldConfig } from './form-field.model' import { FormFieldUpdateFrequencyComponent } from './form-field-update-frequency/form-field-update-frequency.component' import { CatalogRecordKeys } from '@geonetwork-ui/common/domain/model/record' import { FormFieldKeywordsComponent } from './form-field-keywords/form-field-keywords.component' +import { FormFieldConfig } from '../../../models' @Component({ selector: 'gn-ui-form-field', @@ -65,6 +65,7 @@ export class FormFieldComponent { emitEvent: false, }) } + @Output() valueChange: Observable @ViewChild('titleInput') titleInput: ElementRef diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/form-field.model.ts b/libs/feature/editor/src/lib/components/record-form/form-field/form-field.model.ts deleted file mode 100644 index cbc9d543b3..0000000000 --- a/libs/feature/editor/src/lib/components/record-form/form-field/form-field.model.ts +++ /dev/null @@ -1,43 +0,0 @@ -type BaseFormFieldType = - | 'text' - | 'number' - | 'rich' - | 'date' - | 'list' - | 'spatial_extent' - | 'temporal_extent' - | 'url' - | 'file' - | 'toggle' - -type AllFormFieldType = BaseFormFieldType | 'object' | 'array' - -interface FormFieldConfigBase { - type: AllFormFieldType - labelKey: string - hintKey?: string - tooltipKey?: string - required?: boolean - locked?: boolean - invalid?: boolean - invalidHintKey?: string -} - -export interface FormFieldConfigSimple extends FormFieldConfigBase { - type: BaseFormFieldType -} - -export interface FormFieldConfigArray extends FormFieldConfigBase { - type: 'array' - items: FormFieldConfig -} - -export interface FormFieldConfigObject extends FormFieldConfigBase { - type: 'object' - fields: Array -} - -export type FormFieldConfig = - | FormFieldConfigSimple - | FormFieldConfigArray - | FormFieldConfigObject diff --git a/libs/feature/editor/src/lib/components/record-form/form-field/index.ts b/libs/feature/editor/src/lib/components/record-form/form-field/index.ts index 053dede8e5..8555c39727 100644 --- a/libs/feature/editor/src/lib/components/record-form/form-field/index.ts +++ b/libs/feature/editor/src/lib/components/record-form/form-field/index.ts @@ -9,4 +9,3 @@ export * from './form-field-object/form-field-object.component' export * from './form-field-array/form-field-array.component' export * from './form-field-spatial-extent/form-field-spatial-extent.component' export * from './form-field.component' -export * from './form-field.model' diff --git a/libs/feature/editor/src/lib/components/record-form/record-form.component.html b/libs/feature/editor/src/lib/components/record-form/record-form.component.html index 7b07459330..ed64b72b3a 100644 --- a/libs/feature/editor/src/lib/components/record-form/record-form.component.html +++ b/libs/feature/editor/src/lib/components/record-form/record-form.component.html @@ -1,11 +1,43 @@ -
- - - -
+ +
+ + +
+
+
+ {{ section.labelKey }} +
+
+ {{ section.descriptionKey }} +
+
+ + + + + +
+
+
+
+
diff --git a/libs/feature/editor/src/lib/components/record-form/record-form.component.spec.ts b/libs/feature/editor/src/lib/components/record-form/record-form.component.spec.ts index ca1d821f0a..2042e4c857 100644 --- a/libs/feature/editor/src/lib/components/record-form/record-form.component.spec.ts +++ b/libs/feature/editor/src/lib/components/record-form/record-form.component.spec.ts @@ -32,10 +32,7 @@ describe('RecordFormComponent', () => { describe('handleFieldValueChange', () => { it('should call facade.updateRecordField', () => { - component.handleFieldValueChange( - { config: { model: 'title' }, value: 'old title' }, - 'new title' - ) + component.handleFieldValueChange('title', 'new title') expect(component.facade.updateRecordField).toHaveBeenCalledWith( 'title', 'new title' diff --git a/libs/feature/editor/src/lib/components/record-form/record-form.component.ts b/libs/feature/editor/src/lib/components/record-form/record-form.component.ts index 310fa77fea..06863d04b7 100644 --- a/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +++ b/libs/feature/editor/src/lib/components/record-form/record-form.component.ts @@ -1,8 +1,14 @@ import { CommonModule } from '@angular/common' -import { ChangeDetectionStrategy, Component } from '@angular/core' +import { ChangeDetectionStrategy, Component, Input } from '@angular/core' import { EditorFacade } from '../../+state/editor.facade' -import { EditorFieldState, EditorFieldValue } from '../../models/fields.model' +import { + EditorField, + EditorFieldPage, + EditorFieldValue, + EditorSection, +} from '../../models' import { FormFieldComponent } from './form-field' +import { TranslateModule } from '@ngx-translate/core' @Component({ selector: 'gn-ui-record-form', @@ -10,21 +16,25 @@ import { FormFieldComponent } from './form-field' styleUrls: ['./record-form.component.css'], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [CommonModule, FormFieldComponent], + imports: [CommonModule, FormFieldComponent, TranslateModule], }) export class RecordFormComponent { - fields$ = this.facade.recordFields$ + @Input() page: EditorFieldPage constructor(public facade: EditorFacade) {} - handleFieldValueChange(field: EditorFieldState, newValue: EditorFieldValue) { - if (!field.config.model) { + handleFieldValueChange(model: string, newValue: EditorFieldValue) { + if (!model) { return } - this.facade.updateRecordField(field.config.model, newValue) + this.facade.updateRecordField(model, newValue) } - fieldTracker(index: number, field: EditorFieldState) { - return field.config.model + fieldTracker(index: number, field: EditorField): any { + return field.model + } + + sectionTracker(index: number, section: EditorSection): any { + return section.labelKey } } diff --git a/libs/feature/editor/src/lib/expressions.spec.ts b/libs/feature/editor/src/lib/expressions.spec.ts index 6de626a823..e36b9e7fc2 100644 --- a/libs/feature/editor/src/lib/expressions.spec.ts +++ b/libs/feature/editor/src/lib/expressions.spec.ts @@ -1,13 +1,4 @@ import { evaluate, ExpressionEvaluator } from './expressions' -import { EditorFieldConfig } from './models/fields.model' - -const SAMPLE_CONFIG: EditorFieldConfig = { - formFieldConfig: { - labelKey: 'Metadata title', - type: 'text', - }, - model: 'myModel', -} const originalDate = window.Date window.Date = function () { @@ -22,7 +13,7 @@ describe('expressions', () => { evaluator = evaluate('${dateNow()}') }) it('returns the current time at evaluation', () => { - expect(evaluator({ config: SAMPLE_CONFIG, value: 'bla' })).toEqual( + expect(evaluator({ model: 'keywords', value: 'bla' })).toEqual( new Date() ) }) diff --git a/libs/feature/editor/src/lib/expressions.ts b/libs/feature/editor/src/lib/expressions.ts index 59aabd6885..253f52a2fa 100644 --- a/libs/feature/editor/src/lib/expressions.ts +++ b/libs/feature/editor/src/lib/expressions.ts @@ -1,4 +1,4 @@ -import { EditorFieldState, EditorFieldValue } from './models/fields.model' +import { EditorFieldState, EditorFieldValue } from './models/' export type ExpressionEvaluator = (field: EditorFieldState) => EditorFieldValue diff --git a/libs/feature/editor/src/lib/fields.config.ts b/libs/feature/editor/src/lib/fields.config.ts index 6591a3090c..62a7d83bbe 100644 --- a/libs/feature/editor/src/lib/fields.config.ts +++ b/libs/feature/editor/src/lib/fields.config.ts @@ -1,71 +1,185 @@ import { marker } from '@biesbjerg/ngx-translate-extract-marker' -import { EditorFieldsConfig } from './models/fields.model' - -export const DEFAULT_FIELDS: EditorFieldsConfig = [ - { - model: 'title', - formFieldConfig: { - labelKey: marker('editor.record.form.metadata.title'), - type: 'text', - }, +import { + EditorConfig, + EditorField, + EditorSection, +} from './models/editor-config.model' + +/** + * This file contains the configuration of the fields that will be displayed in the editor. + * To add a new field, you need to create a new EditorField object in the fields part of this file. + * Then add it to the corresponding section in the sections part of this file. + * Finally, add the section to the corresponding page in the pages part of this file. + */ + +/************************************************************ + *************** FIELDS ***************** + ************************************************************ + */ + +export const RECORD_LICENSE_FIELD: EditorField = { + model: 'licenses', + formFieldConfig: { + labelKey: marker('editor.record.form.field.license'), }, - { - model: 'abstract', - formFieldConfig: { - labelKey: marker('editor.record.form.abstract'), - type: 'rich', - }, +} + +export const RECORD_KEYWORDS_FIELD: EditorField = { + model: 'keywords', + formFieldConfig: { + labelKey: marker('editor.record.form.field.keywords'), }, - { - model: 'uniqueIdentifier', - formFieldConfig: { - labelKey: marker('editor.record.form.unique.identifier'), - type: 'text', - locked: true, - }, +} + +export const RECORD_UNIQUE_IDENTIFIER_FIELD: EditorField = { + model: 'uniqueIdentifier', + formFieldConfig: { + labelKey: marker('editor.record.form.field.uniqueIdentifier'), + locked: true, }, - { - model: 'recordUpdated', - formFieldConfig: { - labelKey: marker('editor.record.form.record.updated'), - type: 'text', - locked: true, - }, - onSaveProcess: '${dateNow()}', +} + +export const RECORD_RESOURCE_UPDATED_FIELD: EditorField = { + model: 'resourceUpdated', + formFieldConfig: { + labelKey: marker('editor.record.form.field.resourceUpdated'), }, - { - model: 'licenses', - formFieldConfig: { - labelKey: marker('editor.record.form.license'), - type: 'list', - }, +} + +export const RECORD_UPDATED_FIELD: EditorField = { + model: 'recordUpdated', + formFieldConfig: { + labelKey: marker('editor.record.form.field.recordUpdated'), + locked: true, }, - { - model: 'resourceUpdated', - formFieldConfig: { - labelKey: marker('editor.record.form.resourceUpdated'), - type: 'date', - }, + onSaveProcess: '${dateNow()}', +} + +export const RECORD_UPDATE_FREQUENCY_FIELD: EditorField = { + model: 'updateFrequency', + formFieldConfig: { + labelKey: marker('editor.record.form.field.updateFrequency'), }, - { - model: 'updateFrequency', - formFieldConfig: { - labelKey: marker('editor.record.form.updateFrequency'), - type: 'text', - }, +} + +export const RECORD_TEMPORAL_EXTENTS_FIELD: EditorField = { + model: 'temporalExtents', + formFieldConfig: { + labelKey: marker('editor.record.form.field.temporalExtents'), }, - { - model: 'temporalExtents', - formFieldConfig: { - labelKey: marker('editor.record.form.temporalExtents'), - type: 'list', - }, +} + +export const RECORD_TITLE_FIELD: EditorField = { + model: 'title', + formFieldConfig: { + labelKey: marker('editor.record.form.field.title'), }, - { - model: 'keywords', - formFieldConfig: { - labelKey: marker('editor.record.form.keywords'), - type: 'list', - }, +} + +export const RECORD_ABSTRACT_FIELD: EditorField = { + model: 'abstract', + formFieldConfig: { + labelKey: marker('editor.record.form.field.abstract'), }, -] +} + +/************************************************************ + *************** SECTIONS ***************** + ************************************************************ + */ + +export const TITLE_SECTION: EditorSection = { + hidden: false, + fields: [RECORD_TITLE_FIELD, RECORD_ABSTRACT_FIELD], +} + +export const ABOUT_SECTION: EditorSection = { + labelKey: marker('editor.record.form.section.about.label'), + descriptionKey: marker('editor.record.form.section.about.description'), + hidden: false, + fields: [ + RECORD_UNIQUE_IDENTIFIER_FIELD, + RECORD_RESOURCE_UPDATED_FIELD, + RECORD_UPDATED_FIELD, + RECORD_UPDATE_FREQUENCY_FIELD, + RECORD_TEMPORAL_EXTENTS_FIELD, + ], +} + +export const GEOGRAPHICAL_COVERAGE_SECTION: EditorSection = { + labelKey: marker('editor.record.form.section.geographicalCoverage.label'), + hidden: false, + fields: [], +} + +export const ASSOCIATED_RESOURCES_SECTION: EditorSection = { + labelKey: marker('editor.record.form.section.associatedResources.label'), + descriptionKey: marker( + 'editor.record.form.section.associatedResources.description' + ), + hidden: false, + fields: [], +} + +export const ANNEXES_SECTION: EditorSection = { + labelKey: marker('editor.record.form.section.annexes.label'), + hidden: false, + fields: [], +} + +export const CLASSIFICATION_SECTION: EditorSection = { + labelKey: marker('editor.record.form.section.classification.label'), + descriptionKey: marker( + 'editor.record.form.section.classification.description' + ), + hidden: false, + fields: [RECORD_KEYWORDS_FIELD], +} + +export const USE_AND_ACCESS_CONDITIONS_SECTION: EditorSection = { + labelKey: marker('editor.record.form.section.useAndAccessConditions.label'), + hidden: false, + fields: [RECORD_LICENSE_FIELD], +} + +export const DATA_MANAGERS_SECTION: EditorSection = { + labelKey: marker('editor.record.form.section.dataManagers.label'), + descriptionKey: marker('editor.record.form.section.dataManagers.description'), + hidden: false, + fields: [], +} + +export const DATA_POINT_OF_CONTACT_SECTION: EditorSection = { + labelKey: marker('editor.record.form.section.dataPointOfContact.label'), + descriptionKey: marker( + 'editor.record.form.section.dataPointOfContact.description' + ), + hidden: false, + fields: [], +} + +/************************************************************ + *************** PAGES ***************** + ************************************************************ + */ +export const DEFAULT_FIELDS: EditorConfig = { + pages: [ + { + labelKey: marker('editor.record.form.page.description'), + sections: [TITLE_SECTION, ABOUT_SECTION, GEOGRAPHICAL_COVERAGE_SECTION], + }, + { + labelKey: marker('editor.record.form.page.ressources'), + sections: [ASSOCIATED_RESOURCES_SECTION, ANNEXES_SECTION], + }, + { + labelKey: marker('editor.record.form.page.accessAndContact'), + sections: [ + CLASSIFICATION_SECTION, + USE_AND_ACCESS_CONDITIONS_SECTION, + DATA_MANAGERS_SECTION, + DATA_POINT_OF_CONTACT_SECTION, + ], + }, + ], +} diff --git a/libs/feature/editor/src/lib/fixtures/editor.fixtures.ts b/libs/feature/editor/src/lib/fixtures/editor.fixtures.ts new file mode 100644 index 0000000000..d220a192ef --- /dev/null +++ b/libs/feature/editor/src/lib/fixtures/editor.fixtures.ts @@ -0,0 +1,158 @@ +import { EditorConfig, EditorField, EditorSection } from '../models' + +export const EDITOR_CONFIG = (): EditorConfig => ({ + pages: [ + { + labelKey: 'Resource description', + sections: [EDITOR_SECTION_ABOUT()], + }, + { + labelKey: 'Resources', + sections: [EDITOR_SECTION_CLASSIFICATION()], + }, + { + labelKey: 'Access and contact', + sections: [ + EDITOR_SECTION_USE_AND_ACCESS_CONDITIONS(), + EDITOR_SECTION_DATA_MANAGER(), + ], + }, + ], +}) + +export const EDITOR_SECTION_ABOUT = (): EditorSection => ({ + labelKey: 'About the resource', + descriptionKey: 'This section describes the resource.', + hidden: false, + fields: [ + EDITOR_FIELD_TITLE(), + EDITOR_FIELD_ABSTRACT(), + EDITOR_FIELD_RESOURCE_UPDATED(), + EDITOR_FIELD_RECORD_UPDATED(), + EDITOR_FIELD_UPDATE_FREQUENCY(), + EDITOR_FIELD_TEMPORAL_EXTENTS(), + ], +}) + +export const EDITOR_SECTION_DATA_MANAGER = (): EditorSection => ({ + labelKey: 'Data manager', + descriptionKey: '', + hidden: false, + fields: [], +}) + +export const EDITOR_SECTION_USE_AND_ACCESS_CONDITIONS = (): EditorSection => ({ + labelKey: 'Data manager', + descriptionKey: '', + hidden: false, + fields: [EDITOR_FIELD_LICENSE()], +}) + +export const EDITOR_SECTION_CLASSIFICATION = (): EditorSection => ({ + labelKey: 'Classification', + descriptionKey: 'The classification has an impact on the access to the data.', + hidden: false, + fields: [EDITOR_FIELD_KEYWORDS(), EDITOR_FIELD_UNIQUE_IDENTIFIER()], +}) + +export const EDITOR_FIELD_TITLE = (): EditorField => ({ + model: 'title', + hidden: false, + value: 'Accroches vélos MEL', + formFieldConfig: { + labelKey: 'editor.record.form.field.title', + }, +}) + +export const EDITOR_FIELD_ABSTRACT = (): EditorField => ({ + model: 'abstract', + hidden: false, + value: 'Abstract', + formFieldConfig: { + labelKey: 'editor.record.form.field.abstract', + }, +}) + +export const EDITOR_FIELD_RESOURCE_UPDATED = (): EditorField => ({ + model: 'resourceUpdated', + hidden: false, + formFieldConfig: { + labelKey: 'editor.record.form.field.resourceUpdated', + }, +}) + +export const EDITOR_FIELD_RECORD_UPDATED = (): EditorField => ({ + model: 'recordUpdated', + hidden: false, + formFieldConfig: { + labelKey: 'editor.record.form.field.recordUpdated', + locked: true, + }, + value: '2024-07-16T05:18:53.000Z', + onSaveProcess: '${dateNow()}', +}) + +export const EDITOR_FIELD_UPDATE_FREQUENCY = (): EditorField => ({ + model: 'updateFrequency', + hidden: false, + formFieldConfig: { + labelKey: 'editor.record.form.field.updateFrequency', + }, + value: 'unknown', +}) + +export const EDITOR_FIELD_TEMPORAL_EXTENTS = (): EditorField => ({ + model: 'temporalExtents', + hidden: false, + formFieldConfig: { + labelKey: 'editor.record.form.field.temporalExtents', + }, + value: [], +}) + +export const EDITOR_FIELD_SPATIAL_EXTENTS = (): EditorField => ({ + model: 'spatialExtents', + hidden: false, + formFieldConfig: { + labelKey: 'editor.record.form.field.spatialExtents', + }, +}) + +export const EDITOR_FIELD_KEYWORDS = (): EditorField => ({ + model: 'keywords', + hidden: false, + formFieldConfig: { + labelKey: 'editor.record.form.field.keywords', + }, +}) + +export const EDITOR_FIELD_UNIQUE_IDENTIFIER = (): EditorField => ({ + model: 'uniqueIdentifier', + hidden: false, + formFieldConfig: { + labelKey: 'editor.record.form.field.uniqueIdentifier', + locked: true, + }, + value: 'accroche_velos', +}) + +export const EDITOR_FIELD_LICENSE = (): EditorField => ({ + model: 'licenses', + hidden: false, + formFieldConfig: { + labelKey: 'editor.record.form.field.license', + locked: true, + }, +}) + +export const EDITOR_FIELDS = (): EditorField[] => [ + EDITOR_FIELD_TITLE(), + EDITOR_FIELD_ABSTRACT(), + EDITOR_FIELD_RESOURCE_UPDATED(), + EDITOR_FIELD_RECORD_UPDATED(), + EDITOR_FIELD_UPDATE_FREQUENCY(), + EDITOR_FIELD_TEMPORAL_EXTENTS(), + EDITOR_FIELD_SPATIAL_EXTENTS(), + EDITOR_FIELD_KEYWORDS(), + EDITOR_FIELD_UNIQUE_IDENTIFIER(), +] diff --git a/libs/feature/editor/src/lib/fixtures/index.ts b/libs/feature/editor/src/lib/fixtures/index.ts new file mode 100644 index 0000000000..ed9fbc8aeb --- /dev/null +++ b/libs/feature/editor/src/lib/fixtures/index.ts @@ -0,0 +1 @@ +export * from './editor.fixtures' diff --git a/libs/feature/editor/src/lib/models/editor-config.model.ts b/libs/feature/editor/src/lib/models/editor-config.model.ts new file mode 100644 index 0000000000..8530049354 --- /dev/null +++ b/libs/feature/editor/src/lib/models/editor-config.model.ts @@ -0,0 +1,55 @@ +import { CatalogRecordKeys } from '@geonetwork-ui/common/domain/model/record' + +// Expressions should be enclosed in `${}` to be recognized as such +// eg. ${dateNow()} +export type EditorFieldExpression = `$\{${string}}` + +export type EditorFieldValue = string | number | boolean | unknown + +export interface FormFieldConfig { + labelKey?: string + hintKey?: string + tooltipKey?: string + required?: boolean + locked?: boolean + invalid?: boolean + invalidHintKey?: string +} + +export interface EditorField { + // configuration of the form field used as presentation + formFieldConfig: FormFieldConfig + + // name of the target field in the record; will not change the record directly if not defined + model?: CatalogRecordKeys + + // a hidden field won't show but can still be used to modify the record + // FIXME: currently this is redundant with an absence of formFieldConfig but necessary for clarity + hidden?: boolean + + // the result of this expression will replace the field value on save + onSaveProcess?: EditorFieldExpression + + value?: EditorFieldValue +} + +export interface EditorSection { + labelKey?: string + descriptionKey?: string + hidden: boolean + fields: EditorField[] +} + +export interface EditorFieldPage { + labelKey?: string + sections: EditorSection[] +} + +export interface EditorConfig { + pages: EditorFieldPage[] +} + +export interface EditorFieldState { + model: string + value: EditorFieldValue +} diff --git a/libs/feature/editor/src/lib/models/fields.model.ts b/libs/feature/editor/src/lib/models/fields.model.ts deleted file mode 100644 index 0dae06b007..0000000000 --- a/libs/feature/editor/src/lib/models/fields.model.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { FormFieldConfig } from '../components/record-form/form-field' - -// Expressions should be enclosed in `${}` to be recognized as such -// eg. ${dateNow()} -export type EditorFieldExpression = `$\{${string}}` - -export interface EditorFieldConfig { - // configuration of the form field used as presentation; optional, nothing shown if not defined - formFieldConfig?: FormFieldConfig - - // name of the target field in the record; will not change the record directly if not defined - model?: string - - // a hidden field won't show but can still be used to modify the record - // FIXME: currently this is redundant with an absence of formFieldConfig but necessary for clarity - hidden?: boolean - - // the result of this expression will replace the field value on save - onSaveProcess?: EditorFieldExpression -} - -export type EditorFieldsConfig = EditorFieldConfig[] - -export type EditorFieldValue = string | number | boolean | unknown - -export interface EditorFieldState { - config: EditorFieldConfig - value: string | number | boolean | unknown -} diff --git a/libs/feature/editor/src/lib/models/index.ts b/libs/feature/editor/src/lib/models/index.ts index 65975121b2..1adb10500d 100644 --- a/libs/feature/editor/src/lib/models/index.ts +++ b/libs/feature/editor/src/lib/models/index.ts @@ -1,2 +1,3 @@ export * from './wizard-field.model' export * from './wizard-field.type' +export * from './editor-config.model' diff --git a/libs/feature/editor/src/lib/services/editor.service.ts b/libs/feature/editor/src/lib/services/editor.service.ts index 9b7c005438..1cc1b67791 100644 --- a/libs/feature/editor/src/lib/services/editor.service.ts +++ b/libs/feature/editor/src/lib/services/editor.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core' import { Observable, switchMap } from 'rxjs' import { map, tap } from 'rxjs/operators' import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record' -import { EditorFieldsConfig } from '../models/fields.model' +import { EditorConfig } from '../models/' import { evaluate } from '../expressions' import { RecordsRepositoryInterface } from '@geonetwork-ui/common/domain/repository/records-repository.interface' @@ -15,17 +15,21 @@ export class EditorService { // returns the record as it was when saved, alongside its source saveRecord( record: CatalogRecord, - fieldsConfig: EditorFieldsConfig, + fieldsConfig: EditorConfig, generateNewUniqueIdentifier = false ): Observable<[CatalogRecord, string]> { const savedRecord = { ...record } + const fields = fieldsConfig.pages.flatMap((page) => + page.sections.flatMap((section) => section.fields) + ) + // run onSave processes - for (const field of fieldsConfig) { + for (const field of fields) { if (field.onSaveProcess && field.model) { const evaluator = evaluate(field.onSaveProcess) savedRecord[field.model] = evaluator({ - config: field, + model: field.model, value: record[field.model], }) } diff --git a/libs/feature/editor/tsconfig.json b/libs/feature/editor/tsconfig.json index cdea0bdb38..9e29358f76 100644 --- a/libs/feature/editor/tsconfig.json +++ b/libs/feature/editor/tsconfig.json @@ -16,11 +16,7 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "target": "es2020", - "lib": [ - "dom", - "es2020", - "dom.iterable" - ], + "lib": ["dom", "es2020", "dom.iterable"], "downlevelIteration": true }, "angularCompilerOptions": { diff --git a/libs/feature/editor/tsconfig.lib.json b/libs/feature/editor/tsconfig.lib.json index 7ca4377996..2a4c9a5e36 100644 --- a/libs/feature/editor/tsconfig.lib.json +++ b/libs/feature/editor/tsconfig.lib.json @@ -7,11 +7,7 @@ "declarationMap": true, "inlineSources": true, "types": [], - "lib": [ - "dom", - "es2020", - "dom.iterable" - ], + "lib": ["dom", "es2020", "dom.iterable"], "downlevelIteration": true }, "exclude": [ @@ -20,7 +16,5 @@ "**/*.test.ts", "jest.config.ts" ], - "include": [ - "**/*.ts" - ] + "include": ["**/*.ts"] } diff --git a/libs/util/shared/tsconfig.lib.json b/libs/util/shared/tsconfig.lib.json index 9bb502669e..02d129fa3b 100644 --- a/libs/util/shared/tsconfig.lib.json +++ b/libs/util/shared/tsconfig.lib.json @@ -7,11 +7,7 @@ "declarationMap": true, "inlineSources": true, "types": [], - "lib": [ - "dom", - "es2020", - "dom.iterable" - ] + "lib": ["dom", "es2020", "dom.iterable"] }, "exclude": [ "src/test-setup.ts", diff --git a/translations/de.json b/translations/de.json index 25539c677e..12b58965fd 100644 --- a/translations/de.json +++ b/translations/de.json @@ -165,6 +165,18 @@ "downloads.format.unknown": "unbekannt", "downloads.wfs.featuretype.not.found": "Der Layer wurde nicht gefunden", "dropFile": "Datei ablegen", + "editor.record.form.bottomButtons.comeBackLater": "", + "editor.record.form.bottomButtons.next": "", + "editor.record.form.bottomButtons.previous": "", + "editor.record.form.field.abstract": "", + "editor.record.form.field.keywords": "Schlagwörter", + "editor.record.form.field.license": "Lizenz", + "editor.record.form.field.recordUpdated": "", + "editor.record.form.field.resourceUpdated": "", + "editor.record.form.field.temporalExtents": "", + "editor.record.form.field.title": "", + "editor.record.form.field.uniqueIdentifier": "", + "editor.record.form.field.updateFrequency": "", "editor.record.form.abstract": "Kurzbeschreibung", "editor.record.form.keywords": "Schlüsselwörter", "editor.record.form.license": "Lizenz", @@ -177,6 +189,22 @@ "editor.record.form.license.odc-by": "Open Data Commons ODC-By", "editor.record.form.license.pddl": "Open Data Commons PDDL", "editor.record.form.license.unknown": "Unbekannt oder nicht vorhanden", + "editor.record.form.page.accessAndContact": "", + "editor.record.form.page.description": "", + "editor.record.form.page.ressources": "", + "editor.record.form.section.about.description": "", + "editor.record.form.section.about.label": "", + "editor.record.form.section.annexes.label": "", + "editor.record.form.section.associatedResources.description": "", + "editor.record.form.section.associatedResources.label": "", + "editor.record.form.section.classification.description": "", + "editor.record.form.section.classification.label": "", + "editor.record.form.section.dataManagers.description": "", + "editor.record.form.section.dataManagers.label": "", + "editor.record.form.section.dataPointOfContact.description": "", + "editor.record.form.section.dataPointOfContact.label": "", + "editor.record.form.section.geographicalCoverage.label": "", + "editor.record.form.section.useAndAccessConditions.label": "", "editor.record.form.metadata.title": "Metadaten-Titel", "editor.record.form.record.updated": "Datensatz zuletzt aktualisiert", "editor.record.form.resourceUpdated": "Letztes Aktualisierungsdatum", diff --git a/translations/en.json b/translations/en.json index c3f80d04d0..4055d950f6 100644 --- a/translations/en.json +++ b/translations/en.json @@ -165,6 +165,18 @@ "downloads.format.unknown": "unknown", "downloads.wfs.featuretype.not.found": "The layer was not found", "dropFile": "drop file", + "editor.record.form.bottomButtons.comeBackLater": "Come back later", + "editor.record.form.bottomButtons.next": "Next", + "editor.record.form.bottomButtons.previous": "Previous", + "editor.record.form.field.abstract": "Abstract", + "editor.record.form.field.keywords": "Keywords", + "editor.record.form.field.license": "License", + "editor.record.form.field.recordUpdated": "Record Updated", + "editor.record.form.field.resourceUpdated": "Resource Updated", + "editor.record.form.field.temporalExtents": "Temporal extents", + "editor.record.form.field.title": "Metadata title", + "editor.record.form.field.uniqueIdentifier": "Unique identifier", + "editor.record.form.field.updateFrequency": "Update frequency", "editor.record.form.abstract": "Abstract", "editor.record.form.keywords": "Keywords", "editor.record.form.license": "License", @@ -177,6 +189,22 @@ "editor.record.form.license.odc-by": "Open Data Commons ODC-By", "editor.record.form.license.pddl": "Open Data Commons PDDL", "editor.record.form.license.unknown": "Unknown or absent", + "editor.record.form.page.accessAndContact": "Access and contact", + "editor.record.form.page.description": "Resource description", + "editor.record.form.page.ressources": "Resources", + "editor.record.form.section.about.description": "This section describes the resource.", + "editor.record.form.section.about.label": "About the resource", + "editor.record.form.section.annexes.label": "Annexes", + "editor.record.form.section.associatedResources.description": "Drop files here to associate them with the resource.", + "editor.record.form.section.associatedResources.label": "Associated resources", + "editor.record.form.section.classification.description": "The classification has an impact on the access to the data.", + "editor.record.form.section.classification.label": "Classification", + "editor.record.form.section.dataManagers.description": "The data managers are responsible for the data.", + "editor.record.form.section.dataManagers.label": "Data managers", + "editor.record.form.section.dataPointOfContact.description": "This information concerns the metadata.", + "editor.record.form.section.dataPointOfContact.label": "Data point of contact", + "editor.record.form.section.geographicalCoverage.label": "Geographical coverage", + "editor.record.form.section.useAndAccessConditions.label": "Use and access conditions", "editor.record.form.metadata.title": "Metadata title", "editor.record.form.record.updated": "Record updated", "editor.record.form.resourceUpdated": "Last update date", diff --git a/translations/es.json b/translations/es.json index e74e4256e4..54dfd827fb 100644 --- a/translations/es.json +++ b/translations/es.json @@ -165,6 +165,18 @@ "downloads.format.unknown": "", "downloads.wfs.featuretype.not.found": "", "dropFile": "", + "editor.record.form.bottomButtons.comeBackLater": "", + "editor.record.form.bottomButtons.next": "", + "editor.record.form.bottomButtons.previous": "", + "editor.record.form.field.abstract": "", + "editor.record.form.field.keywords": "", + "editor.record.form.field.license": "", + "editor.record.form.field.recordUpdated": "", + "editor.record.form.field.resourceUpdated": "", + "editor.record.form.field.temporalExtents": "", + "editor.record.form.field.title": "", + "editor.record.form.field.uniqueIdentifier": "", + "editor.record.form.field.updateFrequency": "", "editor.record.form.abstract": "", "editor.record.form.keywords": "", "editor.record.form.license": "", @@ -177,6 +189,22 @@ "editor.record.form.license.odc-by": "", "editor.record.form.license.pddl": "", "editor.record.form.license.unknown": "", + "editor.record.form.page.accessAndContact": "", + "editor.record.form.page.description": "", + "editor.record.form.page.ressources": "", + "editor.record.form.section.about.description": "", + "editor.record.form.section.about.label": "", + "editor.record.form.section.annexes.label": "", + "editor.record.form.section.associatedResources.description": "", + "editor.record.form.section.associatedResources.label": "", + "editor.record.form.section.classification.description": "", + "editor.record.form.section.classification.label": "", + "editor.record.form.section.dataManagers.description": "", + "editor.record.form.section.dataManagers.label": "", + "editor.record.form.section.dataPointOfContact.description": "", + "editor.record.form.section.dataPointOfContact.label": "", + "editor.record.form.section.geographicalCoverage.label": "", + "editor.record.form.section.useAndAccessConditions.label": "", "editor.record.form.metadata.title": "", "editor.record.form.record.updated": "", "editor.record.form.resourceUpdated": "", diff --git a/translations/fr.json b/translations/fr.json index c3124afef3..29374cb89a 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -165,6 +165,18 @@ "downloads.format.unknown": "inconnu", "downloads.wfs.featuretype.not.found": "La couche n'a pas été retrouvée", "dropFile": "Faites glisser votre fichier", + "editor.record.form.bottomButtons.comeBackLater": "Revenir plus tard", + "editor.record.form.bottomButtons.next": "Suivant", + "editor.record.form.bottomButtons.previous": "Précédent", + "editor.record.form.field.abstract": "Résumé", + "editor.record.form.field.keywords": "Mots-clés", + "editor.record.form.field.license": "Licence", + "editor.record.form.field.recordUpdated": "Date de dernière révision", + "editor.record.form.field.resourceUpdated": "Date de dernière révision", + "editor.record.form.field.temporalExtents": "Étendue temporelle", + "editor.record.form.field.title": "Titre", + "editor.record.form.field.uniqueIdentifier": "Identifiant unique", + "editor.record.form.field.updateFrequency": "Fréquence de mise à jour", "editor.record.form.abstract": "", "editor.record.form.keywords": "", "editor.record.form.license": "Licence", @@ -177,6 +189,22 @@ "editor.record.form.license.odc-by": "", "editor.record.form.license.pddl": "", "editor.record.form.license.unknown": "Non-reconnue ou absente", + "editor.record.form.page.accessAndContact": "Acces et contact", + "editor.record.form.page.description": "Description de la ressource", + "editor.record.form.page.ressources": "Ressources", + "editor.record.form.section.about.description": "Ces informations concernent la donnée.", + "editor.record.form.section.about.label": "A propos de la ressource", + "editor.record.form.section.annexes.label": "Annexes", + "editor.record.form.section.associatedResources.description": "Déposez les jeux de données associées à cette fiche de métadonnée.", + "editor.record.form.section.associatedResources.label": "Ressources associees", + "editor.record.form.section.classification.description": "La classification a un impact sur la recherche du jeux de données.", + "editor.record.form.section.classification.label": "Classification", + "editor.record.form.section.dataManagers.description": "Cette information concerne la donnée.", + "editor.record.form.section.dataManagers.label": "Responsables de la donnee", + "editor.record.form.section.dataPointOfContact.description": "Cette information concerne la fiche de métadonnée.", + "editor.record.form.section.dataPointOfContact.label": "Point de contact de la metadonee", + "editor.record.form.section.geographicalCoverage.label": "Couverture geographique", + "editor.record.form.section.useAndAccessConditions.label": "Conditions d'acces et usage", "editor.record.form.metadata.title": "", "editor.record.form.record.updated": "", "editor.record.form.resourceUpdated": "Date de dernière révision", diff --git a/translations/it.json b/translations/it.json index fd42ba00df..b945330f98 100644 --- a/translations/it.json +++ b/translations/it.json @@ -165,6 +165,18 @@ "downloads.format.unknown": "sconosciuto", "downloads.wfs.featuretype.not.found": "Il layer non è stato trovato", "dropFile": "Trascina il suo file", + "editor.record.form.bottomButtons.comeBackLater": "", + "editor.record.form.bottomButtons.next": "", + "editor.record.form.bottomButtons.previous": "", + "editor.record.form.field.abstract": "", + "editor.record.form.field.keywords": "", + "editor.record.form.field.license": "Licenza", + "editor.record.form.field.recordUpdated": "", + "editor.record.form.field.resourceUpdated": "", + "editor.record.form.field.temporalExtents": "", + "editor.record.form.field.title": "", + "editor.record.form.field.uniqueIdentifier": "", + "editor.record.form.field.updateFrequency": "", "editor.record.form.abstract": "", "editor.record.form.keywords": "", "editor.record.form.license": "Licenza", @@ -177,6 +189,22 @@ "editor.record.form.license.odc-by": "", "editor.record.form.license.pddl": "", "editor.record.form.license.unknown": "Non riconosciuta o assente", + "editor.record.form.page.accessAndContact": "", + "editor.record.form.page.description": "", + "editor.record.form.page.ressources": "", + "editor.record.form.section.about.description": "", + "editor.record.form.section.about.label": "", + "editor.record.form.section.annexes.label": "", + "editor.record.form.section.associatedResources.description": "", + "editor.record.form.section.associatedResources.label": "", + "editor.record.form.section.classification.description": "", + "editor.record.form.section.classification.label": "", + "editor.record.form.section.dataManagers.description": "", + "editor.record.form.section.dataManagers.label": "", + "editor.record.form.section.dataPointOfContact.description": "", + "editor.record.form.section.dataPointOfContact.label": "", + "editor.record.form.section.geographicalCoverage.label": "", + "editor.record.form.section.useAndAccessConditions.label": "", "editor.record.form.metadata.title": "", "editor.record.form.record.updated": "", "editor.record.form.resourceUpdated": "", diff --git a/translations/nl.json b/translations/nl.json index f714c53ec2..4fcfa583f1 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -165,6 +165,18 @@ "downloads.format.unknown": "", "downloads.wfs.featuretype.not.found": "", "dropFile": "", + "editor.record.form.bottomButtons.comeBackLater": "", + "editor.record.form.bottomButtons.next": "", + "editor.record.form.bottomButtons.previous": "", + "editor.record.form.field.abstract": "", + "editor.record.form.field.keywords": "", + "editor.record.form.field.license": "", + "editor.record.form.field.recordUpdated": "", + "editor.record.form.field.resourceUpdated": "", + "editor.record.form.field.temporalExtents": "", + "editor.record.form.field.title": "", + "editor.record.form.field.uniqueIdentifier": "", + "editor.record.form.field.updateFrequency": "", "editor.record.form.abstract": "", "editor.record.form.keywords": "", "editor.record.form.license": "", @@ -177,6 +189,22 @@ "editor.record.form.license.odc-by": "", "editor.record.form.license.pddl": "", "editor.record.form.license.unknown": "", + "editor.record.form.page.accessAndContact": "", + "editor.record.form.page.description": "", + "editor.record.form.page.ressources": "", + "editor.record.form.section.about.description": "", + "editor.record.form.section.about.label": "", + "editor.record.form.section.annexes.label": "", + "editor.record.form.section.associatedResources.description": "", + "editor.record.form.section.associatedResources.label": "", + "editor.record.form.section.classification.description": "", + "editor.record.form.section.classification.label": "", + "editor.record.form.section.dataManagers.description": "", + "editor.record.form.section.dataManagers.label": "", + "editor.record.form.section.dataPointOfContact.description": "", + "editor.record.form.section.dataPointOfContact.label": "", + "editor.record.form.section.geographicalCoverage.label": "", + "editor.record.form.section.useAndAccessConditions.label": "", "editor.record.form.metadata.title": "", "editor.record.form.record.updated": "", "editor.record.form.resourceUpdated": "", diff --git a/translations/pt.json b/translations/pt.json index a702a9c851..f6782e7344 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -165,6 +165,18 @@ "downloads.format.unknown": "", "downloads.wfs.featuretype.not.found": "", "dropFile": "", + "editor.record.form.bottomButtons.comeBackLater": "", + "editor.record.form.bottomButtons.next": "", + "editor.record.form.bottomButtons.previous": "", + "editor.record.form.field.abstract": "", + "editor.record.form.field.keywords": "", + "editor.record.form.field.license": "", + "editor.record.form.field.recordUpdated": "", + "editor.record.form.field.resourceUpdated": "", + "editor.record.form.field.temporalExtents": "", + "editor.record.form.field.title": "", + "editor.record.form.field.uniqueIdentifier": "", + "editor.record.form.field.updateFrequency": "", "editor.record.form.abstract": "", "editor.record.form.keywords": "", "editor.record.form.license": "", @@ -177,6 +189,22 @@ "editor.record.form.license.odc-by": "", "editor.record.form.license.pddl": "", "editor.record.form.license.unknown": "", + "editor.record.form.page.accessAndContact": "", + "editor.record.form.page.description": "", + "editor.record.form.page.ressources": "", + "editor.record.form.section.about.description": "", + "editor.record.form.section.about.label": "", + "editor.record.form.section.annexes.label": "", + "editor.record.form.section.associatedResources.description": "", + "editor.record.form.section.associatedResources.label": "", + "editor.record.form.section.classification.description": "", + "editor.record.form.section.classification.label": "", + "editor.record.form.section.dataManagers.description": "", + "editor.record.form.section.dataManagers.label": "", + "editor.record.form.section.dataPointOfContact.description": "", + "editor.record.form.section.dataPointOfContact.label": "", + "editor.record.form.section.geographicalCoverage.label": "", + "editor.record.form.section.useAndAccessConditions.label": "", "editor.record.form.metadata.title": "", "editor.record.form.record.updated": "", "editor.record.form.resourceUpdated": "", diff --git a/translations/sk.json b/translations/sk.json index f3dd2a423b..2df4e8b133 100644 --- a/translations/sk.json +++ b/translations/sk.json @@ -165,6 +165,18 @@ "downloads.format.unknown": "neznámy", "downloads.wfs.featuretype.not.found": "Vrstva nebola nájdená", "dropFile": "nahrať súbor", + "editor.record.form.bottomButtons.comeBackLater": "", + "editor.record.form.bottomButtons.next": "", + "editor.record.form.bottomButtons.previous": "", + "editor.record.form.field.abstract": "", + "editor.record.form.field.keywords": "", + "editor.record.form.field.license": "Licencia", + "editor.record.form.field.recordUpdated": "", + "editor.record.form.field.resourceUpdated": "", + "editor.record.form.field.temporalExtents": "", + "editor.record.form.field.title": "", + "editor.record.form.field.uniqueIdentifier": "", + "editor.record.form.field.updateFrequency": "", "editor.record.form.abstract": "", "editor.record.form.keywords": "", "editor.record.form.license": "Licencia", @@ -177,6 +189,22 @@ "editor.record.form.license.odc-by": "", "editor.record.form.license.pddl": "", "editor.record.form.license.unknown": "Neznáme alebo chýbajúce", + "editor.record.form.page.accessAndContact": "", + "editor.record.form.page.description": "", + "editor.record.form.page.ressources": "", + "editor.record.form.section.about.description": "", + "editor.record.form.section.about.label": "", + "editor.record.form.section.annexes.label": "", + "editor.record.form.section.associatedResources.description": "", + "editor.record.form.section.associatedResources.label": "", + "editor.record.form.section.classification.description": "", + "editor.record.form.section.classification.label": "", + "editor.record.form.section.dataManagers.description": "", + "editor.record.form.section.dataManagers.label": "", + "editor.record.form.section.dataPointOfContact.description": "", + "editor.record.form.section.dataPointOfContact.label": "", + "editor.record.form.section.geographicalCoverage.label": "", + "editor.record.form.section.useAndAccessConditions.label": "", "editor.record.form.metadata.title": "", "editor.record.form.record.updated": "", "editor.record.form.resourceUpdated": "",