geonetwork-ui 2.2.0-dev.c15a456d → 2.2.0-dev.dc3a671b

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 (125) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.mjs +2 -1
  2. package/esm2022/libs/feature/catalog/src/lib/organisations/organisations.component.mjs +4 -15
  3. package/esm2022/libs/feature/map/src/lib/add-layer-from-catalog/add-layer-record-preview/add-layer-record-preview.component.mjs +1 -1
  4. package/esm2022/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.mjs +106 -0
  5. package/esm2022/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.mjs +64 -0
  6. package/esm2022/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.mjs +63 -0
  7. package/esm2022/libs/feature/map/src/lib/feature-map.module.mjs +11 -2
  8. package/esm2022/libs/feature/map/src/lib/layers-panel/layers-panel.component.mjs +6 -3
  9. package/esm2022/libs/feature/map/src/lib/map-context/map-context.service.mjs +3 -1
  10. package/esm2022/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.mjs +7 -4
  11. package/esm2022/libs/feature/search/src/lib/results-list/results-list.container.component.mjs +1 -1
  12. package/esm2022/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.mjs +4 -4
  13. package/esm2022/libs/ui/catalog/src/lib/organisation-preview/organisation-preview.component.mjs +1 -1
  14. package/esm2022/libs/ui/elements/src/index.mjs +3 -1
  15. package/esm2022/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.mjs +27 -0
  16. package/esm2022/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.mjs +17 -0
  17. package/esm2022/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.mjs +10 -3
  18. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +12 -6
  19. package/esm2022/libs/ui/elements/src/lib/related-record-card/related-record-card.component.mjs +3 -3
  20. package/esm2022/libs/ui/elements/src/lib/thumbnail/thumbnail.component.mjs +7 -3
  21. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +13 -3
  22. package/esm2022/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.mjs +6 -3
  23. package/esm2022/libs/ui/inputs/src/lib/navigation-button/navigation-button.component.mjs +3 -3
  24. package/esm2022/libs/ui/inputs/src/lib/star-toggle/star-toggle.component.mjs +2 -2
  25. package/esm2022/libs/ui/search/src/lib/record-preview-card/record-preview-card.component.mjs +1 -1
  26. package/esm2022/libs/ui/search/src/lib/record-preview-feed/record-preview-feed.component.mjs +1 -1
  27. package/esm2022/libs/ui/search/src/lib/record-preview-list/record-preview-list.component.mjs +1 -1
  28. package/esm2022/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.mjs +1 -1
  29. package/esm2022/libs/ui/search/src/lib/record-preview-title/record-preview-title.component.mjs +1 -1
  30. package/esm2022/libs/util/i18n/src/index.mjs +2 -1
  31. package/esm2022/libs/util/shared/src/lib/utils/fuzzy-filter.mjs +27 -0
  32. package/esm2022/libs/util/shared/src/lib/utils/index.mjs +2 -1
  33. package/esm2022/translations/de.json +15 -1
  34. package/esm2022/translations/en.json +18 -4
  35. package/esm2022/translations/es.json +14 -0
  36. package/esm2022/translations/fr.json +18 -4
  37. package/esm2022/translations/it.json +26 -12
  38. package/esm2022/translations/nl.json +14 -0
  39. package/esm2022/translations/pt.json +14 -0
  40. package/fesm2022/geonetwork-ui.mjs +480 -93
  41. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  42. package/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.d.ts.map +1 -1
  43. package/libs/feature/catalog/src/lib/organisations/organisations.component.d.ts +0 -1
  44. package/libs/feature/catalog/src/lib/organisations/organisations.component.d.ts.map +1 -1
  45. package/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.d.ts +22 -0
  46. package/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.d.ts.map +1 -0
  47. package/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.d.ts +22 -0
  48. package/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.d.ts.map +1 -0
  49. package/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.d.ts +22 -0
  50. package/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.d.ts.map +1 -0
  51. package/libs/feature/map/src/lib/feature-map.module.d.ts +15 -12
  52. package/libs/feature/map/src/lib/feature-map.module.d.ts.map +1 -1
  53. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts +1 -0
  54. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts.map +1 -1
  55. package/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.d.ts +2 -1
  56. package/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.d.ts.map +1 -1
  57. package/libs/ui/elements/src/index.d.ts +2 -0
  58. package/libs/ui/elements/src/index.d.ts.map +1 -1
  59. package/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.d.ts +10 -0
  60. package/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.d.ts.map +1 -0
  61. package/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.d.ts +8 -0
  62. package/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.d.ts.map +1 -0
  63. package/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.d.ts +1 -0
  64. package/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.d.ts.map +1 -1
  65. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts +1 -0
  66. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts.map +1 -1
  67. package/libs/ui/elements/src/lib/thumbnail/thumbnail.component.d.ts +3 -2
  68. package/libs/ui/elements/src/lib/thumbnail/thumbnail.component.d.ts.map +1 -1
  69. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +13 -11
  70. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  71. package/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.d.ts.map +1 -1
  72. package/libs/util/i18n/src/index.d.ts +1 -0
  73. package/libs/util/i18n/src/index.d.ts.map +1 -1
  74. package/libs/util/shared/src/lib/utils/fuzzy-filter.d.ts +9 -0
  75. package/libs/util/shared/src/lib/utils/fuzzy-filter.d.ts.map +1 -0
  76. package/libs/util/shared/src/lib/utils/index.d.ts +1 -0
  77. package/libs/util/shared/src/lib/utils/index.d.ts.map +1 -1
  78. package/package.json +1 -1
  79. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.ts +1 -0
  80. package/src/libs/feature/catalog/src/lib/organisations/organisations.component.ts +3 -17
  81. package/src/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.css +0 -0
  82. package/src/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.html +21 -0
  83. package/src/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.ts +107 -0
  84. package/src/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.css +0 -0
  85. package/src/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.html +37 -0
  86. package/src/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.ts +64 -0
  87. package/src/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.css +0 -0
  88. package/src/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.html +55 -0
  89. package/src/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.ts +63 -0
  90. package/src/libs/feature/map/src/lib/feature-map.module.ts +6 -0
  91. package/src/libs/feature/map/src/lib/layers-panel/layers-panel.component.html +9 -3
  92. package/src/libs/feature/map/src/lib/map-context/map-context.service.ts +6 -0
  93. package/src/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.html +12 -4
  94. package/src/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.ts +1 -0
  95. package/src/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.html +1 -0
  96. package/src/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.ts +1 -1
  97. package/src/libs/ui/elements/src/index.ts +2 -0
  98. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.css +0 -0
  99. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.html +29 -0
  100. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.ts +15 -0
  101. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.css +264 -0
  102. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.html +1 -0
  103. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.ts +16 -0
  104. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.html +93 -27
  105. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.ts +7 -0
  106. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.css +4 -0
  107. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +59 -32
  108. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +5 -0
  109. package/src/libs/ui/elements/src/lib/related-record-card/related-record-card.component.html +1 -1
  110. package/src/libs/ui/elements/src/lib/thumbnail/thumbnail.component.ts +4 -0
  111. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +6 -0
  112. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.ts +7 -4
  113. package/src/libs/ui/inputs/src/lib/navigation-button/navigation-button.component.html +8 -3
  114. package/src/libs/ui/inputs/src/lib/star-toggle/star-toggle.component.css +1 -0
  115. package/src/libs/util/i18n/src/index.ts +1 -0
  116. package/src/libs/util/shared/src/lib/utils/fuzzy-filter.ts +32 -0
  117. package/src/libs/util/shared/src/lib/utils/index.ts +1 -0
  118. package/translations/de.json +15 -1
  119. package/translations/en.json +18 -4
  120. package/translations/es.json +14 -0
  121. package/translations/fr.json +18 -4
  122. package/translations/it.json +26 -12
  123. package/translations/nl.json +14 -0
  124. package/translations/pt.json +14 -0
  125. package/translations/sk.json +14 -0
