geonetwork-ui 2.10.0-dev.fb2893f44 → 2.10.0

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.
Files changed (109) hide show
  1. package/fesm2022/geonetwork-ui.mjs +1017 -468
  2. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  3. package/index.d.ts +112 -111
  4. package/index.d.ts.map +1 -1
  5. package/package.json +1 -1
  6. package/src/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts +11 -0
  7. package/src/libs/api/metadata-converter/src/lib/fixtures/eu.dcat-ap.records.ts +2 -0
  8. package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +22 -0
  9. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.reuse+ongules.ts +1 -0
  10. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.reuse+roilaye.ts +1 -0
  11. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +1 -0
  12. package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +1 -0
  13. package/src/libs/api/metadata-converter/src/lib/fixtures/georhena.records.ts +1 -0
  14. package/src/libs/api/metadata-converter/src/lib/fixtures/metadata-for-i18n.records.ts +2 -0
  15. package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +22 -0
  16. package/src/libs/api/metadata-converter/src/lib/fixtures/opendataswiss.records.ts +1 -0
  17. package/src/libs/api/metadata-converter/src/lib/fixtures/sextant.records.ts +2 -0
  18. package/src/libs/api/metadata-converter/src/lib/fixtures/vlaanderen.dcat-ap.records.ts +1 -0
  19. package/src/libs/api/metadata-converter/src/lib/fixtures/wallonie.records.reuse.ts +1 -0
  20. package/src/libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts +48 -7
  21. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.converter.ts +1 -0
  22. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +4 -3
  23. package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +1 -0
  24. package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +4 -0
  25. package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +13 -0
  26. package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +45 -1
  27. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +13 -1
  28. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +40 -0
  29. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +47 -1
  30. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +12 -8
  31. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +9 -20
  32. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +12 -0
  33. package/src/libs/common/domain/src/lib/model/thesaurus/thesaurus.model.ts +2 -1
  34. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +2 -1
  35. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +57 -0
  36. package/src/libs/feature/editor/src/index.ts +1 -0
  37. package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +4 -1
  38. package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +26 -19
  39. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +5 -1
  40. package/src/libs/feature/editor/src/lib/components/contact-details/contact-details-form.component.html +7 -6
  41. package/src/libs/feature/editor/src/lib/components/contact-details/contact-details-form.component.ts +10 -8
  42. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.html +5 -14
  43. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.ts +3 -28
  44. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.html +5 -5
  45. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +2 -1
  46. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-constraints-shortcuts/form-field-constraints-shortcuts.component.ts +1 -0
  47. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.ts +1 -1
  48. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +12 -5
  49. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.html +4 -4
  50. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.ts +7 -0
  51. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +6 -2
  52. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +3 -1
  53. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +27 -16
  54. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +11 -0
  55. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +14 -5
  56. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +41 -0
  57. package/src/libs/feature/editor/src/lib/expressions.ts +380 -8
  58. package/src/libs/feature/editor/src/lib/fields.config.ts +295 -291
  59. package/src/libs/feature/editor/src/lib/models/editor-config.model.ts +6 -3
  60. package/src/libs/feature/editor/src/lib/services/editor.service.ts +8 -12
  61. package/src/libs/feature/notify-reuse/src/index.ts +1 -0
  62. package/src/libs/feature/notify-reuse/src/lib/edit-delete-reuse-buttons/edit-delete-reuse-buttons.component.css +0 -0
  63. package/src/libs/feature/notify-reuse/src/lib/edit-delete-reuse-buttons/edit-delete-reuse-buttons.component.html +23 -0
  64. package/src/libs/feature/notify-reuse/src/lib/edit-delete-reuse-buttons/edit-delete-reuse-buttons.component.ts +114 -0
  65. package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.html +111 -1
  66. package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.ts +219 -8
  67. package/src/libs/feature/notify-reuse/src/lib/utils/url.ts +16 -0
  68. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +10 -5
  69. package/src/libs/ui/elements/src/index.ts +1 -0
  70. package/src/libs/ui/elements/src/lib/contact-details/contact-details.component.html +48 -56
  71. package/src/libs/ui/elements/src/lib/external-link-card/external-link-card.component.html +2 -1
  72. package/src/libs/ui/elements/src/lib/external-link-card/external-link-card.component.ts +2 -2
  73. package/src/libs/ui/elements/src/lib/keyword-badge/keyword-badge.component.html +14 -0
  74. package/src/libs/ui/elements/src/lib/keyword-badge/keyword-badge.component.ts +85 -0
  75. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.css +5 -0
  76. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +4 -7
  77. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +2 -2
  78. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +4 -5
  79. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +4 -0
  80. package/src/libs/ui/inputs/src/lib/badge/badge.component.html +33 -26
  81. package/src/libs/ui/inputs/src/lib/badge/badge.component.ts +9 -0
  82. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html +1 -1
  83. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.ts +3 -3
  84. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.css +0 -3
  85. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +11 -7
  86. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +56 -30
  87. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +5 -5
  88. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.ts +9 -1
  89. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +1 -1
  90. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.ts +3 -8
  91. package/src/libs/ui/layout/src/lib/sortable-list/sortable-list.component.html +7 -7
  92. package/src/libs/ui/layout/src/lib/sortable-list/sortable-list.component.ts +14 -1
  93. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.html +12 -8
  94. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.ts +3 -1
  95. package/src/libs/ui/search/src/lib/results-table/results-table.component.html +1 -0
  96. package/src/libs/ui/widgets/src/lib/popover/popover.component.ts +7 -1
  97. package/src/libs/ui/widgets/src/lib/spinning-loader/spinning-loader.component.html +1 -1
  98. package/src/libs/util/shared/src/lib/links/link-utils.ts +22 -0
  99. package/tailwind.base.css +9 -2
  100. package/translations/de.json +84 -31
  101. package/translations/en.json +94 -41
  102. package/translations/es.json +58 -5
  103. package/translations/fr.json +91 -38
  104. package/translations/it.json +85 -32
  105. package/translations/nl.json +57 -4
  106. package/translations/pt.json +58 -5
  107. package/translations/sk.json +58 -5
  108. package/material-styles.css +0 -483
  109. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.css +0 -3
