geonetwork-ui 2.10.0-dev.574947486 → 2.10.0-dev.69145ed6a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/geonetwork-ui.mjs +267 -109
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/index.d.ts +66 -26
- package/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +14 -2
- package/src/libs/api/repository/src/lib/gn4/gn4.provider.ts +6 -1
- package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +6 -0
- package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +0 -1
- package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +10 -1
- package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.html +18 -3
- package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.ts +33 -40
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-constraints-shortcuts/form-field-constraints-shortcuts.component.ts +34 -34
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.html +8 -15
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.ts +6 -4
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.html +8 -7
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.ts +6 -6
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-single-link-resource/form-field-online-single-link-resource.component.css +0 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-single-link-resource/form-field-online-single-link-resource.component.html +5 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-single-link-resource/form-field-online-single-link-resource.component.ts +89 -0
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.css +3 -0
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +1 -0
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +57 -3
- package/src/libs/feature/notify-reuse/src/index.ts +1 -0
- package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.css +0 -0
- package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.html +1 -0
- package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.ts +21 -0
- package/src/libs/ui/elements/src/index.ts +1 -0
- package/src/libs/ui/elements/src/lib/contact-pill/contact-pill.component.html +16 -0
- package/src/libs/ui/elements/src/lib/contact-pill/contact-pill.component.ts +26 -0
- package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.html +1 -1
- package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.ts +0 -1
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.css +0 -4
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +27 -66
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +30 -10
- package/src/libs/ui/inputs/src/lib/button/button.component.ts +4 -0
- package/src/libs/ui/map/src/lib/components/map-container/map-container.component.ts +2 -1
- package/src/libs/ui/map/src/lib/components/spatial-extent/spatial-extent.component.ts +11 -10
- package/src/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.html +0 -1
- package/src/libs/util/app-config/src/lib/app-config.ts +36 -0
- package/src/libs/util/app-config/src/lib/model.ts +4 -0
- package/src/libs/util/app-config/src/lib/parse-utils.ts +23 -1
- package/src/libs/util/shared/src/lib/record/quality-score.util.ts +33 -18
- package/src/libs/util/shared/src/lib/utils/index.ts +1 -0
- package/src/libs/util/shared/src/lib/utils/user-display.ts +23 -0
- package/tailwind.base.css +11 -2
- package/translations/de.json +2 -0
- package/translations/en.json +2 -0
- package/translations/es.json +2 -0
- package/translations/fr.json +2 -0
- package/translations/it.json +2 -0
- package/translations/nl.json +2 -0
- package/translations/pt.json +2 -0
- package/translations/sk.json +2 -0
|
@@ -28,11 +28,12 @@
|
|
|
28
28
|
<gn-ui-max-lines [maxLines]="7">
|
|
29
29
|
<div class="metadata-info-keywords sm:pb-4 flex flex-wrap gap-2">
|
|
30
30
|
@for (keyword of metadata.keywords; track keyword) {
|
|
31
|
-
<gn-ui-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
<gn-ui-button
|
|
32
|
+
type="primary-light"
|
|
33
|
+
class="inline-block opacity-70"
|
|
34
|
+
extraClass="lowercase text-sm py-1 px-2"
|
|
35
|
+
(buttonClick)="onKeywordClick(keyword)"
|
|
36
|
+
>{{ keyword.label }}</gn-ui-button
|
|
36
37
|
>
|
|
37
38
|
}
|
|
38
39
|
</div>
|
|
@@ -105,9 +106,29 @@
|
|
|
105
106
|
</div>
|
|
106
107
|
</gn-ui-expandable-panel>
|
|
107
108
|
}
|
|
109
|
+
@if (metadata.contactsForResource?.length) {
|
|
110
|
+
<gn-ui-expandable-panel
|
|
111
|
+
[title]="'record.metadata.resource.contacts' | translate"
|
|
112
|
+
data-test="contacts-panel"
|
|
113
|
+
>
|
|
114
|
+
<div class="flex flex-col gap-1 pt-3 pb-4">
|
|
115
|
+
@for (group of contactGroups; track group.role) {
|
|
116
|
+
<div class="flex flex-col gap-1 rounded bg-gray-50 py-4 px-2">
|
|
117
|
+
<p class="text-xs font-normal text-black">
|
|
118
|
+
{{ group.roleLabel | translate }}
|
|
119
|
+
</p>
|
|
120
|
+
<div class="grid gap-0.5 grid-cols-1 md:grid-cols-2">
|
|
121
|
+
@for (contact of group.contacts; track contact.email) {
|
|
122
|
+
<gn-ui-contact-pill [contact]="contact"></gn-ui-contact-pill>
|
|
123
|
+
}
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
}
|
|
127
|
+
</div>
|
|
128
|
+
</gn-ui-expandable-panel>
|
|
129
|
+
}
|
|
108
130
|
@if (
|
|
109
131
|
(metadata.kind === 'dataset' && metadata.lineage) ||
|
|
110
|
-
resourceContact ||
|
|
111
132
|
metadata.resourceCreated ||
|
|
112
133
|
metadata.resourcePublished ||
|
|
113
134
|
metadata.resourceUpdated ||
|
|
@@ -129,66 +150,6 @@
|
|
|
129
150
|
</p>
|
|
130
151
|
</div>
|
|
131
152
|
}
|
|
132
|
-
@if (resourceContact) {
|
|
133
|
-
<div
|
|
134
|
-
class="flex flex-row gap-6 mt-5 mb-8 resource-contact"
|
|
135
|
-
data-test="details-panel-resource-contact"
|
|
136
|
-
>
|
|
137
|
-
@if (resourceContact.organization?.logoUrl?.href) {
|
|
138
|
-
<div
|
|
139
|
-
class="flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden"
|
|
140
|
-
>
|
|
141
|
-
<gn-ui-thumbnail
|
|
142
|
-
class="relative h-full w-full"
|
|
143
|
-
[thumbnailUrl]="resourceContact.organization.logoUrl.href"
|
|
144
|
-
fit="contain"
|
|
145
|
-
></gn-ui-thumbnail>
|
|
146
|
-
</div>
|
|
147
|
-
}
|
|
148
|
-
<div class="flex flex-col gap-1">
|
|
149
|
-
<p class="text-sm font-medium" translate>record.metadata.producer</p>
|
|
150
|
-
<div
|
|
151
|
-
class="text-primary font-title text-21 mr-2 cursor-pointer hover:underline"
|
|
152
|
-
data-cy="organization-name"
|
|
153
|
-
>
|
|
154
|
-
{{ resourceContact.organization?.name }}
|
|
155
|
-
</div>
|
|
156
|
-
@if (resourceContact.organization?.website) {
|
|
157
|
-
<div>
|
|
158
|
-
<a
|
|
159
|
-
[href]="resourceContact.organization.website"
|
|
160
|
-
target="_blank"
|
|
161
|
-
class="contact-website text-primary text-sm cursor-pointer hover:underline transition-all"
|
|
162
|
-
>{{ resourceContact.organization.website }}
|
|
163
|
-
<ng-icon
|
|
164
|
-
class="!w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0"
|
|
165
|
-
name="matOpenInNew"
|
|
166
|
-
></ng-icon>
|
|
167
|
-
</a>
|
|
168
|
-
</div>
|
|
169
|
-
}
|
|
170
|
-
@if (resourceContact.email) {
|
|
171
|
-
<div class="mt-4">
|
|
172
|
-
<div class="flex">
|
|
173
|
-
<ng-icon
|
|
174
|
-
class="!w-5 !h-5 !text-[20px] opacity-75 shrink-0"
|
|
175
|
-
name="matMailOutline"
|
|
176
|
-
></ng-icon>
|
|
177
|
-
@if (resourceContact.email) {
|
|
178
|
-
<a
|
|
179
|
-
[href]="'mailto:' + resourceContact.email"
|
|
180
|
-
class="text-sm hover:underline ml-2"
|
|
181
|
-
target="_blank"
|
|
182
|
-
data-cy="contact-email"
|
|
183
|
-
>{{ resourceContact?.email }}</a
|
|
184
|
-
>
|
|
185
|
-
}
|
|
186
|
-
</div>
|
|
187
|
-
</div>
|
|
188
|
-
}
|
|
189
|
-
</div>
|
|
190
|
-
</div>
|
|
191
|
-
}
|
|
192
153
|
<div
|
|
193
154
|
class="py-6 px-6 rounded bg-gray-100 grid grid-cols-2 gap-y-6 gap-x-[20px] text-gray-700"
|
|
194
155
|
>
|
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
} from '@angular/core'
|
|
9
9
|
import {
|
|
10
10
|
CatalogRecord,
|
|
11
|
+
Individual,
|
|
11
12
|
Keyword,
|
|
13
|
+
Role,
|
|
14
|
+
RoleLabels,
|
|
12
15
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
13
16
|
import { DateService, getTemporalRangeUnion } from '../../../../../../libs/util/shared/src'
|
|
14
17
|
import { MarkdownParserComponent } from '../markdown-parser/markdown-parser.component'
|
|
@@ -19,17 +22,18 @@ import {
|
|
|
19
22
|
import { TranslateDirective, TranslatePipe } from '@ngx-translate/core'
|
|
20
23
|
import {
|
|
21
24
|
BadgeComponent,
|
|
25
|
+
ButtonComponent,
|
|
22
26
|
CopyTextButtonComponent,
|
|
23
27
|
} from '../../../../../../libs/ui/inputs/src'
|
|
24
28
|
import { ContentGhostComponent } from '../content-ghost/content-ghost.component'
|
|
25
29
|
import { NgIcon, provideIcons } from '@ng-icons/core'
|
|
26
30
|
import { matOpenInNew } from '@ng-icons/material-icons/baseline'
|
|
27
31
|
import { matMailOutline } from '@ng-icons/material-icons/outline'
|
|
28
|
-
import { ThumbnailComponent } from '../thumbnail/thumbnail.component'
|
|
29
32
|
import { GnUiLinkifyDirective } from './linkify.directive'
|
|
30
33
|
import { GnUiHumanizeDateDirective } from '../../../../../../libs/util/shared/src'
|
|
31
34
|
|
|
32
35
|
import { SpatialExtentComponent } from '../../../../../../libs/ui/map/src'
|
|
36
|
+
import { ContactPillComponent } from '../contact-pill/contact-pill.component'
|
|
33
37
|
|
|
34
38
|
@Component({
|
|
35
39
|
selector: 'gn-ui-metadata-info',
|
|
@@ -42,15 +46,16 @@ import { SpatialExtentComponent } from '../../../../../../libs/ui/map/src'
|
|
|
42
46
|
TranslatePipe,
|
|
43
47
|
MarkdownParserComponent,
|
|
44
48
|
ExpandablePanelComponent,
|
|
49
|
+
ButtonComponent,
|
|
45
50
|
BadgeComponent,
|
|
46
51
|
ContentGhostComponent,
|
|
47
|
-
ThumbnailComponent,
|
|
48
52
|
MaxLinesComponent,
|
|
49
53
|
CopyTextButtonComponent,
|
|
50
54
|
NgIcon,
|
|
51
55
|
GnUiLinkifyDirective,
|
|
52
56
|
GnUiHumanizeDateDirective,
|
|
53
57
|
SpatialExtentComponent,
|
|
58
|
+
ContactPillComponent,
|
|
54
59
|
],
|
|
55
60
|
viewProviders: [
|
|
56
61
|
provideIcons({
|
|
@@ -132,18 +137,33 @@ export class MetadataInfoComponent {
|
|
|
132
137
|
return getTemporalRangeUnion(temporalExtents, this.dateService)
|
|
133
138
|
}
|
|
134
139
|
|
|
135
|
-
get shownOrganization() {
|
|
136
|
-
return this.metadata.ownerOrganization
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
get resourceContact() {
|
|
140
|
-
return this.metadata.contactsForResource?.[0]
|
|
141
|
-
}
|
|
142
|
-
|
|
143
140
|
fieldReady(propName: string) {
|
|
144
141
|
return !this.incomplete || propName in this.metadata
|
|
145
142
|
}
|
|
146
143
|
|
|
144
|
+
get contactGroups(): {
|
|
145
|
+
role: Role
|
|
146
|
+
roleLabel: string
|
|
147
|
+
contacts: Individual[]
|
|
148
|
+
}[] {
|
|
149
|
+
const groups: { role: Role; roleLabel: string; contacts: Individual[] }[] =
|
|
150
|
+
[]
|
|
151
|
+
const indexByRole = new Map<Role, number>()
|
|
152
|
+
for (const contact of this.metadata.contactsForResource ?? []) {
|
|
153
|
+
if (indexByRole.has(contact.role)) {
|
|
154
|
+
groups[indexByRole.get(contact.role)].contacts.push(contact)
|
|
155
|
+
} else {
|
|
156
|
+
indexByRole.set(contact.role, groups.length)
|
|
157
|
+
groups.push({
|
|
158
|
+
role: contact.role,
|
|
159
|
+
roleLabel: RoleLabels.get(contact.role),
|
|
160
|
+
contacts: [contact],
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return groups
|
|
165
|
+
}
|
|
166
|
+
|
|
147
167
|
onKeywordClick(keyword: Keyword) {
|
|
148
168
|
this.keyword.emit(keyword)
|
|
149
169
|
}
|
|
@@ -26,6 +26,7 @@ export class ButtonComponent {
|
|
|
26
26
|
| 'light'
|
|
27
27
|
| 'gray'
|
|
28
28
|
| 'black'
|
|
29
|
+
| 'primary-light'
|
|
29
30
|
) {
|
|
30
31
|
// btn-classes are written in full to be picked up by tailwind
|
|
31
32
|
switch (value) {
|
|
@@ -47,6 +48,9 @@ export class ButtonComponent {
|
|
|
47
48
|
case 'black':
|
|
48
49
|
this.btnClass = 'gn-ui-btn-black'
|
|
49
50
|
break
|
|
51
|
+
case 'primary-light':
|
|
52
|
+
this.btnClass = 'gn-ui-btn-primary-light'
|
|
53
|
+
break
|
|
50
54
|
case 'default':
|
|
51
55
|
default:
|
|
52
56
|
this.btnClass = 'gn-ui-btn-default'
|
|
@@ -204,11 +204,12 @@ export class MapContainerComponent implements AfterViewInit, OnChanges {
|
|
|
204
204
|
|
|
205
205
|
async ngOnChanges(changes: SimpleChanges) {
|
|
206
206
|
if ('context' in changes && !changes['context'].isFirstChange()) {
|
|
207
|
+
const olMap = await this.openlayersMap
|
|
207
208
|
const diff = computeMapContextDiff(
|
|
208
209
|
this.processContext(changes['context'].currentValue),
|
|
209
210
|
this.processContext(changes['context'].previousValue)
|
|
210
211
|
)
|
|
211
|
-
await applyContextDiffToMap(
|
|
212
|
+
await applyContextDiffToMap(olMap, diff)
|
|
212
213
|
|
|
213
214
|
if (this._resolvedExtentChange && diff.viewChanges) {
|
|
214
215
|
this._resolvedExtentChange.emit(this.calculateCurrentMapExtent())
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, Input } from '@angular/core'
|
|
1
|
+
import { ChangeDetectorRef, Component, inject, Input } from '@angular/core'
|
|
2
2
|
import { CommonModule } from '@angular/common'
|
|
3
3
|
import { Geometry } from 'geojson'
|
|
4
4
|
import { GeoJSONFeatureCollection } from 'ol/format/GeoJSON.js'
|
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
MapContextLayer,
|
|
11
11
|
} from '@geospatial-sdk/core'
|
|
12
12
|
import { MapContainerComponent } from '../map-container/map-container.component'
|
|
13
|
-
import { BehaviorSubject, Observable } from 'rxjs'
|
|
14
|
-
import { switchMap } from 'rxjs/operators'
|
|
13
|
+
import { BehaviorSubject, from, Observable, of } from 'rxjs'
|
|
14
|
+
import { map, switchMap, tap } from 'rxjs/operators'
|
|
15
15
|
import { DatasetSpatialExtent } from '../../../../../../../libs/common/domain/src/lib/model/record'
|
|
16
16
|
|
|
17
17
|
@Component({
|
|
@@ -22,14 +22,16 @@ import { DatasetSpatialExtent } from '../../../../../../../libs/common/domain/sr
|
|
|
22
22
|
styleUrl: './spatial-extent.component.css',
|
|
23
23
|
})
|
|
24
24
|
export class SpatialExtentComponent {
|
|
25
|
+
private _cdr = inject(ChangeDetectorRef)
|
|
26
|
+
|
|
25
27
|
@Input() set spatialExtents(value: DatasetSpatialExtent[]) {
|
|
26
28
|
this.spatialExtents$.next(value)
|
|
27
29
|
}
|
|
28
30
|
spatialExtents$ = new BehaviorSubject<DatasetSpatialExtent[]>([])
|
|
29
31
|
mapContext$: Observable<MapContext> = this.spatialExtents$.pipe(
|
|
30
|
-
switchMap(
|
|
32
|
+
switchMap((extents) => {
|
|
31
33
|
if (extents.length === 0) {
|
|
32
|
-
return null
|
|
34
|
+
return of(null)
|
|
33
35
|
}
|
|
34
36
|
const featureCollection: GeoJSONFeatureCollection = {
|
|
35
37
|
type: 'FeatureCollection',
|
|
@@ -61,11 +63,10 @@ export class SpatialExtentComponent {
|
|
|
61
63
|
'fill-color': 'rgba(153, 153, 153, 0.3)',
|
|
62
64
|
},
|
|
63
65
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
66
|
+
return from(createViewFromLayer(layer)).pipe(
|
|
67
|
+
map((view) => ({ view, layers: [layer] }) as MapContext),
|
|
68
|
+
tap(() => this._cdr.markForCheck())
|
|
69
|
+
)
|
|
69
70
|
})
|
|
70
71
|
)
|
|
71
72
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as TOML from '@ltd/j-toml'
|
|
2
2
|
import {
|
|
3
3
|
checkMetadataLanguage,
|
|
4
|
+
checkNewRecordDefaultLanguage,
|
|
4
5
|
parseConfigSection,
|
|
5
6
|
parseMultiConfigSection,
|
|
6
7
|
parseTranslationsConfigSection,
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
import {
|
|
9
10
|
CustomTranslations,
|
|
10
11
|
CustomTranslationsAllLanguages,
|
|
12
|
+
EditorConfig,
|
|
11
13
|
GlobalConfig,
|
|
12
14
|
LayerConfig,
|
|
13
15
|
MapConfig,
|
|
@@ -51,6 +53,12 @@ export function getOptionalSearchConfig(): SearchConfig | null {
|
|
|
51
53
|
return searchConfig
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
let editorConfig: EditorConfig = null
|
|
57
|
+
|
|
58
|
+
export function getOptionalEditorConfig(): EditorConfig | null {
|
|
59
|
+
return editorConfig
|
|
60
|
+
}
|
|
61
|
+
|
|
54
62
|
let metadataQualityConfig: MetadataQualityConfig = null
|
|
55
63
|
export function getMetadataQualityConfig(): MetadataQualityConfig {
|
|
56
64
|
return (
|
|
@@ -285,6 +293,33 @@ export function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
|
|
|
285
293
|
SORTABLE: parsedMetadataQualitySection.sortable,
|
|
286
294
|
} as MetadataQualityConfig)
|
|
287
295
|
|
|
296
|
+
let parsedEditingSection = parseConfigSection(
|
|
297
|
+
parsed,
|
|
298
|
+
'editing',
|
|
299
|
+
[],
|
|
300
|
+
['new_record_default_language'],
|
|
301
|
+
warnings,
|
|
302
|
+
errors
|
|
303
|
+
)
|
|
304
|
+
if (
|
|
305
|
+
parsedEditingSection !== null &&
|
|
306
|
+
parsedEditingSection.new_record_default_language !== undefined
|
|
307
|
+
) {
|
|
308
|
+
parsedEditingSection = checkNewRecordDefaultLanguage(
|
|
309
|
+
parsedEditingSection,
|
|
310
|
+
warnings
|
|
311
|
+
)
|
|
312
|
+
}
|
|
313
|
+
editorConfig =
|
|
314
|
+
parsedEditingSection === null
|
|
315
|
+
? null
|
|
316
|
+
: ({
|
|
317
|
+
NEW_RECORD_DEFAULT_LANGUAGE:
|
|
318
|
+
parsedEditingSection.new_record_default_language as
|
|
319
|
+
| string
|
|
320
|
+
| undefined,
|
|
321
|
+
} as EditorConfig)
|
|
322
|
+
|
|
288
323
|
customTranslations = parseTranslationsConfigSection(
|
|
289
324
|
parsed,
|
|
290
325
|
'translations'
|
|
@@ -309,6 +344,7 @@ export function isConfigLoaded() {
|
|
|
309
344
|
export function _reset() {
|
|
310
345
|
globalConfig = null
|
|
311
346
|
themeConfig = null
|
|
347
|
+
editorConfig = null
|
|
312
348
|
customTranslations = null
|
|
313
349
|
}
|
|
314
350
|
|
|
@@ -69,6 +69,10 @@ export interface MetadataQualityConfig {
|
|
|
69
69
|
ENABLED: boolean
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
export interface EditorConfig {
|
|
73
|
+
NEW_RECORD_DEFAULT_LANGUAGE?: string
|
|
74
|
+
}
|
|
75
|
+
|
|
72
76
|
export type CustomTranslations = { [translationKey: string]: string }
|
|
73
77
|
export type CustomTranslationsAllLanguages = {
|
|
74
78
|
[lang: string]: CustomTranslations
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { toLang2 } from '../../../../../libs/util/i18n/src'
|
|
1
|
+
import { LANG_2_TO_3_MAPPER, toLang2 } from '../../../../../libs/util/i18n/src'
|
|
2
2
|
|
|
3
3
|
const flatten = (
|
|
4
4
|
base: string,
|
|
@@ -137,3 +137,25 @@ export function checkMetadataLanguage(
|
|
|
137
137
|
}
|
|
138
138
|
return parsedConfigSection
|
|
139
139
|
}
|
|
140
|
+
|
|
141
|
+
export function checkNewRecordDefaultLanguage(
|
|
142
|
+
parsedConfigSection: any,
|
|
143
|
+
outWarnings: string[]
|
|
144
|
+
) {
|
|
145
|
+
const lang2 = toLang2(
|
|
146
|
+
parsedConfigSection.new_record_default_language.toLowerCase()
|
|
147
|
+
)
|
|
148
|
+
if (!(lang2 in LANG_2_TO_3_MAPPER)) {
|
|
149
|
+
outWarnings.push(
|
|
150
|
+
`In the [editing] section: new_record_default_language = "${parsedConfigSection.new_record_default_language}" is not a recognized ISO 639 language code`
|
|
151
|
+
)
|
|
152
|
+
return {
|
|
153
|
+
...parsedConfigSection,
|
|
154
|
+
new_record_default_language: undefined,
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
...parsedConfigSection,
|
|
159
|
+
new_record_default_language: lang2,
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -3,27 +3,41 @@ import {
|
|
|
3
3
|
RecordKind,
|
|
4
4
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
5
5
|
|
|
6
|
+
type TValidatorEntry = {
|
|
7
|
+
validator: (metadata: Partial<CatalogRecord>) => boolean
|
|
8
|
+
alias?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
6
11
|
type TValidatorMapper = {
|
|
7
|
-
[key: string]:
|
|
12
|
+
[key: string]: TValidatorEntry
|
|
8
13
|
}
|
|
9
14
|
|
|
10
15
|
const ValidatorMapper: TValidatorMapper = {
|
|
11
|
-
title: (record) => !!record?.title,
|
|
12
|
-
abstract: (record) => !!record?.abstract,
|
|
13
|
-
keywords: (record) => (record?.keywords?.length ?? 0) > 0,
|
|
14
|
-
legalConstraints:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
title: { validator: (record) => !!record?.title },
|
|
17
|
+
abstract: { validator: (record) => !!record?.abstract },
|
|
18
|
+
keywords: { validator: (record) => (record?.keywords?.length ?? 0) > 0 },
|
|
19
|
+
legalConstraints: {
|
|
20
|
+
validator: (record) =>
|
|
21
|
+
!!(
|
|
22
|
+
record?.legalConstraints?.length &&
|
|
23
|
+
record.legalConstraints.some((c) => c?.text?.trim().length > 0)
|
|
24
|
+
),
|
|
25
|
+
},
|
|
26
|
+
contacts: {
|
|
27
|
+
validator: (record) =>
|
|
28
|
+
!!record?.contacts?.[0]?.email &&
|
|
29
|
+
record.contacts[0].email !== 'missing@missing.com',
|
|
30
|
+
},
|
|
31
|
+
updateFrequency: {
|
|
32
|
+
validator: (record) =>
|
|
33
|
+
!!record?.updateFrequency && record.updateFrequency !== 'unknown',
|
|
34
|
+
},
|
|
35
|
+
topics: { validator: (record) => (record?.topics?.length ?? 0) > 0 },
|
|
36
|
+
organisation: {
|
|
37
|
+
validator: (record) => !!record?.contacts?.[0]?.organization?.name,
|
|
38
|
+
alias: 'contacts',
|
|
39
|
+
},
|
|
40
|
+
source: { validator: (record) => !!record?.extras?.sourcesIdentifiers },
|
|
27
41
|
} as const
|
|
28
42
|
|
|
29
43
|
export type ValidatorMapperKeys = keyof typeof ValidatorMapper & string
|
|
@@ -67,6 +81,7 @@ export function getQualityValidators(
|
|
|
67
81
|
|
|
68
82
|
return filteredProps.map((name) => ({
|
|
69
83
|
name,
|
|
70
|
-
validator: () => ValidatorMapper[name](record),
|
|
84
|
+
validator: () => ValidatorMapper[name].validator(record),
|
|
85
|
+
alias: ValidatorMapper[name].alias,
|
|
71
86
|
}))
|
|
72
87
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { UserModel } from '../../../../../../libs/common/domain/src/lib/model/user'
|
|
2
|
+
import { Individual } from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
3
|
+
|
|
4
|
+
export function getIndividualDisplayName(individual: Individual): string {
|
|
5
|
+
const nameParts = [individual.firstName, individual.lastName]
|
|
6
|
+
.filter(Boolean)
|
|
7
|
+
.join(' ')
|
|
8
|
+
const orgPart = individual.organization?.name
|
|
9
|
+
? ` (${individual.organization.name})`
|
|
10
|
+
: ''
|
|
11
|
+
if (nameParts) return `${nameParts}${orgPart}`
|
|
12
|
+
return individual.organization?.name ?? individual.email ?? ''
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function toIndividual(user: UserModel): Individual {
|
|
16
|
+
return {
|
|
17
|
+
firstName: user.name,
|
|
18
|
+
lastName: user.surname,
|
|
19
|
+
email: user.email,
|
|
20
|
+
role: 'unspecified',
|
|
21
|
+
organization: user.organisation ? { name: user.organisation } : undefined,
|
|
22
|
+
}
|
|
23
|
+
}
|
package/tailwind.base.css
CHANGED
|
@@ -74,7 +74,10 @@
|
|
|
74
74
|
--bg-hover: var(--gn-ui-button-bg-hover, var(--color-background));
|
|
75
75
|
--font-size: var(--gn-ui-button-font-size, 1em);
|
|
76
76
|
--color: var(--gn-ui-button-color, var(--color-main));
|
|
77
|
-
|
|
77
|
+
--disabled-opacity: var(--gn-ui-button-disabled-opacity, 0.5);
|
|
78
|
+
--justify: var(--gn-ui-button-justify, center);
|
|
79
|
+
justify-content: var(--justify);
|
|
80
|
+
@apply flex flex-row items-center
|
|
78
81
|
text-[length:--font-size] leading-none
|
|
79
82
|
text-[color:--color]
|
|
80
83
|
p-[--padding] rounded-[--rounded] w-[--width] h-[--height] overflow-hidden
|
|
@@ -82,7 +85,7 @@
|
|
|
82
85
|
hover:bg-[--bg-hover] focus:bg-[--bg-hover] active:bg-[--background]
|
|
83
86
|
outline-none
|
|
84
87
|
relative
|
|
85
|
-
disabled:opacity-
|
|
88
|
+
disabled:opacity-[--disabled-opacity] disabled:pointer-events-none
|
|
86
89
|
focus:z-10 active:z-10 hover:z-10;
|
|
87
90
|
}
|
|
88
91
|
/* makes sure icons will not make the buttons grow vertically */
|
|
@@ -134,6 +137,12 @@
|
|
|
134
137
|
bg-white border-white focus:ring-4 focus:ring-gray-300;
|
|
135
138
|
}
|
|
136
139
|
|
|
140
|
+
.gn-ui-btn-primary-light {
|
|
141
|
+
@apply gn-ui-btn text-primary-darkest
|
|
142
|
+
bg-primary-white hover:bg-primary focus:bg-primary hover:text-white focus:text-white active:bg-primary-darker
|
|
143
|
+
border-transparent;
|
|
144
|
+
}
|
|
145
|
+
|
|
137
146
|
.gn-ui-card-s {
|
|
138
147
|
@apply min-h-[64px] w-full xs:min-w-[260px] xs:max-w-[280px] sm:min-w-[300px] sm:max-w-[500px] md:min-w-[230px];
|
|
139
148
|
}
|
package/translations/de.json
CHANGED
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"editor.record.form.field.legalConstraints": "Rechtliche Einschränkung",
|
|
160
160
|
"editor.record.form.field.license": "Lizenz",
|
|
161
161
|
"editor.record.form.field.onlineLinkResources": "Beigefügte Ressourcen",
|
|
162
|
+
"editor.record.form.field.onlineLinkageResource.defaultName": "Link",
|
|
162
163
|
"editor.record.form.field.onlineResource.cancel": "Abbrechen",
|
|
163
164
|
"editor.record.form.field.onlineResource.confirm": "Bestätigen",
|
|
164
165
|
"editor.record.form.field.onlineResource.dialogTitle": "Vorschau des Datensatzes bearbeiten",
|
|
@@ -520,6 +521,7 @@
|
|
|
520
521
|
"record.metadata.quality.updateFrequency.failed": "Aktualisierungsfrequenz nicht angegeben",
|
|
521
522
|
"record.metadata.quality.updateFrequency.success": "Aktualisierungsfrequenz angegeben",
|
|
522
523
|
"record.metadata.related": "Entdecken Sie den Katalog",
|
|
524
|
+
"record.metadata.resource.contacts": "Kontakte zur Ressource",
|
|
523
525
|
"record.metadata.resourceCreated": "Erstellt",
|
|
524
526
|
"record.metadata.resourcePublished": "Veröffentlicht",
|
|
525
527
|
"record.metadata.resourceUpdated": "Zuletzt aktualisiert",
|
package/translations/en.json
CHANGED
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"editor.record.form.field.legalConstraints": "Legal constraint",
|
|
160
160
|
"editor.record.form.field.license": "License",
|
|
161
161
|
"editor.record.form.field.onlineLinkResources": "Attached resources",
|
|
162
|
+
"editor.record.form.field.onlineLinkageResource.defaultName": "Link",
|
|
162
163
|
"editor.record.form.field.onlineResource.cancel": "Cancel",
|
|
163
164
|
"editor.record.form.field.onlineResource.confirm": "Confirm",
|
|
164
165
|
"editor.record.form.field.onlineResource.dialogTitle": "Modify the dataset preview",
|
|
@@ -520,6 +521,7 @@
|
|
|
520
521
|
"record.metadata.quality.updateFrequency.failed": "Update frequency is not specified",
|
|
521
522
|
"record.metadata.quality.updateFrequency.success": "Update frequency is specified",
|
|
522
523
|
"record.metadata.related": "Explore the catalog",
|
|
524
|
+
"record.metadata.resource.contacts": "Contacts for the resource",
|
|
523
525
|
"record.metadata.resourceCreated": "Created",
|
|
524
526
|
"record.metadata.resourcePublished": "Published",
|
|
525
527
|
"record.metadata.resourceUpdated": "Last updated",
|
package/translations/es.json
CHANGED
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"editor.record.form.field.legalConstraints": "",
|
|
160
160
|
"editor.record.form.field.license": "",
|
|
161
161
|
"editor.record.form.field.onlineLinkResources": "",
|
|
162
|
+
"editor.record.form.field.onlineLinkageResource.defaultName": "",
|
|
162
163
|
"editor.record.form.field.onlineResource.cancel": "",
|
|
163
164
|
"editor.record.form.field.onlineResource.confirm": "",
|
|
164
165
|
"editor.record.form.field.onlineResource.dialogTitle": "",
|
|
@@ -520,6 +521,7 @@
|
|
|
520
521
|
"record.metadata.quality.updateFrequency.failed": "",
|
|
521
522
|
"record.metadata.quality.updateFrequency.success": "",
|
|
522
523
|
"record.metadata.related": "",
|
|
524
|
+
"record.metadata.resource.contacts": "",
|
|
523
525
|
"record.metadata.resourceCreated": "",
|
|
524
526
|
"record.metadata.resourcePublished": "",
|
|
525
527
|
"record.metadata.resourceUpdated": "",
|
package/translations/fr.json
CHANGED
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"editor.record.form.field.legalConstraints": "Contrainte légale",
|
|
160
160
|
"editor.record.form.field.license": "Licence",
|
|
161
161
|
"editor.record.form.field.onlineLinkResources": "Ressources attachées",
|
|
162
|
+
"editor.record.form.field.onlineLinkageResource.defaultName": "Lien",
|
|
162
163
|
"editor.record.form.field.onlineResource.cancel": "Annuler",
|
|
163
164
|
"editor.record.form.field.onlineResource.confirm": "Valider",
|
|
164
165
|
"editor.record.form.field.onlineResource.dialogTitle": "Modifier l'aperçu du jeu de données",
|
|
@@ -520,6 +521,7 @@
|
|
|
520
521
|
"record.metadata.quality.updateFrequency.failed": "La fréquence de mise à jour n'est pas renseignée",
|
|
521
522
|
"record.metadata.quality.updateFrequency.success": "La fréquence de mise à jour est renseignée",
|
|
522
523
|
"record.metadata.related": "Explorez le catalogue",
|
|
524
|
+
"record.metadata.resource.contacts": "Contacts liés à la donnée",
|
|
523
525
|
"record.metadata.resourceCreated": "Créé",
|
|
524
526
|
"record.metadata.resourcePublished": "Publié",
|
|
525
527
|
"record.metadata.resourceUpdated": "Mis à jour",
|
package/translations/it.json
CHANGED
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"editor.record.form.field.legalConstraints": "Vincolo legale",
|
|
160
160
|
"editor.record.form.field.license": "Licenza",
|
|
161
161
|
"editor.record.form.field.onlineLinkResources": "Risorse allegate",
|
|
162
|
+
"editor.record.form.field.onlineLinkageResource.defaultName": "Link",
|
|
162
163
|
"editor.record.form.field.onlineResource.cancel": "Annulla",
|
|
163
164
|
"editor.record.form.field.onlineResource.confirm": "Convalida",
|
|
164
165
|
"editor.record.form.field.onlineResource.dialogTitle": "Modifica anteprima dataset",
|
|
@@ -520,6 +521,7 @@
|
|
|
520
521
|
"record.metadata.quality.updateFrequency.failed": "La frequenza di aggiornamento non è specificata",
|
|
521
522
|
"record.metadata.quality.updateFrequency.success": "La frequenza di aggiornamento è specificata",
|
|
522
523
|
"record.metadata.related": "Vedi anche",
|
|
524
|
+
"record.metadata.resource.contacts": "Contatti per la risorsa",
|
|
523
525
|
"record.metadata.resourceCreated": "Creato",
|
|
524
526
|
"record.metadata.resourcePublished": "Pubblicato",
|
|
525
527
|
"record.metadata.resourceUpdated": "Ultimo aggiornamento",
|
package/translations/nl.json
CHANGED
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"editor.record.form.field.legalConstraints": "",
|
|
160
160
|
"editor.record.form.field.license": "",
|
|
161
161
|
"editor.record.form.field.onlineLinkResources": "",
|
|
162
|
+
"editor.record.form.field.onlineLinkageResource.defaultName": "",
|
|
162
163
|
"editor.record.form.field.onlineResource.cancel": "",
|
|
163
164
|
"editor.record.form.field.onlineResource.confirm": "",
|
|
164
165
|
"editor.record.form.field.onlineResource.dialogTitle": "",
|
|
@@ -520,6 +521,7 @@
|
|
|
520
521
|
"record.metadata.quality.updateFrequency.failed": "",
|
|
521
522
|
"record.metadata.quality.updateFrequency.success": "",
|
|
522
523
|
"record.metadata.related": "",
|
|
524
|
+
"record.metadata.resource.contacts": "",
|
|
523
525
|
"record.metadata.resourceCreated": "",
|
|
524
526
|
"record.metadata.resourcePublished": "",
|
|
525
527
|
"record.metadata.resourceUpdated": "",
|
package/translations/pt.json
CHANGED
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"editor.record.form.field.legalConstraints": "",
|
|
160
160
|
"editor.record.form.field.license": "",
|
|
161
161
|
"editor.record.form.field.onlineLinkResources": "",
|
|
162
|
+
"editor.record.form.field.onlineLinkageResource.defaultName": "",
|
|
162
163
|
"editor.record.form.field.onlineResource.cancel": "",
|
|
163
164
|
"editor.record.form.field.onlineResource.confirm": "",
|
|
164
165
|
"editor.record.form.field.onlineResource.dialogTitle": "",
|
|
@@ -520,6 +521,7 @@
|
|
|
520
521
|
"record.metadata.quality.updateFrequency.failed": "",
|
|
521
522
|
"record.metadata.quality.updateFrequency.success": "",
|
|
522
523
|
"record.metadata.related": "",
|
|
524
|
+
"record.metadata.resource.contacts": "",
|
|
523
525
|
"record.metadata.resourceCreated": "",
|
|
524
526
|
"record.metadata.resourcePublished": "",
|
|
525
527
|
"record.metadata.resourceUpdated": "",
|