@@ -1,32 +1,98 @@
1
- <div *ngIf="shownOrganization" class="mb-6 sm:mb-12">
2
- <p class="text-gray-700 text-xs mb-3 uppercase" translate>
3
- record.metadata.contact
4
- </p>
5
- <div class="flex mb-1">
1
+ <div class="py-5 px-5 rounded bg-gray-100 text-black mb-6 sm:mb-12">
2
+ <div class="grid gap-3">
3
+ <div>
4
+ <p class="text-sm font-medium" translate>record.metadata.contact</p>
5
+ </div>
6
6
  <div
7
- class="text-primary font-title text-21 mr-2 cursor-pointer hover:underline"
8
- (click)="onOrganizationClick()"
7
+ *ngIf="shownOrganization?.logoUrl?.href"
8
+ class="flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden"
9
9
  >
10
- {{ shownOrganization.name }}
10
+ <gn-ui-thumbnail
11
+ class="relative h-full w-full"
12
+ [thumbnailUrl]="shownOrganization.logoUrl.href"
13
+ fit="contain"
14
+ ></gn-ui-thumbnail>
15
+ </div>
16
+ <div class="grid gap-1">
17
+ <div class="flex">
18
+ <div
19
+ class="text-primary font-title text-21 mr-2 cursor-pointer hover:underline"
20
+ (click)="onOrganizationClick()"
21
+ data-cy="organization-name"
22
+ >
23
+ {{ shownOrganization?.name }}
24
+ </div>
25
+ </div>
26
+ <div *ngIf="shownOrganization?.website">
27
+ <a
28
+ [href]="shownOrganization.website"
29
+ target="_blank"
30
+ class="contact-website text-primary text-sm cursor-pointer hover:underline transition-all"
31
+ >{{ shownOrganization.website }}
32
+ <mat-icon
33
+ class="material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0"
34
+ >open_in_new</mat-icon
35
+ >
36
+ </a>
37
+ </div>
38
+ </div>
39
+ <div class="grid gap-5 py-3 overflow-hidden">
40
+ <div *ngIf="contacts[0]?.phone">
41
+ <div class="flex">
42
+ <mat-icon
43
+ class="material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0"
44
+ >call_outline</mat-icon
45
+ >
46
+ <div class="flex flex-col ml-2">
47
+ <p class="text-sm">{{ contacts[0].phone }}</p>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <div *ngIf="contacts[0]?.email">
52
+ <div class="flex">
53
+ <mat-icon
54
+ class="material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0"
55
+ >
56
+ mail_outline</mat-icon
57
+ >
58
+ <a
59
+ *ngIf="contacts.length"
60
+ [href]="'mailto:' + contacts[0].email"
61
+ class="text-sm hover:underline ml-2"
62
+ target="_blank"
63
+ data-cy="contact-email"
64
+ >{{ contacts[0].email }}</a
65
+ >
66
+ </div>
67
+ </div>
68
+ <div *ngIf="contacts[0]?.firstName || contacts[0]?.lastName">
69
+ <div class="flex">
70
+ <mat-icon
71
+ class="material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0"
72
+ >person_outline</mat-icon
73
+ >
74
+ <div class="flex flex-col ml-2">
75
+ <p class="text-sm">
76
+ {{ contacts[0]?.firstName || '' }}
77
+ {{ contacts[0]?.lastName || '' }}
78
+ </p>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ <div *ngIf="contacts[0]?.address">
83
+ <div class="flex">
84
+ <mat-icon
85
+ class="material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0"
86
+ >
87
+ location_on</mat-icon
88
+ >
89
+ <div class="flex flex-col ml-2">
90
+ <p *ngFor="let addressPart of address" class="text-sm">
91
+ {{ addressPart }}
92
+ </p>
93
+ </div>
94
+ </div>
95
+ </div>
11
96
  </div>
