geonetwork-ui 2.5.0-dev.59720aa72 → 2.5.0-dev.5d0c263b8

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 (65) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +4 -2
  2. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +14 -13
  3. package/esm2022/libs/feature/editor/src/lib/components/constraint-card/constraint-card.component.mjs +2 -2
  4. package/esm2022/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.mjs +2 -2
  5. package/esm2022/libs/feature/editor/src/lib/components/import-record/import-record.component.mjs +2 -2
  6. package/esm2022/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.mjs +5 -3
  7. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.mjs +2 -2
  8. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.mjs +2 -2
  9. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.mjs +2 -2
  10. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.mjs +2 -2
  11. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.mjs +3 -3
  12. package/esm2022/libs/feature/map/src/lib/add-layer-from-catalog/add-layer-from-catalog.component.mjs +1 -1
  13. package/esm2022/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.mjs +12 -3
  14. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.component.mjs +3 -3
  15. package/esm2022/libs/ui/elements/src/lib/image-input/image-input.component.mjs +46 -30
  16. package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +23 -3
  17. package/esm2022/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.mjs +53 -7
  18. package/esm2022/libs/ui/inputs/src/lib/file-input/file-input.component.mjs +2 -2
  19. package/esm2022/libs/ui/inputs/src/lib/url-input/url-input.component.mjs +10 -3
  20. package/esm2022/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.mjs +3 -3
  21. package/esm2022/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.mjs +10 -3
  22. package/esm2022/translations/de.json +1 -1
  23. package/esm2022/translations/en.json +1 -1
  24. package/esm2022/translations/fr.json +1 -1
  25. package/esm2022/translations/it.json +1 -1
  26. package/fesm2022/geonetwork-ui.mjs +185 -79
  27. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  28. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  29. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  30. package/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.d.ts +1 -0
  31. package/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.d.ts.map +1 -1
  32. package/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.d.ts +4 -1
  33. package/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.d.ts.map +1 -1
  34. package/libs/ui/elements/src/lib/image-input/image-input.component.d.ts +11 -9
  35. package/libs/ui/elements/src/lib/image-input/image-input.component.d.ts.map +1 -1
  36. package/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.d.ts.map +1 -1
  37. package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts +8 -1
  38. package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts.map +1 -1
  39. package/libs/ui/inputs/src/lib/url-input/url-input.component.d.ts +5 -3
  40. package/libs/ui/inputs/src/lib/url-input/url-input.component.d.ts.map +1 -1
  41. package/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.d.ts +1 -1
  42. package/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.d.ts.map +1 -1
  43. package/package.json +1 -1
  44. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +19 -17
  45. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +24 -26
  46. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.html +1 -0
  47. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +2 -0
  48. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +1 -1
  49. package/src/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.html +2 -0
  50. package/src/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.ts +6 -0
  51. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.html +3 -1
  52. package/src/libs/ui/elements/src/lib/image-input/image-input.component.html +15 -10
  53. package/src/libs/ui/elements/src/lib/image-input/image-input.component.ts +45 -29
  54. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +21 -9
  55. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.ts +13 -0
  56. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.html +36 -19
  57. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +43 -2
  58. package/src/libs/ui/inputs/src/lib/url-input/url-input.component.ts +8 -1
  59. package/src/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.html +1 -1
  60. package/src/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.html +36 -11
  61. package/src/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.ts +9 -1
  62. package/translations/de.json +1 -1
  63. package/translations/en.json +1 -1
  64. package/translations/fr.json +1 -1
  65. package/translations/it.json +1 -1
@@ -66,9 +66,22 @@ import { ImageOverlayPreviewComponent } from '../image-overlay-preview/image-ove
66
66
  ],
67
67
  })
