From 65c2806160c16957fb6fec0bebdf94be1d8763e8 Mon Sep 17 00:00:00 2001
From: Camille Moinier
Date: Thu, 21 Dec 2023 18:21:06 +0100
Subject: [PATCH 01/11] feat(dh): adapt api card to handle form
---
.../src/lib/api-card/api-card.component.html | 38 ++++++++++++++++---
.../lib/api-card/api-card.component.spec.ts | 33 ++++++++++------
.../src/lib/api-card/api-card.component.ts | 36 +++++++++++++++++-
3 files changed, 88 insertions(+), 19 deletions(-)
diff --git a/libs/ui/elements/src/lib/api-card/api-card.component.html b/libs/ui/elements/src/lib/api-card/api-card.component.html
index ba834b4d0d..676de845c2 100644
--- a/libs/ui/elements/src/lib/api-card/api-card.component.html
+++ b/libs/ui/elements/src/lib/api-card/api-card.component.html
@@ -1,23 +1,51 @@
{{ link.name || link.description }}
{{ link.accessServiceProtocol.toUpperCase() }}{{ link.accessServiceProtocol }}
+
diff --git a/libs/ui/elements/src/lib/api-card/api-card.component.spec.ts b/libs/ui/elements/src/lib/api-card/api-card.component.spec.ts
index 1261e98035..2da1df059b 100644
--- a/libs/ui/elements/src/lib/api-card/api-card.component.spec.ts
+++ b/libs/ui/elements/src/lib/api-card/api-card.component.spec.ts
@@ -1,18 +1,16 @@
-import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed } from '@angular/core/testing'
-import { MatIconModule } from '@angular/material/icon'
-import { TranslateModule } from '@ngx-translate/core'
import { ApiCardComponent } from './api-card.component'
+import { TranslateModule } from '@ngx-translate/core'
+import { DatasetServiceDistribution } from '@geonetwork-ui/common/domain/model/record'
describe('ApiCardComponent', () => {
let component: ApiCardComponent
let fixture: ComponentFixture
-
+ let openRecordApiFormEmit
beforeEach(async () => {
await TestBed.configureTestingModule({
- schemas: [NO_ERRORS_SCHEMA],
declarations: [ApiCardComponent],
- imports: [MatIconModule, TranslateModule.forRoot()],
+ imports: [TranslateModule.forRoot()],
}).compileComponents()
})
@@ -20,16 +18,27 @@ describe('ApiCardComponent', () => {
fixture = TestBed.createComponent(ApiCardComponent)
component = fixture.componentInstance
component.link = {
- name: 'Allroads',
- description: 'A file that contains all roads',
- url: new URL('https://roads.com/wfs'),
- type: 'service',
- accessServiceProtocol: 'wfs',
- }
+ accessServiceProtocol: 'ogcFeatures',
+ } as DatasetServiceDistribution
+ openRecordApiFormEmit = component.openRecordApiForm
+ jest.resetAllMocks()
+ jest.spyOn(openRecordApiFormEmit, 'emit')
fixture.detectChanges()
})
it('should create', () => {
expect(component).toBeTruthy()
})
+
+ it('should initialize custom property based on accessServiceProtocol', () => {
+ component.ngOnInit()
+ expect(component.displayApiFormButton).toBe(true)
+ })
+
+ it('should toggle currentlyActive and emit openRecordApiForm event', () => {
+ component.openRecordApiFormPanel()
+
+ expect(component.currentlyActive).toBe(true)
+ expect(openRecordApiFormEmit.emit).toHaveBeenCalled()
+ })
})
diff --git a/libs/ui/elements/src/lib/api-card/api-card.component.ts b/libs/ui/elements/src/lib/api-card/api-card.component.ts
index 9f9888d3a0..c10ad4f600 100644
--- a/libs/ui/elements/src/lib/api-card/api-card.component.ts
+++ b/libs/ui/elements/src/lib/api-card/api-card.component.ts
@@ -1,5 +1,14 @@
-import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { DatasetServiceDistribution } from '@geonetwork-ui/common/domain/model/record'
+import {
+ ChangeDetectionStrategy,
+ Component,
+ EventEmitter,
+ Input,
+ OnChanges,
+ OnInit,
+ Output,
+ SimpleChanges,
+} from '@angular/core'
@Component({
selector: 'gn-ui-api-card',
@@ -7,6 +16,29 @@ import { DatasetServiceDistribution } from '@geonetwork-ui/common/domain/model/r
styleUrls: ['./api-card.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class ApiCardComponent {
+export class ApiCardComponent implements OnInit, OnChanges {
@Input() link: DatasetServiceDistribution
+ @Input() currentLink: DatasetServiceDistribution
+ displayApiFormButton: boolean
+ currentlyActive = false
+ @Output() openRecordApiForm: EventEmitter =
+ new EventEmitter()
+
+ ngOnInit() {
+ this.displayApiFormButton =
+ this.link.accessServiceProtocol === 'ogcFeatures' ? true : false
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
+ this.currentlyActive =
+ changes.currentLink.currentValue === this.link ? true : false
+ }
+
+ openRecordApiFormPanel() {
+ if (this.displayApiFormButton) {
+ this.currentlyActive = !this.currentlyActive
+ console.log(this.currentlyActive)
+ this.openRecordApiForm.emit(this.currentlyActive ? this.link : undefined)
+ }
+ }
}
From a15caad6d0d34474f93cc4a674702c5ba0bc3c43 Mon Sep 17 00:00:00 2001
From: Camille Moinier
Date: Thu, 21 Dec 2023 18:21:33 +0100
Subject: [PATCH 02/11] feat(dh): create record api form
---
.../record-api-form.component.css | 22 +++++
.../record-api-form.component.html | 75 ++++++++++++++++
.../record-api-form.component.spec.ts | 90 +++++++++++++++++++
.../record-api-form.component.ts | 65 ++++++++++++++
4 files changed, 252 insertions(+)
create mode 100644 libs/ui/elements/src/lib/record-api-form/record-api-form.component.css
create mode 100644 libs/ui/elements/src/lib/record-api-form/record-api-form.component.html
create mode 100644 libs/ui/elements/src/lib/record-api-form/record-api-form.component.spec.ts
create mode 100644 libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts
diff --git a/libs/ui/elements/src/lib/record-api-form/record-api-form.component.css b/libs/ui/elements/src/lib/record-api-form/record-api-form.component.css
new file mode 100644
index 0000000000..0aa4ba7d0b
--- /dev/null
+++ b/libs/ui/elements/src/lib/record-api-form/record-api-form.component.css
@@ -0,0 +1,22 @@
+:host ::ng-deep input {
+ color: black;
+ opacity: 1;
+}
+
+:host ::ng-deep gn-ui-copy-text-button input[type='text'] {
+ color: black;
+ background-color: white;
+}
+
+:host ::ng-deep gn-ui-copy-text-button button,
+host ::ng-deep gn-ui-copy-text-button button:hover {
+ background-color: var(--color-secondary) !important;
+}
+
+:host ::ng-deep gn-ui-copy-text-button button mat-icon {
+ color: white !important;
+ opacity: 1 !important;
+}
+:host ::ng-deep gn-ui-copy-text-button button:hover mat-icon {
+ color: lightgrey !important;
+}
diff --git a/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html b/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html
new file mode 100644
index 0000000000..b6328f5891
--- /dev/null
+++ b/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html
@@ -0,0 +1,75 @@
+
+
+
+
+ record.metadata.api.form.create
+
+
+
+
+
+
record.metadata.api.form.limit
+
+
+
+
+
+ record.metadata.api.form.limit.all
+
+
+
+
+
record.metadata.api.form.offset
+
+
+
+
+
record.metadata.api.form.type
+
+
+
+
+
+
+ record.metadata.api.form.customUrl
+
+
+
+
+
+
diff --git a/libs/ui/elements/src/lib/record-api-form/record-api-form.component.spec.ts b/libs/ui/elements/src/lib/record-api-form/record-api-form.component.spec.ts
new file mode 100644
index 0000000000..d21e700497
--- /dev/null
+++ b/libs/ui/elements/src/lib/record-api-form/record-api-form.component.spec.ts
@@ -0,0 +1,90 @@
+import { TestBed, ComponentFixture } from '@angular/core/testing'
+import { RecordApiFormComponent } from './record-api-form.component'
+import { DatasetServiceDistribution } from '@geonetwork-ui/common/domain/model/record'
+import { firstValueFrom } from 'rxjs'
+import { UiInputsModule } from '@geonetwork-ui/ui/inputs'
+import { TranslateModule } from '@ngx-translate/core'
+
+const mockDatasetServiceDistribution: DatasetServiceDistribution = {
+ url: new URL('https://api.example.com/data'),
+ type: 'service',
+ accessServiceProtocol: 'ogcFeatures',
+}
+
+describe('RecordApFormComponent', () => {
+ let component: RecordApiFormComponent
+ let fixture: ComponentFixture
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [RecordApiFormComponent],
+ imports: [UiInputsModule, TranslateModule.forRoot()],
+ }).compileComponents()
+
+ fixture = TestBed.createComponent(RecordApiFormComponent)
+ component = fixture.componentInstance
+ component.apiLink = mockDatasetServiceDistribution
+ fixture.detectChanges()
+ })
+
+ it('should create', () => {
+ expect(component).toBeTruthy()
+ })
+ describe('When panel is opened', () => {
+ it('should set the links and initial values correctly', async () => {
+ expect(component.apiBaseUrl).toBe('https://api.example.com/data')
+ expect(component.offset$.getValue()).toBe('')
+ expect(component.limit$.getValue()).toBe('')
+ expect(component.format$.getValue()).toBe('json')
+ const url = await firstValueFrom(component.apiQueryUrl$)
+ expect(url).toBe('https://api.example.com/data?f=json')
+ })
+ })
+ describe('When URL params are changed', () => {
+ it('should update query URL correctly when setting offset, limit, and format', async () => {
+ const mockOffset = '10'
+ const mockLimit = '20'
+ const mockFormat = 'json'
+ component.setOffset(mockOffset)
+ component.setLimit(mockLimit)
+ component.setFormat(mockFormat)
+ const url = await firstValueFrom(component.apiQueryUrl$)
+ expect(url).toBe(
+ `https://api.example.com/data?offset=${mockOffset}&limit=${mockLimit}&f=${mockFormat}`
+ )
+ })
+ it('should remove the param in url if value is null', async () => {
+ const mockOffset = null
+ const mockLimit = '20'
+ const mockFormat = 'json'
+ component.setOffset(mockOffset)
+ component.setLimit(mockLimit)
+ component.setFormat(mockFormat)
+ const url = await firstValueFrom(component.apiQueryUrl$)
+ expect(url).toBe(
+ `https://api.example.com/data?limit=${mockLimit}&f=${mockFormat}`
+ )
+ })
+ it('should remove the param in url if value is zero', async () => {
+ const mockOffset = '10'
+ const mockLimit = '0'
+ const mockFormat = 'json'
+ component.setOffset(mockOffset)
+ component.setLimit(mockLimit)
+ component.setFormat(mockFormat)
+ const url = await firstValueFrom(component.apiQueryUrl$)
+ expect(url).toBe(
+ `https://api.example.com/data?offset=${mockOffset}&f=${mockFormat}`
+ )
+ })
+ })
+
+ describe('#resetUrl', () => {
+ it('should reset URL to default parameters', () => {
+ component.resetUrl()
+ expect(component.offset$.getValue()).toBe('')
+ expect(component.limit$.getValue()).toBe('')
+ expect(component.format$.getValue()).toBe('json')
+ })
+ })
+})
diff --git a/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts b/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts
new file mode 100644
index 0000000000..497eddab1a
--- /dev/null
+++ b/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts
@@ -0,0 +1,65 @@
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
+import { DatasetServiceDistribution } from '@geonetwork-ui/common/domain/model/record'
+import { BehaviorSubject, combineLatest, map } from 'rxjs'
+
+const DEFAULT_PARAMS = {
+ OFFSET: '',
+ LIMIT: '',
+ FORMAT: 'json',
+}
+@Component({
+ selector: 'gn-ui-record-api-form',
+ templateUrl: './record-api-form.component.html',
+ styleUrls: ['./record-api-form.component.css'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class RecordApiFormComponent {
+ @Input() set apiLink(value: DatasetServiceDistribution) {
+ this.apiBaseUrl = value ? value.url.href : undefined
+ this.resetUrl()
+ }
+ offset$ = new BehaviorSubject('')
+ limit$ = new BehaviorSubject('')
+ format$ = new BehaviorSubject('')
+ apiBaseUrl: string
+ formatsList = [
+ { label: 'JSON', value: 'json' },
+ { label: 'CSV', value: 'csv' },
+ ]
+ apiQueryUrl$ = combineLatest([this.offset$, this.limit$, this.format$]).pipe(
+ map(([offset, limit, format]) => {
+ let outputUrl
+ if (this.apiBaseUrl) {
+ const url = new URL(this.apiBaseUrl)
+ const params = { offset: offset, limit: limit, f: format }
+ for (const [key, value] of Object.entries(params)) {
+ if (value && value !== '0') {
+ url.searchParams.set(key, value)
+ } else {
+ url.searchParams.delete(key)
+ }
+ }
+ outputUrl = url.toString()
+ }
+ return outputUrl
+ })
+ )
+
+ setOffset(value: string) {
+ this.offset$.next(value)
+ }
+
+ setLimit(value: string) {
+ this.limit$.next(value)
+ }
+
+ setFormat(value: string) {
+ this.format$.next(value)
+ }
+
+ resetUrl() {
+ this.offset$.next(DEFAULT_PARAMS.OFFSET)
+ this.limit$.next(DEFAULT_PARAMS.LIMIT)
+ this.format$.next(DEFAULT_PARAMS.FORMAT)
+ }
+}
From e7d57bbc721450e82b27cd41216f4e677298b6f4 Mon Sep 17 00:00:00 2001
From: Camille Moinier
Date: Thu, 21 Dec 2023 18:21:56 +0100
Subject: [PATCH 03/11] feat(dh/me): create date range picker
---
.../date-range-picker.component.css | 3 ++
.../date-range-picker.component.html | 24 ++++++++++++
.../date-range-picker.component.spec.ts | 38 +++++++++++++++++++
.../date-range-picker.component.ts | 20 ++++++++++
4 files changed, 85 insertions(+)
create mode 100644 libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.css
create mode 100644 libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.html
create mode 100644 libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.spec.ts
create mode 100644 libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.ts
diff --git a/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.css b/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.css
new file mode 100644
index 0000000000..58dae5804f
--- /dev/null
+++ b/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.css
@@ -0,0 +1,3 @@
+mat-datepicker-toggle {
+ @apply text-primary;
+}
diff --git a/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.html b/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.html
new file mode 100644
index 0000000000..dc7eb44a9e
--- /dev/null
+++ b/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.html
@@ -0,0 +1,24 @@
+
diff --git a/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.spec.ts b/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.spec.ts
new file mode 100644
index 0000000000..d3fe405cef
--- /dev/null
+++ b/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.spec.ts
@@ -0,0 +1,38 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing'
+import { MatDatepickerInputEvent } from '@angular/material/datepicker'
+import { DateRangePickerComponent } from './date-range-picker.component'
+
+describe('DateRangePickerComponent', () => {
+ let component: DateRangePickerComponent
+ let fixture: ComponentFixture
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [DateRangePickerComponent],
+ }).compileComponents()
+
+ fixture = TestBed.createComponent(DateRangePickerComponent)
+ component = fixture.componentInstance
+ fixture.detectChanges()
+ })
+
+ it('should create', () => {
+ expect(component).toBeTruthy()
+ })
+
+ it('should set start date on startDateSelected', () => {
+ const event = {
+ value: new Date('2023-01-01'),
+ } as MatDatepickerInputEvent
+ component.startDateSelected(event)
+ expect(component.startDate).toEqual(new Date('2023-01-01'))
+ })
+
+ it('should set end date on endDateSelected', () => {
+ const event = {
+ value: new Date('2023-01-31'),
+ } as MatDatepickerInputEvent
+ component.endDateSelected(event)
+ expect(component.endDate).toEqual(new Date('2023-01-31'))
+ })
+})
diff --git a/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.ts b/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.ts
new file mode 100644
index 0000000000..a4593cdf75
--- /dev/null
+++ b/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.ts
@@ -0,0 +1,20 @@
+import { Component } from '@angular/core'
+import { MatDatepickerInputEvent } from '@angular/material/datepicker'
+
+@Component({
+ selector: 'gn-ui-date-range-picker',
+ templateUrl: './date-range-picker.component.html',
+ styleUrls: ['./date-range-picker.component.css'],
+})
+export class DateRangePickerComponent {
+ startDate: Date
+ endDate: Date
+
+ startDateSelected(event: MatDatepickerInputEvent) {
+ this.startDate = event.value
+ }
+
+ endDateSelected(event: MatDatepickerInputEvent) {
+ this.endDate = event.value
+ }
+}
From 26ef852048d6a3193dbed8ffda6a4f832b54f052 Mon Sep 17 00:00:00 2001
From: Camille Moinier
Date: Thu, 21 Dec 2023 18:22:16 +0100
Subject: [PATCH 04/11] feat(dh): implement api form
---
.../record-apis/record-apis.component.css | 3 +
.../record-apis/record-apis.component.html | 88 ++++++++++++++-----
.../record-apis/record-apis.component.spec.ts | 35 ++++++--
.../record-apis/record-apis.component.ts | 26 +++++-
4 files changed, 121 insertions(+), 31 deletions(-)
diff --git a/apps/datahub/src/app/record/record-apis/record-apis.component.css b/apps/datahub/src/app/record/record-apis/record-apis.component.css
index e69de29bb2..5b19499cd1 100644
--- a/apps/datahub/src/app/record/record-apis/record-apis.component.css
+++ b/apps/datahub/src/app/record/record-apis/record-apis.component.css
@@ -0,0 +1,3 @@
+.tab-header-label {
+ @apply uppercase text-sm text-primary opacity-75 hover:text-primary-darker;
+}
diff --git a/apps/datahub/src/app/record/record-apis/record-apis.component.html b/apps/datahub/src/app/record/record-apis/record-apis.component.html
index b7b623d5e7..329f7b34b2 100644
--- a/apps/datahub/src/app/record/record-apis/record-apis.component.html
+++ b/apps/datahub/src/app/record/record-apis/record-apis.component.html
@@ -1,25 +1,65 @@
-
- record.metadata.api
-
-
-
+
-
-
+ record.metadata.api
+
+
+
+
+
+
+
+
+
+
+
+ record.metadata.api.form.title
+
+
+
+
+
+
+
diff --git a/apps/datahub/src/app/record/record-apis/record-apis.component.spec.ts b/apps/datahub/src/app/record/record-apis/record-apis.component.spec.ts
index 948b6b2fc0..6ff7242cb3 100644
--- a/apps/datahub/src/app/record/record-apis/record-apis.component.spec.ts
+++ b/apps/datahub/src/app/record/record-apis/record-apis.component.spec.ts
@@ -1,19 +1,29 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
-import { Subject } from 'rxjs'
import { RecordApisComponent } from './record-apis.component'
+import { TranslateModule } from '@ngx-translate/core'
+import { DatasetServiceDistribution } from '@geonetwork-ui/common/domain/model/record'
import { MdViewFacade } from '@geonetwork-ui/feature/record'
+import { BehaviorSubject, firstValueFrom } from 'rxjs'
class MdViewFacadeMock {
- apiLinks$ = new Subject()
+ selectedApiLink$ = new BehaviorSubject([])
}
-describe('DataApisComponent', () => {
+const serviceDistributionMock = {
+ type: 'service',
+ url: new URL('http://myogcapifeatures.test'),
+ accessServiceProtocol: 'ogcFeatures',
+} as DatasetServiceDistribution
+
+describe('RecordApisComponent', () => {
let component: RecordApisComponent
let fixture: ComponentFixture
+ let facade
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [RecordApisComponent],
+ imports: [TranslateModule.forRoot()],
providers: [
{
provide: MdViewFacade,
@@ -21,15 +31,30 @@ describe('DataApisComponent', () => {
},
],
}).compileComponents()
- })
- beforeEach(() => {
fixture = TestBed.createComponent(RecordApisComponent)
component = fixture.componentInstance
+ facade = TestBed.inject(MdViewFacade)
fixture.detectChanges()
})
it('should create', () => {
expect(component).toBeTruthy()
})
+
+ describe('#openRecordApiForm', () => {
+ beforeEach(() => {
+ component.openRecordApiForm(serviceDistributionMock)
+ })
+ it('should update selectedApiLink$', async () => {
+ expect(component.selectedApiLink).toEqual(serviceDistributionMock)
+ })
+ })
+
+ describe('#closeRecordApiForm', () => {
+ it('should pass undefined to selectedApiLink$', async () => {
+ component.closeRecordApiForm()
+ expect(component.selectedApiLink).toBeUndefined()
+ })
+ })
})
diff --git a/apps/datahub/src/app/record/record-apis/record-apis.component.ts b/apps/datahub/src/app/record/record-apis/record-apis.component.ts
index 8bcfd1ce86..050fc87475 100644
--- a/apps/datahub/src/app/record/record-apis/record-apis.component.ts
+++ b/apps/datahub/src/app/record/record-apis/record-apis.component.ts
@@ -1,4 +1,5 @@
-import { Component, ChangeDetectionStrategy } from '@angular/core'
+import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core'
+import { DatasetServiceDistribution } from '@geonetwork-ui/common/domain/model/record'
import { MdViewFacade } from '@geonetwork-ui/feature/record'
@Component({
@@ -7,6 +8,27 @@ import { MdViewFacade } from '@geonetwork-ui/feature/record'
styleUrls: ['./record-apis.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class RecordApisComponent {
+export class RecordApisComponent implements OnInit {
+ maxHeight = ''
+ selectedApiLink: DatasetServiceDistribution
constructor(public facade: MdViewFacade) {}
+
+ ngOnInit(): void {
+ this.maxHeight = this.setMaxHeight(undefined)
+ this.selectedApiLink = undefined
+ }
+
+ openRecordApiForm(link: DatasetServiceDistribution) {
+ this.selectedApiLink = link
+ this.maxHeight = this.setMaxHeight(link)
+ }
+
+ closeRecordApiForm() {
+ this.selectedApiLink = undefined
+ this.maxHeight = this.setMaxHeight(undefined)
+ }
+
+ setMaxHeight(link: DatasetServiceDistribution) {
+ return `${link === undefined ? '0' : '428'}px`
+ }
}
From 73998bfb4483e6d910cc85b77ba052ac46cb5902 Mon Sep 17 00:00:00 2001
From: Camille Moinier
Date: Thu, 21 Dec 2023 18:23:04 +0100
Subject: [PATCH 05/11] feat(dh): change record-api implementation
---
.../record-metadata.component.html | 9 +-
.../record-metadata.component.spec.ts | 86 +++++++++++++++----
2 files changed, 76 insertions(+), 19 deletions(-)
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 f7f020a96c..e332f92203 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
@@ -114,13 +114,16 @@
-
-
+
diff --git a/apps/datahub/src/app/record/record-metadata/record-metadata.component.spec.ts b/apps/datahub/src/app/record/record-metadata/record-metadata.component.spec.ts
index f1ba243c25..70ffa20d2a 100644
--- a/apps/datahub/src/app/record/record-metadata/record-metadata.component.spec.ts
+++ b/apps/datahub/src/app/record/record-metadata/record-metadata.component.spec.ts
@@ -1,4 +1,10 @@
-import { Component, NO_ERRORS_SCHEMA } from '@angular/core'
+import {
+ Component,
+ EventEmitter,
+ Input,
+ NO_ERRORS_SCHEMA,
+ Output,
+} from '@angular/core'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { By } from '@angular/platform-browser'
import { SourcesService } from '@geonetwork-ui/feature/catalog'
@@ -6,18 +12,21 @@ import { MapManagerService } from '@geonetwork-ui/feature/map'
import { SearchService } from '@geonetwork-ui/feature/search'
import {
ErrorType,
- MetadataCatalogComponent,
- MetadataContactComponent,
- MetadataInfoComponent,
SearchResultsErrorComponent,
- UiElementsModule,
} from '@geonetwork-ui/ui/elements'
import { TranslateModule } from '@ngx-translate/core'
-import { BehaviorSubject, of } from 'rxjs'
+import { BehaviorSubject, firstValueFrom, of } from 'rxjs'
import { RecordMetadataComponent } from './record-metadata.component'
import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface'
import { DATASET_RECORDS } from '@geonetwork-ui/common/fixtures'
import { MdViewFacade } from '@geonetwork-ui/feature/record'
+import {
+ CatalogRecord,
+ DatasetRecord,
+ DatasetServiceDistribution,
+ Individual,
+ Organization,
+} from '@geonetwork-ui/common/domain/model/record'
const SAMPLE_RECORD = {
...DATASET_RECORDS[0],
@@ -100,6 +109,46 @@ export class MockDataApisComponent {}
})
export class MockRelatedComponent {}
+@Component({
+ // eslint-disable-next-line @angular-eslint/component-selector
+ selector: 'gn-ui-metadata-info',
+ template: '
',
+})
+export class MockMetadataInfoComponent {
+ @Input() metadata: Partial
+ @Input() incomplete: boolean
+ @Output() keyword = new EventEmitter()
+}
+
+@Component({
+ // eslint-disable-next-line @angular-eslint/component-selector
+ selector: 'gn-ui-metadata-contact',
+ template: '',
+})
+export class MockMetadataContactComponent {
+ @Input() metadata: Partial
+ @Output() organizationClick = new EventEmitter()
+ @Output() contactClick = new EventEmitter()
+}
+
+@Component({
+ // eslint-disable-next-line @angular-eslint/component-selector
+ selector: 'gn-ui-metadata-catalog',
+ template: '',
+})
+export class MockMetadataCatalogComponent {
+ @Input() sourceLabel: string
+}
+
+@Component({
+ // eslint-disable-next-line @angular-eslint/component-selector
+ selector: 'gn-ui-record-api-form',
+ template: '',
+})
+export class MockRecordApiFormComponent {
+ @Input() apiLink: DatasetServiceDistribution
+}
+
describe('RecordMetadataComponent', () => {
let component: RecordMetadataComponent
let fixture: ComponentFixture
@@ -119,9 +168,14 @@ describe('RecordMetadataComponent', () => {
MockDataApisComponent,
MockRelatedComponent,
SearchResultsErrorComponent,
+ MockMetadataInfoComponent,
+ MockMetadataCatalogComponent,
+ MockMetadataContactComponent,
+
+ MockRecordApiFormComponent,
],
schemas: [NO_ERRORS_SCHEMA],
- imports: [UiElementsModule, TranslateModule.forRoot()],
+ imports: [TranslateModule.forRoot()],
providers: [
{
provide: MdViewFacade,
@@ -161,21 +215,21 @@ describe('RecordMetadataComponent', () => {
})
describe('about', () => {
- let metadataInfo: MetadataInfoComponent
- let metadataContact: MetadataContactComponent
- let catalogComponent: MetadataCatalogComponent
+ let metadataInfo: MockMetadataInfoComponent
+ let metadataContact: MockMetadataContactComponent
+ let catalogComponent: MockMetadataCatalogComponent
beforeEach(() => {
facade.isPresent$.next(true)
fixture.detectChanges()
metadataInfo = fixture.debugElement.query(
- By.directive(MetadataInfoComponent)
+ By.directive(MockMetadataInfoComponent)
).componentInstance
metadataContact = fixture.debugElement.query(
- By.directive(MetadataContactComponent)
+ By.directive(MockMetadataContactComponent)
).componentInstance
catalogComponent = fixture.debugElement.query(
- By.directive(MetadataCatalogComponent)
+ By.directive(MockMetadataCatalogComponent)
).componentInstance
})
describe('if metadata present', () => {
@@ -197,7 +251,7 @@ describe('RecordMetadataComponent', () => {
facade.isPresent$.next(false)
fixture.detectChanges()
metadataInfo = fixture.debugElement.query(
- By.directive(MetadataInfoComponent)
+ By.directive(MockMetadataInfoComponent)
).componentInstance
})
it('shows a placeholder', () => {
@@ -206,12 +260,12 @@ describe('RecordMetadataComponent', () => {
})
it('does not display the metadata contact component', () => {
expect(
- fixture.debugElement.query(By.directive(MetadataContactComponent))
+ fixture.debugElement.query(By.directive(MockMetadataContactComponent))
).toBeFalsy()
})
it('does not display the metadata catalog component', () => {
expect(
- fixture.debugElement.query(By.directive(MetadataCatalogComponent))
+ fixture.debugElement.query(By.directive(MockMetadataCatalogComponent))
).toBeFalsy()
})
})
From 2e6c0b67cf44bdc9a0d25aa2864d6859e93d015d Mon Sep 17 00:00:00 2001
From: Camille Moinier
Date: Thu, 21 Dec 2023 18:23:51 +0100
Subject: [PATCH 06/11] feat(dh): handle ogc api types
---
.../src/lib/common/distribution.mapper.ts | 1 +
.../src/lib/gn4/gn4.field.mapper.spec.ts | 1 +
.../api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts | 3 ++-
libs/common/domain/src/lib/model/record/metadata.model.ts | 1 +
.../src/lib/elasticsearch/metadata-links.fixtures.ts | 5 +++++
libs/common/fixtures/src/lib/link.fixtures.ts | 7 +++++++
libs/feature/record/src/lib/state/mdview.facade.ts | 1 +
libs/util/shared/src/lib/links/link-classifier.service.ts | 2 ++
8 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/libs/api/metadata-converter/src/lib/common/distribution.mapper.ts b/libs/api/metadata-converter/src/lib/common/distribution.mapper.ts
index bde80a250e..e5d66e3b66 100644
--- a/libs/api/metadata-converter/src/lib/common/distribution.mapper.ts
+++ b/libs/api/metadata-converter/src/lib/common/distribution.mapper.ts
@@ -5,6 +5,7 @@ export function matchProtocol(protocol: string): ServiceProtocol {
if (/wfs/i.test(protocol)) return 'wfs'
if (/wmts/i.test(protocol)) return 'wmts'
if (/wps/i.test(protocol)) return 'wps'
+ if (/ogc\W*api\W*features/i.test(protocol)) return 'ogcFeatures'
if (/esri/i.test(protocol)) return 'esriRest'
return 'other'
}
diff --git a/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.spec.ts b/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.spec.ts
index 3263349036..ee7619dc54 100644
--- a/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.spec.ts
+++ b/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.spec.ts
@@ -72,6 +72,7 @@ describe('Gn4FieldMapper', () => {
'link',
'link',
'download',
+ 'service',
])
})
})
diff --git a/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts b/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts
index c9ab874094..cda6afbc21 100644
--- a/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts
+++ b/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts
@@ -323,7 +323,8 @@ export class Gn4FieldMapper {
(/^ESRI:REST/.test(protocol) && /FeatureServer/.test(url)) ||
/^OGC:WMS/.test(protocol) ||
/^OGC:WFS/.test(protocol) ||
- /^OGC:WMTS/.test(protocol)
+ /^OGC:WMTS/.test(protocol) ||
+ /ogc\W*api\W*features/i.test(protocol)
) {
return 'service'
}
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 90d2fba553..38ebcd6e1e 100644
--- a/libs/common/domain/src/lib/model/record/metadata.model.ts
+++ b/libs/common/domain/src/lib/model/record/metadata.model.ts
@@ -98,6 +98,7 @@ export type ServiceProtocol =
| 'wps'
| 'wmts'
| 'esriRest'
+ | 'ogcFeatures'
| 'other'
export type DatasetDistributionType = 'service' | 'download' | 'link'
diff --git a/libs/common/fixtures/src/lib/elasticsearch/metadata-links.fixtures.ts b/libs/common/fixtures/src/lib/elasticsearch/metadata-links.fixtures.ts
index d09abce176..38b6a80cc2 100644
--- a/libs/common/fixtures/src/lib/elasticsearch/metadata-links.fixtures.ts
+++ b/libs/common/fixtures/src/lib/elasticsearch/metadata-links.fixtures.ts
@@ -141,4 +141,9 @@ export const ES_LINK_FIXTURES: Record = deepFreeze({
name: 'Vue HTML des métadonnées sur internet',
url: 'http://catalogue.geo-ide.developpement-durable.gouv.fr/catalogue/srv/fre/catalog.search#/metadata/fr-120066022-jdd-199fd14c-2abb-4c14-b0f8-6c8d92e7b480',
},
+ geodataogcfeatures: {
+ protocol: 'OGC API - Features',
+ name: 'ogcapi features layer',
+ url: 'https://mel.integration.apps.gs-fr-prod.camptocamp.com/data/ogcapi/collections/comptages_velo/items?',
+ },
})
diff --git a/libs/common/fixtures/src/lib/link.fixtures.ts b/libs/common/fixtures/src/lib/link.fixtures.ts
index 7d1aa5014b..9c25448e77 100644
--- a/libs/common/fixtures/src/lib/link.fixtures.ts
+++ b/libs/common/fixtures/src/lib/link.fixtures.ts
@@ -151,4 +151,11 @@ export const LINK_FIXTURES: Record = deepFreeze({
'http://catalogue.geo-ide.developpement-durable.gouv.fr/catalogue/srv/fre/catalog.search#/metadata/fr-120066022-jdd-199fd14c-2abb-4c14-b0f8-6c8d92e7b480'
),
},
+ ogcApiFormat: {
+ name: 'ogc api features layer',
+ type: 'service',
+ url: new URL(
+ 'https://mel.integration.apps.gs-fr-prod.camptocamp.com/data/ogcapi/collections/comptages_velo/items?'
+ ),
+ },
})
diff --git a/libs/feature/record/src/lib/state/mdview.facade.ts b/libs/feature/record/src/lib/state/mdview.facade.ts
index a2e4a0064f..e73e1518e5 100644
--- a/libs/feature/record/src/lib/state/mdview.facade.ts
+++ b/libs/feature/record/src/lib/state/mdview.facade.ts
@@ -6,6 +6,7 @@ import * as MdViewSelectors from './mdview.selectors'
import { LinkClassifierService, LinkUsage } from '@geonetwork-ui/util/shared'
import { DatavizConfigurationModel } from '@geonetwork-ui/common/domain/model/dataviz/dataviz-configuration.model'
import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record'
+import { BehaviorSubject } from 'rxjs'
@Injectable()
/**
diff --git a/libs/util/shared/src/lib/links/link-classifier.service.ts b/libs/util/shared/src/lib/links/link-classifier.service.ts
index f25fc65103..a900e0400e 100644
--- a/libs/util/shared/src/lib/links/link-classifier.service.ts
+++ b/libs/util/shared/src/lib/links/link-classifier.service.ts
@@ -25,6 +25,8 @@ export class LinkClassifierService {
case 'wms':
case 'wmts':
return [LinkUsage.API, LinkUsage.MAP_API]
+ case 'ogcFeatures':
+ return [LinkUsage.API]
default:
return [LinkUsage.UNKNOWN]
}
From 1c3be2c5a71d468b626d3e83bb77ab4aef1c5d4e Mon Sep 17 00:00:00 2001
From: Camille Moinier
Date: Thu, 21 Dec 2023 18:24:09 +0100
Subject: [PATCH 07/11] feat(dh): module imports
---
.../ui/elements/src/lib/ui-elements.module.ts | 3 +++
libs/ui/inputs/src/lib/ui-inputs.module.ts | 11 +++++++++++
.../docker-entrypoint-initdb.d/dump | Bin 415147 -> 415542 bytes
tailwind.base.css | 2 +-
4 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/libs/ui/elements/src/lib/ui-elements.module.ts b/libs/ui/elements/src/lib/ui-elements.module.ts
index 377675c95f..73b00327a2 100644
--- a/libs/ui/elements/src/lib/ui-elements.module.ts
+++ b/libs/ui/elements/src/lib/ui-elements.module.ts
@@ -28,6 +28,7 @@ import { UserPreviewComponent } from './user-preview/user-preview.component'
import { GnUiLinkifyDirective } from './metadata-info/linkify.directive'
import { PaginationButtonsComponent } from './pagination-buttons/pagination-buttons.component'
import { MaxLinesComponent } from './max-lines/max-lines.component'
+import { RecordApiFormComponent } from './record-api-form/record-api-form.component'
@NgModule({
imports: [
@@ -63,6 +64,7 @@ import { MaxLinesComponent } from './max-lines/max-lines.component'
GnUiLinkifyDirective,
PaginationButtonsComponent,
MaxLinesComponent,
+ RecordApiFormComponent,
],
exports: [
MetadataInfoComponent,
@@ -82,6 +84,7 @@ import { MaxLinesComponent } from './max-lines/max-lines.component'
AvatarComponent,
UserPreviewComponent,
PaginationButtonsComponent,
+ RecordApiFormComponent,
],
})
export class UiElementsModule {}
diff --git a/libs/ui/inputs/src/lib/ui-inputs.module.ts b/libs/ui/inputs/src/lib/ui-inputs.module.ts
index 4e9fa30fe7..9960dde5e5 100644
--- a/libs/ui/inputs/src/lib/ui-inputs.module.ts
+++ b/libs/ui/inputs/src/lib/ui-inputs.module.ts
@@ -36,6 +36,11 @@ import { MatTooltipModule } from '@angular/material/tooltip'
import { CommonModule } from '@angular/common'
import { CheckboxComponent } from './checkbox/checkbox.component'
import { SearchInputComponent } from './search-input/search-input.component'
+import { DateRangePickerComponent } from './date-range-picker/date-range-picker.component'
+import { MatFormFieldModule } from '@angular/material/form-field'
+import { MatInputModule } from '@angular/material/input'
+import { MatDatepickerModule } from '@angular/material/datepicker'
+import { MatNativeDateModule } from '@angular/material/core'
@NgModule({
declarations: [
@@ -62,6 +67,7 @@ import { SearchInputComponent } from './search-input/search-input.component'
CopyTextButtonComponent,
CheckboxComponent,
SearchInputComponent,
+ DateRangePickerComponent,
],
imports: [
CommonModule,
@@ -77,6 +83,10 @@ import { SearchInputComponent } from './search-input/search-input.component'
OverlayModule,
MatCheckboxModule,
MatTooltipModule,
+ MatFormFieldModule,
+ MatInputModule,
+ MatDatepickerModule,
+ MatNativeDateModule,
],
exports: [
DropdownSelectorComponent,
@@ -95,6 +105,7 @@ import { SearchInputComponent } from './search-input/search-input.component'
CopyTextButtonComponent,
CheckboxComponent,
SearchInputComponent,
+ DateRangePickerComponent,
],
})
export class UiInputsModule {}
diff --git a/support-services/docker-entrypoint-initdb.d/dump b/support-services/docker-entrypoint-initdb.d/dump
index 6a86fefc3d016a0975749cebca0c8f3b4679402e..82c0a6847d74e5c61a0b580a4c712d6f431d54dc 100644
GIT binary patch
delta 59852
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