12
- </div>
13
- <a
14
- *ngIf="contacts.length"
15
- [href]="'mailto:' + contacts[0].email"
16
- class="text-gray-700 text-sm hover:underline"
17
- target="_blank"
18
- >{{ contacts[0].email }}</a
19
- >
20
- <div *ngIf="shownOrganization.website" class="mb-2">
21
- <a
22
- [href]="shownOrganization.website"
23
- target="_blank"
24
- class="contact-website text-primary text-sm cursor-pointer hover:underline transition-all"
25
- >{{ shownOrganization.website }}
26
- <mat-icon
27
- class="material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75"
28
- >open_in_new</mat-icon
29
- >
30
- </a>
31
97
  </div>
32
98
  </div>
@@ -34,6 +34,13 @@ export class MetadataContactComponent {
34
34
  )
35
35
  }
36
36
 
37
+ get address() {
38
+ const addressParts = this.contacts[0].address
39
+ .split(',')
40
+ .map((part) => part.trim())
41
+ return addressParts
42
+ }
43
+
37
44
  onOrganizationClick() {
38
45
  this.organizationClick.emit(this.shownOrganization)
39
46
  }
@@ -7,3 +7,7 @@
7
7
  padding-bottom: 10px;
8
8
  @apply border-b border-gray-300;
9
9
  }
10
+
11
+ :host ::ng-deep gn-ui-copy-text-button button mat-icon {
12
+ transform: scale(0.8);
13
+ }
@@ -1,32 +1,10 @@
1
- <p
2
- class="text-[28px] text-title text-center mb-6 font-title sm:text-left"
3
- translate
4
- >
5
- record.metadata.about
6
- </p>
7
1
  <div class="mb-6 md-description sm:mb-4 sm:pr-16">
8
2
  <gn-ui-content-ghost ghostClass="h-32" [showContent]="fieldReady('abstract')">
9
3
  <gn-ui-max-lines [maxLines]="6" *ngIf="metadata.abstract">