68
68
  export class ImageInputComponent {
69
- @Input() maxSizeMB: number
69
+ private _altText?: string
70
+
70
71
  @Input() previewUrl?: string
71
- @Input() altText?: string
72
+ @Input()
73
+ get altText(): string | undefined {
74
+ return this._altText
75
+ }
76
+ set altText(value: string | undefined) {
77
+ if (value !== 'KO' && this._altText === 'KO') {
78
+ //This is a dataset rollback after upload error
79
+ this.resetErrors()
80
+ }
81
+ this._altText = value
82
+ }
83
+
84
+ @Input() maxSizeMB: number
72
85
  @Input() uploadProgress?: number
73
86
  @Input() uploadError?: boolean
74
87
  @Input() disabled?: boolean = false
@@ -80,11 +93,9 @@ export class ImageInputComponent {
80
93
 
81
94
  dragFilesOver = false
82
95
  showUrlInput = false
83
- downloadError = false
96
+ imageFileError = this.uploadError
84
97
  showAltTextInput = false
85
-
86
- lastUploadType?: 'file' | 'url'
87
- lastUploadContent?: string | File
98
+ pendingAltText: string
88
99
 
89
100
  get isUploadInProgress() {
90
101
  return this.uploadProgress !== undefined
@@ -95,8 +106,12 @@ export class ImageInputComponent {
95
106
  private cd: ChangeDetectorRef
96
107
  ) {}
97
108
 
109
+ getIsActionBlocked() {
110
+ return this.isUploadInProgress || this.disabled
111
+ }
112
+
98
113
  getPrimaryText() {
99
- if (this.uploadError) {
114
+ if (this.imageFileError) {
100
115
  return marker('input.image.uploadErrorLabel')
101
116
  }
102
117
  if (this.uploadProgress) {
@@ -106,8 +121,8 @@ export class ImageInputComponent {
106
121
  }
107
122
 
108
123
  getSecondaryText() {
109
- if (this.uploadError) {
110
- return marker('input.image.uploadErrorRetry')
124
+ if (this.imageFileError) {
125
+ return '\u00A0' // (only to keep same spacing, next step is to handle "Retry")
111
126
  }
112
127
  if (this.uploadProgress) {
113
128
  return marker('input.image.uploadProgressCancel')
@@ -123,18 +138,26 @@ export class ImageInputComponent {
123
138
  }
124
139
 
125
140
  handleDropFiles(files: File[]) {
141
+ this.resetErrors()
126
142
  const validFiles = this.filterTypeImage(files)
127
143
  if (validFiles.length > 0) {
128
144
  this.showUrlInput = false
129
145
  this.resizeAndEmit(validFiles[0])
146
+ } else {
147
+ this.imageFileError = true
148
+ this.handleAltTextChange('KO')
130
149
  }
131
150
  }
132
151
 
133
152
  handleFileInput(event: Event) {
153
+ this.resetErrors()
134
154
  const inputFiles = Array.from((event.target as HTMLInputElement).files)
135
155
  const validFiles = this.filterTypeImage(inputFiles)
136
156
  if (validFiles.length > 0) {
137
157
  this.resizeAndEmit(validFiles[0])
158
+ } else {
159
+ this.imageFileError = true
160
+ this.handleAltTextChange('KO')
138
161
  }
139
162
  }
140
163
 
@@ -144,7 +167,7 @@ export class ImageInputComponent {
144
167
  }
145
168
 
146
169
  async downloadUrl(url: string) {
147
- this.downloadError = false
170
+ this.resetErrors()
148
171
  const name = url.split('/').pop()
149
172
  try {
150
173
  const response = await firstValueFrom(
@@ -162,47 +185,41 @@ export class ImageInputComponent {
162
185
  this.fileChange.emit(file)
163
186
  },
164
187
  error: () => {
165
- this.downloadError = true
188
+ this.imageFileError = true
189
+ this.handleAltTextChange('KO')
166
190
  this.cd.markForCheck()
167
191
  this.urlChange.emit(url)
168
192
  },
169
193
  })
170
194
  }
171
195
  } catch {
172
- this.downloadError = true
196
+ this.imageFileError = true
197
+ this.handleAltTextChange('KO')
173
198
  this.cd.markForCheck()
174
199
  return
175
200
  }
176
201
  }
177
202
 
178
203
  handleSecondaryTextClick(event: Event) {
179
- if (this.uploadError) {
180
- this.handleRetry()
181
- } else if (this.uploadProgress) {
182
- this.handleCancel()
204
+ if (this.uploadProgress) {
205
+ this.handleCancelUpload()
183
206
  event.preventDefault()
184
207
  }
185
208
  }
186
209
 
187
- handleCancel() {
210
+ handleCancelUpload() {
188
211
  this.uploadCancel.emit()
189
212
  }
190
213
 
191
- handleRetry() {
192
- switch (this.lastUploadType) {
193
- case 'file':
194
- this.fileChange.emit(this.lastUploadContent as File)
195
- break
196
- case 'url':
197
- this.urlChange.emit(this.lastUploadContent as string)
198
- break
199
- }
200
- }
201
-
202
214
  handleDelete() {
203
215
  this.delete.emit()
204
216
  }
205
217
 
218
+ resetErrors() {
219
+ this.imageFileError = false
220
+ this.uploadError = false
221
+ }
222
+
206
223
  toggleAltTextInput() {
207
224
  this.showAltTextInput = !this.showAltTextInput
208
225
  }
@@ -210,7 +227,6 @@ export class ImageInputComponent {
210
227
  handleAltTextChange(altText: string) {
211
228
  this.altTextChange.emit(altText)
212
229
  }
213
-
214
230
  private filterTypeImage(files: File[]) {
215
231
  return files.filter((file) => {
216
232
  return file.type.startsWith('image/')
@@ -1,13 +1,25 @@
1
1
  <div *ngIf="metadataQualityDisplay" class="mb-6 metadata-quality">
2
- <gn-ui-popover [content]="popoverItems" theme="light-border">
3
- <div class="min-w-[200px]" [class]="smaller ? 'leading-[8px]' : ''">
4
- <gn-ui-progress-bar
5
- tabindex="0"
6
- [value]="qualityScore"
7
- type="primary"
8
- ></gn-ui-progress-bar>
9
- </div>
10
- </gn-ui-popover>
2
+ <div
3
+ class="flex items-center"
4
+ [class]="smaller ? 'leading-[8px] min-w-[120px]' : 'min-w-[200px]'"
5
+ >
6
+ <gn-ui-progress-bar
7
+ tabindex="0"
8
+ [value]="qualityScore"
9
+ [type]="'light'"
10
+ class="flex-grow"
11
+ ></gn-ui-progress-bar>
12
+ <gn-ui-popover
13
+ [content]="popoverItems"
14
+ theme="light-border"
15
+ [class]="smaller ? 'ml-2' : 'ml-2 mt-1'"
16
+ >
17
+ <ng-icon
18
+ name="matInfoOutline"
19
+ class="flex-shrink-0 text-gray-600"
20
+ ></ng-icon>
21
+ </gn-ui-popover>
22
+ </div>
11
23
  </div>
12
24
  <ng-template #popoverItems>
13
25
  <div class="p-2 py-4">
@@ -16,6 +16,9 @@ import {
16
16
  } from '../../../../../../libs/ui/widgets/src'
17
17
  import { CommonModule } from '@angular/common'
18
18
  import { TranslateModule } from '@ngx-translate/core'
19
+ import { NgIcon } from '@ng-icons/core'
20
+ import { matInfoOutline } from '@ng-icons/material-icons/outline'
21
+ import { provideIcons, provideNgIconsConfig } from '@ng-icons/core'
19
22
 
20
23
  @Component({
21
24
  selector: 'gn-ui-metadata-quality',
@@ -29,6 +32,16 @@ import { TranslateModule } from '@ngx-translate/core'
29
32
  ProgressBarComponent,
30
33
  MetadataQualityItemComponent,
31
34
  TranslateModule,
35
+ NgIcon,
36
+ ],
37
+ providers: [
38
+ provideIcons({
39
+ matInfoOutline,
40
+ }),
41
+ provideNgIconsConfig({
42
+ size: '1.2em',
43
+ strokeWidth: '1.5px',
44
+ }),
32
45
  ],
33
46
  })
34
47
  export class MetadataQualityComponent implements OnChanges {
@@ -5,31 +5,48 @@
5
5
  >
6
6
  <ng-icon name="iconoirSearch" class="text-primary search"></ng-icon>
7
7
  </div>
8
- <input
9
- #searchInput
10
- type="text"
11
- class="gn-ui-text-input"
12
- [ngClass]="{
13
- 'px-[--icon-width]': !allowSubmit,
14
- }"
15
- [placeholder]="placeholder"
16
- [formControl]="control"
17
- [matAutocomplete]="auto"
18
- (keyup.enter)="handleEnter(searchInput.value)"
19
- />
8
+ <div class="flex flex-row">
9
+ <input
10
+ #searchInput
11
+ type="text"
12
+ class="gn-ui-text-input"
13
+ (input)="handleInput($event)"
14
+ [placeholder]="placeholder"
15
+ [formControl]="control"
16
+ [matAutocomplete]="auto"
17
+ (keyup.enter)="handleEnter(searchInput.value)"
18
+ [ngClass]="{
19
+ 'text-primary': searchActive && enterButton,
20
+ 'text-gray-900': !searchActive,
21
+ 'px-[--icon-width]': !allowSubmit,
22
+ }"
23
+ />
24
+ <gn-ui-button
25
+ type="gray"
26
+ *ngIf="searchInput.value && displayEnterBtn"
27
+ extraClass="w-32 h-8 !opacity-100"
28
+ [ngStyle]="{ left: enterBtnPosition + 'px' }"
29
+ class="absolute"
30
+ disabled="true"
31
+ >
32
+ <ng-icon
33
+ name="iconoirLongArrowDownLeft"
34
+ class="!w-4 text-gray-900 font-bold"
35
+ ></ng-icon>
36
+ <span translate class="text-bold text-gray-900 font-bold">
37
+ Enter to search
38
+ </span>
39
+ </gn-ui-button>
40
+ </div>
20
41
  <gn-ui-button
21
- type="light"
22
- extraClass="border-0 text-primary-lightest hover:text-primary focus:text-primary absolute inset-y-[--icon-padding] {{
23
- allowSubmit
24
- ? 'right-[calc(var(--icon-width)+var(--icon-padding))]'
25
- : 'right-[--icon-padding]'
26
- }}"
42
+ type="primary"
43
+ [extraClass]="getExtraClass()"
27
44
  data-test="clear-btn"
28
45
  *ngIf="searchInput.value"
29
46
  aria-label="Clear"
30
47
  (buttonClick)="clear()"
31
48
  >
32
- <ng-icon name="matClose"></ng-icon>
49
+ <ng-icon class="text-white" name="matClose"></ng-icon>
33
50
  </gn-ui-button>
34
51
  <gn-ui-button
35
52
  type="light"
@@ -41,7 +41,7 @@ import {
41
41
  provideIcons,
42
42
  provideNgIconsConfig,
43
43
  } from '@ng-icons/core'
44
- import { iconoirSearch } from '@ng-icons/iconoir'
44
+ import { iconoirLongArrowDownLeft, iconoirSearch } from '@ng-icons/iconoir'
45
45
  import { matClose } from '@ng-icons/material-icons/baseline'
46
46
 
47
47
  export type AutocompleteItem = unknown
@@ -65,9 +65,10 @@ export type AutocompleteItem = unknown
65
65
  provideIcons({
66
66
  iconoirSearch,
67
67
  matClose,
68
+ iconoirLongArrowDownLeft,
68
69
  }),
69
70
  provideNgIconsConfig({
70
- size: '1.5rem',
71
+ size: '1.75rem',
71
72
  }),
72
73
  ],
73
74
  })
@@ -75,6 +76,7 @@ export class AutocompleteComponent
75
76
  implements OnInit, AfterViewInit, OnDestroy, OnChanges
76
77
  {
77
78
  @Input() placeholder: string
79
+ @Input() enterButton = false
78
80
  @Input() action: (value: string) => Observable<AutocompleteItem[]>
79
81
  @Input() value?: AutocompleteItem
80
82
  @Input() clearOnSelection = false
@@ -87,6 +89,7 @@ export class AutocompleteComponent
87
89
  @Output() itemSelected = new EventEmitter<AutocompleteItem>()
88
90
  @Output() inputSubmitted = new EventEmitter<string>()
89
91
  @Output() inputCleared = new EventEmitter<void>()
92
+ @Output() isSearchActive = new EventEmitter<boolean>()
90
93
  @ViewChild(MatAutocompleteTrigger) triggerRef: MatAutocompleteTrigger
91
94
  @ViewChild(MatAutocomplete) autocomplete: MatAutocomplete
92
95
  @ViewChild('searchInput') inputRef: ElementRef<HTMLInputElement>
@@ -101,15 +104,36 @@ export class AutocompleteComponent
101
104
  subscription = new Subscription()
102
105
  private lastPosition: DOMRect | null = null
103
106
  private intervalIdPosition: number | undefined
107
+ enterBtnPosition = 0
108
+ searchActive = false
104
109
 
105
110
  @Input() displayWithFn: (item: AutocompleteItem) => string = (item) =>
106
111
  item.toString()
107
112
 
113
+ get displayEnterBtn() {
114
+ return this.enterButton && this.allowSubmit && !this.searchActive
115
+ }
116
+
108
117
  displayWithFnInternal = (item?: AutocompleteItem) => {
109
118
  if (item === null || item === undefined) return null
110
119
  return this.displayWithFn(item)
111
120
  }
112
121
 
122
+ getExtraClass(): string {
123
+ if (this.allowSubmit) {
124
+ if (this.enterButton) {
125
+ return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+var(--icon-padding))] inset-y-[--icon-padding]'
126
+ } else {
127
+ return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+0.25*var(--icon-width))] inset-y-[calc(0.25*var(--icon-width))]'
128
+ }
129
+ } else {
130
+ if (!this.enterButton) {
131
+ return 'border rounded-lg absolute w-8 h-8 right-2 inset-y-2'
132
+ }
133
+ }
134
+ return 'border rounded-lg absolute w-8 h-8'
135
+ }
136
+
113
137
  constructor(private cdRef: ChangeDetectorRef) {}
114
138
  ngOnChanges(changes: SimpleChanges): void {
115
139
  const { value } = changes
@@ -117,6 +141,13 @@ export class AutocompleteComponent
117
141
  const previousTextValue = this.displayWithFnInternal(value.previousValue)
118
142
  const currentTextValue = this.displayWithFnInternal(value.currentValue)
119
143
  if (previousTextValue !== currentTextValue) {
144
+ if (currentTextValue) {
145
+ this.searchActive = true
146
+ this.isSearchActive.emit(true)
147
+ } else {
148
+ this.searchActive = false
149
+ this.isSearchActive.emit(false)
150
+ }
120
151
  this.updateInputValue(value.currentValue)
121
152
  }
122
153
  }
@@ -256,6 +287,8 @@ export class AutocompleteComponent
256
287
 
257
288
  clear(): void {
258
289
  this.inputRef.nativeElement.value = ''
290
+ this.searchActive = false
291
+ this.isSearchActive.emit(false)
259
292
  this.inputCleared.emit()
260
293
  this.selectionSubject
261
294
  .pipe(take(1))
@@ -265,6 +298,8 @@ export class AutocompleteComponent
265
298
 
266
299
  handleEnter(any: string) {
267
300
  if (!this.cancelEnter && this.allowSubmit) {
301
+ this.isSearchActive.emit(true)
302
+ this.searchActive = true
268
303
  this.inputSubmitted.emit(any)
269
304
  }
270
305
  }
@@ -294,4 +329,10 @@ export class AutocompleteComponent
294
329
  this.control.setValue('')
295
330
  }
296
331
  }
332
+
333
+ handleInput(event: InputEvent) {
334
+ this.searchActive = false
335
+ this.isSearchActive.emit(false)
336
+ this.enterBtnPosition = event.target['value'].length * 8 + 80
337
+ }
297
338
  }
@@ -31,7 +31,7 @@ import { iconoirArrowUp, iconoirLink } from '@ng-icons/iconoir'
31
31
  ],