@@ -3,6 +3,7 @@ import {
3
3
  DatasetRecord,
4
4
  DatasetSpatialExtent,
5
5
  Keyword,
6
+ ReuseRecord,
6
7
  ServiceRecord,
7
8
  } from '../../../../../libs/common/domain/src/lib/model/record'
8
9
 
@@ -135,6 +136,7 @@ Cette section contient des *caractères internationaux* (ainsi que des "caractè
135
136
 
136
137
  As such, **it is not very interesting at all.**`,
137
138
  sourceRecords: [],
139
+ associatedRecords: [],
138
140
  licenses: [
139
141
  {
140
142
  text: 'Licence ODbL mai 2013 (basée sur ODbL 1.0)',
@@ -312,6 +314,7 @@ Malgré l'attention portée à la création de ces données, il est rappelé que
312
314
  lineage: `Document d’urbanisme numérisé conformément aux prescriptions nationales du CNIG par le Service d'Information Géographique de l'Agglomération de la Région de Compiègne.
313
315
  Ce lot de données produit en 2019, a été numérisé à partir du PCI Vecteur de 2019 et contrôlé par le Service d'Information Géographique de l'Agglomération de la Région de Compiègne.`,
314
316
  sourceRecords: [],
317
+ associatedRecords: [],
315
318
  legalConstraints: [],
316
319
  securityConstraints: [],
317
320
  otherConstraints: [],
@@ -364,6 +367,7 @@ export const simpleDatasetRecordFixture = (): DatasetRecord => ({
364
367
  spatialExtents: [],
365
368
  temporalExtents: [],
366
369
  sourceRecords: [],
370
+ associatedRecords: [],
367
371
  onlineResources: [
368
372
  {
369
373
  type: 'download',
@@ -417,6 +421,7 @@ export const simpleDatasetRecordWithFcatsFixture = (): DatasetRecord => ({
417
421
  spatialExtents: [],
418
422
  temporalExtents: [],
419
423
  sourceRecords: [],
424
+ associatedRecords: [],
420
425
  onlineResources: [],
421
426
  updateFrequency: { per: 'month', updatedTimes: 3 },
422
427
  translations: {},
@@ -983,6 +988,7 @@ export const multilingualDatasetFixture: () => DatasetRecord = () => ({
983
988
  abstract: 'English Abstract',
984
989
  lineage: 'English Lineage',
985
990
  sourceRecords: [],
991
+ associatedRecords: [],
986
992
  translations: {
987
993
  title: { fr: 'Titre Français', de: 'Titel DE' },
988
994
  abstract: { fr: 'Résumé Français', de: 'Beschreibung DE' },
@@ -1027,3 +1033,54 @@ export const multilingualDatasetFixture: () => DatasetRecord = () => ({
1027
1033
  topics: [],
1028
1034
  recordUpdated: null,
1029
1035
  })
1036
+
1037
+ export const simpleReuseRecordFixture = (): ReuseRecord => ({
1038
+ abstract: `Sample reuse record`,
1039
+ kind: 'reuse',
1040
+ reuseType: 'application',
1041
+ recordUpdated: new Date('2023-03-17T07:38:08.875Z'),
1042
+ recordPublished: null,
1043
+ ownerOrganization: null,
1044
+ licenses: [],
1045
+ legalConstraints: [],
1046
+ securityConstraints: [],
1047
+ otherConstraints: [],
1048
+ contacts: [],
1049
+ contactsForResource: [],
1050
+ keywords: [],
1051
+ topics: [],
1052
+ spatialExtents: [],
1053
+ temporalExtents: [],
1054
+ lineage: 'bla',
1055
+ sourceRecords: [],
1056
+ associatedRecords: [],
1057
+ overviews: [],
1058
+ defaultLanguage: null,
1059
+ otherLanguages: [],
1060
+ title: 'Sites de gestion des déchets miniers - Service de visualisation WMS',
1061
+ onlineResources: [
1062
+ {
1063
+ name: 'Rapport de disponibilité du service WMS',
1064
+ description:
1065
+ 'Ce service de visualisation WMS permet de consulter la série de couches de données "Sites de gestion des déchets miniers - Série".',
1066
+ mimeType: 'text/html',
1067
+ type: 'link',
1068
+ url: new URL(
1069
+ 'https://geoservices.wallonie.be/rapportDisponibilite/wms/sites_de_gestion_des_dechets_miniers_srie.html'
1070
+ ),
1071
+ accessRestricted: false,
1072
+ },
1073
+ ],
1074
+ uniqueIdentifier: '00b22798-ec8e-4500-89e8-90eeeda45919',
1075
+ landingPage: new URL(
1076
+ 'http://localhost:4200/geonetwork/srv/fre/catalog.search#/metadata/00b22798-ec8e-4500-89e8-90eeeda45919'
1077
+ ),
1078
+ extras: {
1079
+ isPublishedToAll: true,
1080
+ id: '723',
1081
+ isHarvested: true,
1082
+ ownerInfo: 'admin|admin|admin|Administrator',
1083
+ edit: true,
1084
+ },
1085
+ recordCreated: new Date('2023-03-17T07:38:08.875Z'),
1086
+ })
@@ -3,6 +3,7 @@ export * from './lib/+state/editor.facade'
3
3
  export * from './lib/+state/editor.models'
4
4
  export * from './lib/+state/editor.reducer'
5
5
  export * from './lib/+state/editor.selectors'
6
+ export * from './lib/components/contact-details/contact-details-form.component'
6
7
  export * from './lib/components/import-record/import-record.component'
7
8
  export * from './lib/components/metadata-quality-panel/metadata-quality-panel.component'
8
9
  export * from './lib/components/multilingual-panel/multilingual-panel.component'
@@ -29,7 +29,10 @@ export const markRecordAsChanged = createAction(
29
29
  '[Editor] Mark record as changed'
30
30
  )
31
31
 
32
- export const saveRecord = createAction('[Editor] Save record')
32
+ export const saveRecord = createAction(
33
+ '[Editor] Save record',
34
+ props<{ publish: boolean }>()
35
+ )
33
36
  export const saveRecordSuccess = createAction('[Editor] Save record success')
34
37
  export const saveRecordFailure = createAction(
35
38
  '[Editor] Save record failure',
@@ -28,30 +28,37 @@ export class EditorEffects {
28
28
  this.store.select(selectRecordSource),
29
29
  this.store.select(selectEditorConfig)
30
30
  ),
31
- switchMap(([, record, recordSource, fieldsConfig]) =>
32
- this.editorService.saveRecord(record, recordSource, fieldsConfig).pipe(
33
- switchMap(([savedRecord, savedRecordSource]) => {
34
- const actions: Action[] = [EditorActions.saveRecordSuccess()]
31
+ switchMap(([{ publish }, record, recordSource, fieldsConfig]) =>
32
+ this.editorService
33
+ .saveRecord(record, recordSource, fieldsConfig, publish)
34
+ .pipe(
35
+ switchMap(([savedRecord, savedRecordSource]) => {
36
+ const actions: Action[] = [EditorActions.saveRecordSuccess()]
37
+
38
+ if (publish) {
39
+ // saving without publishing doesn't unpublish
40
+ actions.push(EditorActions.isPublished({ isPublished: true }))
41
+ }
35
42
 
36
- if (!record?.uniqueIdentifier) {
37
- actions.push(
38
- EditorActions.openRecord({
39
- record: savedRecord,
40
- recordSource: savedRecordSource,
43
+ if (!record?.uniqueIdentifier) {
44
+ actions.push(
45
+ EditorActions.openRecord({
46
+ record: savedRecord,
47
+ recordSource: savedRecordSource,
48
+ })
49
+ )
50
+ }
51
+
52
+ return of(...actions)
53
+ }),
54
+ catchError((error) =>
55
+ of(
56
+ EditorActions.saveRecordFailure({
57
+ error,
41
58
  })
42
59
  )
43
- }
44
-
45
- return of(...actions)
46
- }),
47
- catchError((error) =>
48
- of(
49
- EditorActions.saveRecordFailure({
50
- error,
51
- })
52
60
  )
53
61
  )
54
- )
55
62
  )
56
63
  )
57
64
  )
@@ -54,7 +54,11 @@ export class EditorFacade {
54
54
  }
55
55
 
56
56
  saveRecord() {
57
- this.store.dispatch(EditorActions.saveRecord())
57
+ this.store.dispatch(EditorActions.saveRecord({ publish: false }))
58
+ }
59
+
60
+ saveAndPublishRecord() {
61
+ this.store.dispatch(EditorActions.saveRecord({ publish: true }))
58
62
  }
59
63
 
60
64
  undoRecordDraft() {
@@ -7,8 +7,8 @@
7
7
  <gn-ui-text-input
8
8
  class="block w-full"
9
9
  extraClass="w-full"
10
- [(value)]="contact.lastName"
11
- (valueChange)="emitContactChange()"
10
+ [value]="contact.lastName ?? ''"
11
+ (valueChange)="handleChange({ lastName: $event })"
12
12
  [placeholder]="
13
13
  'editor.record.form.field.contactDetails.lastName.placeholder'
14
14
  | translate
@@ -23,8 +23,8 @@
23
23
  <gn-ui-text-input
24
24
  class="block w-full"
25
25
  extraClass="w-full"
26
- [(value)]="contact.firstName"
27
- (valueChange)="emitContactChange()"
26
+ [value]="contact.firstName ?? ''"
27
+ (valueChange)="handleChange({ firstName: $event })"
28
28
  [placeholder]="
29
29
  'editor.record.form.field.contactDetails.firstName.placeholder'
30
30
  | translate
@@ -40,8 +40,9 @@
40
40
  <gn-ui-text-input
41
41
  class="block w-full"
42
42
  extraClass="w-full"
43
- [value]="contact.organization?.email ?? ''"
44
- (valueChange)="handleOrganizationChange({ email: $event })"
43
+ [type]="'email'"
44
+ [value]="contact.email ?? ''"
45
+ (valueChange)="handleChange({ email: $event })"
45
46
  [placeholder]="
46
47
  'editor.record.form.field.contactDetails.email.placeholder' | translate
47
48
  "
@@ -24,16 +24,18 @@ export class ContactDetailsFormComponent {
24
24
  @Input() contact: Individual
25
25
  @Output() contactChange = new EventEmitter<Individual>()
26
26
 
27
- emitContactChange() {
28
- this.contactChange.emit(this.contact)
27
+ // emit a fresh contact on each change; never mutate the @Input
28
+ handleChange(change: Partial<Individual>) {
29
+ this.contactChange.emit({ ...this.contact, ...change })
29
30
  }
30
31
 
31
32
  handleOrganizationChange(change: Partial<Organization>) {
32
- this.contact.organization = {
33
- ...(this.contact.organization ?? ({} as Organization)),
34
- ...change,
35
- } as Organization
36
-
37
- this.emitContactChange()
33
+ this.contactChange.emit({
34
+ ...this.contact,
35
+ organization: {
36
+ ...(this.contact.organization ?? ({} as Organization)),
37
+ ...change,
38
+ } as Organization,
39
+ })
38
40
  }
39
41
  }
@@ -11,20 +11,11 @@
11
11
  ></gn-ui-autocomplete>
12
12
  <div class="flex gap-2 flex-wrap">
13
13
  @for (keyword of keywords; track keyword) {
14
- <gn-ui-badge
15
- [removable]="true"
16
- (badgeRemoveClicked)="removeKeyword(keyword)"
17
- >{{ keyword.label }}
18
- @if (isPlaceWithoutExtent(keyword)) {
19
- <ng-icon
20
- [title]="
21
- 'editor.record.form.keywords.place.withoutExtent' | translate
22
- "
23
- class="badge-warning"
24
- name="matWarningAmberOutline"
25
- ></ng-icon>
26
- }
27
- </gn-ui-badge>
14
+ <gn-ui-keyword-badge
15
+ [keyword]="keyword"
16
+ [editable]="true"
17
+ (keywordRemove)="removeKeyword($event)"
18
+ ></gn-ui-keyword-badge>
28
19
  }
29
20
  </div>
30
21
  </div>
@@ -7,40 +7,20 @@ import {
7
7
  inject,
8
8
  } from '@angular/core'
9
9
  import { PlatformServiceInterface } from '../../../../../../../libs/common/domain/src/lib/platform.service.interface'
10
- import { AutocompleteComponent, BadgeComponent } from '../../../../../../../libs/ui/inputs/src'
10
+ import { AutocompleteComponent } from '../../../../../../../libs/ui/inputs/src'
11
+ import { KeywordBadgeComponent } from '../../../../../../../libs/ui/elements/src'
11
12
  import { map } from 'rxjs'
12
13
  import { Keyword } from '../../../../../../../libs/common/domain/src/lib/model/record'
13
14
  import { KeywordType } from '../../../../../../../libs/common/domain/src/lib/model/thesaurus'
14
- import { TranslatePipe } from '@ngx-translate/core'
15
- import {
16
- NgIconComponent,
17
- provideIcons,
18
- provideNgIconsConfig,
19
- } from '@ng-icons/core'
20
- import { matWarningAmberOutline } from '@ng-icons/material-icons/outline'
21
15
 
22
16
  type AutocompleteItem = { title: string; value: Keyword }
23
17
 
24
18
  @Component({
25
19
  selector: 'gn-ui-generic-keywords',
26
20
  templateUrl: './generic-keywords.component.html',
27
- styleUrls: ['./generic-keywords.component.css'],
28
21
  changeDetection: ChangeDetectionStrategy.OnPush,
29
22
  standalone: true,
30
- imports: [
31
- AutocompleteComponent,
32
- NgIconComponent,
33
- BadgeComponent,
34
- TranslatePipe,
35
- ],
36
- providers: [
37
- provideIcons({
38
- matWarningAmberOutline,
39
- }),
40
- provideNgIconsConfig({
41
- size: '1.5em',
42
- }),
43
- ],
23
+ imports: [AutocompleteComponent, KeywordBadgeComponent],
44
24
  })
45
25
  export class GenericKeywordsComponent {
46
26
  private platformService = inject(PlatformServiceInterface)
@@ -87,9 +67,4 @@ export class GenericKeywordsComponent {
87
67
  this.changedKeywords.emit(this.keywords)
88
68
  this.deletedKeyword.emit(keyword)
89
69
  }
90
-
91
- isPlaceWithoutExtent(keyword: Keyword): boolean {
92
- if (keyword.type !== 'place') return false
93
- return !keyword.bbox
94
- }
95
70
  }
@@ -3,13 +3,13 @@
3
3
  editor.record.form.field.onlineResource.edit.protocol
4
4
  </h3>
5
5
  @if (protocolHint) {
6
- <span
7
- class="material-symbols-outlined m-2 gn-ui-icon-small"
6
+ <ng-icon
7
+ name="matHelpOutline"
8
+ size="16"
9
+ class="m-2"
8
10
  [matTooltip]="protocolHint"
9
11
  matTooltipPosition="above"
10
- >
11
- help
12
- </span>
12
+ ></ng-icon>
13
13
  }
14
14
  </div>
15
15
  <div class="flex flex-row items-center gap-4 h-[48px]">
@@ -30,6 +30,7 @@ import {
30
30
  provideNgIconsConfig,
31
31
  } from '@ng-icons/core'
32
32
  import { iconoirRefresh } from '@ng-icons/iconoir'
33
+ import { matHelpOutline } from '@ng-icons/material-icons/outline'
33
34
  import { TranslateDirective, TranslatePipe } from '@ngx-translate/core'
34
35
  import {
35
36
  BehaviorSubject,
@@ -65,7 +66,7 @@ marker(
65
66
  UrlInputComponent,
66
67
  ],
67
68
  providers: [
68
- provideIcons({ iconoirRefresh }),
69
+ provideIcons({ iconoirRefresh, matHelpOutline }),
69
70
  provideNgIconsConfig({
70
71
  size: '1.5em',
71
72
  }),
@@ -138,6 +138,7 @@ export class FormFieldConstraintsShortcutsComponent implements OnDestroy {
138
138
  this.editorFacade.setFieldVisibility({ model }, visible)
139
139
  })
140
140
  }
141
+ hideEmptyConstraints(this.legalConstraints$, 'legalConstraints')
141
142
  hideEmptyConstraints(this.securityConstraints$, 'securityConstraints')
142
143
  hideEmptyConstraints(this.otherConstraints$, 'otherConstraints')
143
144
  })
@@ -3,11 +3,11 @@ import {
3
3
  ChangeDetectorRef,
4
4
  Component,
5
5
  EventEmitter,
6
+ inject,
6
7
  Input,
7
8
  Output,
8
9
  TemplateRef,
9
10
  ViewChild,
10
- inject,
11
11
  } from '@angular/core'
12
12
  import { MatDialog } from '@angular/material/dialog'
13
13
  import { marker } from '@biesbjerg/ngx-translate-extract-marker'
@@ -3,11 +3,14 @@ import {
3
3
  ChangeDetectorRef,
4
4
  Component,
5
5
  EventEmitter,
6
+ inject,
6
7
  Input,
7
8
  Output,
8
- inject,
9
9
  } from '@angular/core'
10
- import { GraphicOverview } from '../../../../../../../../../libs/common/domain/src/lib/model/record'
10
+ import {
11
+ GraphicOverview,
12
+ RecordKind,
13
+ } from '../../../../../../../../../libs/common/domain/src/lib/model/record'
11
14
  import { ImageInputComponent } from '../../../../../../../../../libs/ui/elements/src'
12
15
  import { PlatformServiceInterface } from '../../../../../../../../../libs/common/domain/src/lib/platform.service.interface'
13
16
  import { NotificationsService } from '../../../../../../../../../libs/feature/notifications/src'
@@ -30,6 +33,7 @@ export class FormFieldOverviewsComponent {
30
33
  private cd = inject(ChangeDetectorRef)
31
34
 
32
35
  @Input() metadataUuid: string
36
+ @Input() recordKind: RecordKind
33
37
  @Input() value: Array<GraphicOverview>
34
38
  @Output() valueChange: EventEmitter<Array<GraphicOverview>> =
35
39
  new EventEmitter()
@@ -111,13 +115,16 @@ export class FormFieldOverviewsComponent {
111
115
  {
112
116
  type: 'error',
113
117
  title: this.translateService.instant(
114
- 'editor.record.resourceError.title'
118
+ 'editor.record.resourceError.title',
119
+ { recordKind: this.recordKind }
115
120
  ),
116
121
  text: `${this.translateService.instant(
117
- 'editor.record.resourceError.body'
122
+ 'editor.record.resourceError.body',
123
+ { recordKind: this.recordKind }
118
124
  )} ${error.message}`,
119
125
  closeMessage: this.translateService.instant(
120
- 'editor.record.resourceError.closeMessage'
126
+ 'editor.record.resourceError.closeMessage',
127
+ { recordKind: this.recordKind }
121
128
  ),
122
129
  },
123
130
  undefined,
@@ -9,11 +9,11 @@
9
9
  "
10
10
  (buttonClick)="togglePreview()"
11
11
  >
12
- <span
13
- class="material-symbols-outlined gn-ui-icon-small"
12
+ <ng-icon
13
+ [name]="preview ? 'matVisibilityOffOutline' : 'matVisibilityOutline'"
14
+ size="16"
14
15
  [ngClass]="{ 'text-primary': !preview }"
15
- >{{ preview ? 'visibility_off' : 'visibility' }}</span
16
- >
16
+ ></ng-icon>
17
17
  &nbsp;
18
18
  {{ preview ? 'Edit' : 'Preview' }}
19
19
  </gn-ui-button>
@@ -10,6 +10,11 @@ import { ReactiveFormsModule } from '@angular/forms'
10
10
  import { MarkdownEditorComponent } from '../../../../../../../../../libs/ui/elements/src'
11
11
  import { ButtonComponent } from '../../../../../../../../../libs/ui/inputs/src'
12
12
  import { FormFieldWrapperComponent } from '../../../../../../../../../libs/ui/layout/src'
13
+ import { NgIconComponent, provideIcons } from '@ng-icons/core'
14
+ import {
15
+ matVisibilityOffOutline,
16
+ matVisibilityOutline,
17
+ } from '@ng-icons/material-icons/outline'
13
18
 
14
19
  @Component({
15
20
  selector: 'gn-ui-form-field-rich',
@@ -23,7 +28,9 @@ import { FormFieldWrapperComponent } from '../../../../../../../../../libs/ui/la
23
28
  MarkdownEditorComponent,
24
29
  FormFieldWrapperComponent,
25
30
  ButtonComponent,
31
+ NgIconComponent,
26
32
  ],
33
+ providers: [provideIcons({ matVisibilityOutline, matVisibilityOffOutline })],
27
34
  })
28
35
  export class FormFieldRichComponent {
29
36
  @Input() label: string
@@ -1,11 +1,15 @@
1
1
  <div class="flex flex-col gap-2">
2
2
  <gn-ui-check-toggle
3
- [label]="'editor.record.form.updateFrequency.planned' | translate"
3
+ [label]="
4
+ 'editor.record.form.updateFrequency.planned' | translate: { recordKind }
5
+ "
4
6
  [value]="planned"
5
7
  (toggled)="onPlannedToggled()"
6
8
  ></gn-ui-check-toggle>
7
9
  <gn-ui-dropdown-selector
8
- [title]="'editor.record.form.field.updateFrequency' | translate"
10
+ [title]="
11
+ 'editor.record.form.field.updateFrequency' | translate: { recordKind }
12
+ "
9
13
  [showTitle]="false"
10
14
  [choices]="choices"
11
15
  [selected]="selectedFrequency"
@@ -2,12 +2,13 @@ import {
2
2
  ChangeDetectionStrategy,
3
3
  Component,
4
4
  EventEmitter,
5
+ inject,
5
6
  Input,
6
7
  OnInit,
7
8
  Output,
8
- inject,
9
9
  } from '@angular/core'
10
10
  import {
11
+ RecordKind,
11
12
  UpdateFrequency,
12
13
  UpdateFrequencyCode,
13
14
  updateFrequencyCodeValues,
@@ -37,6 +38,7 @@ export class FormFieldUpdateFrequencyComponent implements OnInit {
37
38
  private translateService = inject(TranslateService)
38
39
 
39
40
  @Input() value: UpdateFrequency
41
+ @Input() recordKind: RecordKind
40
42
  @Output() valueChange: EventEmitter<UpdateFrequency> = new EventEmitter()
41
43
 
42
44
  protected choices: DropdownChoice[] = []
@@ -12,8 +12,8 @@
12
12
  </ng-container>
13
13
  <ng-template #withGenericWrapper>
14
14
  <gn-ui-form-field-wrapper
15
- [label]="config.labelKey! | translate"
16
- [hint]="config.hintKey! | translate"
15
+ [label]="config.labelKey! | translate: { recordKind }"
16
+ [hint]="config.hintKey! | translate: { recordKind }"
17
17
  >
18
18
  <ng-container *ngTemplateOutlet="fieldContent"></ng-container>
19
19
  </gn-ui-form-field-wrapper>
@@ -34,30 +34,32 @@
34
34
  [value]="valueAsString"
35
35
  (change)="valueChange.emit($event.target.value)"
36
36
  [placeholder]="
37
- 'editor.record.form.field.title.placeholder' | translate
37
+ 'editor.record.form.field.title.placeholder'
38
+ | translate: { recordKind }
38
39
  "
39
40
  ></textarea>
40
41
  <div class="flex flex-row justify-between self-start mt-0.5">
41
- <span
42
- class="material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer"
42
+ <ng-icon
43
+ name="matEditOutline"
44
+ size="16"
45
+ class="m-2 cursor-pointer"
43
46
  (click)="focusTitleInput()"
44
- >edit</span
45
- >
46
- <span
47
+ ></ng-icon>
48
+ <ng-icon
47
49
  *ngIf="config.hintKey"
48
- class="material-symbols-outlined gn-ui-icon-small m-2"
49
- [matTooltip]="config.hintKey! | translate"
50
+ name="matHelpOutline"
51
+ size="16"
52
+ class="m-2"
53
+ [matTooltip]="config.hintKey! | translate: { recordKind }"
50
54
  matTooltipPosition="above"
51
- >
52
- help
53
- </span>
55
+ ></ng-icon>
54
56
  </div>
55
57
  </div>
56
58
  </ng-container>
57
59
  <ng-container *ngSwitchCase="'abstract'">
58
60
  <gn-ui-form-field-rich
59
- [label]="config.labelKey! | translate"
60
- [hint]="config.hintKey! | translate"
61
+ [label]="config.labelKey! | translate: { recordKind }"
62
+ [hint]="config.hintKey! | translate: { recordKind }"
61
63
  [value]="valueAsString"
62
64
  (valueChange)="valueChange.emit($event)"
63
65
  ></gn-ui-form-field-rich>
@@ -65,6 +67,7 @@
65
67
  <ng-container *ngSwitchCase="'overviews'">
66
68
  <gn-ui-form-field-overviews
67
69
  [metadataUuid]="uniqueIdentifier"
70
+ [recordKind]="recordKind"
68
71
  [value]="valueAsOverviews"
69
72
  (valueChange)="valueChange.emit($event)"
70
73
  ></gn-ui-form-field-overviews>
@@ -92,6 +95,7 @@
92
95
  <gn-ui-form-field-update-frequency
93
96
  [value]="valueAsUpdateFrequency"
94
97
  (valueChange)="valueChange.emit($event)"
98
+ [recordKind]="recordKind"
95
99
  ></gn-ui-form-field-update-frequency>
96
100
  </ng-container>
97
101
  <ng-container *ngSwitchCase="'temporalExtents'">
@@ -117,7 +121,7 @@
117
121
  </ng-container>
118
122
  <ng-container *ngSwitchCase="'licenses'">
119
123
  <gn-ui-form-field-license
120
- [label]="config.labelKey! | translate"
124
+ [label]="config.labelKey! | translate: { recordKind }"
121
125
  [recordLicences]="valueAsConstraints"
122
126
  (recordLicencesChange)="valueChange.emit($event)"
123
127
  ></gn-ui-form-field-license>
@@ -170,6 +174,13 @@
170
174
  (valueChange)="valueChange.emit($event)"
171
175
  ></gn-ui-form-field-online-link-resources>
172
176
  </ng-container>
177
+ <ng-container *ngSwitchCase="'onlineResources'">
178
+ <gn-ui-form-field-online-single-link-resource
179
+ *ngIf="modelSpecifier === 'onlineResourceType:singleLink'"
180
+ [value]="valueAsOnlineResources"
181
+ (valueChange)="valueChange.emit($event)"
182
+ ></gn-ui-form-field-online-single-link-resource>
183
+ </ng-container>
173
184
  </ng-container>
174
185
 
175
186
  <ng-container *ngIf="!model">