10
4
  <div>
11
- <p
12
- class="whitespace-pre-line break-words sm:mb-4 sm:pr-16"
13
- [innerHTML]="metadata.abstract"
14
- gnUiLinkify
15
- ></p>
16
- <ng-container *ngIf="metadata.keywords?.length">
17
- <p class="mb-3 font-medium text-primary text-sm" translate>
18
- record.metadata.keywords
19
- </p>
20
- <div class="sm:pb-4 sm:pr-16">
21
- <gn-ui-badge
22
- class="inline-block mr-2 mb-2 lowercase"
23
- (click)="onKeywordClick(keyword)"
24
- [clickable]="true"
25
- *ngFor="let keyword of metadata.keywords"
26
- >{{ keyword }}</gn-ui-badge
27
- >
28
- </div>
29
- </ng-container>
5
+ <gn-ui-markdown-parser
6
+ [textContent]="metadata.abstract"
7
+ ></gn-ui-markdown-parser>
30
8
  </div>
31
9
  </gn-ui-max-lines>
32
10
  </gn-ui-content-ghost>
@@ -97,12 +75,61 @@
97
75
  *ngIf="metadata.landingPage"
98
76
  [title]="'record.metadata.details' | translate"
99
77
  >
100
- <div class="py-5 px-5 rounded bg-gray-100 text-gray-700">
101
- <p class="text-sm" translate>record.metadata.sheet</p>
102
- <p class="text-primary font-medium mt-1" translate>
103
- <a [href]="metadata.landingPage" target="_blank">
104
- <span class="break-all" gnUiLinkify>{{ metadata.landingPage }}</span>
105
- </a>
106
- </p>
78
+ <div class="flex flex-col gap-4 mr-4 py-5 rounded text-gray-700">
79
+ <div *ngIf="metadata.recordUpdated">
80
+ <p class="text-sm" translate>record.metadata.updatedOn</p>
81
+ <p class="text-primary font-medium">
82
+ {{ metadata.recordUpdated && metadata.recordUpdated.toLocaleString() }}
83
+ </p>
84
+ </div>
85
+ <div *ngIf="metadata.landingPage">
86
+ <p class="text-sm" translate>record.metadata.sheet</p>
87
+ <p class="text-primary font-medium" translate>
88
+ <a [href]="metadata.landingPage" target="_blank">
89
+ <span class="break-all" gnUiLinkify>{{ metadata.landingPage }}</span>
90
+ </a>
91
+ </p>
92
+ </div>
93
+ <div *ngIf="metadata.ownerOrganization">
94
+ <p class="text-sm" translate>record.metadata.owner</p>
95
+ <p class="text-primary font-medium">
96
+ {{ metadata.ownerOrganization.name }}
97
+ </p>
98
+ </div>
99
+ <div *ngIf="metadata.uniqueIdentifier">
100
+ <p class="text-sm" translate>record.metadata.uniqueId</p>
101
+ <div class="flex flex-row content-align items-end gap-1">
102
+ <gn-ui-copy-text-button
103
+ [text]="metadata.uniqueIdentifier"
104
+ [tooltipText]="'tooltip.id.copy' | translate"
105
+ [displayText]="false"
106
+ ></gn-ui-copy-text-button>
107
+ <p class="text-primary font-medium">
108
+ {{ metadata.uniqueIdentifier }}
109
+ </p>
110
+ </div>
111
+ </div>
112
+ <div *ngIf="metadata.themes?.length">
113
+ <p class="text-sm mb-1" translate>record.metadata.themes</p>
114
+ <div class="sm:pb-4 sm:pr-16">
115
+ <gn-ui-badge
116
+ class="inline-block mr-2 lowercase"
117
+ *ngFor="let theme of metadata.themes"
118
+ >{{ theme }}</gn-ui-badge
119
+ >
120
+ </div>
121
+ </div>
122
+ <div *ngIf="metadata.keywords?.length">
123
+ <p class="text-sm mb-1" translate>record.metadata.keywords</p>
124
+ <div class="sm:pb-4 sm:pr-16">
125
+ <gn-ui-badge
126
+ class="inline-block mr-2 mb-2 lowercase"
127
+ (click)="onKeywordClick(keyword)"
128
+ [clickable]="true"
129
+ *ngFor="let keyword of metadata.keywords"
130
+ >{{ keyword }}</gn-ui-badge
131
+ >
132
+ </div>
133
+ </div>
107
134
  </div>
108
135
  </gn-ui-expandable-panel>