32
32
  changeDetection: ChangeDetectionStrategy.OnPush,
33
33
  })
34
- export class UrlInputComponent {
34
+ export class UrlInputComponent implements OnChanges {
35
35
  @Input() set value(v: string) {
36
36
  // we're making sure to only update the input if the URL representation of it has changed; otherwise we keep it identical
37
37
  // to avoid glitches when starting to write a URL and having some characters added/replaced automatically
@@ -48,6 +48,7 @@ export class UrlInputComponent {
48
48
  @Input() placeholder = 'https://'
49
49
  @Input() disabled: boolean
50
50
  @Input() showValidateButton = true
51
+ @Input() resetUrlOnChange: number
51
52
 
52
53
  /**
53
54
  * This will emit null if the field is emptied
@@ -59,6 +60,12 @@ export class UrlInputComponent {
59
60
 
60
61
  constructor(private cd: ChangeDetectorRef) {}
61
62
 
63
+ ngOnChanges(changes: SimpleChanges) {
64
+ if (changes['resetUrlOnChange']) {
65
+ this.inputValue = ''
66
+ }
67
+ }
68
+
62
69
  handleInput(event: Event) {
63
70
  const value = (event.target as HTMLInputElement).value
64
71
  this.inputValue = value
@@ -64,7 +64,7 @@
64
64
  class="col-start-2 row-start-4 sm:row-start-3 absolute right-[4em] sm:right-[5em]"
65
65
  >
66
66
  <gn-ui-metadata-quality
67
- smaller="true"
67
+ [smaller]="true"
68
68
  [metadata]="record"
69
69
  [metadataQualityDisplay]="metadataQualityDisplay"
70
70
  ></gn-ui-metadata-quality>
@@ -1,12 +1,37 @@
1
- <div class="flex h-full {{ color.outerBar }} rounded-t-lg rounded-b-lg">
2
- <div
3
- [style.width.%]="progress"
4
- class="flex {{
5
- color.innerBar
6
- }} my-1 mx-1 transition-width duration-500 ease-in-out rounded-t-md rounded-b-md shadow-xl"
7
- >
8
- <div class="flex items-center pl-2 py-1 {{ color.text }} font-bold text-4">
9
- {{ progress }}%
1
+ <ng-container [ngSwitch]="type">
2
+ <!-- Light Theme -->
3
+ <ng-container *ngSwitchCase="'light'">
4
+ <div class="flex items-center relative">
5
+ <div
6
+ class="flex-shrink-0 {{ color.text }} text-xs font-medium mr-2
7
+ text-opacity-100 !text-slate-800"
8
+ >
9
+ {{ progress }}%
10
+ </div>
11
+ <div class="flex-grow h-[6px] w-full {{ color.outerBar }} rounded-full">
12
+ <div
13
+ [style.width.%]="progress"
14
+ class="{{ color.innerBar }} transition-width duration-500
15
+ ease-in-out rounded-full shadow-sm h-full"
16
+ ></div>
17
+ </div>
10
18
  </div>
11
- </div>
12
- </div>
19
+ </ng-container>
20
+
21
+ <!-- Default / Primary / Secondary Themes -->
22
+ <ng-container *ngSwitchDefault>
23
+ <div class="flex h-full {{ color.outerBar }} rounded-t-lg rounded-b-lg">
24
+ <div
25
+ [style.width.%]="progress"
26
+ class="flex {{ color.innerBar }} my-1 mx-1 transition-width
27
+ duration-500 ease-in-out rounded-t-md rounded-b-md shadow-xl"
28
+ >
29
+ <div
30
+ class="flex items-center pl-2 py-1 {{ color.text }} font-bold text-4"
31
+ >
32
+ {{ progress }}%
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </ng-container>
37
+ </ng-container>
@@ -1,4 +1,5 @@
1
1
  import { Component, Input } from '@angular/core'
2
+ import { NgSwitch, NgSwitchCase, NgSwitchDefault } from '@angular/common'
2
3
 
3
4
  interface ColorScheme {
4
5
  outerBar: string
@@ -11,10 +12,11 @@ interface ColorScheme {
11
12
  templateUrl: './progress-bar.component.html',
12
13
  styleUrls: ['./progress-bar.component.css'],
13
14
  standalone: true,
15
+ imports: [NgSwitch, NgSwitchCase, NgSwitchDefault],
14
16
  })
15
17
  export class ProgressBarComponent {
16
18
  @Input() value = 0
17
- @Input() type: 'primary' | 'secondary' | 'default' = 'default'
19
+ @Input() type: 'primary' | 'secondary' | 'default' | 'light' = 'default'
18
20
 
19
21
  get progress() {
20
22
  return this.value > 0 ? (this.value < 100 ? this.value : 100) : 0
@@ -40,6 +42,12 @@ export class ProgressBarComponent {
40
42
  innerBar: 'bg-secondary-lighter',
41
43
  text: 'text-white',
42
44
  }
45
+ case 'light':
46
+ return {
47
+ outerBar: 'bg-primary-white',
48
+ innerBar: 'bg-primary',
49
+ text: 'text-main',
50
+ }
43
51
  }
44
52
  }
45
53
  }
@@ -472,7 +472,7 @@
472
472
  "search.error.receivedError": "Ein Fehler ist aufgetreten",
473
473
  "search.error.recordHasnolink": "",
474
474
  "search.error.recordNotFound": "Der Datensatz mit der Kennung \"{ id }\" konnte nicht gefunden werden.",
475
- "search.field.any.placeholder": "Suche Datensätze ...",
475
+ "search.field.any.placeholder": "Suche im katalog ...",
476
476
  "search.field.sortBy": "Sortieren nach:",
477
477
  "search.filters.availableServices.download": "",
478
478
  "search.filters.availableServices.view": "",
@@ -472,7 +472,7 @@
472
472
  "search.error.receivedError": "An error was received",
473
473
  "search.error.recordHasnolink": "This dataset currently has no link yet, please come back later.",
474
474
  "search.error.recordNotFound": "The dataset with identifier \"{ id }\" could not be found.",
475
- "search.field.any.placeholder": "Search datasets ...",
475
+ "search.field.any.placeholder": "Search in the catalog ...",
476
476
  "search.field.sortBy": "Sort by:",
477
477
  "search.filters.availableServices.download": "",
478
478
  "search.filters.availableServices.view": "",
@@ -472,7 +472,7 @@
472
472
  "search.error.receivedError": "Erreur retournée",
473
473
  "search.error.recordHasnolink": "Ce jeu de données n'a pas encore de lien, réessayez plus tard s'il vous plaît.",
474
474
  "search.error.recordNotFound": "Cette donnée n'a pu être trouvée.",
475
- "search.field.any.placeholder": "Rechercher un jeu de données...",
475
+ "search.field.any.placeholder": "Rechercher dans le catalogue...",
476
476
  "search.field.sortBy": "Trier par :",
477
477
  "search.filters.availableServices.download": "",
478
478
  "search.filters.availableServices.view": "",
@@ -472,7 +472,7 @@
472
472
  "search.error.receivedError": "Errore restituito",
473
473
  "search.error.recordHasnolink": "Questo dataset non ha ancora alcun collegamento, riprova più tardi.",
474
474
  "search.error.recordNotFound": "Impossibile trovare questi dati.",
475
- "search.field.any.placeholder": "Cerca un dataset...",
475
+ "search.field.any.placeholder": "Cerca del catalogo...",
476
476
  "search.field.sortBy": "Ordina per:",
477
477
  "search.filters.availableServices.download": "",
478
478
  "search.filters.availableServices.view": "",