@@ -56,4 +56,9 @@ export class MetadataInfoComponent {
56
56
  onKeywordClick(keyword: string) {
57
57
  this.keyword.emit(keyword)
58
58
  }
59
+
60
+ copyText() {
61
+ navigator.clipboard.writeText(this.metadata.uniqueIdentifier)
62
+ ;(event.target as HTMLElement).blur()
63
+ }
59
64
  }
@@ -6,7 +6,7 @@
6
6
  <div class="h-52 bg-gray-100">
7
7
  <gn-ui-thumbnail
8
8
  class="h-52 w-full object-cover"
9
- [thumbnailUrl]="record.overviews?.[0].url.toString()"
9
+ [thumbnailUrl]="record.overviews?.[0]?.url.toString()"
10
10
  ></gn-ui-thumbnail>
11
11
  </div>
12
12
  <div class="flex flex-col justify-between h-44 px-5 pt-4 pb-6">
@@ -10,6 +10,8 @@ import {
10
10
  Optional,
11
11
  SimpleChanges,
12
12
  ViewChild,
13
+ Output,
14
+ EventEmitter,
13
15
  } from '@angular/core'
14
16
 
15
17
  export const THUMBNAIL_PLACEHOLDER = new InjectionToken<string>(
@@ -36,6 +38,7 @@ export class ThumbnailComponent implements OnInit, OnChanges {
36
38
  @Input() fit: FitOptions | FitOptions[] = 'cover'
37
39
  @ViewChild('imageElement') imgElement: ElementRef<HTMLImageElement>
38
40
  @ViewChild('containerElement') containerElement: ElementRef<HTMLDivElement>
41
+ @Output() placeholderShown = new EventEmitter<boolean>()
39
42
  imgUrl: string
40
43
  imgFit: FitOptions
41
44
  placeholderUrl = this.optionalPlaceholderUrl || DEFAULT_PLACEHOLDER
@@ -85,6 +88,7 @@ export class ThumbnailComponent implements OnInit, OnChanges {
85
88
  private setNewSrcImage(image: ThumbnailImageObject) {
86
89
  this.imgFit = image.fit
87
90
  this.imgUrl = image.url
91
+ this.placeholderShown.emit(this.isPlaceholder)
88
92
  }
89
93
 
90
94
  private setPlaceholder(): void {
@@ -29,6 +29,8 @@ import { GnUiLinkifyDirective } from './metadata-info/linkify.directive'
29
29
  import { PaginationButtonsComponent } from './pagination-buttons/pagination-buttons.component'
30
30
  import { MaxLinesComponent } from './max-lines/max-lines.component'
31
31
  import { RecordApiFormComponent } from './record-api-form/record-api-form.component'
32
+ import { MarkdownParserComponent } from './markdown-parser/markdown-parser.component'
33
+ import { ImageOverlayPreviewComponent } from './image-overlay-preview/image-overlay-preview.component'
32
34
 
33
35
  @NgModule({
34
36
  imports: [
@@ -65,6 +67,8 @@ import { RecordApiFormComponent } from './record-api-form/record-api-form.compon
65
67
  PaginationButtonsComponent,
66
68
  MaxLinesComponent,
67
69
  RecordApiFormComponent,
70
+ MarkdownParserComponent,
71
+ ImageOverlayPreviewComponent,
68
72
  ],
69
73
  exports: [
70
74
  MetadataInfoComponent,
@@ -85,6 +89,8 @@ import { RecordApiFormComponent } from './record-api-form/record-api-form.compon
85
89
  UserPreviewComponent,
86
90
  PaginationButtonsComponent,
87
91
  RecordApiFormComponent,
92
+ MarkdownParserComponent,
93
+ ImageOverlayPreviewComponent,
88
94
  ],
89
95
  })
90
96
  export class UiElementsModule {}
@@ -17,7 +17,10 @@ import {
17
17
  } from '@angular/cdk/overlay'
18
18
  import { take } from 'rxjs/operators'
19
19
  import { Choice } from './dropdown-multiselect.model'
20
- import { propagateToDocumentOnly } from '../../../../../../libs/util/shared/src'
20
+ import {
21
+ createFuzzyFilter,
22
+ propagateToDocumentOnly,
23
+ } from '../../../../../../libs/util/shared/src'
21
24
 
22
25
  @Component({
23
26
  selector: 'gn-ui-dropdown-multiselect',
@@ -74,9 +77,9 @@ export class DropdownMultiselectComponent {
74
77
  }
75
78
 
76
79
  get filteredChoicesByText() {
77
- return this.choices.filter((choice) =>
78
- choice.label.toLowerCase().includes(this.searchInputValue?.toLowerCase())
79
- )
80
+ if (!this.searchInputValue) return this.choices
81
+ const filter = createFuzzyFilter(this.searchInputValue)
82
+ return this.choices.filter((choice) => filter(choice.label))
80
83
  }
81
84
 
82
85
  get focusedIndex(): number | -1 {
@@ -1,6 +1,11 @@
1
1
  <button
2
- class="group flex items-center justify-center backdrop-blur p-1 bg-primary-opacity-50 text-white rounded"
2
+ class="group flex items-center justify-center gap-1 backdrop-blur p-1 bg-primary-opacity-30 text-white rounded content-center"
3
3
  >
4
- <mat-icon class="material-symbols-outlined align-middle">{{ icon }}</mat-icon>
5
- <span class="mx-2 hidden group-hover:inline">{{ label }}</span>
4
+ <mat-icon class="material-symbols-outlined align-middle w-[18px]">{{
5
+ icon
6
+ }}</mat-icon>
7
+ <span
8
+ class="mx-2 mt-0.5 text-[16px] tracking-widest content-center opacity-75"
9
+ >{{ label.toUpperCase() }}</span
10
+ >
6
11
  </button>
@@ -11,6 +11,7 @@ mat-icon {
11
11
  font-size: 1.5em;
12
12
  margin-top: -0.1em;
13
13
  font-variation-settings: 'opsz' 40;
14
+ stroke: var(--color-primary-darker);
14
15
  }
15
16
 
16
17
  .star-filled {
@@ -5,3 +5,4 @@ export * from './lib/lang.service'
5
5
  export * from './lib/file.translate.loader'
6
6
  export * from './lib/testing/test.translate.module'
7
7
  export * from './lib/embedded.translate.loader'
8
+ export * from './lib/translate.loader.utils'
@@ -0,0 +1,32 @@
1
+ type FuzzyFilter = (input: string) => boolean
2
+
3
+ function normalize(input: string) {
4
+ return input
5
+ .toLowerCase()
6
+ .normalize('NFD') // explode composite chars (e.g. é) into multiple chars
7
+ .replace(/[\u0300-\u036f]/g, '') // remove accents
8
+ .replace(/œ/g, 'oe') // remove accents
9
+ .replace(/[^a-z0-9\s]/g, ' ') // replace special characters with space
10
+ }
11
+
12
+ function asNormalizedParts(input: string): string[] {
13
+ return normalize(input)
14
+ .split(/\s+/)
15
+ .map((part) => part.trim())
16
+ .filter((part) => part.length > 0)
17
+ }
18
+
19
+ /**
20
+ * This creates a filter function based on a pattern (typically a user-input
21
+ * search text).
22
+ * @param pattern
23
+ */
24
+ export function createFuzzyFilter(pattern: string): FuzzyFilter {
25
+ const patternParts = asNormalizedParts(pattern)
26
+ return (input: string) => {
27
+ const inputParts = asNormalizedParts(input)
28
+ return patternParts.every((patternPart) =>
29
+ inputParts.some((part) => part.includes(patternPart))
30
+ )
31
+ }
32
+ }
@@ -5,3 +5,4 @@ export * from './geojson'
5
5
  export * from './sort-by'
6
6
  export * from './url'
7
7
  export * from './event'
8
+ export * from './fuzzy-filter'
@@ -115,6 +115,7 @@
115
115
  "datahub.news.contact.title": "",
116
116
  "datahub.news.feed": "Nachrichtenfeed",
117
117
  "datahub.news.figures": "Indikatoren",
118
+ "datahub.record.addToFavorites": "",
118
119
  "datahub.search.back": "Zurück zu den Ergebnissen",
119
120
  "datahub.search.filter.all": "Alle",
120
121
  "datahub.search.filter.generatedByWfs": "Generiert durch API",
@@ -175,10 +176,17 @@
175
176
  "map.add.layer.file": "Aus einer Datei",
176
177
  "map.add.layer.wfs": "Aus WFS",
177
178
  "map.add.layer.wms": "Aus WMS",
179
+ "map.addFromFile.placeholder": "",
180
+ "map.help.addFromFile": "",
181
+ "map.layer.add": "",
182
+ "map.layers.available": "",
178
183
  "map.layers.list": "Ebenen",
179
184
  "map.loading.data": "Kartendaten werden geladen...",
185
+ "map.loading.service": "",
180
186
  "map.navigation.message": "Bitte verwenden Sie STRG + Maus (oder zwei Finger auf einem Mobilgerät), um die Karte zu navigieren",
181
187
  "map.select.layer": "Datenquelle",
188
+ "map.wfs.urlInput.hint": "",
189
+ "map.wms.urlInput.hint": "",
182
190
  "multiselect.filter.placeholder": "Suche",
183
191
  "nav.back": "Zurück",
184
192
  "next": "weiter",
@@ -213,14 +221,16 @@
213
221
  "record.metadata.catalog": "Katalog",
214
222
  "record.metadata.contact": "Kontakt",
215
223
  "record.metadata.createdOn": "Erstellt am",
216
- "record.metadata.details": "Details",
224
+ "record.metadata.details": "Technische Informationen",
217
225
  "record.metadata.download": "Downloads",
218
226
  "record.metadata.formats": "",
219
227
  "record.metadata.isOpenData": "Open Data",
220
228
  "record.metadata.keywords": "Stichworte",
229
+ "record.metadata.lastUpdate": "",
221
230
  "record.metadata.links": "Links",
222
231
  "record.metadata.noUsage": "Für diesen Datensatz sind keine Verwendungsbedingungen angegeben.",
223
232
  "record.metadata.origin": "Über die Daten",
233
+ "record.metadata.owner": "",
224
234
  "record.metadata.preview": "Vorschau",
225
235
  "record.metadata.publications": "Veröffentlichungen",
226
236
  "record.metadata.quality": "",
@@ -243,7 +253,10 @@
243
253
  "record.metadata.quality.updateFrequency.success": "",
244
254
  "record.metadata.related": "Ähnliche Datensätze",
245
255
  "record.metadata.sheet": "Weitere Informationen erhalten Sie unter :",
256
+ "record.metadata.themes": "",
246
257
  "record.metadata.title": "Titel",
258
+ "record.metadata.type": "",
259
+ "record.metadata.uniqueId": "",
247
260
  "record.metadata.updateFrequency": "Aktualisierungsfrequenz der Daten",
248
261
  "record.metadata.updateStatus": "Aktualisierungsstatus der Daten",
249
262
  "record.metadata.updatedOn": "Letzte Aktualisierung der Dateninformationen",
@@ -307,6 +320,7 @@
307
320
  "table.object.count": "Objekte in diesem Datensatz",
308
321
  "table.select.data": "Datenquelle",
309
322
  "tooltip.html.copy": "HTML kopieren",
323
+ "tooltip.id.copy": "",
310
324
  "tooltip.url.copy": "URL kopieren",
311
325
  "tooltip.url.open": "URL öffnen",
312
326
  "ui.readLess": "Weniger lesen",
@@ -115,7 +115,8 @@
115
115
  "datahub.news.contact.title": "A specific need?",
116
116
  "datahub.news.feed": "News feed",
117
117
  "datahub.news.figures": "Indicators",
118
- "datahub.search.back": "Back to results",
118
+ "datahub.record.addToFavorites": "Add to favorites",
119
+ "datahub.search.back": "Back",
119
120
  "datahub.search.filter.all": "All",
120
121
  "datahub.search.filter.generatedByWfs": "generated by an API",
121
122
  "datahub.search.filter.others": "Others",
@@ -175,10 +176,17 @@
175
176
  "map.add.layer.file": "From a file",
176
177
  "map.add.layer.wfs": "From WFS",
177
178
  "map.add.layer.wms": "From WMS",
179
+ "map.addFromFile.placeholder": "Click or drop a file here",
180
+ "map.help.addFromFile": "Click or drag and drop a file to add to the map (currently supports GeoJSON format only).",
181
+ "map.layer.add": "Add",
182
+ "map.layers.available": "Available Layers",
178
183
  "map.layers.list": "Layers",
179
184
  "map.loading.data": "Loading map data...",
185
+ "map.loading.service": "Loading service...",
180
186
  "map.navigation.message": "Please use CTRL + mouse (or two fingers on mobile) to navigate the map",
181
187
  "map.select.layer": "Data source",
188
+ "map.wfs.urlInput.hint": "Enter WFS service URL",
189
+ "map.wms.urlInput.hint": "Enter WMS service URL",
182
190
  "multiselect.filter.placeholder": "Search",
183
191
  "nav.back": "Back",
184
192
  "next": "next",
@@ -213,14 +221,16 @@
213
221
  "record.metadata.catalog": "Catalog",
214
222
  "record.metadata.contact": "Contact",
215
223
  "record.metadata.createdOn": "Created on",
216
- "record.metadata.details": "Details",
224
+ "record.metadata.details": "Technical information",
217
225
  "record.metadata.download": "Downloads",
218
226
  "record.metadata.formats": "Formats",
219
227
  "record.metadata.isOpenData": "Open Data",
220
228
  "record.metadata.keywords": "Keywords",
229
+ "record.metadata.lastUpdate": "Last updated on",
221
230
  "record.metadata.links": "Links",
222
231
  "record.metadata.noUsage": "No usage conditions specified for this record.",
223
232
  "record.metadata.origin": "About the data",
233
+ "record.metadata.owner": "Catalog of origin",
224
234
  "record.metadata.preview": "Preview",
225
235
  "record.metadata.publications": "publications",
226
236
  "record.metadata.quality": "Metadata Quality",
@@ -242,11 +252,14 @@
242
252
  "record.metadata.quality.updateFrequency.failed": "Update frequency is not completed",
243
253
  "record.metadata.quality.updateFrequency.success": "Update frequency is completed",
244
254
  "record.metadata.related": "Related records",
245
- "record.metadata.sheet": "More information available from:",
255
+ "record.metadata.sheet": "Original metadata",
256
+ "record.metadata.themes": "Categories",
246
257
  "record.metadata.title": "Title",
258
+ "record.metadata.type": "Geographical dataset",
259
+ "record.metadata.uniqueId": "Unique Identifier",
247
260
  "record.metadata.updateFrequency": "Data Update Frequency",
248
261
  "record.metadata.updateStatus": "Data Update Status",
249
- "record.metadata.updatedOn": "Last Data Information Update",
262
+ "record.metadata.updatedOn": "Metadata's last update",
250
263
  "record.metadata.usage": "Usage & constraints",
251
264
  "record.more.details": "Read more",
252
265
  "record.tab.chart": "Chart",
@@ -307,6 +320,7 @@
307
320
  "table.object.count": "objects in this dataset",
308
321
  "table.select.data": "Data source",
309
322
  "tooltip.html.copy": "Copy HTML",
323
+ "tooltip.id.copy": "Copy unique identifier",
310
324
  "tooltip.url.copy": "Copy URL",
311
325
  "tooltip.url.open": "Open URL",
312
326
  "ui.readLess": "Read less",
@@ -115,6 +115,7 @@
115
115
  "datahub.news.contact.title": "",
116
116
  "datahub.news.feed": "",
117
117
  "datahub.news.figures": "",
118
+ "datahub.record.addToFavorites": "",
118
119
  "datahub.search.back": "",
119
120
  "datahub.search.filter.all": "",
120
121
  "datahub.search.filter.generatedByWfs": "",
@@ -175,10 +176,17 @@
175
176
  "map.add.layer.file": "",
176
177
  "map.add.layer.wfs": "",
177
178
  "map.add.layer.wms": "",
179
+ "map.addFromFile.placeholder": "",
180
+ "map.help.addFromFile": "",
181
+ "map.layer.add": "",
182
+ "map.layers.available": "",
178
183
  "map.layers.list": "",
179
184
  "map.loading.data": "",
185
+ "map.loading.service": "",
180
186
  "map.navigation.message": "",
181
187
  "map.select.layer": "",
188
+ "map.wfs.urlInput.hint": "",
189
+ "map.wms.urlInput.hint": "",
182
190
  "multiselect.filter.placeholder": "",
183
191
  "nav.back": "",
184
192
  "next": "",
@@ -218,9 +226,11 @@
218
226
  "record.metadata.formats": "",
219
227
  "record.metadata.isOpenData": "",
220
228
  "record.metadata.keywords": "",
229
+ "record.metadata.lastUpdate": "",
221
230
  "record.metadata.links": "",
222
231
  "record.metadata.noUsage": "",
223
232
  "record.metadata.origin": "",
233
+ "record.metadata.owner": "",
224
234
  "record.metadata.preview": "",
225
235
  "record.metadata.publications": "",
226
236
  "record.metadata.quality": "",
@@ -243,7 +253,10 @@
243
253
  "record.metadata.quality.updateFrequency.success": "",
244
254
  "record.metadata.related": "",
245
255
  "record.metadata.sheet": "",
256
+ "record.metadata.themes": "",
246
257
  "record.metadata.title": "",
258
+ "record.metadata.type": "",
259
+ "record.metadata.uniqueId": "",
247
260
  "record.metadata.updateFrequency": "",
248
261
  "record.metadata.updateStatus": "",
249
262
  "record.metadata.updatedOn": "",
@@ -307,6 +320,7 @@
307
320
  "table.object.count": "",
308
321
  "table.select.data": "",
309
322
  "tooltip.html.copy": "",
323
+ "tooltip.id.copy": "",
310
324
  "tooltip.url.copy": "",
311
325
  "tooltip.url.open": "",
312
326
  "ui.readLess": "",