geonetwork-ui 2.11.0-dev.fb3fea50c → 2.11.0-dev.fb48cfeee
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 +1675 -1322
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/index.d.ts +205 -111
- package/index.d.ts.map +1 -1
- package/package.json +6 -5
- package/src/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts +2 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/mel.records.dataset+featurecatalog.ts +395 -0
- package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +35 -8
- package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +19 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +17 -6
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +110 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +131 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +9 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +2 -1
- package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +67 -10
- package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +83 -35
- package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +11 -0
- package/src/libs/common/domain/src/lib/model/record/flags.model.ts +1 -0
- package/src/libs/common/domain/src/lib/model/record/index.ts +1 -0
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +14 -18
- package/src/libs/common/domain/src/lib/model/search/aggregation.model.ts +2 -0
- package/src/libs/common/domain/src/lib/model/search/filter.model.ts +12 -2
- package/src/libs/common/domain/src/lib/platform.service.interface.ts +1 -0
- package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +20 -1
- package/src/libs/common/fixtures/src/lib/records.fixtures.ts +42 -62
- package/src/libs/feature/dataviz/src/lib/service/data.service.ts +32 -19
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-constraints/form-field-constraints.component.ts +3 -5
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.ts +2 -2
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-record-flags/form-field-record-flag-component.html +18 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-record-flags/form-field-record-flag-component.ts +86 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +100 -88
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +11 -4
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +18 -4
- package/src/libs/feature/editor/src/lib/expressions.ts +67 -0
- package/src/libs/feature/editor/src/lib/fields.config.ts +13 -0
- package/src/libs/feature/editor/src/lib/models/editor-config.model.ts +10 -4
- package/src/libs/feature/map/src/index.ts +0 -2
- package/src/libs/feature/map/src/lib/feature-map.module.ts +1 -8
- package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.ts +8 -3
- package/src/libs/feature/record/src/lib/state/mdview.effects.ts +3 -1
- package/src/libs/feature/record/src/lib/state/mdview.facade.ts +1 -1
- package/src/libs/feature/search/src/index.ts +2 -0
- package/src/libs/feature/search/src/lib/filter-dropdown/filter-dropdown.component.html +7 -1
- package/src/libs/feature/search/src/lib/filter-dropdown/filter-dropdown.component.ts +26 -4
- package/src/libs/feature/search/src/lib/geocoding/geocoding.service.ts +105 -0
- package/src/libs/feature/search/src/lib/location-search/location-search.component.html +18 -0
- package/src/libs/feature/search/src/lib/location-search/location-search.component.ts +114 -0
- package/src/libs/feature/search/src/lib/search-filters-summary-item/search-filters-summary-item.component.ts +1 -0
- package/src/libs/feature/search/src/lib/state/reducer.ts +1 -4
- package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +56 -4
- package/src/libs/feature/search/src/lib/utils/service/fields.ts +58 -16
- package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.html +3 -3
- package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.ts +2 -2
- package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.ts +2 -1
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.css +0 -4
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.html +12 -3
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +11 -3
- package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html +7 -4
- package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.ts +12 -9
- package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.model.ts +2 -2
- package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.ts +2 -1
- package/src/libs/ui/inputs/src/lib/spatial-extent-dropdown/spatial-extent-dropdown.component.html +8 -2
- package/src/libs/ui/inputs/src/lib/spatial-extent-dropdown/spatial-extent-dropdown.component.ts +34 -5
- package/src/libs/ui/layout/src/lib/block-list/block-list.component.css +1 -0
- package/src/libs/util/app-config/src/lib/app-config.ts +34 -0
- package/src/libs/util/app-config/src/lib/fixtures.ts +37 -1
- package/src/libs/util/app-config/src/lib/model.ts +24 -1
- package/src/libs/util/shared/src/lib/links/link-utils.ts +19 -10
- package/src/libs/util/shared/src/lib/utils/geojson.ts +16 -0
- package/translations/de.json +12 -2
- package/translations/en.json +14 -4
- package/translations/es.json +12 -2
- package/translations/fr.json +19 -9
- package/translations/it.json +12 -2
- package/translations/nl.json +12 -2
- package/translations/pt.json +12 -2
- package/translations/sk.json +12 -2
- package/src/libs/feature/map/src/lib/geocoding/geocoding.component.html +0 -41
- package/src/libs/feature/map/src/lib/geocoding/geocoding.component.ts +0 -112
- package/src/libs/feature/map/src/lib/geocoding.service.ts +0 -57
- package/src/libs/feature/map/src/lib/style/index.ts +0 -2
- package/src/libs/feature/map/src/lib/style/map-style.fixtures.ts +0 -47
- package/src/libs/feature/map/src/lib/style/map-style.service.ts +0 -108
- /package/src/libs/feature/{map/src/lib/geocoding/geocoding.component.css → editor/src/lib/components/record-form/form-field/form-field-record-flags/form-field-record-flag-component.css} +0 -0
|
@@ -6,7 +6,7 @@ import GeoJSON from 'ol/format/GeoJSON.js';
|
|
|
6
6
|
import { parse as parse$1 } from 'ol/xml.js';
|
|
7
7
|
import { format } from 'date-fns/format';
|
|
8
8
|
import { Namespace, Literal, lit, parse as parse$2, sym, BlankNode, graph } from 'rdflib';
|
|
9
|
-
import { lastValueFrom, fromEvent, startWith, map as map$2, shareReplay, filter, pairwise, of, switchMap, Subject, forkJoin, combineLatest, from, exhaustMap, throwError, takeLast, firstValueFrom, merge, BehaviorSubject, timer, ReplaySubject, Subscription, first, distinctUntilChanged as distinctUntilChanged$1, animationFrameScheduler, debounceTime as debounceTime$1, Observable, buffer, tap as tap$2, combineLatestWith, take as take$1, catchError as catchError$1,
|
|
9
|
+
import { lastValueFrom, fromEvent, startWith, map as map$2, shareReplay, filter, pairwise, of, switchMap, Subject, forkJoin, combineLatest, from, exhaustMap, throwError, takeLast, firstValueFrom, merge, BehaviorSubject, timer, ReplaySubject, Subscription, first, distinctUntilChanged as distinctUntilChanged$1, animationFrameScheduler, debounceTime as debounceTime$1, Observable, buffer, tap as tap$2, combineLatestWith, take as take$1, catchError as catchError$1, EMPTY, mergeMap as mergeMap$1, withLatestFrom as withLatestFrom$1, takeUntil } from 'rxjs';
|
|
10
10
|
import * as i0 from '@angular/core';
|
|
11
11
|
import { InjectionToken, inject, Injectable, NgModule, Injector, provideAppInitializer, makeEnvironmentProviders, ElementRef, afterNextRender, booleanAttribute, Input, Directive, HostListener, Renderer2, DestroyRef, EventEmitter, Output, ViewChild, ChangeDetectionStrategy, Component, ViewEncapsulation, ChangeDetectorRef, HostBinding, ViewContainerRef, TemplateRef, ViewChildren, ContentChild, input, output, signal, viewChild, computed, ContentChildren, NgZone, ComponentFactoryResolver, viewChildren } from '@angular/core';
|
|
12
12
|
import { HttpClient, HttpHeaders, HttpParams, HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi, HttpEventType } from '@angular/common/http';
|
|
@@ -14,7 +14,7 @@ import * as i4 from '@ngx-translate/core';
|
|
|
14
14
|
import { TranslateLoader, TranslateCompiler, TranslateDefaultParser, TranslateParser, TranslateService, provideTranslateService, TranslateDirective, TranslatePipe, TranslateModule } from '@ngx-translate/core';
|
|
15
15
|
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
|
|
16
16
|
import { TranslateHttpLoader, TRANSLATE_HTTP_LOADER_CONFIG } from '@ngx-translate/http-loader';
|
|
17
|
-
import { map as map$1, shareReplay as shareReplay$1, catchError, tap as tap$1, filter as filter$1, startWith as startWith$1,
|
|
17
|
+
import { map as map$1, shareReplay as shareReplay$1, catchError, tap as tap$1, withLatestFrom, filter as filter$1, startWith as startWith$1, switchMap as switchMap$1, take, mergeMap, delay, debounceTime, distinctUntilChanged, finalize, throttleTime, first as first$1, pairwise as pairwise$1, share, defaultIfEmpty, toArray } from 'rxjs/operators';
|
|
18
18
|
import { lt, valid, coerce, satisfies, ltr } from 'semver';
|
|
19
19
|
import chroma from 'chroma-js';
|
|
20
20
|
import * as i1$1 from '@angular/common';
|
|
@@ -26,7 +26,6 @@ import { getLength } from 'ol/sphere.js';
|
|
|
26
26
|
import { LineString } from 'ol/geom.js';
|
|
27
27
|
import * as i1 from '@ngrx/store';
|
|
28
28
|
import { createAction, props, createReducer, on, createFeatureSelector, createSelector, Store, select, StoreModule } from '@ngrx/store';
|
|
29
|
-
import { queryDataGouvFr, queryGeonames, queryGeoadmin } from '@geospatial-sdk/geocoding';
|
|
30
29
|
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
31
30
|
import { FeaturesClickEventType, FeaturesHoverEventType, MapClickEventType, MapExtentChangeEventType, SourceLoadErrorType, computeMapContextDiff, createViewFromLayer } from '@geospatial-sdk/core';
|
|
32
31
|
import { createMapFromContext, applyContextDiffToMap, listen } from '@geospatial-sdk/openlayers';
|
|
@@ -37,11 +36,8 @@ import { createLegendFromLayer } from '@geospatial-sdk/legend';
|
|
|
37
36
|
import { mouseOnly, noModifierKeys, primaryAction, platformModifierKeyOnly } from 'ol/events/condition.js';
|
|
38
37
|
import { defaults, DragPan, MouseWheelZoom } from 'ol/interaction.js';
|
|
39
38
|
import { extend } from 'ol/extent.js';
|
|
40
|
-
import * as TOML from '@ltd/j-toml';
|
|
41
|
-
import { Style, Stroke, Fill, Circle } from 'ol/style.js';
|
|
42
|
-
import CircleStyle from 'ol/style/Circle.js';
|
|
43
39
|
import EmblaCarousel from 'embla-carousel';
|
|
44
|
-
import { iconoirNavArrowLeft, iconoirNavArrowRight, iconoirLongArrowDownLeft, iconoirSearch, iconoirCalendar, iconoirArrowUp, iconoirLink, iconoirFramePlusIn, iconoirCloudUpload, iconoirTrash, iconoirSquareDashed,
|
|
40
|
+
import { iconoirNavArrowLeft, iconoirNavArrowRight, iconoirLongArrowDownLeft, iconoirSearch, iconoirCalendar, iconoirArrowUp, iconoirLink, iconoirFramePlusIn, iconoirCloudUpload, iconoirUpload, iconoirTrash, iconoirSquareDashed, iconoirCheckCircle, iconoirReduce, iconoirNavArrowUp, iconoirNavArrowDown, iconoirExpand, iconoirSettings, iconoirDownload, iconoirPlus, iconoirBin, iconoirMediaImageXmark, iconoirMediaImage, iconoirAppWindow, iconoirCode, iconoirDatabase, iconoirAppleWallet, iconoirBank, iconoirList, iconoirTranslate, iconoirLock, iconoirUser, iconoirArrowLeft, iconoirLightBulbOn, iconoirImport, iconoirBadgeCheck, iconoirSystemShut, iconoirCircle, iconoirAttachment, iconoirRefresh } from '@ng-icons/iconoir';
|
|
45
41
|
import { MatButtonModule } from '@angular/material/button';
|
|
46
42
|
import * as i1$7 from '@angular/cdk/overlay';
|
|
47
43
|
import { ScrollStrategyOptions, OverlayModule, CdkConnectedOverlay, ScrollDispatcher, Overlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
|
|
@@ -56,7 +52,7 @@ import { matClose, matContentCopy, matExpandMore, matExpandLess, matSearch, matS
|
|
|
56
52
|
import * as i1$4 from '@angular/material/checkbox';
|
|
57
53
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
58
54
|
import * as i1$5 from '@angular/material/tooltip';
|
|
59
|
-
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
55
|
+
import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
|
|
60
56
|
import { MAT_DATE_LOCALE, MAT_DATE_FORMATS, DateAdapter } from '@angular/material/core';
|
|
61
57
|
import { MAT_DATE_FNS_FORMATS, DateFnsAdapter } from '@angular/material-date-fns-adapter';
|
|
62
58
|
import { enUS } from 'date-fns/locale/en-US';
|
|
@@ -74,6 +70,8 @@ import { MatTabsModule } from '@angular/material/tabs';
|
|
|
74
70
|
import * as i2$2 from '@ngrx/effects';
|
|
75
71
|
import { Actions, createEffect, ofType, EffectsModule } from '@ngrx/effects';
|
|
76
72
|
import { valid as valid$1 } from 'geojson-validation';
|
|
73
|
+
import { queryGeoplateforme, queryGeonames, queryGeoadmin } from '@geospatial-sdk/geocoding';
|
|
74
|
+
import pointer from 'jsonpointer';
|
|
77
75
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
78
76
|
import { parse as parse$3 } from 'marked';
|
|
79
77
|
import * as i2$3 from '@angular/cdk/scrolling';
|
|
@@ -101,6 +99,7 @@ import { TextFieldModule } from '@angular/cdk/text-field';
|
|
|
101
99
|
import * as i2$5 from '@ngrx/router-store';
|
|
102
100
|
import { getRouterSelectors, routerReducer, StoreRouterConnectingModule, FullRouterStateSerializer } from '@ngrx/router-store';
|
|
103
101
|
import { navigation } from '@ngrx/router-store/data-persistence';
|
|
102
|
+
import * as TOML from '@ltd/j-toml';
|
|
104
103
|
|
|
105
104
|
class MetadataMapperContext {
|
|
106
105
|
}
|
|
@@ -1139,7 +1138,7 @@ function kindToCodeListValue(record) {
|
|
|
1139
1138
|
}
|
|
1140
1139
|
|
|
1141
1140
|
function extractCharacterString() {
|
|
1142
|
-
return pipe(fallback(findChildElement('gco:CharacterString', false), findChildElement('gmx:Anchor', false), findChildElement('gmx:MimeFileType', false)), readText());
|
|
1141
|
+
return pipe(fallback(findChildElement('gco:CharacterString', false), findChildElement('gmx:Anchor', false), findChildElement('gmx:MimeFileType', false), findChildElement('gco:LocalName', false)), readText());
|
|
1143
1142
|
}
|
|
1144
1143
|
/**
|
|
1145
1144
|
* Translated values will also be collected in the translations object
|
|
@@ -2202,6 +2201,7 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2202
2201
|
lineage: readLineage$1,
|
|
2203
2202
|
sourceRecords: readSourceRecords$1,
|
|
2204
2203
|
associatedRecords: readAssociatedRecords$1,
|
|
2204
|
+
featureTypeDescriptions: () => undefined,
|
|
2205
2205
|
onlineResources: readOnlineResources$2,
|
|
2206
2206
|
temporalExtents: readTemporalExtents,
|
|
2207
2207
|
spatialExtents: readSpatialExtents$1,
|
|
@@ -2241,6 +2241,7 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2241
2241
|
lineage: writeLineage$1,
|
|
2242
2242
|
sourceRecords: writeSourceRecords$1,
|
|
2243
2243
|
associatedRecords: writeAssociatedRecords$1,
|
|
2244
|
+
featureTypeDescriptions: () => undefined,
|
|
2244
2245
|
onlineResources: writeOnlineResources$1,
|
|
2245
2246
|
temporalExtents: writeTemporalExtents,
|
|
2246
2247
|
spatialExtents: writeSpatialExtents,
|
|
@@ -2367,6 +2368,7 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2367
2368
|
const sourceRecords = this.readers['sourceRecords'](rootEl, tr);
|
|
2368
2369
|
const associatedRecords = this.readers['associatedRecords'](rootEl, tr);
|
|
2369
2370
|
const updateFrequency = this.readers['updateFrequency'](rootEl, tr);
|
|
2371
|
+
const featureTypeDescriptions = this.readers['featureTypeDescriptions'](rootEl, tr);
|
|
2370
2372
|
return this.afterRecordRead({
|
|
2371
2373
|
...this.readBaseRecord(rootEl, tr),
|
|
2372
2374
|
kind,
|
|
@@ -2377,6 +2379,7 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2377
2379
|
...(spatialRepresentation && { spatialRepresentation }),
|
|
2378
2380
|
temporalExtents,
|
|
2379
2381
|
updateFrequency,
|
|
2382
|
+
...(featureTypeDescriptions?.length && { featureTypeDescriptions }),
|
|
2380
2383
|
translations: tr,
|
|
2381
2384
|
});
|
|
2382
2385
|
}
|
|
@@ -2466,6 +2469,8 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2466
2469
|
this.writers['resourceIdentifiers'](record, rootEl);
|
|
2467
2470
|
if (record.kind === 'dataset') {
|
|
2468
2471
|
fieldChanged('status') && this.writers['status'](record, rootEl);
|
|
2472
|
+
fieldChanged('featureTypeDescriptions') &&
|
|
2473
|
+
this.writers['featureTypeDescriptions'](record, rootEl);
|
|
2469
2474
|
}
|
|
2470
2475
|
if (record.kind === 'dataset' || record.kind === 'reuse') {
|
|
2471
2476
|
fieldChanged('updateFrequency') &&
|
|
@@ -2633,6 +2638,34 @@ function readDefaultLanguage$1(rootEl) {
|
|
|
2633
2638
|
function readOtherLanguages(rootEl) {
|
|
2634
2639
|
return pipe(findChildrenElement('mdb:otherLocale', false), mapArray(readLocaleElement()), map((languages) => languages.filter((lang) => lang !== null)))(rootEl);
|
|
2635
2640
|
}
|
|
2641
|
+
function extractCharacterStringOrText() {
|
|
2642
|
+
return fallback(extractCharacterString(), readText());
|
|
2643
|
+
}
|
|
2644
|
+
function extractListedValue() {
|
|
2645
|
+
return pipe(combine(pipe(findChildElement('gfc:code', false), extractCharacterString()), pipe(findChildElement('gfc:label', false), extractCharacterString()), pipe(findChildElement('gfc:definition', false), extractCharacterString())), map(([code, label, description]) => ({
|
|
2646
|
+
value: code ?? '',
|
|
2647
|
+
...(label && { label }),
|
|
2648
|
+
...(description && { description }),
|
|
2649
|
+
})));
|
|
2650
|
+
}
|
|
2651
|
+
function extractFeatureAttribute() {
|
|
2652
|
+
return pipe(combine(pipe(findChildElement('gfc:memberName', false), extractCharacterStringOrText()), pipe(findChildElement('gfc:designation', false), extractCharacterString()), pipe(findChildElement('gfc:definition', false), extractCharacterString()), pipe(findChildElement('gfc:code', false), extractCharacterString()), pipe(findNestedElement('gfc:valueType', 'gco:TypeName', 'gco:aName'), extractCharacterString()), pipe(findNestedElements('gfc:listedValue', 'gfc:FC_ListedValue'), mapArray(extractListedValue()), filterArray((value) => !!(value.value || value.label)))), map(([name, label, description, code, type, values]) => ({
|
|
2653
|
+
name: name ?? '',
|
|
2654
|
+
...(label && { label }),
|
|
2655
|
+
...(description && { description }),
|
|
2656
|
+
...(code && { code }),
|
|
2657
|
+
...(type && { type }),
|
|
2658
|
+
...(values.length > 0 && { values }),
|
|
2659
|
+
})));
|
|
2660
|
+
}
|
|
2661
|
+
function readFeatureTypeDescriptions(rootEl) {
|
|
2662
|
+
return pipe(findNestedElements('mdb:contentInfo', 'mrc:MD_FeatureCatalogue', 'mrc:featureCatalogue', 'gfc:FC_FeatureCatalogue', 'gfc:featureType', 'gfc:FC_FeatureType'), mapArray(pipe(combine(pipe(findChildElement('gfc:typeName', false), extractCharacterStringOrText()), pipe(findChildElement('gfc:designation', false), extractCharacterString()), pipe(findChildElement('gfc:definition', false), extractCharacterString()), pipe(findNestedElements('gfc:carrierOfCharacteristics', 'gfc:FC_FeatureAttribute'), mapArray(extractFeatureAttribute()))), map(([name, label, description, attributes]) => ({
|
|
2663
|
+
name: name ?? '',
|
|
2664
|
+
...(label && { label }),
|
|
2665
|
+
...(description && { description }),
|
|
2666
|
+
attributes,
|
|
2667
|
+
})))))(rootEl);
|
|
2668
|
+
}
|
|
2636
2669
|
|
|
2637
2670
|
function writeUniqueIdentifier$1(record, rootEl) {
|
|
2638
2671
|
pipe(findNestedChildOrCreate('mdb:metadataIdentifier', 'mcc:MD_Identifier', 'mcc:code'), writeCharacterString(record.uniqueIdentifier))(rootEl);
|
|
@@ -2787,6 +2820,52 @@ function writeAssociatedRecords(record, rootEl) {
|
|
|
2787
2820
|
.filter((assoc) => assoc.uniqueIdentifier && assoc.associationType)
|
|
2788
2821
|
.map((assoc) => pipe(createNestedElement('mri:associatedResource', 'mri:MD_AssociatedResource'), appendChildren(pipe(createNestedElement('mri:associationType', 'mri:DS_AssociationTypeCode'), writeAttribute('codeList', 'http://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#DS_AssociationTypeCode'), writeAttribute('codeListValue', assoc.associationType)), pipe(createElement('mri:metadataReference'), writeAttribute('uuidref', assoc.uniqueIdentifier)))))))(rootEl);
|
|
2789
2822
|
}
|
|
2823
|
+
function createNilElement(name, nilReason) {
|
|
2824
|
+
return pipe(createElement(name), writeAttribute('gco:nilReason', nilReason));
|
|
2825
|
+
}
|
|
2826
|
+
function createFeatureCatalogueShell() {
|
|
2827
|
+
return pipe(createNestedElement('mdb:contentInfo', 'mrc:MD_FeatureCatalogue', 'mrc:featureCatalogue', 'gfc:FC_FeatureCatalogue'),
|
|
2828
|
+
// create mandatory elements which are not part of the model yet
|
|
2829
|
+
appendChildren(createNilElement('cat:name', 'missing'), createNilElement('cat:scope', 'missing'), createNilElement('cat:versionNumber', 'missing'), createNilElement('cat:versionDate', 'missing'), createNilElement('gfc:producer', 'missing')));
|
|
2830
|
+
}
|
|
2831
|
+
function createListedValue(value) {
|
|
2832
|
+
return pipe(createNestedElement('gfc:listedValue', 'gfc:FC_ListedValue'), appendChildren(value.label
|
|
2833
|
+
? pipe(createElement('gfc:label'), writeCharacterString(value.label))
|
|
2834
|
+
: createNilElement('gfc:label', 'missing'), value.value
|
|
2835
|
+
? pipe(createElement('gfc:code'), writeCharacterString(value.value))
|
|
2836
|
+
: null, value.description
|
|
2837
|
+
? pipe(createElement('gfc:definition'), writeCharacterString(value.description))
|
|
2838
|
+
: null));
|
|
2839
|
+
}
|
|
2840
|
+
function createFeatureAttribute(attribute) {
|
|
2841
|
+
return pipe(createNestedElement('gfc:carrierOfCharacteristics', 'gfc:FC_FeatureAttribute'), appendChildren(pipe(createElement('gfc:memberName'), setTextContent(attribute.name)), attribute.description
|
|
2842
|
+
? pipe(createElement('gfc:definition'), writeCharacterString(attribute.description))
|
|
2843
|
+
: null, createNilElement('gfc:cardinality', 'missing'), attribute.label
|
|
2844
|
+
? pipe(createElement('gfc:designation'), writeCharacterString(attribute.label))
|
|
2845
|
+
: null, attribute.code
|
|
2846
|
+
? pipe(createElement('gfc:code'), writeCharacterString(attribute.code))
|
|
2847
|
+
: null, attribute.type
|
|
2848
|
+
? pipe(createNestedElement('gfc:valueType', 'gco:TypeName', 'gco:aName'), writeCharacterString(attribute.type))
|
|
2849
|
+
: null, ...(attribute.values ?? [])
|
|
2850
|
+
.filter((value) => value.value || value.label)
|
|
2851
|
+
.map(createListedValue)));
|
|
2852
|
+
}
|
|
2853
|
+
function createFeatureType(featureType) {
|
|
2854
|
+
return pipe(createNestedElement('gfc:featureType', 'gfc:FC_FeatureType'), appendChildren(pipe(createElement('gfc:typeName'), setTextContent(featureType.name)), featureType.description
|
|
2855
|
+
? pipe(createElement('gfc:definition'), writeCharacterString(featureType.description))
|
|
2856
|
+
: null, pipe(createNestedElement('gfc:isAbstract', 'gco:Boolean'), setTextContent('false')), featureType.label
|
|
2857
|
+
? pipe(createElement('gfc:designation'), writeCharacterString(featureType.label))
|
|
2858
|
+
: null, ...featureType.attributes.map(createFeatureAttribute), createNilElement('gfc:featureCatalogue', 'missing')));
|
|
2859
|
+
}
|
|
2860
|
+
function writeFeatureTypeDescriptions(record, rootEl) {
|
|
2861
|
+
const featureTypes = record.featureTypeDescriptions ?? [];
|
|
2862
|
+
const catalogues = findNestedElements('mdb:contentInfo', 'mrc:MD_FeatureCatalogue', 'mrc:featureCatalogue', 'gfc:FC_FeatureCatalogue')(rootEl);
|
|
2863
|
+
catalogues.forEach((catalogue) => removeChildrenByName('gfc:featureType')(catalogue));
|
|
2864
|
+
if (!featureTypes.length)
|
|
2865
|
+
return;
|
|
2866
|
+
const catalogue = catalogues[0] ?? appendChildTree(createFeatureCatalogueShell())(rootEl);
|
|
2867
|
+
appendChildren(...featureTypes.map(createFeatureType))(catalogue);
|
|
2868
|
+
}
|
|
2790
2869
|
|
|
2791
2870
|
class Iso191153Converter extends Iso19139Converter {
|
|
2792
2871
|
constructor() {
|
|
@@ -2803,6 +2882,7 @@ class Iso191153Converter extends Iso19139Converter {
|
|
|
2803
2882
|
this.readers['lineage'] = readLineage;
|
|
2804
2883
|
this.readers['sourceRecords'] = readSourceRecords;
|
|
2805
2884
|
this.readers['associatedRecords'] = readAssociatedRecords;
|
|
2885
|
+
this.readers['featureTypeDescriptions'] = readFeatureTypeDescriptions;
|
|
2806
2886
|
this.readers['onlineResources'] = readOnlineResources$1;
|
|
2807
2887
|
this.readers['defaultLanguage'] = readDefaultLanguage$1;
|
|
2808
2888
|
this.readers['otherLanguages'] = readOtherLanguages;
|
|
@@ -2823,6 +2903,7 @@ class Iso191153Converter extends Iso19139Converter {
|
|
|
2823
2903
|
this.writers['lineage'] = writeLineage;
|
|
2824
2904
|
this.writers['sourceRecords'] = writeSourceRecords;
|
|
2825
2905
|
this.writers['associatedRecords'] = writeAssociatedRecords;
|
|
2906
|
+
this.writers['featureTypeDescriptions'] = writeFeatureTypeDescriptions;
|
|
2826
2907
|
this.writers['onlineResources'] = writeOnlineResources;
|
|
2827
2908
|
this.writers['status'] = writeStatus;
|
|
2828
2909
|
this.writers['spatialRepresentation'] = writeSpatialRepresentation;
|
|
@@ -2912,10 +2993,12 @@ class Iso191153Converter extends Iso19139Converter {
|
|
|
2912
2993
|
});
|
|
2913
2994
|
}
|
|
2914
2995
|
async writeRecord(record, reference) {
|
|
2915
|
-
|
|
2916
|
-
// fix gco namespace
|
|
2917
|
-
|
|
2918
|
-
return result
|
|
2996
|
+
const result = await super.writeRecord(record, reference);
|
|
2997
|
+
// fix the gco and gfc namespace definitions (they change between iso19139 and iso19115-3);
|
|
2998
|
+
// only on the root element, where they are declared, so that nested declarations stay untouched
|
|
2999
|
+
return result.replace(/<mdb:MD_Metadata[^>]*>/, (rootTag) => rootTag
|
|
3000
|
+
.replace('"http://www.isotc211.org/2005/gco"', '"http://standards.iso.org/iso/19115/-3/gco/1.0"')
|
|
3001
|
+
.replace('"http://www.isotc211.org/2005/gfc"', '"http://standards.iso.org/iso/19110/gfc/1.1"'));
|
|
2919
3002
|
}
|
|
2920
3003
|
}
|
|
2921
3004
|
|
|
@@ -3459,6 +3542,7 @@ class DcatApConverter extends BaseConverter {
|
|
|
3459
3542
|
lineage: () => '',
|
|
3460
3543
|
sourceRecords: () => [],
|
|
3461
3544
|
associatedRecords: () => [],
|
|
3545
|
+
featureTypeDescriptions: () => undefined,
|
|
3462
3546
|
temporalExtents: () => [],
|
|
3463
3547
|
spatialRepresentation: () => undefined,
|
|
3464
3548
|
extras: () => undefined,
|
|
@@ -3494,6 +3578,7 @@ class DcatApConverter extends BaseConverter {
|
|
|
3494
3578
|
lineage: () => undefined,
|
|
3495
3579
|
sourceRecords: () => [],
|
|
3496
3580
|
associatedRecords: () => [],
|
|
3581
|
+
featureTypeDescriptions: () => undefined,
|
|
3497
3582
|
onlineResources: () => undefined,
|
|
3498
3583
|
temporalExtents: () => undefined,
|
|
3499
3584
|
spatialExtents: () => undefined,
|
|
@@ -18904,9 +18989,15 @@ class Gn4FieldMapper {
|
|
|
18904
18989
|
isOpenData: (output, source) => this.addExtra({
|
|
18905
18990
|
isOpenData: selectField(source, 'isOpenData') !== 'false',
|
|
18906
18991
|
}, output),
|
|
18907
|
-
featureTypes: (output, source) =>
|
|
18908
|
-
featureTypes
|
|
18909
|
-
|
|
18992
|
+
featureTypes: (output, source) => {
|
|
18993
|
+
const featureTypes = getAsArray(selectField(source, 'featureTypes'));
|
|
18994
|
+
if (!featureTypes.length)
|
|
18995
|
+
return output;
|
|
18996
|
+
return {
|
|
18997
|
+
...output,
|
|
18998
|
+
featureTypeDescriptions: this.featureTypesField(featureTypes),
|
|
18999
|
+
};
|
|
19000
|
+
},
|
|
18910
19001
|
related: (output, source) => {
|
|
18911
19002
|
const related = selectField(source, 'related');
|
|
18912
19003
|
const fcatSource = selectField(getFirstValue(selectField(related, 'fcats')) ?? {}, '_source');
|
|
@@ -19042,6 +19133,27 @@ class Gn4FieldMapper {
|
|
|
19042
19133
|
},
|
|
19043
19134
|
};
|
|
19044
19135
|
this.genericField = (output) => output;
|
|
19136
|
+
this.featureTypesField = (featureTypes) => featureTypes.map((featureType) => ({
|
|
19137
|
+
name: featureType.typeName ?? '',
|
|
19138
|
+
...(featureType.definition && {
|
|
19139
|
+
description: featureType.definition,
|
|
19140
|
+
}),
|
|
19141
|
+
attributes: getAsArray(featureType.attributeTable ?? []).map((attr) => {
|
|
19142
|
+
const values = (attr.values ?? [])
|
|
19143
|
+
.filter((value) => value.code || value.label)
|
|
19144
|
+
.map((value) => ({
|
|
19145
|
+
value: value.code || '',
|
|
19146
|
+
...(value.label && { label: value.label }),
|
|
19147
|
+
}));
|
|
19148
|
+
return {
|
|
19149
|
+
name: attr.name ?? '',
|
|
19150
|
+
...(attr.definition && { description: attr.definition }),
|
|
19151
|
+
...(attr.code && { code: attr.code }),
|
|
19152
|
+
...(attr.type && { type: attr.type }),
|
|
19153
|
+
...(values.length > 0 && { values }),
|
|
19154
|
+
};
|
|
19155
|
+
}),
|
|
19156
|
+
}));
|
|
19045
19157
|
this.constraintField = (type, output, constraintArray) => {
|
|
19046
19158
|
let outputField;
|
|
19047
19159
|
switch (type) {
|
|
@@ -19596,6 +19708,19 @@ function isBoundingBox(value) {
|
|
|
19596
19708
|
value.length === 4 &&
|
|
19597
19709
|
value.every((item) => typeof item === 'number'));
|
|
19598
19710
|
}
|
|
19711
|
+
/**
|
|
19712
|
+
* Checks that a bounding box's coordinates stay within the valid
|
|
19713
|
+
* longitude (-180/180) and latitude (-90/90) ranges.
|
|
19714
|
+
*/
|
|
19715
|
+
function isBoundingBoxWithinWorldExtent(bbox) {
|
|
19716
|
+
const [minX, minY, maxX, maxY] = bbox;
|
|
19717
|
+
return (minX >= -180 &&
|
|
19718
|
+
maxX <= 180 &&
|
|
19719
|
+
minY >= -90 &&
|
|
19720
|
+
maxY <= 90 &&
|
|
19721
|
+
minX <= maxX &&
|
|
19722
|
+
minY <= maxY);
|
|
19723
|
+
}
|
|
19599
19724
|
function getGeometryBoundingBox(geometry) {
|
|
19600
19725
|
// use the bounding box if specified in the GeoJSON object
|
|
19601
19726
|
if (geometry.bbox) {
|
|
@@ -20264,7 +20389,7 @@ function getLinkLabel(link) {
|
|
|
20264
20389
|
const label = link.description || ('name' in link ? link.name : '');
|
|
20265
20390
|
return format ? `${label} (${format})` : label;
|
|
20266
20391
|
}
|
|
20267
|
-
async function getLayers(url, serviceProtocol) {
|
|
20392
|
+
async function getLayers(url, serviceProtocol, deep = false) {
|
|
20268
20393
|
switch (serviceProtocol) {
|
|
20269
20394
|
case 'ogcFeatures': {
|
|
20270
20395
|
const layers = await new OgcApiEndpoint(url).allCollections;
|
|
@@ -20272,7 +20397,10 @@ async function getLayers(url, serviceProtocol) {
|
|
|
20272
20397
|
}
|
|
20273
20398
|
case 'wfs': {
|
|
20274
20399
|
const endpointWfs = await new WfsEndpoint(url).isReady();
|
|
20275
|
-
const featureTypes =
|
|
20400
|
+
const featureTypes = endpointWfs.getFeatureTypes();
|
|
20401
|
+
if (!deep) {
|
|
20402
|
+
return featureTypes;
|
|
20403
|
+
}
|
|
20276
20404
|
const layers = (await Promise.allSettled(featureTypes.map((collection) => {
|
|
20277
20405
|
return endpointWfs.getFeatureTypeFull(collection.name);
|
|
20278
20406
|
})))
|
|
@@ -20282,12 +20410,14 @@ async function getLayers(url, serviceProtocol) {
|
|
|
20282
20410
|
}
|
|
20283
20411
|
case 'wms': {
|
|
20284
20412
|
const endpointWms = await new WmsEndpoint(url).isReady();
|
|
20285
|
-
const
|
|
20413
|
+
const layersSummary = endpointWms
|
|
20286
20414
|
.getLayers()
|
|
20287
20415
|
.flatMap(wmsLayerFlatten)
|
|
20288
|
-
.filter((l) => l.name)
|
|
20289
|
-
|
|
20290
|
-
|
|
20416
|
+
.filter((l) => l.name);
|
|
20417
|
+
if (!deep) {
|
|
20418
|
+
return layersSummary;
|
|
20419
|
+
}
|
|
20420
|
+
const layers = layersSummary.map((collection) => endpointWms.getLayerByName(collection.name));
|
|
20291
20421
|
return layers;
|
|
20292
20422
|
}
|
|
20293
20423
|
case 'wmts': {
|
|
@@ -20434,7 +20564,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
20434
20564
|
}] } });
|
|
20435
20565
|
|
|
20436
20566
|
var name = "geonetwork-ui";
|
|
20437
|
-
var version = "2.11.0-dev.
|
|
20567
|
+
var version = "2.11.0-dev.fb48cfeee";
|
|
20438
20568
|
var engines = {
|
|
20439
20569
|
node: ">=24"
|
|
20440
20570
|
};
|
|
@@ -20476,10 +20606,10 @@ var dependencies = {
|
|
|
20476
20606
|
"@biesbjerg/ngx-translate-extract-marker": "~1.0.0",
|
|
20477
20607
|
"@camptocamp/ogc-client": "1.3.1-dev.200c02a",
|
|
20478
20608
|
"@duckdb/duckdb-wasm": "~1.32.0",
|
|
20479
|
-
"@geospatial-sdk/core": "0.0.5-dev.
|
|
20480
|
-
"@geospatial-sdk/geocoding": "0.0.5-dev.
|
|
20481
|
-
"@geospatial-sdk/legend": "0.0.5-dev.
|
|
20482
|
-
"@geospatial-sdk/openlayers": "0.0.5-dev.
|
|
20609
|
+
"@geospatial-sdk/core": "0.0.5-dev.86.sha-124eae3",
|
|
20610
|
+
"@geospatial-sdk/geocoding": "0.0.5-dev.86.sha-124eae3",
|
|
20611
|
+
"@geospatial-sdk/legend": "0.0.5-dev.86.sha-124eae3",
|
|
20612
|
+
"@geospatial-sdk/openlayers": "0.0.5-dev.86.sha-124eae3",
|
|
20483
20613
|
"@ltd/j-toml": "~1.38.0",
|
|
20484
20614
|
"@messageformat/core": "~3.4.0",
|
|
20485
20615
|
"@ng-icons/core": "~32.5.0",
|
|
@@ -20496,6 +20626,7 @@ var dependencies = {
|
|
|
20496
20626
|
"embla-carousel": "~8.6.0",
|
|
20497
20627
|
"flag-icons": "~7.5.0",
|
|
20498
20628
|
"geojson-validation": "~1.0.2",
|
|
20629
|
+
jsonpointer: "^5.0.1",
|
|
20499
20630
|
marked: "~17.0.4",
|
|
20500
20631
|
"ngx-dropzone": "~3.1.0",
|
|
20501
20632
|
"ngx-translate-messageformat-compiler": "~7.2.0",
|
|
@@ -20672,6 +20803,7 @@ class ElasticsearchService {
|
|
|
20672
20803
|
// runtime fields are computed using a Painless script
|
|
20673
20804
|
// see: https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-mapping-fields.html
|
|
20674
20805
|
this.runtimeFields = {};
|
|
20806
|
+
this.fieldAliases = {};
|
|
20675
20807
|
}
|
|
20676
20808
|
// we're using getters in case the defined languages change over time
|
|
20677
20809
|
get metadataLang() {
|
|
@@ -20743,6 +20875,9 @@ class ElasticsearchService {
|
|
|
20743
20875
|
registerRuntimeField(fieldName, expression, type = 'keyword') {
|
|
20744
20876
|
this.runtimeFields[fieldName] = { script: expression, type };
|
|
20745
20877
|
}
|
|
20878
|
+
registerFieldAlias(fieldIdentifier, esFieldName) {
|
|
20879
|
+
this.fieldAliases[fieldIdentifier] = esFieldName;
|
|
20880
|
+
}
|
|
20746
20881
|
getMetadataByIdsPayload(uuids) {
|
|
20747
20882
|
return {
|
|
20748
20883
|
query: {
|
|
@@ -20864,6 +20999,55 @@ class ElasticsearchService {
|
|
|
20864
20999
|
}
|
|
20865
21000
|
return Object.values(filters).find(isBoundingBox);
|
|
20866
21001
|
}
|
|
21002
|
+
// builds a query matching records whose dates intersect the filter range
|
|
21003
|
+
buildDateRangeQuery(searchField, dateRange) {
|
|
21004
|
+
// fields ending with 'DateRange' maps as ES range type
|
|
21005
|
+
if (searchField.endsWith('DateRange')) {
|
|
21006
|
+
return {
|
|
21007
|
+
range: {
|
|
21008
|
+
[searchField]: {
|
|
21009
|
+
...(dateRange.start && { gte: formatDate(dateRange.start) }),
|
|
21010
|
+
...(dateRange.end && { lte: formatDate(dateRange.end) }),
|
|
21011
|
+
format: 'yyyy-MM-dd',
|
|
21012
|
+
relation: 'intersects',
|
|
21013
|
+
},
|
|
21014
|
+
},
|
|
21015
|
+
};
|
|
21016
|
+
}
|
|
21017
|
+
const minField = `${searchField}Min`;
|
|
21018
|
+
const maxField = `${searchField}Max`;
|
|
21019
|
+
if (minField in this.runtimeFields && maxField in this.runtimeFields) {
|
|
21020
|
+
// min/max runtime fields form an interval per record; match if it intersects the filter range
|
|
21021
|
+
const filter = [
|
|
21022
|
+
dateRange.start && {
|
|
21023
|
+
range: {
|
|
21024
|
+
[maxField]: {
|
|
21025
|
+
gte: formatDate(dateRange.start),
|
|
21026
|
+
format: 'yyyy-MM-dd',
|
|
21027
|
+
},
|
|
21028
|
+
},
|
|
21029
|
+
},
|
|
21030
|
+
dateRange.end && {
|
|
21031
|
+
range: {
|
|
21032
|
+
[minField]: {
|
|
21033
|
+
lte: formatDate(dateRange.end),
|
|
21034
|
+
format: 'yyyy-MM-dd',
|
|
21035
|
+
},
|
|
21036
|
+
},
|
|
21037
|
+
},
|
|
21038
|
+
].filter(Boolean);
|
|
21039
|
+
return { bool: { filter } };
|
|
21040
|
+
}
|
|
21041
|
+
return {
|
|
21042
|
+
range: {
|
|
21043
|
+
[searchField]: {
|
|
21044
|
+
...(dateRange.start && { gte: formatDate(dateRange.start) }),
|
|
21045
|
+
...(dateRange.end && { lte: formatDate(dateRange.end) }),
|
|
21046
|
+
format: 'yyyy-MM-dd',
|
|
21047
|
+
},
|
|
21048
|
+
},
|
|
21049
|
+
};
|
|
21050
|
+
}
|
|
20867
21051
|
filtersToQuery(filters, spatialFilterExtent = this.findSpatialFilterExtent(filters)) {
|
|
20868
21052
|
const addQuote = (key) => (/^\/.+\/$/.test(key) ? key : `"${key}"`);
|
|
20869
21053
|
const makeQuery = (filter) => {
|
|
@@ -20888,7 +21072,7 @@ class ElasticsearchService {
|
|
|
20888
21072
|
.filter((fieldname) => !Array.isArray(filters[fieldname]))
|
|
20889
21073
|
.filter((fieldname) => filters[fieldname] &&
|
|
20890
21074
|
JSON.stringify(filters[fieldname]) !== '{}')
|
|
20891
|
-
.map((fieldname) => `${fieldname}:(${makeQuery(filters[fieldname])})`)
|
|
21075
|
+
.map((fieldname) => `${this.fieldAliases[fieldname] ?? fieldname}:(${makeQuery(filters[fieldname])})`)
|
|
20892
21076
|
.join(' AND ');
|
|
20893
21077
|
if (filters['gn-ui-crossFieldFilter']) {
|
|
20894
21078
|
queryString = `${queryString} AND (${filters['gn-ui-crossFieldFilter']})`;
|
|
@@ -20900,15 +21084,7 @@ class ElasticsearchService {
|
|
|
20900
21084
|
query: queryString,
|
|
20901
21085
|
},
|
|
20902
21086
|
},
|
|
20903
|
-
...queryRanges.map(([searchField, dateRange]) => (
|
|
20904
|
-
range: {
|
|
20905
|
-
[searchField]: {
|
|
20906
|
-
...(dateRange.start && { gte: formatDate(dateRange.start) }),
|
|
20907
|
-
...(dateRange.end && { lte: formatDate(dateRange.end) }),
|
|
20908
|
-
format: 'yyyy-MM-dd',
|
|
20909
|
-
},
|
|
20910
|
-
},
|
|
20911
|
-
})),
|
|
21087
|
+
...queryRanges.map(([searchField, dateRange]) => this.buildDateRangeQuery(searchField, dateRange)),
|
|
20912
21088
|
spatialFilterExtent && {
|
|
20913
21089
|
geo_shape: {
|
|
20914
21090
|
geom: {
|
|
@@ -21194,6 +21370,12 @@ class ElasticsearchService {
|
|
|
21194
21370
|
order: {
|
|
21195
21371
|
[`_${aggregation.sort[1]}`]: aggregation.sort[0],
|
|
21196
21372
|
},
|
|
21373
|
+
...(aggregation.includeValues && {
|
|
21374
|
+
include: aggregation.includeValues,
|
|
21375
|
+
}),
|
|
21376
|
+
...(aggregation.excludeValues && {
|
|
21377
|
+
exclude: aggregation.excludeValues,
|
|
21378
|
+
}),
|
|
21197
21379
|
},
|
|
21198
21380
|
};
|
|
21199
21381
|
case 'histogram':
|
|
@@ -21295,10 +21477,21 @@ class Gn4Repository {
|
|
|
21295
21477
|
this.platformService = inject(PlatformServiceInterface);
|
|
21296
21478
|
this.gn4LanguagesApi = inject(LanguagesApiService);
|
|
21297
21479
|
this.settingsService = inject(Gn4SettingsService);
|
|
21480
|
+
this.gn4TagsApi = inject(TagsApiService);
|
|
21298
21481
|
this.disableDraft = inject(DISABLE_DRAFT, { optional: true }) ?? false;
|
|
21299
21482
|
this.defaultConverter = inject(DEFAULT_RECORD_CONVERTER);
|
|
21300
21483
|
this._draftsChanged = new Subject();
|
|
21301
21484
|
this.draftsChanged$ = this._draftsChanged.asObservable();
|
|
21485
|
+
/*
|
|
21486
|
+
* FLAGS
|
|
21487
|
+
* Note: in GN4 API, categories are named "tags"
|
|
21488
|
+
*/
|
|
21489
|
+
this.categoriesIdentifierForFlags = this.gn4TagsApi.getTags().pipe(map$1((categories) => categories.reduce((acc, category) => {
|
|
21490
|
+
if (category.name.startsWith('geonetwork-ui-flag:')) {
|
|
21491
|
+
acc[category.name.replace(/^geonetwork-ui-flag:/, '')] = category.id;
|
|
21492
|
+
}
|
|
21493
|
+
return acc;
|
|
21494
|
+
}, {})), shareReplay$1(1));
|
|
21302
21495
|
}
|
|
21303
21496
|
search({ filters, fields, offset, limit, sort, filterIds, filterGeometry, }) {
|
|
21304
21497
|
return this.gn4SearchApi
|
|
@@ -21328,42 +21521,16 @@ class Gn4Repository {
|
|
|
21328
21521
|
? this.gn4Mapper.readRecords(records)
|
|
21329
21522
|
: of(null)));
|
|
21330
21523
|
}
|
|
21331
|
-
|
|
21332
|
-
return {
|
|
21333
|
-
featureTypes: featureTypes.map((featureType) => ({
|
|
21334
|
-
name: featureType.typeName || '',
|
|
21335
|
-
definition: featureType.definition || '',
|
|
21336
|
-
attributes: Array.isArray(featureType.attributeTable)
|
|
21337
|
-
? featureType.attributeTable.map((attr) => {
|
|
21338
|
-
const values = attr.values
|
|
21339
|
-
?.filter((v) => v.code || v.label)
|
|
21340
|
-
.map((v) => ({
|
|
21341
|
-
code: v.code,
|
|
21342
|
-
label: v.label,
|
|
21343
|
-
}));
|
|
21344
|
-
return {
|
|
21345
|
-
name: attr.name,
|
|
21346
|
-
code: attr.code,
|
|
21347
|
-
definition: attr.definition,
|
|
21348
|
-
type: attr.type,
|
|
21349
|
-
...(values?.length > 0 ? { values } : {}),
|
|
21350
|
-
};
|
|
21351
|
-
})
|
|
21352
|
-
: [],
|
|
21353
|
-
})),
|
|
21354
|
-
};
|
|
21355
|
-
}
|
|
21356
|
-
getFeatureCatalog(record, visited = new Set() // prevent looping
|
|
21524
|
+
queryLinkedFeatureCatalog(record, visited = new Set() // prevent looping
|
|
21357
21525
|
) {
|
|
21358
|
-
if (
|
|
21359
|
-
|
|
21360
|
-
record.
|
|
21361
|
-
return of(this.mapEmbeddedFeatureCatalog(record.extras['featureTypes']));
|
|
21526
|
+
if ('featureTypeDescriptions' in record &&
|
|
21527
|
+
record.featureTypeDescriptions?.length > 0) {
|
|
21528
|
+
return of({ featureTypes: record.featureTypeDescriptions });
|
|
21362
21529
|
}
|
|
21363
21530
|
const featureCatalogIdentifier = record.extras['featureCatalogIdentifier'];
|
|
21364
21531
|
if (featureCatalogIdentifier && !visited.has(featureCatalogIdentifier)) {
|
|
21365
21532
|
visited.add(featureCatalogIdentifier);
|
|
21366
|
-
return this.getRecord(featureCatalogIdentifier).pipe(switchMap((record) => record ? this.
|
|
21533
|
+
return this.getRecord(featureCatalogIdentifier).pipe(switchMap((record) => record ? this.queryLinkedFeatureCatalog(record, visited) : of(null)));
|
|
21367
21534
|
}
|
|
21368
21535
|
return of(null);
|
|
21369
21536
|
}
|
|
@@ -21626,6 +21793,32 @@ class Gn4Repository {
|
|
|
21626
21793
|
removeRecordFromLocalStorage(recordId) {
|
|
21627
21794
|
window.localStorage.removeItem(this.getLocalStorageKeyForRecord(recordId));
|
|
21628
21795
|
}
|
|
21796
|
+
getCategoryIdForFlag(flagName) {
|
|
21797
|
+
return this.categoriesIdentifierForFlags.pipe(map$1((categories) => {
|
|
21798
|
+
const categoryId = categories[flagName];
|
|
21799
|
+
if (categoryId === undefined) {
|
|
21800
|
+
console.warn(`The record flag ${flagName} is not created on GeoNetwork backend; please create a category with the name geonetwork-ui-flag:${flagName} for this to work.`);
|
|
21801
|
+
return null;
|
|
21802
|
+
}
|
|
21803
|
+
return categoryId;
|
|
21804
|
+
}));
|
|
21805
|
+
}
|
|
21806
|
+
setRecordFlag(uniqueIdentifier, flagName, value) {
|
|
21807
|
+
return this.getCategoryIdForFlag(flagName).pipe(switchMap((categoryId) => {
|
|
21808
|
+
if (categoryId === null)
|
|
21809
|
+
return of();
|
|
21810
|
+
return value
|
|
21811
|
+
? this.gn4RecordsApi.tagRecord(uniqueIdentifier, [categoryId], false)
|
|
21812
|
+
: this.gn4RecordsApi.deleteTags(uniqueIdentifier, [categoryId]);
|
|
21813
|
+
}));
|
|
21814
|
+
}
|
|
21815
|
+
getRecordFlag(uniqueIdentifier, flagName) {
|
|
21816
|
+
return this.gn4RecordsApi.getRecordTags(uniqueIdentifier).pipe(withLatestFrom(this.getCategoryIdForFlag(flagName)), map$1(([tags, categoryId]) => {
|
|
21817
|
+
if (categoryId === null)
|
|
21818
|
+
return false;
|
|
21819
|
+
return Array.from(tags).some((tag) => tag.id === categoryId);
|
|
21820
|
+
}));
|
|
21821
|
+
}
|
|
21629
21822
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: Gn4Repository, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21630
21823
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: Gn4Repository }); }
|
|
21631
21824
|
}
|
|
@@ -22241,6 +22434,9 @@ class Gn4PlatformService {
|
|
|
22241
22434
|
this.me$ = this.disableAuth
|
|
22242
22435
|
? of(null)
|
|
22243
22436
|
: of(true).pipe(switchMap(() => this.meApi.getMe()), switchMap((apiUser) => this.mapper.userFromMeApi(apiUser)), shareReplay$1({ bufferSize: 1, refCount: true }));
|
|
22437
|
+
this.isAdmin$ = this.disableAuth
|
|
22438
|
+
? of(false)
|
|
22439
|
+
: of(true).pipe(switchMap(() => this.meApi.getMe()), map$1((apiUser) => !!apiUser?.admin), shareReplay$1({ bufferSize: 1, refCount: true }));
|
|
22244
22440
|
/**
|
|
22245
22441
|
* A map of already loaded thesauri (groups of keywords); the key is a URI
|
|
22246
22442
|
* @private
|
|
@@ -22276,6 +22472,9 @@ class Gn4PlatformService {
|
|
|
22276
22472
|
isAnonymous() {
|
|
22277
22473
|
return this.isUserAnonymous$;
|
|
22278
22474
|
}
|
|
22475
|
+
isAdministrator() {
|
|
22476
|
+
return this.isAdmin$;
|
|
22477
|
+
}
|
|
22279
22478
|
getOrganizations() {
|
|
22280
22479
|
return undefined;
|
|
22281
22480
|
}
|
|
@@ -22582,48 +22781,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
22582
22781
|
type: Injectable
|
|
22583
22782
|
}] });
|
|
22584
22783
|
|
|
22585
|
-
const GEOCODING_PROVIDER = new InjectionToken('geocoding-provider');
|
|
22586
|
-
class GeocodingService {
|
|
22587
|
-
constructor() {
|
|
22588
|
-
this.provider = inject(GEOCODING_PROVIDER);
|
|
22589
|
-
}
|
|
22590
|
-
query(text) {
|
|
22591
|
-
let queryObservable;
|
|
22592
|
-
switch (this.provider[0]) {
|
|
22593
|
-
case 'geoadmin':
|
|
22594
|
-
queryObservable = from(queryGeoadmin(text, this.provider[1]));
|
|
22595
|
-
break;
|
|
22596
|
-
case 'geonames':
|
|
22597
|
-
queryObservable = from(queryGeonames(text, this.provider[1]));
|
|
22598
|
-
break;
|
|
22599
|
-
case 'data-gouv-fr':
|
|
22600
|
-
queryObservable = from(queryDataGouvFr(text, this.provider[1]));
|
|
22601
|
-
break;
|
|
22602
|
-
default:
|
|
22603
|
-
return throwError(() => new Error(`Unsupported geocoding provider: ${this.provider[0]}`));
|
|
22604
|
-
}
|
|
22605
|
-
return queryObservable.pipe(catchError((error) => throwError(error)));
|
|
22606
|
-
}
|
|
22607
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
22608
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, providedIn: 'root' }); }
|
|
22609
|
-
}
|
|
22610
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, decorators: [{
|
|
22611
|
-
type: Injectable,
|
|
22612
|
-
args: [{
|
|
22613
|
-
providedIn: 'root',
|
|
22614
|
-
}]
|
|
22615
|
-
}] });
|
|
22616
|
-
|
|
22617
22784
|
class FeatureMapModule {
|
|
22618
22785
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
22619
22786
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, imports: [i1.StoreFeatureModule] }); }
|
|
22620
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, providers: [
|
|
22621
|
-
MapFacade,
|
|
22622
|
-
{
|
|
22623
|
-
provide: GEOCODING_PROVIDER,
|
|
22624
|
-
useValue: ['geonames', { maxRows: 5 }],
|
|
22625
|
-
},
|
|
22626
|
-
], imports: [StoreModule.forFeature(MAP_FEATURE_KEY, mapReducer)] }); }
|
|
22787
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, providers: [MapFacade], imports: [StoreModule.forFeature(MAP_FEATURE_KEY, mapReducer)] }); }
|
|
22627
22788
|
}
|
|
22628
22789
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, decorators: [{
|
|
22629
22790
|
type: NgModule,
|
|
@@ -22631,13 +22792,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
22631
22792
|
imports: [
|
|
22632
22793
|
StoreModule.forFeature(MAP_FEATURE_KEY, mapReducer),
|
|
22633
22794
|
],
|
|
22634
|
-
providers: [
|
|
22635
|
-
MapFacade,
|
|
22636
|
-
{
|
|
22637
|
-
provide: GEOCODING_PROVIDER,
|
|
22638
|
-
useValue: ['geonames', { maxRows: 5 }],
|
|
22639
|
-
},
|
|
22640
|
-
],
|
|
22795
|
+
providers: [MapFacade],
|
|
22641
22796
|
}]
|
|
22642
22797
|
}] });
|
|
22643
22798
|
|
|
@@ -23080,1082 +23235,374 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
23080
23235
|
}]
|
|
23081
23236
|
}] });
|
|
23082
23237
|
|
|
23083
|
-
|
|
23084
|
-
|
|
23085
|
-
|
|
23086
|
-
|
|
23087
|
-
|
|
23238
|
+
class AnchorLinkDirective {
|
|
23239
|
+
constructor() {
|
|
23240
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
23241
|
+
this.disabled = false;
|
|
23242
|
+
this.observer = new MutationObserver(() => {
|
|
23243
|
+
this.refreshDisabledState();
|
|
23244
|
+
});
|
|
23245
|
+
this.inView = false;
|
|
23246
|
+
this.initialized = false;
|
|
23088
23247
|
}
|
|
23089
|
-
|
|
23090
|
-
|
|
23091
|
-
|
|
23092
|
-
|
|
23093
|
-
|
|
23248
|
+
get elementClass() {
|
|
23249
|
+
if (this.disabled) {
|
|
23250
|
+
return this.disabledClass;
|
|
23251
|
+
}
|
|
23252
|
+
if (this.inView) {
|
|
23253
|
+
return `${this.inViewClass} ${this.enabledClass}`;
|
|
23254
|
+
}
|
|
23255
|
+
else {
|
|
23256
|
+
return `${this.outOfViewClass} ${this.enabledClass}`;
|
|
23257
|
+
}
|
|
23094
23258
|
}
|
|
23095
|
-
|
|
23096
|
-
|
|
23259
|
+
ngOnInit() {
|
|
23260
|
+
this.observer.observe(document.body, {
|
|
23261
|
+
childList: true,
|
|
23262
|
+
subtree: true,
|
|
23263
|
+
});
|
|
23264
|
+
this.refreshDisabledState();
|
|
23097
23265
|
}
|
|
23098
|
-
|
|
23099
|
-
|
|
23100
|
-
|
|
23101
|
-
|
|
23102
|
-
|
|
23103
|
-
|
|
23104
|
-
|
|
23105
|
-
|
|
23106
|
-
};
|
|
23107
|
-
};
|
|
23108
|
-
/**
|
|
23109
|
-
* Only keeps recognized keys, flatten nested values (to allow having "." in keys),
|
|
23110
|
-
* pushes warnings and errors to the given arrays; returns null in case of error
|
|
23111
|
-
*/
|
|
23112
|
-
function parseConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
23113
|
-
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
23114
|
-
if (mandatoryKeys.length === 0)
|
|
23115
|
-
return null;
|
|
23116
|
-
outErrors.push(`The [${sectionName}] mandatory section is missing.`);
|
|
23117
|
-
return null;
|
|
23266
|
+
ngAfterViewChecked() {
|
|
23267
|
+
if (!this.initialized && !this.disabled) {
|
|
23268
|
+
const target = document.getElementById(this.targetId);
|
|
23269
|
+
if (target) {
|
|
23270
|
+
this.initializeIntersectionObserver(target);
|
|
23271
|
+
this.initialized = true;
|
|
23272
|
+
}
|
|
23273
|
+
}
|
|
23118
23274
|
}
|
|
23119
|
-
|
|
23120
|
-
|
|
23121
|
-
|
|
23122
|
-
|
|
23123
|
-
|
|
23124
|
-
|
|
23275
|
+
initializeIntersectionObserver(target) {
|
|
23276
|
+
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
23277
|
+
entries.forEach((entry) => {
|
|
23278
|
+
this.inView = entry.isIntersecting;
|
|
23279
|
+
this.changeDetector.detectChanges();
|
|
23280
|
+
});
|
|
23281
|
+
}, {
|
|
23282
|
+
root: null,
|
|
23283
|
+
rootMargin: '-30% 0% -60% 0%',
|
|
23284
|
+
});
|
|
23285
|
+
this.intersectionObserver.observe(target);
|
|
23125
23286
|
}
|
|
23126
|
-
|
|
23127
|
-
|
|
23128
|
-
|
|
23287
|
+
ngOnDestroy() {
|
|
23288
|
+
this.observer.disconnect();
|
|
23289
|
+
if (this.intersectionObserver) {
|
|
23290
|
+
this.intersectionObserver.disconnect();
|
|
23291
|
+
}
|
|
23129
23292
|
}
|
|
23130
|
-
|
|
23293
|
+
refreshDisabledState() {
|
|
23294
|
+
const targetNotPresent = !document.getElementById(this.targetId);
|
|
23295
|
+
if (targetNotPresent !== this.disabled) {
|
|
23296
|
+
this.disabled = targetNotPresent;
|
|
23297
|
+
this.changeDetector.detectChanges();
|
|
23298
|
+
}
|
|
23299
|
+
}
|
|
23300
|
+
scrollToTarget() {
|
|
23301
|
+
const target = document.getElementById(this.targetId);
|
|
23302
|
+
if (!target)
|
|
23303
|
+
return;
|
|
23304
|
+
target.scrollIntoView({
|
|
23305
|
+
behavior: 'smooth',
|
|
23306
|
+
block: 'start',
|
|
23307
|
+
});
|
|
23308
|
+
}
|
|
23309
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
23310
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: AnchorLinkDirective, isStandalone: true, selector: "[gnUiAnchorLink]", inputs: { targetId: ["gnUiAnchorLink", "targetId"], disabledClass: ["gnUiAnchorLinkDisabledClass", "disabledClass"], enabledClass: ["gnUiAnchorLinkEnabledClass", "enabledClass"], inViewClass: ["gnUiAnchorLinkInViewClass", "inViewClass"], outOfViewClass: ["gnUiAnchorLinkOutOfViewClass", "outOfViewClass"] }, host: { listeners: { "click": "scrollToTarget()" }, properties: { "class": "this.elementClass" } }, ngImport: i0 }); }
|
|
23131
23311
|
}
|
|
23132
|
-
|
|
23133
|
-
|
|
23134
|
-
|
|
23135
|
-
|
|
23136
|
-
|
|
23137
|
-
|
|
23138
|
-
|
|
23139
|
-
|
|
23312
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, decorators: [{
|
|
23313
|
+
type: Directive,
|
|
23314
|
+
args: [{
|
|
23315
|
+
selector: '[gnUiAnchorLink]',
|
|
23316
|
+
standalone: true,
|
|
23317
|
+
}]
|
|
23318
|
+
}], propDecorators: { targetId: [{
|
|
23319
|
+
type: Input,
|
|
23320
|
+
args: ['gnUiAnchorLink']
|
|
23321
|
+
}], disabledClass: [{
|
|
23322
|
+
type: Input,
|
|
23323
|
+
args: ['gnUiAnchorLinkDisabledClass']
|
|
23324
|
+
}], enabledClass: [{
|
|
23325
|
+
type: Input,
|
|
23326
|
+
args: ['gnUiAnchorLinkEnabledClass']
|
|
23327
|
+
}], inViewClass: [{
|
|
23328
|
+
type: Input,
|
|
23329
|
+
args: ['gnUiAnchorLinkInViewClass']
|
|
23330
|
+
}], outOfViewClass: [{
|
|
23331
|
+
type: Input,
|
|
23332
|
+
args: ['gnUiAnchorLinkOutOfViewClass']
|
|
23333
|
+
}], elementClass: [{
|
|
23334
|
+
type: HostBinding,
|
|
23335
|
+
args: ['class']
|
|
23336
|
+
}], scrollToTarget: [{
|
|
23337
|
+
type: HostListener,
|
|
23338
|
+
args: ['click']
|
|
23339
|
+
}] } });
|
|
23340
|
+
|
|
23341
|
+
class PaginationDotsComponent {
|
|
23342
|
+
constructor() {
|
|
23343
|
+
this.containerClass = '';
|
|
23140
23344
|
}
|
|
23141
|
-
|
|
23345
|
+
// 1-based
|
|
23346
|
+
get steps() {
|
|
23347
|
+
return Array.from({ length: this.listComponent.pagesCount }, (_, i) => i + 1);
|
|
23348
|
+
}
|
|
23349
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23350
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: PaginationDotsComponent, isStandalone: true, selector: "gn-ui-pagination-dots", inputs: { listComponent: "listComponent", containerClass: "containerClass" }, ngImport: i0, template: "@if (listComponent.pagesCount > 1) {\n <div\n class=\"overflow-hidden flex flex-row justify-center gap-[14px] p-1\"\n [ngClass]=\"containerClass\"\n >\n @for (step of steps; track step) {\n <button\n type=\"button\"\n class=\"pagination-dot\"\n (click)=\"listComponent.goToPage(step)\"\n [ngClass]=\"\n listComponent.currentPage === step ? 'bg-primary' : 'bg-gray-400'\n \"\n ></button>\n }\n </div>\n}\n", styles: [".pagination-dot{width:6px;height:6px;border-radius:6px;position:relative;flex-shrink:0}.pagination-dot:after{content:\"\";position:absolute;left:-7px;top:-7px;width:20px;height:20px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], viewProviders: [
|
|
23351
|
+
provideIcons({
|
|
23352
|
+
iconoirNavArrowRight,
|
|
23353
|
+
iconoirNavArrowLeft,
|
|
23354
|
+
}),
|
|
23355
|
+
] }); }
|
|
23142
23356
|
}
|
|
23143
|
-
|
|
23144
|
-
|
|
23145
|
-
|
|
23146
|
-
|
|
23147
|
-
|
|
23148
|
-
|
|
23149
|
-
|
|
23150
|
-
|
|
23151
|
-
|
|
23357
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, decorators: [{
|
|
23358
|
+
type: Component,
|
|
23359
|
+
args: [{ selector: 'gn-ui-pagination-dots', standalone: true, imports: [CommonModule], viewProviders: [
|
|
23360
|
+
provideIcons({
|
|
23361
|
+
iconoirNavArrowRight,
|
|
23362
|
+
iconoirNavArrowLeft,
|
|
23363
|
+
}),
|
|
23364
|
+
], template: "@if (listComponent.pagesCount > 1) {\n <div\n class=\"overflow-hidden flex flex-row justify-center gap-[14px] p-1\"\n [ngClass]=\"containerClass\"\n >\n @for (step of steps; track step) {\n <button\n type=\"button\"\n class=\"pagination-dot\"\n (click)=\"listComponent.goToPage(step)\"\n [ngClass]=\"\n listComponent.currentPage === step ? 'bg-primary' : 'bg-gray-400'\n \"\n ></button>\n }\n </div>\n}\n", styles: [".pagination-dot{width:6px;height:6px;border-radius:6px;position:relative;flex-shrink:0}.pagination-dot:after{content:\"\";position:absolute;left:-7px;top:-7px;width:20px;height:20px}\n"] }]
|
|
23365
|
+
}], propDecorators: { listComponent: [{
|
|
23366
|
+
type: Input
|
|
23367
|
+
}], containerClass: [{
|
|
23368
|
+
type: Input
|
|
23369
|
+
}] } });
|
|
23370
|
+
|
|
23371
|
+
class CarouselComponent {
|
|
23372
|
+
constructor() {
|
|
23373
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
23374
|
+
this.containerClass = '';
|
|
23375
|
+
this.stepsContainerClass = 'w-full bottom-0 top-auto';
|
|
23376
|
+
this.currentStepChange = new EventEmitter();
|
|
23377
|
+
this.steps = [];
|
|
23378
|
+
this.currentStep = 0;
|
|
23379
|
+
this.refreshSteps = () => {
|
|
23380
|
+
this.steps = this.emblaApi.scrollSnapList();
|
|
23381
|
+
this.currentStep = this.emblaApi.selectedScrollSnap();
|
|
23382
|
+
this.currentStepChange.emit(this.currentStep);
|
|
23383
|
+
this.changeDetector.detectChanges();
|
|
23384
|
+
};
|
|
23152
23385
|
}
|
|
23153
|
-
|
|
23154
|
-
|
|
23155
|
-
return
|
|
23386
|
+
// Paginable API
|
|
23387
|
+
get isFirstPage() {
|
|
23388
|
+
return this.currentStep === 0;
|
|
23156
23389
|
}
|
|
23157
|
-
|
|
23158
|
-
|
|
23159
|
-
return null;
|
|
23390
|
+
get isLastPage() {
|
|
23391
|
+
return this.currentStep === this.steps.length - 1;
|
|
23160
23392
|
}
|
|
23161
|
-
|
|
23162
|
-
|
|
23163
|
-
function checkMetadataLanguage(parsedConfigSection, outWarnings) {
|
|
23164
|
-
const lang2 = toLang2(parsedConfigSection.metadata_language.toLowerCase());
|
|
23165
|
-
if (lang2?.length !== 2) {
|
|
23166
|
-
outWarnings.push(`In the [global] section: metadata_language = "${parsedConfigSection.metadata_language}" is not a recognized ISO 639 language code`);
|
|
23393
|
+
get currentPage() {
|
|
23394
|
+
return this.currentStep + 1; // this is 1-based
|
|
23167
23395
|
}
|
|
23168
|
-
|
|
23169
|
-
|
|
23170
|
-
function checkNewRecordDefaultLanguage(parsedConfigSection, outWarnings) {
|
|
23171
|
-
const lang2 = toLang2(parsedConfigSection.new_record_default_language.toLowerCase());
|
|
23172
|
-
if (!(lang2 in LANG_2_TO_3_MAPPER)) {
|
|
23173
|
-
outWarnings.push(`In the [editing] section: new_record_default_language = "${parsedConfigSection.new_record_default_language}" is not a recognized ISO 639 language code`);
|
|
23174
|
-
return {
|
|
23175
|
-
...parsedConfigSection,
|
|
23176
|
-
new_record_default_language: undefined,
|
|
23177
|
-
};
|
|
23396
|
+
get pagesCount() {
|
|
23397
|
+
return this.steps.length;
|
|
23178
23398
|
}
|
|
23179
|
-
|
|
23180
|
-
|
|
23181
|
-
new_record_default_language: lang2,
|
|
23182
|
-
};
|
|
23183
|
-
}
|
|
23184
|
-
function checkNewRecordStandard(parsedConfigSection, outWarnings) {
|
|
23185
|
-
const standard = parsedConfigSection.new_record_standard;
|
|
23186
|
-
const normalizedStandard = typeof standard === 'string' ? standard.trim().toLowerCase() : null;
|
|
23187
|
-
if (normalizedStandard === 'iso19139' ||
|
|
23188
|
-
normalizedStandard === 'iso19115-3') {
|
|
23189
|
-
return {
|
|
23190
|
-
...parsedConfigSection,
|
|
23191
|
-
new_record_standard: normalizedStandard,
|
|
23192
|
-
};
|
|
23399
|
+
goToPage(stepIndex) {
|
|
23400
|
+
this.emblaApi.scrollTo(stepIndex - 1); // this is 0-based
|
|
23193
23401
|
}
|
|
23194
|
-
|
|
23195
|
-
|
|
23196
|
-
|
|
23197
|
-
|
|
23198
|
-
}
|
|
23402
|
+
goToPrevPage() {
|
|
23403
|
+
if (this.isFirstPage)
|
|
23404
|
+
return;
|
|
23405
|
+
this.emblaApi.scrollPrev();
|
|
23406
|
+
}
|
|
23407
|
+
goToNextPage() {
|
|
23408
|
+
if (this.isLastPage)
|
|
23409
|
+
return;
|
|
23410
|
+
this.emblaApi.scrollNext();
|
|
23411
|
+
}
|
|
23412
|
+
ngAfterViewInit() {
|
|
23413
|
+
this.emblaApi = EmblaCarousel(this.carouselOverflowContainer.nativeElement, {
|
|
23414
|
+
duration: 15,
|
|
23415
|
+
});
|
|
23416
|
+
this.emblaApi
|
|
23417
|
+
.on('init', this.refreshSteps)
|
|
23418
|
+
.on('reInit', this.refreshSteps)
|
|
23419
|
+
.on('select', this.refreshSteps);
|
|
23420
|
+
}
|
|
23421
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23422
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: CarouselComponent, isStandalone: true, selector: "gn-ui-carousel", inputs: { containerClass: "containerClass", stepsContainerClass: "stepsContainerClass" }, outputs: { currentStepChange: "currentStepChange" }, viewQueries: [{ propertyName: "carouselOverflowContainer", first: true, predicate: ["carouselOverflowContainer"], descendants: true }], ngImport: i0, template: "<div #carouselOverflowContainer class=\"w-full block\">\n <div class=\"carousel-container flex\" [ngClass]=\"containerClass\">\n <ng-content></ng-content>\n </div>\n</div>\n<gn-ui-pagination-dots\n [containerClass]=\"'absolute ' + stepsContainerClass\"\n [listComponent]=\"this\"\n></gn-ui-pagination-dots>\n", styles: [":host{position:relative}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PaginationDotsComponent, selector: "gn-ui-pagination-dots", inputs: ["listComponent", "containerClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
23199
23423
|
}
|
|
23424
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, decorators: [{
|
|
23425
|
+
type: Component,
|
|
23426
|
+
args: [{ selector: 'gn-ui-carousel', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, PaginationDotsComponent], template: "<div #carouselOverflowContainer class=\"w-full block\">\n <div class=\"carousel-container flex\" [ngClass]=\"containerClass\">\n <ng-content></ng-content>\n </div>\n</div>\n<gn-ui-pagination-dots\n [containerClass]=\"'absolute ' + stepsContainerClass\"\n [listComponent]=\"this\"\n></gn-ui-pagination-dots>\n", styles: [":host{position:relative}\n"] }]
|
|
23427
|
+
}], propDecorators: { carouselOverflowContainer: [{
|
|
23428
|
+
type: ViewChild,
|
|
23429
|
+
args: ['carouselOverflowContainer']
|
|
23430
|
+
}], containerClass: [{
|
|
23431
|
+
type: Input
|
|
23432
|
+
}], stepsContainerClass: [{
|
|
23433
|
+
type: Input
|
|
23434
|
+
}], currentStepChange: [{
|
|
23435
|
+
type: Output
|
|
23436
|
+
}] } });
|
|
23200
23437
|
|
|
23201
|
-
|
|
23202
|
-
|
|
23203
|
-
|
|
23204
|
-
|
|
23205
|
-
|
|
23206
|
-
|
|
23207
|
-
|
|
23208
|
-
|
|
23209
|
-
|
|
23210
|
-
|
|
23211
|
-
|
|
23212
|
-
|
|
23438
|
+
class ProgressBarComponent {
|
|
23439
|
+
constructor() {
|
|
23440
|
+
this.value = 0;
|
|
23441
|
+
this.type = 'default';
|
|
23442
|
+
}
|
|
23443
|
+
get progress() {
|
|
23444
|
+
return this.value > 0 ? (this.value < 100 ? this.value : 100) : 0;
|
|
23445
|
+
}
|
|
23446
|
+
get color() {
|
|
23447
|
+
switch (this.type) {
|
|
23448
|
+
case 'default':
|
|
23449
|
+
return {
|
|
23450
|
+
outerBar: 'bg-gray-200',
|
|
23451
|
+
innerBar: 'bg-gray-100',
|
|
23452
|
+
text: 'text-gray-900',
|
|
23453
|
+
};
|
|
23454
|
+
case 'primary':
|
|
23455
|
+
return {
|
|
23456
|
+
outerBar: 'bg-primary',
|
|
23457
|
+
innerBar: 'bg-primary-lighter',
|
|
23458
|
+
text: 'text-white',
|
|
23459
|
+
};
|
|
23460
|
+
case 'secondary':
|
|
23461
|
+
return {
|
|
23462
|
+
outerBar: 'bg-secondary',
|
|
23463
|
+
innerBar: 'bg-secondary-lighter',
|
|
23464
|
+
text: 'text-white',
|
|
23465
|
+
};
|
|
23466
|
+
case 'light':
|
|
23467
|
+
return {
|
|
23468
|
+
outerBar: 'bg-primary-white',
|
|
23469
|
+
innerBar: 'bg-primary',
|
|
23470
|
+
text: 'text-main',
|
|
23471
|
+
};
|
|
23472
|
+
}
|
|
23213
23473
|
}
|
|
23474
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23475
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: ProgressBarComponent, isStandalone: true, selector: "gn-ui-progress-bar", inputs: { value: "value", type: "type" }, ngImport: i0, template: "@switch (type) {\n <!-- Light Theme -->\n @case ('light') {\n <div class=\"flex items-center relative\">\n <div\n class=\"flex-shrink-0 {{ color.text }} font-medium mr-2\n text-opacity-100 !text-slate-800\"\n data-cy=\"progressPercentage\"\n >\n {{ progress }}%\n </div>\n <div class=\"flex-grow h-[4px] w-[52px] {{ color.outerBar }} rounded-full\">\n <div\n [style.width.%]=\"progress\"\n class=\"{{ color.innerBar }} transition-width duration-500\n ease-in-out rounded-full shadow-sm w-[52px] h-[4px]\"\n ></div>\n </div>\n </div>\n }\n <!-- Default / Primary / Secondary Themes -->\n @default {\n <div class=\"flex h-full {{ color.outerBar }} rounded-t-lg rounded-b-lg\">\n <div\n [style.width.%]=\"progress\"\n class=\"flex {{ color.innerBar }} my-1 mx-1 transition-width\n duration-500 ease-in-out rounded-t-md rounded-b-md shadow-xl\"\n >\n <div\n class=\"flex items-center pl-2 py-1 {{ color.text }} font-bold text-4\"\n >\n {{ progress }}%\n </div>\n </div>\n </div>\n }\n}\n", styles: [".font-bold{font-weight:var(--progress-bar-font-weight, \"bold\")}\n"] }); }
|
|
23214
23476
|
}
|
|
23477
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, decorators: [{
|
|
23478
|
+
type: Component,
|
|
23479
|
+
args: [{ selector: 'gn-ui-progress-bar', standalone: true, imports: [], template: "@switch (type) {\n <!-- Light Theme -->\n @case ('light') {\n <div class=\"flex items-center relative\">\n <div\n class=\"flex-shrink-0 {{ color.text }} font-medium mr-2\n text-opacity-100 !text-slate-800\"\n data-cy=\"progressPercentage\"\n >\n {{ progress }}%\n </div>\n <div class=\"flex-grow h-[4px] w-[52px] {{ color.outerBar }} rounded-full\">\n <div\n [style.width.%]=\"progress\"\n class=\"{{ color.innerBar }} transition-width duration-500\n ease-in-out rounded-full shadow-sm w-[52px] h-[4px]\"\n ></div>\n </div>\n </div>\n }\n <!-- Default / Primary / Secondary Themes -->\n @default {\n <div class=\"flex h-full {{ color.outerBar }} rounded-t-lg rounded-b-lg\">\n <div\n [style.width.%]=\"progress\"\n class=\"flex {{ color.innerBar }} my-1 mx-1 transition-width\n duration-500 ease-in-out rounded-t-md rounded-b-md shadow-xl\"\n >\n <div\n class=\"flex items-center pl-2 py-1 {{ color.text }} font-bold text-4\"\n >\n {{ progress }}%\n </div>\n </div>\n </div>\n }\n}\n", styles: [".font-bold{font-weight:var(--progress-bar-font-weight, \"bold\")}\n"] }]
|
|
23480
|
+
}], propDecorators: { value: [{
|
|
23481
|
+
type: Input
|
|
23482
|
+
}], type: [{
|
|
23483
|
+
type: Input
|
|
23484
|
+
}] } });
|
|
23215
23485
|
|
|
23216
|
-
|
|
23217
|
-
|
|
23218
|
-
|
|
23219
|
-
|
|
23220
|
-
|
|
23221
|
-
|
|
23222
|
-
|
|
23223
|
-
|
|
23224
|
-
|
|
23225
|
-
}
|
|
23226
|
-
|
|
23227
|
-
|
|
23228
|
-
|
|
23229
|
-
|
|
23230
|
-
|
|
23231
|
-
}
|
|
23232
|
-
|
|
23233
|
-
function getOptionalMapConfig() {
|
|
23234
|
-
return mapConfig;
|
|
23235
|
-
}
|
|
23236
|
-
let searchConfig = null;
|
|
23237
|
-
function getOptionalSearchConfig() {
|
|
23238
|
-
return searchConfig;
|
|
23239
|
-
}
|
|
23240
|
-
let editorConfig = null;
|
|
23241
|
-
function getOptionalEditorConfig() {
|
|
23242
|
-
return editorConfig;
|
|
23243
|
-
}
|
|
23244
|
-
let metadataQualityConfig = null;
|
|
23245
|
-
function getMetadataQualityConfig() {
|
|
23246
|
-
return (metadataQualityConfig ||
|
|
23247
|
-
{
|
|
23248
|
-
ENABLED: false,
|
|
23249
|
-
});
|
|
23250
|
-
}
|
|
23251
|
-
let customTranslations = null;
|
|
23252
|
-
function getCustomTranslations(langCode) {
|
|
23253
|
-
if (customTranslations === null)
|
|
23254
|
-
throw new Error(MISSING_CONFIG_ERROR);
|
|
23255
|
-
return langCode in customTranslations ? customTranslations[langCode] : {};
|
|
23256
|
-
}
|
|
23257
|
-
let appConfigLoaded = false;
|
|
23258
|
-
function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
|
|
23259
|
-
console.log(`[geonetwork-ui] Loading application configuration from ${configUrl}`);
|
|
23260
|
-
return fetch(configUrl)
|
|
23261
|
-
.then((resp) => {
|
|
23262
|
-
if (!resp.ok)
|
|
23263
|
-
throw new Error('Configuration file could not be loaded');
|
|
23264
|
-
return resp.text();
|
|
23265
|
-
})
|
|
23266
|
-
.then((conf) => {
|
|
23267
|
-
let parsed;
|
|
23268
|
-
try {
|
|
23269
|
-
parsed = TOML.parse(conf, { joiner: '\n', bigint: false });
|
|
23270
|
-
}
|
|
23271
|
-
catch (e) {
|
|
23272
|
-
throw new Error(`An error occurred when parsing the configuration file: ${e.message}`);
|
|
23273
|
-
}
|
|
23274
|
-
const errors = [];
|
|
23275
|
-
const warnings = [];
|
|
23276
|
-
let parsedGlobalSection = parseConfigSection(parsed, 'global', ['geonetwork4_api_url'], [
|
|
23277
|
-
'datahub_url',
|
|
23278
|
-
'edit_url_template',
|
|
23279
|
-
'proxy_path',
|
|
23280
|
-
'metadata_language',
|
|
23281
|
-
'login_url',
|
|
23282
|
-
'logout_url',
|
|
23283
|
-
'settings_url',
|
|
23284
|
-
'web_component_embedder_url',
|
|
23285
|
-
'languages',
|
|
23286
|
-
'contact_email',
|
|
23287
|
-
'reuse_form_url',
|
|
23288
|
-
], warnings, errors);
|
|
23289
|
-
if (parsedGlobalSection?.metadata_language) {
|
|
23290
|
-
parsedGlobalSection = checkMetadataLanguage(parsedGlobalSection, warnings);
|
|
23486
|
+
class PopoverComponent {
|
|
23487
|
+
constructor() {
|
|
23488
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
23489
|
+
this.renderer = inject(Renderer2);
|
|
23490
|
+
}
|
|
23491
|
+
getContent() {
|
|
23492
|
+
if (this.content instanceof TemplateRef) {
|
|
23493
|
+
if (this.view) {
|
|
23494
|
+
this.view.destroy();
|
|
23495
|
+
}
|
|
23496
|
+
this.view = this.viewContainerRef.createEmbeddedView(this.content);
|
|
23497
|
+
this.view.detectChanges();
|
|
23498
|
+
const wrapper = this.renderer.createElement('div'); // Create a wrapper div
|
|
23499
|
+
this.view.rootNodes.forEach((node) => {
|
|
23500
|
+
this.renderer.appendChild(wrapper, node); // Append each root node to the wrapper
|
|
23501
|
+
});
|
|
23502
|
+
return wrapper;
|
|
23291
23503
|
}
|
|
23292
|
-
|
|
23293
|
-
|
|
23294
|
-
|
|
23295
|
-
|
|
23296
|
-
|
|
23297
|
-
|
|
23298
|
-
|
|
23299
|
-
|
|
23300
|
-
|
|
23301
|
-
|
|
23302
|
-
|
|
23303
|
-
|
|
23304
|
-
|
|
23305
|
-
|
|
23306
|
-
|
|
23307
|
-
LANGUAGES: parsedGlobalSection.languages,
|
|
23308
|
-
CONTACT_EMAIL: parsedGlobalSection.contact_email,
|
|
23309
|
-
REUSE_FORM_URL: parsedGlobalSection.reuse_form_url,
|
|
23310
|
-
};
|
|
23311
|
-
const parsedLayersSections = parseMultiConfigSection(parsed, 'map_layer', ['type'], ['name', 'url', 'data', 'styleUrl', 'accessToken'], warnings, errors);
|
|
23312
|
-
const parsedMapSection = parseConfigSection(parsed, 'map', [], [
|
|
23313
|
-
'max_zoom',
|
|
23314
|
-
'do_not_tile_wms',
|
|
23315
|
-
'max_extent',
|
|
23316
|
-
'max_feature_count',
|
|
23317
|
-
'baselayer',
|
|
23318
|
-
'do_not_use_default_basemap',
|
|
23319
|
-
'external_viewer_url_template',
|
|
23320
|
-
'external_viewer_open_new_tab',
|
|
23321
|
-
], warnings, errors);
|
|
23322
|
-
mapConfig =
|
|
23323
|
-
parsedMapSection === null || parsedLayersSections === null
|
|
23324
|
-
? null
|
|
23325
|
-
: {
|
|
23326
|
-
MAX_ZOOM: parsedMapSection.max_zoom,
|
|
23327
|
-
DO_NOT_TILE_WMS: parsedMapSection.do_not_tile_wms,
|
|
23328
|
-
MAX_EXTENT: parsedMapSection.max_extent,
|
|
23329
|
-
MAX_FEATURE_COUNT: parsedMapSection.max_feature_count,
|
|
23330
|
-
EXTERNAL_VIEWER_URL_TEMPLATE: parsedMapSection.external_viewer_url_template,
|
|
23331
|
-
EXTERNAL_VIEWER_OPEN_NEW_TAB: parsedMapSection.external_viewer_open_new_tab,
|
|
23332
|
-
DO_NOT_USE_DEFAULT_BASEMAP: !!parsedMapSection.do_not_use_default_basemap,
|
|
23333
|
-
MAP_LAYERS: parsedLayersSections.map((map_layer) => ({
|
|
23334
|
-
TYPE: map_layer.type,
|
|
23335
|
-
URL: map_layer.url,
|
|
23336
|
-
NAME: map_layer.name,
|
|
23337
|
-
DATA: map_layer.data,
|
|
23338
|
-
STYLE_URL: map_layer.styleUrl,
|
|
23339
|
-
ACCESS_TOKEN: map_layer.accessToken,
|
|
23340
|
-
})),
|
|
23341
|
-
};
|
|
23342
|
-
const parsedThemeSection = parseConfigSection(parsed, 'theme', ['primary_color', 'secondary_color', 'main_color', 'background_color'], [
|
|
23343
|
-
'header_foreground_color',
|
|
23344
|
-
'main_font',
|
|
23345
|
-
'title_font',
|
|
23346
|
-
'fonts_stylesheet_url',
|
|
23347
|
-
'thumbnail_placeholder',
|
|
23348
|
-
'header_background',
|
|
23349
|
-
'favicon',
|
|
23350
|
-
], warnings, errors);
|
|
23351
|
-
themeConfig =
|
|
23352
|
-
parsedThemeSection === null
|
|
23353
|
-
? null
|
|
23354
|
-
: {
|
|
23355
|
-
PRIMARY_COLOR: parsedThemeSection.primary_color,
|
|
23356
|
-
SECONDARY_COLOR: parsedThemeSection.secondary_color,
|
|
23357
|
-
MAIN_COLOR: parsedThemeSection.main_color,
|
|
23358
|
-
BACKGROUND_COLOR: parsedThemeSection.background_color,
|
|
23359
|
-
HEADER_FOREGROUND_COLOR: parsedThemeSection.header_foreground_color,
|
|
23360
|
-
THUMBNAIL_PLACEHOLDER: parsedThemeSection.thumbnail_placeholder,
|
|
23361
|
-
HEADER_BACKGROUND: parsedThemeSection.header_background,
|
|
23362
|
-
TITLE_FONT: parsedThemeSection.title_font,
|
|
23363
|
-
MAIN_FONT: parsedThemeSection.main_font,
|
|
23364
|
-
FONTS_STYLESHEET_URL: parsedThemeSection.fonts_stylesheet_url,
|
|
23365
|
-
FAVICON: parsedThemeSection.favicon,
|
|
23366
|
-
};
|
|
23367
|
-
const parsedSearchSection = parseConfigSection(parsed, 'search', [], [
|
|
23368
|
-
'record_kind_quick_filter',
|
|
23369
|
-
'filter_geometry_data',
|
|
23370
|
-
'filter_geometry_url',
|
|
23371
|
-
'do_not_use_default_search_preset',
|
|
23372
|
-
'search_preset',
|
|
23373
|
-
'advanced_filters',
|
|
23374
|
-
'limit',
|
|
23375
|
-
'spatial_extent_max_file_size',
|
|
23376
|
-
], warnings, errors);
|
|
23377
|
-
const parsedSearchParams = parseMultiConfigSection(parsed, 'search_preset', ['name'], ['sort', 'filters'], warnings, errors);
|
|
23378
|
-
searchConfig =
|
|
23379
|
-
parsedSearchSection === null
|
|
23380
|
-
? null
|
|
23381
|
-
: {
|
|
23382
|
-
RECORD_KIND_QUICK_FILTER: parsedSearchSection.record_kind_quick_filter,
|
|
23383
|
-
FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
|
|
23384
|
-
FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
|
|
23385
|
-
DO_NOT_USE_DEFAULT_SEARCH_PRESET: !!parsedSearchSection.do_not_use_default_search_preset,
|
|
23386
|
-
SEARCH_PRESET: parsedSearchParams.map((param) => ({
|
|
23387
|
-
sort: param.sort,
|
|
23388
|
-
name: param.name,
|
|
23389
|
-
filters: param.filters,
|
|
23390
|
-
})),
|
|
23391
|
-
ADVANCED_FILTERS: parsedSearchSection.advanced_filters,
|
|
23392
|
-
LIMIT: parsedSearchSection.limit,
|
|
23393
|
-
SPATIAL_EXTENT_MAX_FILE_SIZE: parsedSearchSection.spatial_extent_max_file_size,
|
|
23394
|
-
};
|
|
23395
|
-
const parsedMetadataQualitySection = parseConfigSection(parsed, 'metadata-quality', [], ['enabled'], warnings, errors);
|
|
23396
|
-
metadataQualityConfig =
|
|
23397
|
-
parsedMetadataQualitySection === null
|
|
23398
|
-
? null
|
|
23399
|
-
: {
|
|
23400
|
-
ENABLED: parsedMetadataQualitySection.enabled,
|
|
23401
|
-
SORTABLE: parsedMetadataQualitySection.sortable,
|
|
23402
|
-
};
|
|
23403
|
-
let parsedEditingSection = parseConfigSection(parsed, 'editing', [], ['new_record_default_language', 'new_record_standard'], warnings, errors);
|
|
23404
|
-
if (parsedEditingSection !== null &&
|
|
23405
|
-
parsedEditingSection.new_record_default_language !== undefined) {
|
|
23406
|
-
parsedEditingSection = checkNewRecordDefaultLanguage(parsedEditingSection, warnings);
|
|
23504
|
+
return this.content;
|
|
23505
|
+
}
|
|
23506
|
+
ngAfterViewInit() {
|
|
23507
|
+
this.tippyInstance = tippy(this.popoverContent.nativeElement, {
|
|
23508
|
+
content: this.getContent(),
|
|
23509
|
+
allowHTML: true,
|
|
23510
|
+
theme: this.theme,
|
|
23511
|
+
});
|
|
23512
|
+
}
|
|
23513
|
+
ngOnChanges(changes) {
|
|
23514
|
+
if (changes['theme']) {
|
|
23515
|
+
this.theme = changes['theme'].currentValue;
|
|
23516
|
+
if (this.tippyInstance) {
|
|
23517
|
+
this.tippyInstance.setProps({ theme: this.theme });
|
|
23518
|
+
}
|
|
23407
23519
|
}
|
|
23408
|
-
if (
|
|
23409
|
-
|
|
23410
|
-
|
|
23520
|
+
if (changes['content']) {
|
|
23521
|
+
this.content = changes['content'].currentValue;
|
|
23522
|
+
if (this.tippyInstance) {
|
|
23523
|
+
this.tippyInstance.setContent(this.getContent());
|
|
23524
|
+
}
|
|
23411
23525
|
}
|
|
23412
|
-
|
|
23413
|
-
|
|
23414
|
-
|
|
23415
|
-
|
|
23416
|
-
NEW_RECORD_DEFAULT_LANGUAGE: parsedEditingSection.new_record_default_language,
|
|
23417
|
-
NEW_RECORD_STANDARD: parsedEditingSection.new_record_standard,
|
|
23418
|
-
};
|
|
23419
|
-
customTranslations = parseTranslationsConfigSection(parsed, 'translations');
|
|
23420
|
-
if (errors.length) {
|
|
23421
|
-
throw new Error(`One or more mandatory settings were missing from the configuration file.
|
|
23422
|
-
${errors.join('\n')}`);
|
|
23526
|
+
}
|
|
23527
|
+
ngOnDestroy() {
|
|
23528
|
+
if (this.tippyInstance) {
|
|
23529
|
+
this.tippyInstance.destroy();
|
|
23423
23530
|
}
|
|
23424
|
-
|
|
23425
|
-
|
|
23426
|
-
${warnings.join('\n')}`);
|
|
23531
|
+
if (this.view) {
|
|
23532
|
+
this.view.destroy();
|
|
23427
23533
|
}
|
|
23428
|
-
|
|
23429
|
-
});
|
|
23430
|
-
}
|
|
23431
|
-
function isConfigLoaded() {
|
|
23432
|
-
return appConfigLoaded;
|
|
23433
|
-
}
|
|
23434
|
-
function _reset() {
|
|
23435
|
-
globalConfig = null;
|
|
23436
|
-
themeConfig = null;
|
|
23437
|
-
editorConfig = null;
|
|
23438
|
-
customTranslations = null;
|
|
23534
|
+
}
|
|
23535
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23536
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: PopoverComponent, isStandalone: true, selector: "gn-ui-popover", inputs: { content: "content", theme: "theme" }, viewQueries: [{ propertyName: "popoverContent", first: true, predicate: ["popoverContent"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<span #popoverContent>\n <ng-content></ng-content>\n</span>\n", styles: [""] }); }
|
|
23439
23537
|
}
|
|
23440
|
-
|
|
23441
|
-
|
|
23442
|
-
|
|
23443
|
-
|
|
23444
|
-
|
|
23445
|
-
|
|
23446
|
-
|
|
23447
|
-
|
|
23448
|
-
|
|
23449
|
-
|
|
23450
|
-
|
|
23451
|
-
},
|
|
23452
|
-
},
|
|
23453
|
-
{
|
|
23454
|
-
provide: TranslateLoader,
|
|
23455
|
-
useClass: FileWithOverridesTranslateLoader,
|
|
23456
|
-
deps: [HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
|
|
23457
|
-
},
|
|
23458
|
-
],
|
|
23459
|
-
};
|
|
23460
|
-
|
|
23461
|
-
const okAppConfigFixture = () => `
|
|
23462
|
-
[global]
|
|
23463
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23464
|
-
proxy_path = "/proxy/?url="
|
|
23465
|
-
metadata_language = "fre"
|
|
23466
|
-
login_url = "/cas/login?service="
|
|
23467
|
-
logout_url = "/geonetwork/signout"
|
|
23468
|
-
settings_url = "/geonetwork/settings"
|
|
23469
|
-
web_component_embedder_url = "/datahub/wc-embedder.html"
|
|
23470
|
-
|
|
23471
|
-
[map]
|
|
23472
|
-
max_zoom = 10
|
|
23473
|
-
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
23474
|
-
do_not_use_default_basemap = false
|
|
23475
|
-
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
23476
|
-
external_viewer_open_new_tab = true
|
|
23477
|
-
[[map_layer]]
|
|
23478
|
-
type = "wms"
|
|
23479
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23480
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23481
|
-
[[map_layer]]
|
|
23482
|
-
type = "wfs"
|
|
23483
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23484
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23485
|
-
|
|
23486
|
-
[theme]
|
|
23487
|
-
primary_color = "#093564"
|
|
23488
|
-
secondary_color = "#c2e9dc"
|
|
23489
|
-
main_color = "#212029" # All-purpose text color
|
|
23490
|
-
background_color = "#fdfbff"
|
|
23491
|
-
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
23492
|
-
header_background = 'teal'
|
|
23493
|
-
header_foreground_color = "#872e2e"
|
|
23494
|
-
main_font = 'sans-serif'
|
|
23495
|
-
title_font = 'serif'
|
|
23496
|
-
fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
|
|
23497
|
-
|
|
23498
|
-
[search]
|
|
23499
|
-
record_kind_quick_filter = false
|
|
23500
|
-
filter_geometry_url = 'https://my.domain.org/geom.json'
|
|
23501
|
-
do_not_use_default_search_preset = false
|
|
23502
|
-
advanced_filters = ['publicationYear', 'documentStandard', 'inspireKeyword', 'topic', 'license']
|
|
23503
|
-
|
|
23504
|
-
[[search_preset]]
|
|
23505
|
-
sort = "-createDate"
|
|
23506
|
-
name = 'filterByOrgs'
|
|
23507
|
-
filters.q = 'Carto'
|
|
23508
|
-
filters.organisation = ['Org1', 'Org2']
|
|
23509
|
-
filters.format = ['ESRI Shapefile']
|
|
23510
|
-
filters.topic = ['boundaries']
|
|
23511
|
-
filters.publicationYear = ['2023', '2022']
|
|
23512
|
-
filters.spatial = ['yes']
|
|
23513
|
-
|
|
23514
|
-
[translations.en]
|
|
23515
|
-
"my.first.key" = 'First label.'
|
|
23516
|
-
"my.second.key" = """
|
|
23517
|
-
Second label,
|
|
23518
|
-
on two lines."""
|
|
23519
|
-
|
|
23520
|
-
[translations.de]
|
|
23521
|
-
my.first.key = 'Erste Etikett.'
|
|
23522
|
-
|
|
23523
|
-
[translations.fr]
|
|
23524
|
-
my.sample.text = "Un bon exemple de texte."
|
|
23525
|
-
"my.quoted.text" = 'du texte entre guillements.'
|
|
23526
|
-
`;
|
|
23527
|
-
const appConfigWithTranslationFixture = () => okAppConfigFixture();
|
|
23528
|
-
const minimalAppConfigFixture = () => `
|
|
23529
|
-
[global]
|
|
23530
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23531
|
-
proxy_path = "/proxy/?url="
|
|
23538
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, decorators: [{
|
|
23539
|
+
type: Component,
|
|
23540
|
+
args: [{ selector: 'gn-ui-popover', standalone: true, imports: [], template: "<span #popoverContent>\n <ng-content></ng-content>\n</span>\n" }]
|
|
23541
|
+
}], propDecorators: { popoverContent: [{
|
|
23542
|
+
type: ViewChild,
|
|
23543
|
+
args: ['popoverContent', { static: false }]
|
|
23544
|
+
}], content: [{
|
|
23545
|
+
type: Input
|
|
23546
|
+
}], theme: [{
|
|
23547
|
+
type: Input
|
|
23548
|
+
}] } });
|
|
23532
23549
|
|
|
23533
|
-
|
|
23534
|
-
|
|
23535
|
-
|
|
23536
|
-
main_color = "#212029" # All-purpose text color
|
|
23537
|
-
background_color = "#fdfbff"
|
|
23538
|
-
`;
|
|
23539
|
-
const mapConfigFixture = () => ({
|
|
23540
|
-
MAX_ZOOM: 10,
|
|
23541
|
-
MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
|
|
23542
|
-
DO_NOT_USE_DEFAULT_BASEMAP: false,
|
|
23543
|
-
DO_NOT_TILE_WMS: false,
|
|
23544
|
-
EXTERNAL_VIEWER_URL_TEMPLATE: 'https://example.com/myviewer/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["${layer_name}"],"sources":[{"url":"${service_url}","type":"${service_type}"}]}]',
|
|
23545
|
-
EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
|
|
23546
|
-
MAP_LAYERS: [
|
|
23547
|
-
{
|
|
23548
|
-
TYPE: 'xyz',
|
|
23549
|
-
URL: 'https://some-basemap-server',
|
|
23550
|
-
},
|
|
23551
|
-
{
|
|
23552
|
-
TYPE: 'wms',
|
|
23553
|
-
URL: 'https://some-wms-server',
|
|
23554
|
-
NAME: 'some_layername',
|
|
23555
|
-
},
|
|
23556
|
-
{
|
|
23557
|
-
TYPE: 'wfs',
|
|
23558
|
-
URL: 'https://some-wfs-server',
|
|
23559
|
-
NAME: 'some_layername',
|
|
23560
|
-
},
|
|
23561
|
-
],
|
|
23562
|
-
});
|
|
23563
|
-
const malformedConfigFixture = () => `
|
|
23564
|
-
{
|
|
23565
|
-
"I thought": "we were still doing json"
|
|
23550
|
+
class LoadingMaskComponent {
|
|
23551
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23552
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: LoadingMaskComponent, isStandalone: true, selector: "gn-ui-loading-mask", inputs: { message: "message" }, ngImport: i0, template: "<div class=\"h-full flex flex-col justify-center items-center relative backdrop\">\n <div class=\"absolute background bg-white inset-0\"></div>\n <mat-spinner [diameter]=\"28\" class=\"relative\"></mat-spinner>\n <span class=\"text-sm text-gray-700 mt-3 relative\">{{ message }}</span>\n</div>\n", styles: ["::ng-deep .mat-spinner circle{stroke:var(--color-gray-700);opacity:.5}.backdrop{background-color:#fff6}@supports (-webkit-backdrop-filter: blur()) or (backdrop-filter: blur()){.backdrop{background-color:transparent;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}}.background{opacity:.7}\n"], dependencies: [{ kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
23566
23553
|
}
|
|
23567
|
-
|
|
23568
|
-
|
|
23569
|
-
[
|
|
23570
|
-
|
|
23571
|
-
|
|
23572
|
-
|
|
23573
|
-
main_font = 'sans-serif'
|
|
23574
|
-
`;
|
|
23575
|
-
const wrongLanguageCodeConfigFixture = () => `
|
|
23576
|
-
[global]
|
|
23577
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23578
|
-
proxy_path = "/proxy/?url="
|
|
23579
|
-
metadata_language = "abc"
|
|
23580
|
-
|
|
23581
|
-
[map]
|
|
23582
|
-
|
|
23583
|
-
[theme]
|
|
23584
|
-
primary_color = "#093564"
|
|
23585
|
-
secondary_color = "#c2e9dc"
|
|
23586
|
-
main_color = "#212029" # All-purpose text color
|
|
23587
|
-
background_color = "#fdfbff"
|
|
23588
|
-
`;
|
|
23589
|
-
const unrecognizedKeysConfigFixture = () => `
|
|
23590
|
-
[global]
|
|
23591
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23592
|
-
proxy_path = "/proxy/?url="
|
|
23593
|
-
metadata_language = "fre"
|
|
23594
|
-
another_path = '/whatever'
|
|
23595
|
-
|
|
23596
|
-
[map]
|
|
23597
|
-
max_zoom = 10
|
|
23598
|
-
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
23599
|
-
do_not_use_default_basemap = false
|
|
23600
|
-
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
23601
|
-
external_viewer_open_new_tab = true
|
|
23602
|
-
another_zoom = 15
|
|
23603
|
-
[[map_layer]]
|
|
23604
|
-
type = "wms"
|
|
23605
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23606
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23607
|
-
[[map_layer]]
|
|
23608
|
-
type = "wfs"
|
|
23609
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23610
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23611
|
-
another_layer = "wrong layer definition"
|
|
23612
|
-
|
|
23613
|
-
[theme]
|
|
23614
|
-
primary_color = "#093564"
|
|
23615
|
-
secondary_color = "#c2e9dc"
|
|
23616
|
-
main_color = "#212029" # All-purpose text color
|
|
23617
|
-
background_color = "#fdfbff"
|
|
23618
|
-
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
23619
|
-
header_background = 'teal'
|
|
23620
|
-
header_foreground_color = "#872e2e"
|
|
23621
|
-
main_font = 'sans-serif'
|
|
23622
|
-
title_font = 'serif'
|
|
23623
|
-
another_color = 'red'
|
|
23624
|
-
`;
|
|
23554
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, decorators: [{
|
|
23555
|
+
type: Component,
|
|
23556
|
+
args: [{ selector: 'gn-ui-loading-mask', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatProgressSpinnerModule], standalone: true, template: "<div class=\"h-full flex flex-col justify-center items-center relative backdrop\">\n <div class=\"absolute background bg-white inset-0\"></div>\n <mat-spinner [diameter]=\"28\" class=\"relative\"></mat-spinner>\n <span class=\"text-sm text-gray-700 mt-3 relative\">{{ message }}</span>\n</div>\n", styles: ["::ng-deep .mat-spinner circle{stroke:var(--color-gray-700);opacity:.5}.backdrop{background-color:#fff6}@supports (-webkit-backdrop-filter: blur()) or (backdrop-filter: blur()){.backdrop{background-color:transparent;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}}.background{opacity:.7}\n"] }]
|
|
23557
|
+
}], propDecorators: { message: [{
|
|
23558
|
+
type: Input
|
|
23559
|
+
}] } });
|
|
23625
23560
|
|
|
23626
|
-
|
|
23627
|
-
|
|
23628
|
-
|
|
23629
|
-
return {
|
|
23630
|
-
type: 'wms',
|
|
23631
|
-
url: config.URL,
|
|
23632
|
-
name: config.NAME,
|
|
23633
|
-
};
|
|
23634
|
-
case 'wfs':
|
|
23635
|
-
return {
|
|
23636
|
-
type: 'wfs',
|
|
23637
|
-
url: config.URL,
|
|
23638
|
-
featureType: config.NAME,
|
|
23639
|
-
};
|
|
23640
|
-
case 'xyz':
|
|
23641
|
-
return {
|
|
23642
|
-
type: config.TYPE,
|
|
23643
|
-
url: config.URL,
|
|
23644
|
-
};
|
|
23645
|
-
case 'geojson':
|
|
23646
|
-
return {
|
|
23647
|
-
type: config.TYPE,
|
|
23648
|
-
...(config.DATA ? { data: config.DATA } : { url: config.URL }),
|
|
23649
|
-
};
|
|
23650
|
-
case 'maplibre-style':
|
|
23651
|
-
return {
|
|
23652
|
-
type: config.TYPE,
|
|
23653
|
-
styleUrl: config.STYLE_URL,
|
|
23654
|
-
accessToken: config.ACCESS_TOKEN,
|
|
23655
|
-
};
|
|
23656
|
-
}
|
|
23561
|
+
class ColorScaleComponent {
|
|
23562
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23563
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: ColorScaleComponent, isStandalone: true, selector: "gn-ui-color-scale", ngImport: i0, template: "<div class=\"flex flex-row items-center\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">primary</div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-black\"\n title=\"primary-black\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-darkest\"\n title=\"primary-darkest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-darker\"\n title=\"primary-darker\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary border-2 border-primary-darkest\"\n title=\"primary\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-lighter\"\n title=\"primary-lighter\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-lightest\"\n title=\"primary-lightest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-white\"\n title=\"primary-white\"\n ></div>\n</div>\n<div class=\"flex flex-row\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">\n secondary\n </div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-black\"\n title=\"secondary-black\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-darkest\"\n title=\"secondary-darkest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-darker\"\n title=\"secondary-darker\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary border-2 border-secondary-darkest\"\n title=\"secondary\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-lighter\"\n title=\"secondary-lighter\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-lightest\"\n title=\"secondary-lightest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-white\"\n title=\"secondary-white\"\n ></div>\n</div>\n<div class=\"flex flex-row\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">main</div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-main\" title=\"main\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-900\" title=\"gray-900\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-800\" title=\"gray-800\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-700\" title=\"gray-700\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-600\" title=\"gray-600\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-500\" title=\"gray-500\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-400\" title=\"gray-400\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-300\" title=\"gray-300\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-200\" title=\"gray-200\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-100\" title=\"gray-100\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-50\" title=\"gray-50\"></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-background\"\n title=\"background\"\n ></div>\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32\">background</div>\n</div>\n", styles: [""] }); }
|
|
23657
23564
|
}
|
|
23565
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, decorators: [{
|
|
23566
|
+
type: Component,
|
|
23567
|
+
args: [{ selector: 'gn-ui-color-scale', standalone: true, template: "<div class=\"flex flex-row items-center\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">primary</div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-black\"\n title=\"primary-black\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-darkest\"\n title=\"primary-darkest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-darker\"\n title=\"primary-darker\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary border-2 border-primary-darkest\"\n title=\"primary\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-lighter\"\n title=\"primary-lighter\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-lightest\"\n title=\"primary-lightest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-white\"\n title=\"primary-white\"\n ></div>\n</div>\n<div class=\"flex flex-row\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">\n secondary\n </div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-black\"\n title=\"secondary-black\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-darkest\"\n title=\"secondary-darkest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-darker\"\n title=\"secondary-darker\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary border-2 border-secondary-darkest\"\n title=\"secondary\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-lighter\"\n title=\"secondary-lighter\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-lightest\"\n title=\"secondary-lightest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-white\"\n title=\"secondary-white\"\n ></div>\n</div>\n<div class=\"flex flex-row\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">main</div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-main\" title=\"main\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-900\" title=\"gray-900\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-800\" title=\"gray-800\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-700\" title=\"gray-700\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-600\" title=\"gray-600\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-500\" title=\"gray-500\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-400\" title=\"gray-400\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-300\" title=\"gray-300\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-200\" title=\"gray-200\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-100\" title=\"gray-100\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-50\" title=\"gray-50\"></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-background\"\n title=\"background\"\n ></div>\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32\">background</div>\n</div>\n" }]
|
|
23568
|
+
}] });
|
|
23658
23569
|
|
|
23659
|
-
class
|
|
23570
|
+
class PopupAlertComponent {
|
|
23660
23571
|
constructor() {
|
|
23661
|
-
this.
|
|
23662
|
-
|
|
23663
|
-
|
|
23664
|
-
|
|
23665
|
-
|
|
23666
|
-
color: isConfigLoaded() ? getThemeConfig().SECONDARY_COLOR : 'red',
|
|
23667
|
-
isFocused: true,
|
|
23668
|
-
})),
|
|
23669
|
-
};
|
|
23572
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
23573
|
+
this.type = 'info';
|
|
23574
|
+
this.position = 'top';
|
|
23575
|
+
this.expanded = false;
|
|
23576
|
+
this.timeout = null;
|
|
23670
23577
|
}
|
|
23671
|
-
|
|
23672
|
-
const
|
|
23673
|
-
|
|
23674
|
-
return {
|
|
23675
|
-
polygon: new Style({
|
|
23676
|
-
fill: new Fill({
|
|
23677
|
-
color: this.computeTransparentFillColor(color),
|
|
23678
|
-
}),
|
|
23679
|
-
stroke: new Stroke({
|
|
23680
|
-
color: 'white',
|
|
23681
|
-
width: 2,
|
|
23682
|
-
}),
|
|
23683
|
-
zIndex,
|
|
23684
|
-
}),
|
|
23685
|
-
point: new Style({
|
|
23686
|
-
image: new CircleStyle({
|
|
23687
|
-
fill: new Fill({
|
|
23688
|
-
color,
|
|
23689
|
-
}),
|
|
23690
|
-
stroke: new Stroke({
|
|
23691
|
-
color: 'white',
|
|
23692
|
-
width: isFocused ? 3 : 2,
|
|
23693
|
-
}),
|
|
23694
|
-
radius: isFocused ? 8 : 7,
|
|
23695
|
-
}),
|
|
23696
|
-
zIndex,
|
|
23697
|
-
}),
|
|
23698
|
-
line: [
|
|
23699
|
-
new Style({
|
|
23700
|
-
stroke: new Stroke({
|
|
23701
|
-
color: 'white',
|
|
23702
|
-
width: isFocused ? 8 : 6,
|
|
23703
|
-
}),
|
|
23704
|
-
zIndex,
|
|
23705
|
-
}),
|
|
23706
|
-
new Style({
|
|
23707
|
-
stroke: new Stroke({
|
|
23708
|
-
color,
|
|
23709
|
-
width: isFocused ? 3 : 2,
|
|
23710
|
-
}),
|
|
23711
|
-
zIndex,
|
|
23712
|
-
}),
|
|
23713
|
-
],
|
|
23714
|
-
};
|
|
23578
|
+
get showDuration() {
|
|
23579
|
+
const chars = this.content.nativeElement.innerHTML.length;
|
|
23580
|
+
return Math.max(3000, chars * 20);
|
|
23715
23581
|
}
|
|
23716
|
-
|
|
23717
|
-
|
|
23718
|
-
|
|
23719
|
-
|
|
23720
|
-
|
|
23721
|
-
|
|
23722
|
-
|
|
23723
|
-
return styleByGeometryType.line;
|
|
23724
|
-
case 'Point':
|
|
23725
|
-
case 'MultiPoint':
|
|
23726
|
-
return styleByGeometryType.point;
|
|
23727
|
-
case 'Circle':
|
|
23728
|
-
case 'Polygon':
|
|
23729
|
-
case 'MultiPolygon':
|
|
23730
|
-
return styleByGeometryType.polygon;
|
|
23731
|
-
default:
|
|
23732
|
-
return styleByGeometryType.point;
|
|
23733
|
-
}
|
|
23734
|
-
};
|
|
23582
|
+
ngOnInit() {
|
|
23583
|
+
this.expandAndClose();
|
|
23584
|
+
}
|
|
23585
|
+
expand() {
|
|
23586
|
+
this.expanded = true;
|
|
23587
|
+
this.changeDetector.detectChanges();
|
|
23588
|
+
clearTimeout(this.timeout);
|
|
23735
23589
|
}
|
|
23736
|
-
|
|
23737
|
-
|
|
23590
|
+
expandAndClose() {
|
|
23591
|
+
this.expanded = true;
|
|
23592
|
+
this.changeDetector.detectChanges();
|
|
23593
|
+
clearTimeout(this.timeout);
|
|
23594
|
+
this.timeout = setTimeout(() => {
|
|
23595
|
+
this.expanded = false;
|
|
23596
|
+
this.changeDetector.detectChanges();
|
|
23597
|
+
}, this.showDuration);
|
|
23738
23598
|
}
|
|
23739
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type:
|
|
23740
|
-
static { this.ɵ
|
|
23741
|
-
}
|
|
23742
|
-
|
|
23743
|
-
|
|
23744
|
-
|
|
23745
|
-
|
|
23746
|
-
}]
|
|
23747
|
-
}] });
|
|
23748
|
-
|
|
23749
|
-
const colorPrimary = 'blue';
|
|
23750
|
-
const colorSecondary = 'red';
|
|
23751
|
-
const colorStroke = 'white';
|
|
23752
|
-
const defaultMapStyleFixture = () => new Style({
|
|
23753
|
-
image: new Circle({
|
|
23754
|
-
fill: new Fill({
|
|
23755
|
-
color: colorPrimary,
|
|
23756
|
-
}),
|
|
23757
|
-
stroke: new Stroke({
|
|
23758
|
-
color: colorStroke,
|
|
23759
|
-
width: 2,
|
|
23760
|
-
}),
|
|
23761
|
-
radius: 5,
|
|
23762
|
-
}),
|
|
23763
|
-
fill: new Fill({
|
|
23764
|
-
color: 'rgba(0,0,255,0.25)',
|
|
23765
|
-
}),
|
|
23766
|
-
stroke: new Stroke({
|
|
23767
|
-
color: colorStroke,
|
|
23768
|
-
width: 2,
|
|
23769
|
-
}),
|
|
23770
|
-
});
|
|
23771
|
-
const defaultMapStyleHlFixture = () => new Style({
|
|
23772
|
-
image: new Circle({
|
|
23773
|
-
fill: new Fill({
|
|
23774
|
-
color: colorSecondary,
|
|
23775
|
-
}),
|
|
23776
|
-
stroke: new Stroke({
|
|
23777
|
-
color: colorStroke,
|
|
23778
|
-
width: 3,
|
|
23779
|
-
}),
|
|
23780
|
-
radius: 6,
|
|
23781
|
-
}),
|
|
23782
|
-
fill: new Fill({
|
|
23783
|
-
color: 'rgba(255,0,0,0.25)',
|
|
23784
|
-
}),
|
|
23785
|
-
stroke: new Stroke({
|
|
23786
|
-
color: colorSecondary,
|
|
23787
|
-
width: 3,
|
|
23788
|
-
}),
|
|
23789
|
-
});
|
|
23790
|
-
|
|
23791
|
-
class AnchorLinkDirective {
|
|
23792
|
-
constructor() {
|
|
23793
|
-
this.changeDetector = inject(ChangeDetectorRef);
|
|
23794
|
-
this.disabled = false;
|
|
23795
|
-
this.observer = new MutationObserver(() => {
|
|
23796
|
-
this.refreshDisabledState();
|
|
23797
|
-
});
|
|
23798
|
-
this.inView = false;
|
|
23799
|
-
this.initialized = false;
|
|
23800
|
-
}
|
|
23801
|
-
get elementClass() {
|
|
23802
|
-
if (this.disabled) {
|
|
23803
|
-
return this.disabledClass;
|
|
23804
|
-
}
|
|
23805
|
-
if (this.inView) {
|
|
23806
|
-
return `${this.inViewClass} ${this.enabledClass}`;
|
|
23807
|
-
}
|
|
23808
|
-
else {
|
|
23809
|
-
return `${this.outOfViewClass} ${this.enabledClass}`;
|
|
23810
|
-
}
|
|
23811
|
-
}
|
|
23812
|
-
ngOnInit() {
|
|
23813
|
-
this.observer.observe(document.body, {
|
|
23814
|
-
childList: true,
|
|
23815
|
-
subtree: true,
|
|
23816
|
-
});
|
|
23817
|
-
this.refreshDisabledState();
|
|
23818
|
-
}
|
|
23819
|
-
ngAfterViewChecked() {
|
|
23820
|
-
if (!this.initialized && !this.disabled) {
|
|
23821
|
-
const target = document.getElementById(this.targetId);
|
|
23822
|
-
if (target) {
|
|
23823
|
-
this.initializeIntersectionObserver(target);
|
|
23824
|
-
this.initialized = true;
|
|
23825
|
-
}
|
|
23826
|
-
}
|
|
23827
|
-
}
|
|
23828
|
-
initializeIntersectionObserver(target) {
|
|
23829
|
-
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
23830
|
-
entries.forEach((entry) => {
|
|
23831
|
-
this.inView = entry.isIntersecting;
|
|
23832
|
-
this.changeDetector.detectChanges();
|
|
23833
|
-
});
|
|
23834
|
-
}, {
|
|
23835
|
-
root: null,
|
|
23836
|
-
rootMargin: '-30% 0% -60% 0%',
|
|
23837
|
-
});
|
|
23838
|
-
this.intersectionObserver.observe(target);
|
|
23839
|
-
}
|
|
23840
|
-
ngOnDestroy() {
|
|
23841
|
-
this.observer.disconnect();
|
|
23842
|
-
if (this.intersectionObserver) {
|
|
23843
|
-
this.intersectionObserver.disconnect();
|
|
23844
|
-
}
|
|
23845
|
-
}
|
|
23846
|
-
refreshDisabledState() {
|
|
23847
|
-
const targetNotPresent = !document.getElementById(this.targetId);
|
|
23848
|
-
if (targetNotPresent !== this.disabled) {
|
|
23849
|
-
this.disabled = targetNotPresent;
|
|
23850
|
-
this.changeDetector.detectChanges();
|
|
23851
|
-
}
|
|
23852
|
-
}
|
|
23853
|
-
scrollToTarget() {
|
|
23854
|
-
const target = document.getElementById(this.targetId);
|
|
23855
|
-
if (!target)
|
|
23856
|
-
return;
|
|
23857
|
-
target.scrollIntoView({
|
|
23858
|
-
behavior: 'smooth',
|
|
23859
|
-
block: 'start',
|
|
23860
|
-
});
|
|
23861
|
-
}
|
|
23862
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
23863
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: AnchorLinkDirective, isStandalone: true, selector: "[gnUiAnchorLink]", inputs: { targetId: ["gnUiAnchorLink", "targetId"], disabledClass: ["gnUiAnchorLinkDisabledClass", "disabledClass"], enabledClass: ["gnUiAnchorLinkEnabledClass", "enabledClass"], inViewClass: ["gnUiAnchorLinkInViewClass", "inViewClass"], outOfViewClass: ["gnUiAnchorLinkOutOfViewClass", "outOfViewClass"] }, host: { listeners: { "click": "scrollToTarget()" }, properties: { "class": "this.elementClass" } }, ngImport: i0 }); }
|
|
23864
|
-
}
|
|
23865
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, decorators: [{
|
|
23866
|
-
type: Directive,
|
|
23867
|
-
args: [{
|
|
23868
|
-
selector: '[gnUiAnchorLink]',
|
|
23869
|
-
standalone: true,
|
|
23870
|
-
}]
|
|
23871
|
-
}], propDecorators: { targetId: [{
|
|
23872
|
-
type: Input,
|
|
23873
|
-
args: ['gnUiAnchorLink']
|
|
23874
|
-
}], disabledClass: [{
|
|
23875
|
-
type: Input,
|
|
23876
|
-
args: ['gnUiAnchorLinkDisabledClass']
|
|
23877
|
-
}], enabledClass: [{
|
|
23878
|
-
type: Input,
|
|
23879
|
-
args: ['gnUiAnchorLinkEnabledClass']
|
|
23880
|
-
}], inViewClass: [{
|
|
23881
|
-
type: Input,
|
|
23882
|
-
args: ['gnUiAnchorLinkInViewClass']
|
|
23883
|
-
}], outOfViewClass: [{
|
|
23884
|
-
type: Input,
|
|
23885
|
-
args: ['gnUiAnchorLinkOutOfViewClass']
|
|
23886
|
-
}], elementClass: [{
|
|
23887
|
-
type: HostBinding,
|
|
23888
|
-
args: ['class']
|
|
23889
|
-
}], scrollToTarget: [{
|
|
23890
|
-
type: HostListener,
|
|
23891
|
-
args: ['click']
|
|
23892
|
-
}] } });
|
|
23893
|
-
|
|
23894
|
-
class PaginationDotsComponent {
|
|
23895
|
-
constructor() {
|
|
23896
|
-
this.containerClass = '';
|
|
23897
|
-
}
|
|
23898
|
-
// 1-based
|
|
23899
|
-
get steps() {
|
|
23900
|
-
return Array.from({ length: this.listComponent.pagesCount }, (_, i) => i + 1);
|
|
23901
|
-
}
|
|
23902
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23903
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: PaginationDotsComponent, isStandalone: true, selector: "gn-ui-pagination-dots", inputs: { listComponent: "listComponent", containerClass: "containerClass" }, ngImport: i0, template: "@if (listComponent.pagesCount > 1) {\n <div\n class=\"overflow-hidden flex flex-row justify-center gap-[14px] p-1\"\n [ngClass]=\"containerClass\"\n >\n @for (step of steps; track step) {\n <button\n type=\"button\"\n class=\"pagination-dot\"\n (click)=\"listComponent.goToPage(step)\"\n [ngClass]=\"\n listComponent.currentPage === step ? 'bg-primary' : 'bg-gray-400'\n \"\n ></button>\n }\n </div>\n}\n", styles: [".pagination-dot{width:6px;height:6px;border-radius:6px;position:relative;flex-shrink:0}.pagination-dot:after{content:\"\";position:absolute;left:-7px;top:-7px;width:20px;height:20px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], viewProviders: [
|
|
23904
|
-
provideIcons({
|
|
23905
|
-
iconoirNavArrowRight,
|
|
23906
|
-
iconoirNavArrowLeft,
|
|
23907
|
-
}),
|
|
23908
|
-
] }); }
|
|
23909
|
-
}
|
|
23910
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, decorators: [{
|
|
23911
|
-
type: Component,
|
|
23912
|
-
args: [{ selector: 'gn-ui-pagination-dots', standalone: true, imports: [CommonModule], viewProviders: [
|
|
23913
|
-
provideIcons({
|
|
23914
|
-
iconoirNavArrowRight,
|
|
23915
|
-
iconoirNavArrowLeft,
|
|
23916
|
-
}),
|
|
23917
|
-
], template: "@if (listComponent.pagesCount > 1) {\n <div\n class=\"overflow-hidden flex flex-row justify-center gap-[14px] p-1\"\n [ngClass]=\"containerClass\"\n >\n @for (step of steps; track step) {\n <button\n type=\"button\"\n class=\"pagination-dot\"\n (click)=\"listComponent.goToPage(step)\"\n [ngClass]=\"\n listComponent.currentPage === step ? 'bg-primary' : 'bg-gray-400'\n \"\n ></button>\n }\n </div>\n}\n", styles: [".pagination-dot{width:6px;height:6px;border-radius:6px;position:relative;flex-shrink:0}.pagination-dot:after{content:\"\";position:absolute;left:-7px;top:-7px;width:20px;height:20px}\n"] }]
|
|
23918
|
-
}], propDecorators: { listComponent: [{
|
|
23919
|
-
type: Input
|
|
23920
|
-
}], containerClass: [{
|
|
23921
|
-
type: Input
|
|
23922
|
-
}] } });
|
|
23923
|
-
|
|
23924
|
-
class CarouselComponent {
|
|
23925
|
-
constructor() {
|
|
23926
|
-
this.changeDetector = inject(ChangeDetectorRef);
|
|
23927
|
-
this.containerClass = '';
|
|
23928
|
-
this.stepsContainerClass = 'w-full bottom-0 top-auto';
|
|
23929
|
-
this.currentStepChange = new EventEmitter();
|
|
23930
|
-
this.steps = [];
|
|
23931
|
-
this.currentStep = 0;
|
|
23932
|
-
this.refreshSteps = () => {
|
|
23933
|
-
this.steps = this.emblaApi.scrollSnapList();
|
|
23934
|
-
this.currentStep = this.emblaApi.selectedScrollSnap();
|
|
23935
|
-
this.currentStepChange.emit(this.currentStep);
|
|
23936
|
-
this.changeDetector.detectChanges();
|
|
23937
|
-
};
|
|
23938
|
-
}
|
|
23939
|
-
// Paginable API
|
|
23940
|
-
get isFirstPage() {
|
|
23941
|
-
return this.currentStep === 0;
|
|
23942
|
-
}
|
|
23943
|
-
get isLastPage() {
|
|
23944
|
-
return this.currentStep === this.steps.length - 1;
|
|
23945
|
-
}
|
|
23946
|
-
get currentPage() {
|
|
23947
|
-
return this.currentStep + 1; // this is 1-based
|
|
23948
|
-
}
|
|
23949
|
-
get pagesCount() {
|
|
23950
|
-
return this.steps.length;
|
|
23951
|
-
}
|
|
23952
|
-
goToPage(stepIndex) {
|
|
23953
|
-
this.emblaApi.scrollTo(stepIndex - 1); // this is 0-based
|
|
23954
|
-
}
|
|
23955
|
-
goToPrevPage() {
|
|
23956
|
-
if (this.isFirstPage)
|
|
23957
|
-
return;
|
|
23958
|
-
this.emblaApi.scrollPrev();
|
|
23959
|
-
}
|
|
23960
|
-
goToNextPage() {
|
|
23961
|
-
if (this.isLastPage)
|
|
23962
|
-
return;
|
|
23963
|
-
this.emblaApi.scrollNext();
|
|
23964
|
-
}
|
|
23965
|
-
ngAfterViewInit() {
|
|
23966
|
-
this.emblaApi = EmblaCarousel(this.carouselOverflowContainer.nativeElement, {
|
|
23967
|
-
duration: 15,
|
|
23968
|
-
});
|
|
23969
|
-
this.emblaApi
|
|
23970
|
-
.on('init', this.refreshSteps)
|
|
23971
|
-
.on('reInit', this.refreshSteps)
|
|
23972
|
-
.on('select', this.refreshSteps);
|
|
23973
|
-
}
|
|
23974
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23975
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: CarouselComponent, isStandalone: true, selector: "gn-ui-carousel", inputs: { containerClass: "containerClass", stepsContainerClass: "stepsContainerClass" }, outputs: { currentStepChange: "currentStepChange" }, viewQueries: [{ propertyName: "carouselOverflowContainer", first: true, predicate: ["carouselOverflowContainer"], descendants: true }], ngImport: i0, template: "<div #carouselOverflowContainer class=\"w-full block\">\n <div class=\"carousel-container flex\" [ngClass]=\"containerClass\">\n <ng-content></ng-content>\n </div>\n</div>\n<gn-ui-pagination-dots\n [containerClass]=\"'absolute ' + stepsContainerClass\"\n [listComponent]=\"this\"\n></gn-ui-pagination-dots>\n", styles: [":host{position:relative}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PaginationDotsComponent, selector: "gn-ui-pagination-dots", inputs: ["listComponent", "containerClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
23976
|
-
}
|
|
23977
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, decorators: [{
|
|
23978
|
-
type: Component,
|
|
23979
|
-
args: [{ selector: 'gn-ui-carousel', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, PaginationDotsComponent], template: "<div #carouselOverflowContainer class=\"w-full block\">\n <div class=\"carousel-container flex\" [ngClass]=\"containerClass\">\n <ng-content></ng-content>\n </div>\n</div>\n<gn-ui-pagination-dots\n [containerClass]=\"'absolute ' + stepsContainerClass\"\n [listComponent]=\"this\"\n></gn-ui-pagination-dots>\n", styles: [":host{position:relative}\n"] }]
|
|
23980
|
-
}], propDecorators: { carouselOverflowContainer: [{
|
|
23981
|
-
type: ViewChild,
|
|
23982
|
-
args: ['carouselOverflowContainer']
|
|
23983
|
-
}], containerClass: [{
|
|
23984
|
-
type: Input
|
|
23985
|
-
}], stepsContainerClass: [{
|
|
23986
|
-
type: Input
|
|
23987
|
-
}], currentStepChange: [{
|
|
23988
|
-
type: Output
|
|
23989
|
-
}] } });
|
|
23990
|
-
|
|
23991
|
-
class ProgressBarComponent {
|
|
23992
|
-
constructor() {
|
|
23993
|
-
this.value = 0;
|
|
23994
|
-
this.type = 'default';
|
|
23995
|
-
}
|
|
23996
|
-
get progress() {
|
|
23997
|
-
return this.value > 0 ? (this.value < 100 ? this.value : 100) : 0;
|
|
23998
|
-
}
|
|
23999
|
-
get color() {
|
|
24000
|
-
switch (this.type) {
|
|
24001
|
-
case 'default':
|
|
24002
|
-
return {
|
|
24003
|
-
outerBar: 'bg-gray-200',
|
|
24004
|
-
innerBar: 'bg-gray-100',
|
|
24005
|
-
text: 'text-gray-900',
|
|
24006
|
-
};
|
|
24007
|
-
case 'primary':
|
|
24008
|
-
return {
|
|
24009
|
-
outerBar: 'bg-primary',
|
|
24010
|
-
innerBar: 'bg-primary-lighter',
|
|
24011
|
-
text: 'text-white',
|
|
24012
|
-
};
|
|
24013
|
-
case 'secondary':
|
|
24014
|
-
return {
|
|
24015
|
-
outerBar: 'bg-secondary',
|
|
24016
|
-
innerBar: 'bg-secondary-lighter',
|
|
24017
|
-
text: 'text-white',
|
|
24018
|
-
};
|
|
24019
|
-
case 'light':
|
|
24020
|
-
return {
|
|
24021
|
-
outerBar: 'bg-primary-white',
|
|
24022
|
-
innerBar: 'bg-primary',
|
|
24023
|
-
text: 'text-main',
|
|
24024
|
-
};
|
|
24025
|
-
}
|
|
24026
|
-
}
|
|
24027
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24028
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: ProgressBarComponent, isStandalone: true, selector: "gn-ui-progress-bar", inputs: { value: "value", type: "type" }, ngImport: i0, template: "@switch (type) {\n <!-- Light Theme -->\n @case ('light') {\n <div class=\"flex items-center relative\">\n <div\n class=\"flex-shrink-0 {{ color.text }} font-medium mr-2\n text-opacity-100 !text-slate-800\"\n data-cy=\"progressPercentage\"\n >\n {{ progress }}%\n </div>\n <div class=\"flex-grow h-[4px] w-[52px] {{ color.outerBar }} rounded-full\">\n <div\n [style.width.%]=\"progress\"\n class=\"{{ color.innerBar }} transition-width duration-500\n ease-in-out rounded-full shadow-sm w-[52px] h-[4px]\"\n ></div>\n </div>\n </div>\n }\n <!-- Default / Primary / Secondary Themes -->\n @default {\n <div class=\"flex h-full {{ color.outerBar }} rounded-t-lg rounded-b-lg\">\n <div\n [style.width.%]=\"progress\"\n class=\"flex {{ color.innerBar }} my-1 mx-1 transition-width\n duration-500 ease-in-out rounded-t-md rounded-b-md shadow-xl\"\n >\n <div\n class=\"flex items-center pl-2 py-1 {{ color.text }} font-bold text-4\"\n >\n {{ progress }}%\n </div>\n </div>\n </div>\n }\n}\n", styles: [".font-bold{font-weight:var(--progress-bar-font-weight, \"bold\")}\n"] }); }
|
|
24029
|
-
}
|
|
24030
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, decorators: [{
|
|
24031
|
-
type: Component,
|
|
24032
|
-
args: [{ selector: 'gn-ui-progress-bar', standalone: true, imports: [], template: "@switch (type) {\n <!-- Light Theme -->\n @case ('light') {\n <div class=\"flex items-center relative\">\n <div\n class=\"flex-shrink-0 {{ color.text }} font-medium mr-2\n text-opacity-100 !text-slate-800\"\n data-cy=\"progressPercentage\"\n >\n {{ progress }}%\n </div>\n <div class=\"flex-grow h-[4px] w-[52px] {{ color.outerBar }} rounded-full\">\n <div\n [style.width.%]=\"progress\"\n class=\"{{ color.innerBar }} transition-width duration-500\n ease-in-out rounded-full shadow-sm w-[52px] h-[4px]\"\n ></div>\n </div>\n </div>\n }\n <!-- Default / Primary / Secondary Themes -->\n @default {\n <div class=\"flex h-full {{ color.outerBar }} rounded-t-lg rounded-b-lg\">\n <div\n [style.width.%]=\"progress\"\n class=\"flex {{ color.innerBar }} my-1 mx-1 transition-width\n duration-500 ease-in-out rounded-t-md rounded-b-md shadow-xl\"\n >\n <div\n class=\"flex items-center pl-2 py-1 {{ color.text }} font-bold text-4\"\n >\n {{ progress }}%\n </div>\n </div>\n </div>\n }\n}\n", styles: [".font-bold{font-weight:var(--progress-bar-font-weight, \"bold\")}\n"] }]
|
|
24033
|
-
}], propDecorators: { value: [{
|
|
24034
|
-
type: Input
|
|
24035
|
-
}], type: [{
|
|
24036
|
-
type: Input
|
|
24037
|
-
}] } });
|
|
24038
|
-
|
|
24039
|
-
class PopoverComponent {
|
|
24040
|
-
constructor() {
|
|
24041
|
-
this.viewContainerRef = inject(ViewContainerRef);
|
|
24042
|
-
this.renderer = inject(Renderer2);
|
|
24043
|
-
}
|
|
24044
|
-
getContent() {
|
|
24045
|
-
if (this.content instanceof TemplateRef) {
|
|
24046
|
-
if (this.view) {
|
|
24047
|
-
this.view.destroy();
|
|
24048
|
-
}
|
|
24049
|
-
this.view = this.viewContainerRef.createEmbeddedView(this.content);
|
|
24050
|
-
this.view.detectChanges();
|
|
24051
|
-
const wrapper = this.renderer.createElement('div'); // Create a wrapper div
|
|
24052
|
-
this.view.rootNodes.forEach((node) => {
|
|
24053
|
-
this.renderer.appendChild(wrapper, node); // Append each root node to the wrapper
|
|
24054
|
-
});
|
|
24055
|
-
return wrapper;
|
|
24056
|
-
}
|
|
24057
|
-
return this.content;
|
|
24058
|
-
}
|
|
24059
|
-
ngAfterViewInit() {
|
|
24060
|
-
this.tippyInstance = tippy(this.popoverContent.nativeElement, {
|
|
24061
|
-
content: this.getContent(),
|
|
24062
|
-
allowHTML: true,
|
|
24063
|
-
theme: this.theme,
|
|
24064
|
-
});
|
|
24065
|
-
}
|
|
24066
|
-
ngOnChanges(changes) {
|
|
24067
|
-
if (changes['theme']) {
|
|
24068
|
-
this.theme = changes['theme'].currentValue;
|
|
24069
|
-
if (this.tippyInstance) {
|
|
24070
|
-
this.tippyInstance.setProps({ theme: this.theme });
|
|
24071
|
-
}
|
|
24072
|
-
}
|
|
24073
|
-
if (changes['content']) {
|
|
24074
|
-
this.content = changes['content'].currentValue;
|
|
24075
|
-
if (this.tippyInstance) {
|
|
24076
|
-
this.tippyInstance.setContent(this.getContent());
|
|
24077
|
-
}
|
|
24078
|
-
}
|
|
24079
|
-
}
|
|
24080
|
-
ngOnDestroy() {
|
|
24081
|
-
if (this.tippyInstance) {
|
|
24082
|
-
this.tippyInstance.destroy();
|
|
24083
|
-
}
|
|
24084
|
-
if (this.view) {
|
|
24085
|
-
this.view.destroy();
|
|
24086
|
-
}
|
|
24087
|
-
}
|
|
24088
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24089
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: PopoverComponent, isStandalone: true, selector: "gn-ui-popover", inputs: { content: "content", theme: "theme" }, viewQueries: [{ propertyName: "popoverContent", first: true, predicate: ["popoverContent"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<span #popoverContent>\n <ng-content></ng-content>\n</span>\n", styles: [""] }); }
|
|
24090
|
-
}
|
|
24091
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, decorators: [{
|
|
24092
|
-
type: Component,
|
|
24093
|
-
args: [{ selector: 'gn-ui-popover', standalone: true, imports: [], template: "<span #popoverContent>\n <ng-content></ng-content>\n</span>\n" }]
|
|
24094
|
-
}], propDecorators: { popoverContent: [{
|
|
24095
|
-
type: ViewChild,
|
|
24096
|
-
args: ['popoverContent', { static: false }]
|
|
24097
|
-
}], content: [{
|
|
24098
|
-
type: Input
|
|
24099
|
-
}], theme: [{
|
|
24100
|
-
type: Input
|
|
24101
|
-
}] } });
|
|
24102
|
-
|
|
24103
|
-
class LoadingMaskComponent {
|
|
24104
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24105
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: LoadingMaskComponent, isStandalone: true, selector: "gn-ui-loading-mask", inputs: { message: "message" }, ngImport: i0, template: "<div class=\"h-full flex flex-col justify-center items-center relative backdrop\">\n <div class=\"absolute background bg-white inset-0\"></div>\n <mat-spinner [diameter]=\"28\" class=\"relative\"></mat-spinner>\n <span class=\"text-sm text-gray-700 mt-3 relative\">{{ message }}</span>\n</div>\n", styles: ["::ng-deep .mat-spinner circle{stroke:var(--color-gray-700);opacity:.5}.backdrop{background-color:#fff6}@supports (-webkit-backdrop-filter: blur()) or (backdrop-filter: blur()){.backdrop{background-color:transparent;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}}.background{opacity:.7}\n"], dependencies: [{ kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
24106
|
-
}
|
|
24107
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, decorators: [{
|
|
24108
|
-
type: Component,
|
|
24109
|
-
args: [{ selector: 'gn-ui-loading-mask', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatProgressSpinnerModule], standalone: true, template: "<div class=\"h-full flex flex-col justify-center items-center relative backdrop\">\n <div class=\"absolute background bg-white inset-0\"></div>\n <mat-spinner [diameter]=\"28\" class=\"relative\"></mat-spinner>\n <span class=\"text-sm text-gray-700 mt-3 relative\">{{ message }}</span>\n</div>\n", styles: ["::ng-deep .mat-spinner circle{stroke:var(--color-gray-700);opacity:.5}.backdrop{background-color:#fff6}@supports (-webkit-backdrop-filter: blur()) or (backdrop-filter: blur()){.backdrop{background-color:transparent;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}}.background{opacity:.7}\n"] }]
|
|
24110
|
-
}], propDecorators: { message: [{
|
|
24111
|
-
type: Input
|
|
24112
|
-
}] } });
|
|
24113
|
-
|
|
24114
|
-
class ColorScaleComponent {
|
|
24115
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24116
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: ColorScaleComponent, isStandalone: true, selector: "gn-ui-color-scale", ngImport: i0, template: "<div class=\"flex flex-row items-center\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">primary</div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-black\"\n title=\"primary-black\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-darkest\"\n title=\"primary-darkest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-darker\"\n title=\"primary-darker\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary border-2 border-primary-darkest\"\n title=\"primary\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-lighter\"\n title=\"primary-lighter\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-lightest\"\n title=\"primary-lightest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-white\"\n title=\"primary-white\"\n ></div>\n</div>\n<div class=\"flex flex-row\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">\n secondary\n </div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-black\"\n title=\"secondary-black\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-darkest\"\n title=\"secondary-darkest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-darker\"\n title=\"secondary-darker\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary border-2 border-secondary-darkest\"\n title=\"secondary\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-lighter\"\n title=\"secondary-lighter\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-lightest\"\n title=\"secondary-lightest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-white\"\n title=\"secondary-white\"\n ></div>\n</div>\n<div class=\"flex flex-row\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">main</div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-main\" title=\"main\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-900\" title=\"gray-900\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-800\" title=\"gray-800\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-700\" title=\"gray-700\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-600\" title=\"gray-600\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-500\" title=\"gray-500\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-400\" title=\"gray-400\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-300\" title=\"gray-300\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-200\" title=\"gray-200\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-100\" title=\"gray-100\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-50\" title=\"gray-50\"></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-background\"\n title=\"background\"\n ></div>\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32\">background</div>\n</div>\n", styles: [""] }); }
|
|
24117
|
-
}
|
|
24118
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, decorators: [{
|
|
24119
|
-
type: Component,
|
|
24120
|
-
args: [{ selector: 'gn-ui-color-scale', standalone: true, template: "<div class=\"flex flex-row items-center\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">primary</div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-black\"\n title=\"primary-black\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-darkest\"\n title=\"primary-darkest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-darker\"\n title=\"primary-darker\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary border-2 border-primary-darkest\"\n title=\"primary\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-lighter\"\n title=\"primary-lighter\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-lightest\"\n title=\"primary-lightest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-primary-white\"\n title=\"primary-white\"\n ></div>\n</div>\n<div class=\"flex flex-row\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">\n secondary\n </div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-black\"\n title=\"secondary-black\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-darkest\"\n title=\"secondary-darkest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-darker\"\n title=\"secondary-darker\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary border-2 border-secondary-darkest\"\n title=\"secondary\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-lighter\"\n title=\"secondary-lighter\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-lightest\"\n title=\"secondary-lightest\"\n ></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-secondary-white\"\n title=\"secondary-white\"\n ></div>\n</div>\n<div class=\"flex flex-row\">\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32 text-right\">main</div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-main\" title=\"main\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-900\" title=\"gray-900\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-800\" title=\"gray-800\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-700\" title=\"gray-700\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-600\" title=\"gray-600\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-500\" title=\"gray-500\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-400\" title=\"gray-400\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-300\" title=\"gray-300\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-200\" title=\"gray-200\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-100\" title=\"gray-100\"></div>\n <div class=\"shadow-md rounded w-6 h-6 m-2 bg-gray-50\" title=\"gray-50\"></div>\n <div\n class=\"shadow-md rounded w-6 h-6 m-2 bg-background\"\n title=\"background\"\n ></div>\n <div class=\"text-xs text-gray-700 font-bold m-2 w-32\">background</div>\n</div>\n" }]
|
|
24121
|
-
}] });
|
|
24122
|
-
|
|
24123
|
-
class PopupAlertComponent {
|
|
24124
|
-
constructor() {
|
|
24125
|
-
this.changeDetector = inject(ChangeDetectorRef);
|
|
24126
|
-
this.type = 'info';
|
|
24127
|
-
this.position = 'top';
|
|
24128
|
-
this.expanded = false;
|
|
24129
|
-
this.timeout = null;
|
|
24130
|
-
}
|
|
24131
|
-
get showDuration() {
|
|
24132
|
-
const chars = this.content.nativeElement.innerHTML.length;
|
|
24133
|
-
return Math.max(3000, chars * 20);
|
|
24134
|
-
}
|
|
24135
|
-
ngOnInit() {
|
|
24136
|
-
this.expandAndClose();
|
|
24137
|
-
}
|
|
24138
|
-
expand() {
|
|
24139
|
-
this.expanded = true;
|
|
24140
|
-
this.changeDetector.detectChanges();
|
|
24141
|
-
clearTimeout(this.timeout);
|
|
24142
|
-
}
|
|
24143
|
-
expandAndClose() {
|
|
24144
|
-
this.expanded = true;
|
|
24145
|
-
this.changeDetector.detectChanges();
|
|
24146
|
-
clearTimeout(this.timeout);
|
|
24147
|
-
this.timeout = setTimeout(() => {
|
|
24148
|
-
this.expanded = false;
|
|
24149
|
-
this.changeDetector.detectChanges();
|
|
24150
|
-
}, this.showDuration);
|
|
24151
|
-
}
|
|
24152
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopupAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24153
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: PopupAlertComponent, isStandalone: true, selector: "gn-ui-popup-alert", inputs: { icon: "icon", type: "type", position: "position" }, providers: [
|
|
24154
|
-
provideIcons({ matErrorOutlineOutline }),
|
|
24155
|
-
provideNgIconsConfig({
|
|
24156
|
-
size: '1.5em',
|
|
24157
|
-
}),
|
|
24158
|
-
], viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<div class=\"h-full relative container\">\n <div\n class=\"pointer-events-auto absolute text-white flex flex-row p-2 rounded message\"\n role=\"alert\"\n [ngClass]=\"{\n 'position-bottom': position === 'bottom',\n 'position-top': position === 'top',\n expanded: this.expanded,\n 'bg-red-500': type === 'danger',\n 'bg-yellow-500': type === 'warning',\n 'bg-blue-500': type === 'info',\n }\"\n (mouseenter)=\"expand()\"\n (mouseleave)=\"expandAndClose()\"\n >\n <ng-icon class=\"mr-2 shrink-0 select-none\" [name]=\"icon\"></ng-icon>\n <div class=\"grow\" #content [ngClass]=\"{ invisible: !expanded }\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", styles: [":host{pointer-events:none}.container{filter:drop-shadow(0px 4px 3px rgba(0,0,0,.2))}.message{transition:clip-path .3s cubic-bezier(.25,.46,.45,.94)}.message.expanded{clip-path:circle(100%)}.position-top{clip-path:circle(19px at 20px 20px);align-items:start;top:0;left:0}.position-bottom{clip-path:circle(19px at 20px calc(100% - 20px));align-items:end;bottom:0;left:0}.container ::ng-deep a{text-decoration:underline;font-weight:700}.container ::ng-deep a:hover{opacity:.85}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
23599
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopupAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23600
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: PopupAlertComponent, isStandalone: true, selector: "gn-ui-popup-alert", inputs: { icon: "icon", type: "type", position: "position" }, providers: [
|
|
23601
|
+
provideIcons({ matErrorOutlineOutline }),
|
|
23602
|
+
provideNgIconsConfig({
|
|
23603
|
+
size: '1.5em',
|
|
23604
|
+
}),
|
|
23605
|
+
], viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<div class=\"h-full relative container\">\n <div\n class=\"pointer-events-auto absolute text-white flex flex-row p-2 rounded message\"\n role=\"alert\"\n [ngClass]=\"{\n 'position-bottom': position === 'bottom',\n 'position-top': position === 'top',\n expanded: this.expanded,\n 'bg-red-500': type === 'danger',\n 'bg-yellow-500': type === 'warning',\n 'bg-blue-500': type === 'info',\n }\"\n (mouseenter)=\"expand()\"\n (mouseleave)=\"expandAndClose()\"\n >\n <ng-icon class=\"mr-2 shrink-0 select-none\" [name]=\"icon\"></ng-icon>\n <div class=\"grow\" #content [ngClass]=\"{ invisible: !expanded }\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", styles: [":host{pointer-events:none}.container{filter:drop-shadow(0px 4px 3px rgba(0,0,0,.2))}.message{transition:clip-path .3s cubic-bezier(.25,.46,.45,.94)}.message.expanded{clip-path:circle(100%)}.position-top{clip-path:circle(19px at 20px 20px);align-items:start;top:0;left:0}.position-bottom{clip-path:circle(19px at 20px calc(100% - 20px));align-items:end;bottom:0;left:0}.container ::ng-deep a{text-decoration:underline;font-weight:700}.container ::ng-deep a:hover{opacity:.85}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
24159
23606
|
}
|
|
24160
23607
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopupAlertComponent, decorators: [{
|
|
24161
23608
|
type: Component,
|
|
@@ -24304,15 +23751,15 @@ class AutocompleteComponent {
|
|
|
24304
23751
|
getExtraClass() {
|
|
24305
23752
|
if (this.allowSubmit) {
|
|
24306
23753
|
if (this.enterButton) {
|
|
24307
|
-
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+var(--icon-padding))]
|
|
23754
|
+
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+var(--icon-padding))] top-1/2 -translate-y-1/2';
|
|
24308
23755
|
}
|
|
24309
23756
|
else {
|
|
24310
|
-
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+0.25*var(--icon-width))]
|
|
23757
|
+
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+0.25*var(--icon-width))] top-1/2 -translate-y-1/2';
|
|
24311
23758
|
}
|
|
24312
23759
|
}
|
|
24313
23760
|
else {
|
|
24314
23761
|
if (!this.enterButton) {
|
|
24315
|
-
return 'border rounded-lg absolute w-8 h-8 right-2
|
|
23762
|
+
return 'border rounded-lg absolute w-8 h-8 right-2 top-1/2 -translate-y-1/2';
|
|
24316
23763
|
}
|
|
24317
23764
|
}
|
|
24318
23765
|
return 'border rounded-lg absolute w-8 h-8';
|
|
@@ -24448,7 +23895,7 @@ class AutocompleteComponent {
|
|
|
24448
23895
|
this.enterBtnPosition = event.target['value'].length * 8 + 80;
|
|
24449
23896
|
}
|
|
24450
23897
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24451
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: AutocompleteComponent, isStandalone: true, selector: "gn-ui-autocomplete", inputs: { placeholder: "placeholder", enterButton: "enterButton", action: "action", value: "value", clearOnSelection: "clearOnSelection", preventCompleteOnSelection: "preventCompleteOnSelection", autoFocus: "autoFocus", minCharacterCount: "minCharacterCount", allowSubmit: "allowSubmit", forceTrackPosition: "forceTrackPosition", displayWithFn: "displayWithFn" }, outputs: { itemSelected: "itemSelected", inputSubmitted: "inputSubmitted", inputCleared: "inputCleared", isSearchActive: "isSearchActive" }, providers: [
|
|
23898
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: AutocompleteComponent, isStandalone: true, selector: "gn-ui-autocomplete", inputs: { placeholder: "placeholder", enterButton: "enterButton", action: "action", value: "value", clearOnSelection: "clearOnSelection", preventCompleteOnSelection: "preventCompleteOnSelection", autoFocus: "autoFocus", minCharacterCount: "minCharacterCount", allowSubmit: "allowSubmit", forceTrackPosition: "forceTrackPosition", displayWithTemplate: "displayWithTemplate", displayWithFn: "displayWithFn" }, outputs: { itemSelected: "itemSelected", inputSubmitted: "inputSubmitted", inputCleared: "inputCleared", isSearchActive: "isSearchActive" }, providers: [
|
|
24452
23899
|
provideIcons({
|
|
24453
23900
|
iconoirSearch,
|
|
24454
23901
|
matClose,
|
|
@@ -24457,7 +23904,7 @@ class AutocompleteComponent {
|
|
|
24457
23904
|
provideNgIconsConfig({
|
|
24458
23905
|
size: '1.75rem',
|
|
24459
23906
|
}),
|
|
24460
|
-
], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: MatAutocompleteTrigger, descendants: true }, { propertyName: "autocomplete", first: true, predicate: MatAutocomplete, descendants: true }, { propertyName: "inputRef", first: true, predicate: ["searchInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<span class=\"w-full inline-block relative\">\n @if (!allowSubmit) {\n <div\n class=\"absolute inset-y-[--icon-padding] left-[--icon-padding] w-[--icon-width] pointer-events-none\"\n >\n <ng-icon name=\"iconoirSearch\" class=\"text-primary
|
|
23907
|
+
], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: MatAutocompleteTrigger, descendants: true }, { propertyName: "autocomplete", first: true, predicate: MatAutocomplete, descendants: true }, { propertyName: "inputRef", first: true, predicate: ["searchInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<span class=\"w-full inline-block relative\">\n @if (!allowSubmit) {\n <div\n class=\"absolute inset-y-[--icon-padding] left-[--icon-padding] w-[--icon-width] pointer-events-none flex items-center justify-center\"\n >\n <ng-icon name=\"iconoirSearch\" class=\"text-primary\"></ng-icon>\n </div>\n }\n <div class=\"flex flex-row\">\n <input\n #searchInput\n type=\"text\"\n class=\"gn-ui-text-input\"\n (input)=\"handleInput($event)\"\n [placeholder]=\"placeholder\"\n [formControl]=\"control\"\n [matAutocomplete]=\"auto\"\n (keyup.enter)=\"handleSearch()\"\n [ngClass]=\"{\n 'text-primary': searchActive && enterButton,\n 'text-gray-900': !searchActive,\n 'px-[--icon-width]': !allowSubmit,\n }\"\n />\n @if (searchInput.value && displayEnterBtn) {\n <gn-ui-button\n type=\"gray\"\n extraClass=\"w-32 h-8 !opacity-100\"\n [ngStyle]=\"{ left: enterBtnPosition + 'px' }\"\n class=\"absolute\"\n disabled=\"true\"\n >\n <ng-icon\n name=\"iconoirLongArrowDownLeft\"\n class=\"!w-4 text-gray-900 font-bold\"\n ></ng-icon>\n <span translate class=\"text-bold text-gray-900 font-bold\">\n Enter to search\n </span>\n </gn-ui-button>\n }\n </div>\n @if (searchInput.value) {\n <gn-ui-button\n type=\"primary\"\n [extraClass]=\"getExtraClass()\"\n data-test=\"clear-btn\"\n aria-label=\"Clear\"\n (buttonClick)=\"clear()\"\n >\n <ng-icon class=\"text-white\" name=\"matClose\"></ng-icon>\n </gn-ui-button>\n }\n @if (allowSubmit) {\n <gn-ui-button\n type=\"light\"\n extraClass=\"border-0 border-l-[1px] border-gray-300 hover:border-gray-500 text-primary hover:text-primary-darkest focus:text-primary-darkest absolute inset-y-[--icon-padding] right-[--icon-padding]\"\n aria-label=\"Trigger search\"\n data-test=\"autocomplete-submit-btn\"\n (buttonClick)=\"handleSearch()\"\n >\n <ng-icon name=\"iconoirSearch\"></ng-icon>\n </gn-ui-button>\n }\n\n @if (error) {\n <gn-ui-popup-alert\n class=\"absolute mt-2 w-full top-[100%] left-0\"\n icon=\"matErrorOutlineOutline\"\n position=\"top\"\n type=\"warning\"\n >\n <span translate>search.autocomplete.error</span>\n {{ error }}\n </gn-ui-popup-alert>\n }\n</span>\n\n<mat-autocomplete\n #auto=\"matAutocomplete\"\n (optionSelected)=\"handleSelection($event)\"\n [displayWith]=\"displayWithFnInternal\"\n>\n @for (suggestion of suggestions$ | async; track suggestion) {\n <mat-option [value]=\"suggestion\" class=\"p-2 suggestion text-start\">\n @if (displayWithTemplate) {\n <ng-container\n *ngTemplateOutlet=\"\n displayWithTemplate;\n context: { $implicit: suggestion }\n \"\n ></ng-container>\n } @else {\n {{ displayWithFnInternal(suggestion) }}\n }\n </mat-option>\n }\n</mat-autocomplete>\n", styles: ["span{--icon-padding: var(--gn-ui-text-input-border-size, 2px);--icon-width: calc(var(--gn-ui-text-input-padding, .6em) * 2 + 1.25em)}span>*:not(gn-ui-popup-alert){font-size:var(--gn-ui-text-input-font-size, 1em)}input:placeholder-shown{text-overflow:ellipsis}gn-ui-button{--gn-ui-button-rounded: 0;--gn-ui-button-width: var(--icon-width);--gn-ui-button-padding: 0;font-size:1em}gn-ui-button:last-of-type{--gn-ui-button-rounded: 0 var(--gn-ui-text-input-rounded, .25em) var(--gn-ui-text-input-rounded, .25em) 0}.mat-mdc-option.suggestion.mat-mdc-option-active{background-color:var(--color-primary-lightest)}\n"], dependencies: [{ kind: "component", type: PopupAlertComponent, selector: "gn-ui-popup-alert", inputs: ["icon", "type", "position"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i1$2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i1$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i1$2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
24461
23908
|
}
|
|
24462
23909
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AutocompleteComponent, decorators: [{
|
|
24463
23910
|
type: Component,
|
|
@@ -24478,7 +23925,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
24478
23925
|
provideNgIconsConfig({
|
|
24479
23926
|
size: '1.75rem',
|
|
24480
23927
|
}),
|
|
24481
|
-
], template: "<span class=\"w-full inline-block relative\">\n @if (!allowSubmit) {\n <div\n class=\"absolute inset-y-[--icon-padding] left-[--icon-padding] w-[--icon-width] pointer-events-none\"\n >\n <ng-icon name=\"iconoirSearch\" class=\"text-primary
|
|
23928
|
+
], template: "<span class=\"w-full inline-block relative\">\n @if (!allowSubmit) {\n <div\n class=\"absolute inset-y-[--icon-padding] left-[--icon-padding] w-[--icon-width] pointer-events-none flex items-center justify-center\"\n >\n <ng-icon name=\"iconoirSearch\" class=\"text-primary\"></ng-icon>\n </div>\n }\n <div class=\"flex flex-row\">\n <input\n #searchInput\n type=\"text\"\n class=\"gn-ui-text-input\"\n (input)=\"handleInput($event)\"\n [placeholder]=\"placeholder\"\n [formControl]=\"control\"\n [matAutocomplete]=\"auto\"\n (keyup.enter)=\"handleSearch()\"\n [ngClass]=\"{\n 'text-primary': searchActive && enterButton,\n 'text-gray-900': !searchActive,\n 'px-[--icon-width]': !allowSubmit,\n }\"\n />\n @if (searchInput.value && displayEnterBtn) {\n <gn-ui-button\n type=\"gray\"\n extraClass=\"w-32 h-8 !opacity-100\"\n [ngStyle]=\"{ left: enterBtnPosition + 'px' }\"\n class=\"absolute\"\n disabled=\"true\"\n >\n <ng-icon\n name=\"iconoirLongArrowDownLeft\"\n class=\"!w-4 text-gray-900 font-bold\"\n ></ng-icon>\n <span translate class=\"text-bold text-gray-900 font-bold\">\n Enter to search\n </span>\n </gn-ui-button>\n }\n </div>\n @if (searchInput.value) {\n <gn-ui-button\n type=\"primary\"\n [extraClass]=\"getExtraClass()\"\n data-test=\"clear-btn\"\n aria-label=\"Clear\"\n (buttonClick)=\"clear()\"\n >\n <ng-icon class=\"text-white\" name=\"matClose\"></ng-icon>\n </gn-ui-button>\n }\n @if (allowSubmit) {\n <gn-ui-button\n type=\"light\"\n extraClass=\"border-0 border-l-[1px] border-gray-300 hover:border-gray-500 text-primary hover:text-primary-darkest focus:text-primary-darkest absolute inset-y-[--icon-padding] right-[--icon-padding]\"\n aria-label=\"Trigger search\"\n data-test=\"autocomplete-submit-btn\"\n (buttonClick)=\"handleSearch()\"\n >\n <ng-icon name=\"iconoirSearch\"></ng-icon>\n </gn-ui-button>\n }\n\n @if (error) {\n <gn-ui-popup-alert\n class=\"absolute mt-2 w-full top-[100%] left-0\"\n icon=\"matErrorOutlineOutline\"\n position=\"top\"\n type=\"warning\"\n >\n <span translate>search.autocomplete.error</span>\n {{ error }}\n </gn-ui-popup-alert>\n }\n</span>\n\n<mat-autocomplete\n #auto=\"matAutocomplete\"\n (optionSelected)=\"handleSelection($event)\"\n [displayWith]=\"displayWithFnInternal\"\n>\n @for (suggestion of suggestions$ | async; track suggestion) {\n <mat-option [value]=\"suggestion\" class=\"p-2 suggestion text-start\">\n @if (displayWithTemplate) {\n <ng-container\n *ngTemplateOutlet=\"\n displayWithTemplate;\n context: { $implicit: suggestion }\n \"\n ></ng-container>\n } @else {\n {{ displayWithFnInternal(suggestion) }}\n }\n </mat-option>\n }\n</mat-autocomplete>\n", styles: ["span{--icon-padding: var(--gn-ui-text-input-border-size, 2px);--icon-width: calc(var(--gn-ui-text-input-padding, .6em) * 2 + 1.25em)}span>*:not(gn-ui-popup-alert){font-size:var(--gn-ui-text-input-font-size, 1em)}input:placeholder-shown{text-overflow:ellipsis}gn-ui-button{--gn-ui-button-rounded: 0;--gn-ui-button-width: var(--icon-width);--gn-ui-button-padding: 0;font-size:1em}gn-ui-button:last-of-type{--gn-ui-button-rounded: 0 var(--gn-ui-text-input-rounded, .25em) var(--gn-ui-text-input-rounded, .25em) 0}.mat-mdc-option.suggestion.mat-mdc-option-active{background-color:var(--color-primary-lightest)}\n"] }]
|
|
24482
23929
|
}], propDecorators: { placeholder: [{
|
|
24483
23930
|
type: Input
|
|
24484
23931
|
}], enterButton: [{
|
|
@@ -24516,6 +23963,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
24516
23963
|
}], inputRef: [{
|
|
24517
23964
|
type: ViewChild,
|
|
24518
23965
|
args: ['searchInput']
|
|
23966
|
+
}], displayWithTemplate: [{
|
|
23967
|
+
type: Input
|
|
24519
23968
|
}], displayWithFn: [{
|
|
24520
23969
|
type: Input
|
|
24521
23970
|
}] } });
|
|
@@ -25000,7 +24449,7 @@ class DropdownMultiselectComponent {
|
|
|
25000
24449
|
}
|
|
25001
24450
|
setFocus() {
|
|
25002
24451
|
setTimeout(() => {
|
|
25003
|
-
this.searchFieldInput
|
|
24452
|
+
this.searchFieldInput?.nativeElement.focus();
|
|
25004
24453
|
}, 0);
|
|
25005
24454
|
}
|
|
25006
24455
|
openOverlay() {
|
|
@@ -25106,7 +24555,10 @@ class DropdownMultiselectComponent {
|
|
|
25106
24555
|
matExpandMore,
|
|
25107
24556
|
matExpandLess,
|
|
25108
24557
|
}),
|
|
25109
|
-
|
|
24558
|
+
provideNgIconsConfig({
|
|
24559
|
+
size: '1.5rem',
|
|
24560
|
+
}),
|
|
24561
|
+
], viewQueries: [{ propertyName: "overlayOrigin", first: true, predicate: ["overlayOrigin"], descendants: true }, { propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "overlayContainer", first: true, predicate: ["overlayContainer"], descendants: true, read: ElementRef }, { propertyName: "searchFieldInput", first: true, predicate: ["searchFieldInput"], descendants: true }, { propertyName: "checkboxes", predicate: ["checkBox"], descendants: true, read: ElementRef }], ngImport: i0, template: "<gn-ui-button\n type=\"outline\"\n extraClass=\"bg-background w-full !p-[8px] !pl-[16px]\"\n [title]=\"title\"\n [attr.aria-owns]=\"id\"\n (buttonClick)=\"openOverlay()\"\n (keydown)=\"handleTriggerKeydown($event)\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n>\n <div class=\"grow flex items-center mr-2 gap-2 overflow-hidden\">\n <div class=\"text-left font-medium truncate py-1\">\n {{ title }}\n </div>\n @if (hasSelectedChoices) {\n <div\n class=\"gn-ui-multiselect-counter shrink-0 rounded-full font-bold text-[12px] w-5 h-5 flex items-center justify-center mr-1 selected-count\"\n >\n {{ selected.length }}\n </div>\n }\n </div>\n <button\n class=\"h-6 w-6 flex items-center justify-center\"\n data-test=\"dropdown-clear\"\n >\n @if (hasSelectedChoices && !overlayOpen) {\n <ng-icon\n class=\"shrink-0 opacity-40 hover:opacity-80 transition-colors clear-btn\"\n (click)=\"clearSelection($event)\"\n name=\"matClose\"\n ></ng-icon>\n }\n </button>\n <ng-icon\n [name]=\"overlayOpen ? 'matExpandLess' : 'matExpandMore'\"\n class=\"shrink-0 opacity-40\"\n >\n </ng-icon>\n</gn-ui-button>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-300 rounded shadow-lg py-2 w-full overflow-x-hidden overflow-y-auto overlay-container\"\n [style.max-height]=\"overlayMaxHeight\"\n [style.min-width]=\"overlayMinWidth\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.id]=\"id\"\n [attr.aria-multiselectable]=\"true\"\n [attr.aria-label]=\"title\"\n (keydown)=\"handleOverlayKeydown($event)\"\n #overlayContainer\n >\n <div\n class=\"border border-gray-300 rounded mb-2 mx-2 min-h-[44px] flex flex-row gap-1 flex-wrap p-2 focus-within:rounded focus-within:border-2 focus-within:border-primary\"\n >\n @for (selected of selectedChoices; track selected) {\n <button\n type=\"button\"\n [title]=\"selected.label\"\n class=\"max-w-full bg-main text-white rounded pr-[7px] flex gap-1 items-center opacity-70 hover:opacity-100 focus:opacity-100 transition-opacity\"\n (click)=\"select(selected, false)\"\n >\n <div class=\"text-sm truncate leading-[26px] px-2\">\n {{ selected.label }}\n </div>\n <div\n class=\"flex items-center justify-center rounded-full bg-white text-main h-[13px] w-[13px] pt-px -mt-px shrink-0\"\n >\n <ng-icon\n name=\"matClose\"\n class=\"!h-[12px] !w-[11px] text-[12px]\"\n ></ng-icon>\n </div>\n </button>\n }\n\n @if (allowSearch) {\n <div class=\"w-[50%] relative grow shrink\">\n <input\n #searchFieldInput\n class=\"w-full px-2 truncate text-[14px] h-full overlaySearchInput focus:outline-none\"\n [(ngModel)]=\"searchInputValue\"\n [placeholder]=\"'multiselect.filter.placeholder' | translate\"\n />\n @if (!!searchInputValue) {\n <button\n class=\"absolute top-1/2 -translate-y-1/2 right-0 px-[7px] leading-tight clear-search-input mr-2\"\n (click)=\"clearSearchInputValue($event)\"\n >\n <ng-icon class=\"!h-[10px] !w-[12px] text-[12px]\" name=\"matClose\">\n </ng-icon>\n </button>\n }\n </div>\n }\n </div>\n\n @for (choice of filteredChoicesByText; track choice) {\n <label\n [title]=\"choice.label\"\n class=\"flex px-5 py-1 w-full text-gray-900 cursor-pointer hover:text-primary-darkest hover:bg-gray-50 focus-within:text-primary-darkest focus-within:bg-gray-50 transition-colors\"\n >\n <input\n class=\"w-[18px] h-[18px] align-text-top shrink-0\"\n type=\"checkbox\"\n #checkBox\n [checked]=\"isSelected(choice)\"\n (change)=\"select(choice, checkBox.checked)\"\n />\n <span class=\"ml-[8px] text-[14px] truncate\">\n {{ choice.label }}\n </span>\n </label>\n }\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$7.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$7.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
25110
24562
|
}
|
|
25111
24563
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: DropdownMultiselectComponent, decorators: [{
|
|
25112
24564
|
type: Component,
|
|
@@ -25116,7 +24568,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
25116
24568
|
matExpandMore,
|
|
25117
24569
|
matExpandLess,
|
|
25118
24570
|
}),
|
|
25119
|
-
|
|
24571
|
+
provideNgIconsConfig({
|
|
24572
|
+
size: '1.5rem',
|
|
24573
|
+
}),
|
|
24574
|
+
], standalone: true, template: "<gn-ui-button\n type=\"outline\"\n extraClass=\"bg-background w-full !p-[8px] !pl-[16px]\"\n [title]=\"title\"\n [attr.aria-owns]=\"id\"\n (buttonClick)=\"openOverlay()\"\n (keydown)=\"handleTriggerKeydown($event)\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n>\n <div class=\"grow flex items-center mr-2 gap-2 overflow-hidden\">\n <div class=\"text-left font-medium truncate py-1\">\n {{ title }}\n </div>\n @if (hasSelectedChoices) {\n <div\n class=\"gn-ui-multiselect-counter shrink-0 rounded-full font-bold text-[12px] w-5 h-5 flex items-center justify-center mr-1 selected-count\"\n >\n {{ selected.length }}\n </div>\n }\n </div>\n <button\n class=\"h-6 w-6 flex items-center justify-center\"\n data-test=\"dropdown-clear\"\n >\n @if (hasSelectedChoices && !overlayOpen) {\n <ng-icon\n class=\"shrink-0 opacity-40 hover:opacity-80 transition-colors clear-btn\"\n (click)=\"clearSelection($event)\"\n name=\"matClose\"\n ></ng-icon>\n }\n </button>\n <ng-icon\n [name]=\"overlayOpen ? 'matExpandLess' : 'matExpandMore'\"\n class=\"shrink-0 opacity-40\"\n >\n </ng-icon>\n</gn-ui-button>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-300 rounded shadow-lg py-2 w-full overflow-x-hidden overflow-y-auto overlay-container\"\n [style.max-height]=\"overlayMaxHeight\"\n [style.min-width]=\"overlayMinWidth\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.id]=\"id\"\n [attr.aria-multiselectable]=\"true\"\n [attr.aria-label]=\"title\"\n (keydown)=\"handleOverlayKeydown($event)\"\n #overlayContainer\n >\n <div\n class=\"border border-gray-300 rounded mb-2 mx-2 min-h-[44px] flex flex-row gap-1 flex-wrap p-2 focus-within:rounded focus-within:border-2 focus-within:border-primary\"\n >\n @for (selected of selectedChoices; track selected) {\n <button\n type=\"button\"\n [title]=\"selected.label\"\n class=\"max-w-full bg-main text-white rounded pr-[7px] flex gap-1 items-center opacity-70 hover:opacity-100 focus:opacity-100 transition-opacity\"\n (click)=\"select(selected, false)\"\n >\n <div class=\"text-sm truncate leading-[26px] px-2\">\n {{ selected.label }}\n </div>\n <div\n class=\"flex items-center justify-center rounded-full bg-white text-main h-[13px] w-[13px] pt-px -mt-px shrink-0\"\n >\n <ng-icon\n name=\"matClose\"\n class=\"!h-[12px] !w-[11px] text-[12px]\"\n ></ng-icon>\n </div>\n </button>\n }\n\n @if (allowSearch) {\n <div class=\"w-[50%] relative grow shrink\">\n <input\n #searchFieldInput\n class=\"w-full px-2 truncate text-[14px] h-full overlaySearchInput focus:outline-none\"\n [(ngModel)]=\"searchInputValue\"\n [placeholder]=\"'multiselect.filter.placeholder' | translate\"\n />\n @if (!!searchInputValue) {\n <button\n class=\"absolute top-1/2 -translate-y-1/2 right-0 px-[7px] leading-tight clear-search-input mr-2\"\n (click)=\"clearSearchInputValue($event)\"\n >\n <ng-icon class=\"!h-[10px] !w-[12px] text-[12px]\" name=\"matClose\">\n </ng-icon>\n </button>\n }\n </div>\n }\n </div>\n\n @for (choice of filteredChoicesByText; track choice) {\n <label\n [title]=\"choice.label\"\n class=\"flex px-5 py-1 w-full text-gray-900 cursor-pointer hover:text-primary-darkest hover:bg-gray-50 focus-within:text-primary-darkest focus-within:bg-gray-50 transition-colors\"\n >\n <input\n class=\"w-[18px] h-[18px] align-text-top shrink-0\"\n type=\"checkbox\"\n #checkBox\n [checked]=\"isSelected(choice)\"\n (change)=\"select(choice, checkBox.checked)\"\n />\n <span class=\"ml-[8px] text-[14px] truncate\">\n {{ choice.label }}\n </span>\n </label>\n }\n </div>\n</ng-template>\n" }]
|
|
25120
24575
|
}], propDecorators: { title: [{
|
|
25121
24576
|
type: Input
|
|
25122
24577
|
}], choices: [{
|
|
@@ -25946,7 +25401,8 @@ class SearchFeatureCatalogComponent {
|
|
|
25946
25401
|
const filtered = (this.featureCatalog?.featureTypes || []).filter((featureType) => {
|
|
25947
25402
|
const fuzzyFilter = createFuzzyFilter(searchTerm);
|
|
25948
25403
|
return (fuzzyFilter(featureType.name) ||
|
|
25949
|
-
(featureType.
|
|
25404
|
+
(featureType.description &&
|
|
25405
|
+
fuzzyFilter(featureType.description)));
|
|
25950
25406
|
});
|
|
25951
25407
|
this.filteredFeatureCatalog = {
|
|
25952
25408
|
...this.featureCatalog,
|
|
@@ -26031,8 +25487,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
26031
25487
|
marker('search.filters.spatialExtent.import');
|
|
26032
25488
|
marker('search.filters.spatialExtent.helpText');
|
|
26033
25489
|
marker('search.filters.spatialExtent.error.title');
|
|
25490
|
+
marker('search.filters.spatialExtent.error.outOfBounds');
|
|
26034
25491
|
const LABEL_FROM_FILE = marker('search.filters.spatialExtent.bboxFromFile');
|
|
26035
25492
|
const LABEL_FROM_FILE_DELETE = marker('search.filters.spatialExtent.bboxFromFileDelete');
|
|
25493
|
+
const LABEL_FROM_LOCATION = marker('search.filters.spatialExtent.bboxFromLocation');
|
|
25494
|
+
const LABEL_FROM_LOCATION_DELETE = marker('search.filters.spatialExtent.bboxFromLocationDelete');
|
|
26036
25495
|
const LABEL_INITIAL = marker('search.filters.spatialExtent.bboxInitial');
|
|
26037
25496
|
const LABEL_INITIAL_DELETE = marker('search.filters.spatialExtent.bboxInitialDelete');
|
|
26038
25497
|
class SpatialExtentDropdownComponent {
|
|
@@ -26044,6 +25503,7 @@ class SpatialExtentDropdownComponent {
|
|
|
26044
25503
|
this.errorChange = new EventEmitter();
|
|
26045
25504
|
this.bbox = null;
|
|
26046
25505
|
this.fileName = '';
|
|
25506
|
+
this.locationName = '';
|
|
26047
25507
|
this.overlayPositions = [
|
|
26048
25508
|
{
|
|
26049
25509
|
originX: 'start',
|
|
@@ -26074,13 +25534,21 @@ class SpatialExtentDropdownComponent {
|
|
|
26074
25534
|
return !!this.bbox;
|
|
26075
25535
|
}
|
|
26076
25536
|
get selectionLabelKey() {
|
|
26077
|
-
|
|
25537
|
+
if (this.fileName)
|
|
25538
|
+
return LABEL_FROM_FILE;
|
|
25539
|
+
if (this.locationName)
|
|
25540
|
+
return LABEL_FROM_LOCATION;
|
|
25541
|
+
return LABEL_INITIAL;
|
|
26078
25542
|
}
|
|
26079
25543
|
get selectionDeleteLabelKey() {
|
|
26080
|
-
|
|
25544
|
+
if (this.fileName)
|
|
25545
|
+
return LABEL_FROM_FILE_DELETE;
|
|
25546
|
+
if (this.locationName)
|
|
25547
|
+
return LABEL_FROM_LOCATION_DELETE;
|
|
25548
|
+
return LABEL_INITIAL_DELETE;
|
|
26081
25549
|
}
|
|
26082
25550
|
get selectionLabelParams() {
|
|
26083
|
-
return { fileName: this.fileName };
|
|
25551
|
+
return { fileName: this.fileName, locationName: this.locationName };
|
|
26084
25552
|
}
|
|
26085
25553
|
openOverlay() {
|
|
26086
25554
|
this.overlayMinWidth =
|
|
@@ -26111,8 +25579,13 @@ class SpatialExtentDropdownComponent {
|
|
|
26111
25579
|
return;
|
|
26112
25580
|
}
|
|
26113
25581
|
const bbox = getGeometryBoundingBox(geometry);
|
|
25582
|
+
if (!isBoundingBoxWithinWorldExtent(bbox)) {
|
|
25583
|
+
this.setError(marker('search.filters.spatialExtent.error.outOfBounds'));
|
|
25584
|
+
return;
|
|
25585
|
+
}
|
|
26114
25586
|
this.bbox = bbox;
|
|
26115
25587
|
this.fileName = file.name;
|
|
25588
|
+
this.locationName = '';
|
|
26116
25589
|
this.bboxChange.emit(bbox);
|
|
26117
25590
|
this.cd.markForCheck();
|
|
26118
25591
|
}
|
|
@@ -26121,6 +25594,15 @@ class SpatialExtentDropdownComponent {
|
|
|
26121
25594
|
return;
|
|
26122
25595
|
}
|
|
26123
25596
|
}
|
|
25597
|
+
setLocationBbox(bbox, name) {
|
|
25598
|
+
this.errorKey = null;
|
|
25599
|
+
this.bbox = bbox;
|
|
25600
|
+
this.locationName = name;
|
|
25601
|
+
this.fileName = '';
|
|
25602
|
+
this.fileInput?.clear();
|
|
25603
|
+
this.bboxChange.emit(bbox);
|
|
25604
|
+
this.cd.markForCheck();
|
|
25605
|
+
}
|
|
26124
25606
|
handleFileError(error) {
|
|
26125
25607
|
if (error === 'file-too-large') {
|
|
26126
25608
|
this.setError(marker('search.filters.spatialExtent.error.fileTooLarge'), {
|
|
@@ -26139,6 +25621,7 @@ class SpatialExtentDropdownComponent {
|
|
|
26139
25621
|
removeSelection(event) {
|
|
26140
25622
|
this.bbox = null;
|
|
26141
25623
|
this.fileName = '';
|
|
25624
|
+
this.locationName = '';
|
|
26142
25625
|
this.errorKey = null;
|
|
26143
25626
|
this.fileInput?.clear();
|
|
26144
25627
|
this.bboxChange.emit(null);
|
|
@@ -26148,14 +25631,14 @@ class SpatialExtentDropdownComponent {
|
|
|
26148
25631
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: SpatialExtentDropdownComponent, isStandalone: true, selector: "gn-ui-spatial-extent-dropdown", inputs: { title: "title", maxFileSizeMb: "maxFileSizeMb", initialBbox: "initialBbox" }, outputs: { bboxChange: "bboxChange", errorChange: "errorChange" }, providers: [
|
|
26149
25632
|
provideIcons({
|
|
26150
25633
|
iconoirCheckCircle,
|
|
26151
|
-
iconoirImport,
|
|
26152
25634
|
iconoirSquareDashed,
|
|
26153
25635
|
iconoirTrash,
|
|
25636
|
+
iconoirUpload,
|
|
26154
25637
|
matClose,
|
|
26155
25638
|
matExpandLess,
|
|
26156
25639
|
matExpandMore,
|
|
26157
25640
|
}),
|
|
26158
|
-
], viewQueries: [{ propertyName: "overlayOrigin", first: true, predicate: ["overlayOrigin"], descendants: true }, { propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "fileInput", first: true, predicate: DragAndDropFileInputComponent, descendants: true }], ngImport: i0, template: "<gn-ui-button\n type=\"outline\"\n extraClass=\"bg-background w-full !p-[8px] !pl-[16px]\"\n [title]=\"title\"\n (buttonClick)=\"toggleOverlay()\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n>\n <div class=\"grow flex items-center mr-2 gap-2 overflow-hidden\">\n <div class=\"text-left font-medium truncate py-1\">\n {{ title }}\n </div>\n @if (hasSelection) {\n <div\n class=\"bg-primary-lighter text-white shrink-0 rounded-full font-bold text-[12px] w-[22px] h-[22px] flex items-center justify-center\"\n >\n 1\n </div>\n }\n </div>\n <button class=\"h-6 w-6 flex items-center\" data-cy=\"clearSelection\">\n @if (hasSelection && !overlayOpen) {\n <ng-icon\n class=\"shrink-0 opacity-40 mr-1.5 hover:opacity-80 transition-colors clear-btn\"\n (click)=\"removeSelection($event)\"\n name=\"matClose\"\n ></ng-icon>\n }\n </button>\n <ng-icon\n [name]=\"overlayOpen ? 'matExpandLess' : 'matExpandMore'\"\n class=\"shrink-0 opacity-40\"\n >\n </ng-icon>\n</gn-ui-button>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-400 rounded shadow-lg pt-[12px] px-[16px] overlay-container w-[280px] flex flex-col gap-2\"\n [style.min-width]=\"overlayMinWidth\"\n >\n <div class=\"text-xs text-black\">\n {{ 'search.filters.spatialExtent.helpText' | translate }}\n </div>\n\n <div\n [class]=\"\n (hasSelection\n ? 'border-b-[1px] border-gray-400 pb-[20px]'\n : 'pb-[
|
|
25641
|
+
], viewQueries: [{ propertyName: "overlayOrigin", first: true, predicate: ["overlayOrigin"], descendants: true }, { propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "fileInput", first: true, predicate: DragAndDropFileInputComponent, descendants: true }], ngImport: i0, template: "<gn-ui-button\n type=\"outline\"\n extraClass=\"bg-background w-full !p-[8px] !pl-[16px]\"\n [title]=\"title\"\n (buttonClick)=\"toggleOverlay()\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n>\n <div class=\"grow flex items-center mr-2 gap-2 overflow-hidden\">\n <div class=\"text-left font-medium truncate py-1\">\n {{ title }}\n </div>\n @if (hasSelection) {\n <div\n class=\"bg-primary-lighter text-white shrink-0 rounded-full font-bold text-[12px] w-[22px] h-[22px] flex items-center justify-center\"\n >\n 1\n </div>\n }\n </div>\n <button class=\"h-6 w-6 flex items-center\" data-cy=\"clearSelection\">\n @if (hasSelection && !overlayOpen) {\n <ng-icon\n class=\"shrink-0 opacity-40 mr-1.5 hover:opacity-80 transition-colors clear-btn\"\n (click)=\"removeSelection($event)\"\n name=\"matClose\"\n ></ng-icon>\n }\n </button>\n <ng-icon\n [name]=\"overlayOpen ? 'matExpandLess' : 'matExpandMore'\"\n class=\"shrink-0 opacity-40\"\n >\n </ng-icon>\n</gn-ui-button>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-400 rounded shadow-lg pt-[12px] px-[16px] overlay-container w-[280px] flex flex-col gap-2\"\n [style.min-width]=\"overlayMinWidth\"\n >\n <div class=\"text-xs text-black\">\n {{ 'search.filters.spatialExtent.helpText' | translate }}\n </div>\n\n <div\n [class]=\"\n (hasSelection\n ? 'border-b-[1px] border-gray-400 pb-[20px]'\n : 'pb-[12px]') + ' text-black flex flex-col gap-[8px]'\n \"\n style=\"\n --gn-ui-text-input-rounded: 8px;\n --gn-ui-text-input-border-size: 1px;\n --gn-ui-text-input-padding: 6px;\n \"\n >\n <gn-ui-drag-and-drop-file-input\n accept=\".json,.geojson\"\n [placeholder]=\"'search.filters.spatialExtent.import' | translate\"\n [maxFileSizeMb]=\"maxFileSizeMb\"\n [showFileName]=\"false\"\n textClass=\"text-black truncate\"\n dropzoneBackgroundColor=\"transparent\"\n icon=\"iconoirUpload\"\n extraClass=\"gn-ui-gray-outline-input w-full !h-[32px] px-[8px] py-[4px] justify-between\"\n (fileChange)=\"handleFileSelected($event)\"\n (errorChange)=\"handleFileError($event)\"\n data-cy=\"importGeojson\"\n ></gn-ui-drag-and-drop-file-input>\n <ng-content></ng-content>\n </div>\n\n @if (hasSelection) {\n <gn-ui-button\n [type]=\"'primary-light'\"\n [title]=\"selectionDeleteLabelKey | translate: selectionLabelParams\"\n (buttonClick)=\"removeSelection($event)\"\n extraClass=\"group gap-x-2 w-full h-[28px] px-[8px] py-[4px] mb-[12px] bg-primary-lighter text-white\"\n data-test=\"spatial-extent-selected-item\"\n >\n <ng-icon\n name=\"iconoirSquareDashed\"\n class=\"shrink-0\"\n size=\"15px\"\n ></ng-icon>\n <span class=\"group-hover:hidden truncate text-sm m-auto\">\n {{ selectionLabelKey | translate: selectionLabelParams }}\n </span>\n <span class=\"hidden group-hover:block truncate text-sm m-auto\">\n {{ selectionDeleteLabelKey | translate: selectionLabelParams }}\n </span>\n <ng-icon\n name=\"iconoirCheckCircle\"\n class=\"group-hover:hidden shrink-0\"\n size=\"14px\"\n ></ng-icon>\n <ng-icon\n name=\"iconoirTrash\"\n class=\"!hidden group-hover:!block shrink-0\"\n size=\"15px\"\n ></ng-icon>\n </gn-ui-button>\n }\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$7.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$7.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: DragAndDropFileInputComponent, selector: "gn-ui-drag-and-drop-file-input", inputs: ["placeholder", "accept", "maxFileSizeMb", "icon", "dropzoneBackgroundColor", "textClass", "extraClass", "showFileName"], outputs: ["fileChange", "errorChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
26159
25642
|
}
|
|
26160
25643
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SpatialExtentDropdownComponent, decorators: [{
|
|
26161
25644
|
type: Component,
|
|
@@ -26168,14 +25651,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
26168
25651
|
], providers: [
|
|
26169
25652
|
provideIcons({
|
|
26170
25653
|
iconoirCheckCircle,
|
|
26171
|
-
iconoirImport,
|
|
26172
25654
|
iconoirSquareDashed,
|
|
26173
25655
|
iconoirTrash,
|
|
25656
|
+
iconoirUpload,
|
|
26174
25657
|
matClose,
|
|
26175
25658
|
matExpandLess,
|
|
26176
25659
|
matExpandMore,
|
|
26177
25660
|
}),
|
|
26178
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<gn-ui-button\n type=\"outline\"\n extraClass=\"bg-background w-full !p-[8px] !pl-[16px]\"\n [title]=\"title\"\n (buttonClick)=\"toggleOverlay()\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n>\n <div class=\"grow flex items-center mr-2 gap-2 overflow-hidden\">\n <div class=\"text-left font-medium truncate py-1\">\n {{ title }}\n </div>\n @if (hasSelection) {\n <div\n class=\"bg-primary-lighter text-white shrink-0 rounded-full font-bold text-[12px] w-[22px] h-[22px] flex items-center justify-center\"\n >\n 1\n </div>\n }\n </div>\n <button class=\"h-6 w-6 flex items-center\" data-cy=\"clearSelection\">\n @if (hasSelection && !overlayOpen) {\n <ng-icon\n class=\"shrink-0 opacity-40 mr-1.5 hover:opacity-80 transition-colors clear-btn\"\n (click)=\"removeSelection($event)\"\n name=\"matClose\"\n ></ng-icon>\n }\n </button>\n <ng-icon\n [name]=\"overlayOpen ? 'matExpandLess' : 'matExpandMore'\"\n class=\"shrink-0 opacity-40\"\n >\n </ng-icon>\n</gn-ui-button>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-400 rounded shadow-lg pt-[12px] px-[16px] overlay-container w-[280px] flex flex-col gap-2\"\n [style.min-width]=\"overlayMinWidth\"\n >\n <div class=\"text-xs text-black\">\n {{ 'search.filters.spatialExtent.helpText' | translate }}\n </div>\n\n <div\n [class]=\"\n (hasSelection\n ? 'border-b-[1px] border-gray-400 pb-[20px]'\n : 'pb-[
|
|
25661
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<gn-ui-button\n type=\"outline\"\n extraClass=\"bg-background w-full !p-[8px] !pl-[16px]\"\n [title]=\"title\"\n (buttonClick)=\"toggleOverlay()\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n>\n <div class=\"grow flex items-center mr-2 gap-2 overflow-hidden\">\n <div class=\"text-left font-medium truncate py-1\">\n {{ title }}\n </div>\n @if (hasSelection) {\n <div\n class=\"bg-primary-lighter text-white shrink-0 rounded-full font-bold text-[12px] w-[22px] h-[22px] flex items-center justify-center\"\n >\n 1\n </div>\n }\n </div>\n <button class=\"h-6 w-6 flex items-center\" data-cy=\"clearSelection\">\n @if (hasSelection && !overlayOpen) {\n <ng-icon\n class=\"shrink-0 opacity-40 mr-1.5 hover:opacity-80 transition-colors clear-btn\"\n (click)=\"removeSelection($event)\"\n name=\"matClose\"\n ></ng-icon>\n }\n </button>\n <ng-icon\n [name]=\"overlayOpen ? 'matExpandLess' : 'matExpandMore'\"\n class=\"shrink-0 opacity-40\"\n >\n </ng-icon>\n</gn-ui-button>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-400 rounded shadow-lg pt-[12px] px-[16px] overlay-container w-[280px] flex flex-col gap-2\"\n [style.min-width]=\"overlayMinWidth\"\n >\n <div class=\"text-xs text-black\">\n {{ 'search.filters.spatialExtent.helpText' | translate }}\n </div>\n\n <div\n [class]=\"\n (hasSelection\n ? 'border-b-[1px] border-gray-400 pb-[20px]'\n : 'pb-[12px]') + ' text-black flex flex-col gap-[8px]'\n \"\n style=\"\n --gn-ui-text-input-rounded: 8px;\n --gn-ui-text-input-border-size: 1px;\n --gn-ui-text-input-padding: 6px;\n \"\n >\n <gn-ui-drag-and-drop-file-input\n accept=\".json,.geojson\"\n [placeholder]=\"'search.filters.spatialExtent.import' | translate\"\n [maxFileSizeMb]=\"maxFileSizeMb\"\n [showFileName]=\"false\"\n textClass=\"text-black truncate\"\n dropzoneBackgroundColor=\"transparent\"\n icon=\"iconoirUpload\"\n extraClass=\"gn-ui-gray-outline-input w-full !h-[32px] px-[8px] py-[4px] justify-between\"\n (fileChange)=\"handleFileSelected($event)\"\n (errorChange)=\"handleFileError($event)\"\n data-cy=\"importGeojson\"\n ></gn-ui-drag-and-drop-file-input>\n <ng-content></ng-content>\n </div>\n\n @if (hasSelection) {\n <gn-ui-button\n [type]=\"'primary-light'\"\n [title]=\"selectionDeleteLabelKey | translate: selectionLabelParams\"\n (buttonClick)=\"removeSelection($event)\"\n extraClass=\"group gap-x-2 w-full h-[28px] px-[8px] py-[4px] mb-[12px] bg-primary-lighter text-white\"\n data-test=\"spatial-extent-selected-item\"\n >\n <ng-icon\n name=\"iconoirSquareDashed\"\n class=\"shrink-0\"\n size=\"15px\"\n ></ng-icon>\n <span class=\"group-hover:hidden truncate text-sm m-auto\">\n {{ selectionLabelKey | translate: selectionLabelParams }}\n </span>\n <span class=\"hidden group-hover:block truncate text-sm m-auto\">\n {{ selectionDeleteLabelKey | translate: selectionLabelParams }}\n </span>\n <ng-icon\n name=\"iconoirCheckCircle\"\n class=\"group-hover:hidden shrink-0\"\n size=\"14px\"\n ></ng-icon>\n <ng-icon\n name=\"iconoirTrash\"\n class=\"!hidden group-hover:!block shrink-0\"\n size=\"15px\"\n ></ng-icon>\n </gn-ui-button>\n }\n </div>\n</ng-template>\n" }]
|
|
26179
25662
|
}], propDecorators: { title: [{
|
|
26180
25663
|
type: Input
|
|
26181
25664
|
}], maxFileSizeMb: [{
|
|
@@ -26701,11 +26184,11 @@ class BlockListComponent {
|
|
|
26701
26184
|
this.goToPage(this.currentPage + 1);
|
|
26702
26185
|
}
|
|
26703
26186
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BlockListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
26704
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: BlockListComponent, isStandalone: true, selector: "gn-ui-block-list", inputs: { containerClass: "containerClass", paginationContainerClass: "paginationContainerClass" }, outputs: { listChanges: "listChanges" }, host: { listeners: { "window:resize": "onResize()" } }, queries: [{ propertyName: "blocks", predicate: ["block"], read: ElementRef }], viewQueries: [{ propertyName: "blockContainer", first: true, predicate: ["blockContainer"], descendants: true }], ngImport: i0, template: "<div\n class=\"grid gap-4 w-full sm:grid-cols-2\"\n #blockContainer\n [ngClass]=\"[containerClass, 'size-' + subComponentSize]\"\n>\n <ng-content></ng-content>\n</div>\n<gn-ui-pagination-dots\n [containerClass]=\"'absolute ' + paginationContainerClass\"\n [listComponent]=\"this\"\n></gn-ui-pagination-dots>\n", styles: [":host .block-list-container ::ng-deep>*{flex-shrink:0}:host{position:relative}@media screen and (min-width: 769px){.size-L{grid-template-columns:repeat(1,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-M{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-S{grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-XS{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PaginationDotsComponent, selector: "gn-ui-pagination-dots", inputs: ["listComponent", "containerClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
26187
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: BlockListComponent, isStandalone: true, selector: "gn-ui-block-list", inputs: { containerClass: "containerClass", paginationContainerClass: "paginationContainerClass" }, outputs: { listChanges: "listChanges" }, host: { listeners: { "window:resize": "onResize()" } }, queries: [{ propertyName: "blocks", predicate: ["block"], read: ElementRef }], viewQueries: [{ propertyName: "blockContainer", first: true, predicate: ["blockContainer"], descendants: true }], ngImport: i0, template: "<div\n class=\"grid gap-4 w-full sm:grid-cols-2\"\n #blockContainer\n [ngClass]=\"[containerClass, 'size-' + subComponentSize]\"\n>\n <ng-content></ng-content>\n</div>\n<gn-ui-pagination-dots\n [containerClass]=\"'absolute ' + paginationContainerClass\"\n [listComponent]=\"this\"\n></gn-ui-pagination-dots>\n", styles: [":host .block-list-container ::ng-deep>*{flex-shrink:0}:host{display:block;position:relative}@media screen and (min-width: 769px){.size-L{grid-template-columns:repeat(1,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-M{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-S{grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-XS{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PaginationDotsComponent, selector: "gn-ui-pagination-dots", inputs: ["listComponent", "containerClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
26705
26188
|
}
|
|
26706
26189
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BlockListComponent, decorators: [{
|
|
26707
26190
|
type: Component,
|
|
26708
|
-
args: [{ selector: 'gn-ui-block-list', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, PaginationDotsComponent], template: "<div\n class=\"grid gap-4 w-full sm:grid-cols-2\"\n #blockContainer\n [ngClass]=\"[containerClass, 'size-' + subComponentSize]\"\n>\n <ng-content></ng-content>\n</div>\n<gn-ui-pagination-dots\n [containerClass]=\"'absolute ' + paginationContainerClass\"\n [listComponent]=\"this\"\n></gn-ui-pagination-dots>\n", styles: [":host .block-list-container ::ng-deep>*{flex-shrink:0}:host{position:relative}@media screen and (min-width: 769px){.size-L{grid-template-columns:repeat(1,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-M{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-S{grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-XS{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}}\n"] }]
|
|
26191
|
+
args: [{ selector: 'gn-ui-block-list', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, PaginationDotsComponent], template: "<div\n class=\"grid gap-4 w-full sm:grid-cols-2\"\n #blockContainer\n [ngClass]=\"[containerClass, 'size-' + subComponentSize]\"\n>\n <ng-content></ng-content>\n</div>\n<gn-ui-pagination-dots\n [containerClass]=\"'absolute ' + paginationContainerClass\"\n [listComponent]=\"this\"\n></gn-ui-pagination-dots>\n", styles: [":host .block-list-container ::ng-deep>*{flex-shrink:0}:host{display:block;position:relative}@media screen and (min-width: 769px){.size-L{grid-template-columns:repeat(1,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-M{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-S{grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}.size-XS{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:minmax(0,min-content)}}\n"] }]
|
|
26709
26192
|
}], propDecorators: { containerClass: [{
|
|
26710
26193
|
type: Input
|
|
26711
26194
|
}], paginationContainerClass: [{
|
|
@@ -27444,9 +26927,7 @@ const initSearch = () => {
|
|
|
27444
26927
|
},
|
|
27445
26928
|
params: {
|
|
27446
26929
|
filters: {},
|
|
27447
|
-
pageSize:
|
|
27448
|
-
? getOptionalSearchConfig().LIMIT
|
|
27449
|
-
: DEFAULT_PAGE_SIZE,
|
|
26930
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
27450
26931
|
currentPage: 0,
|
|
27451
26932
|
favoritesOnly: false,
|
|
27452
26933
|
useSpatialFilter: true,
|
|
@@ -27895,6 +27376,146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
27895
27376
|
}]
|
|
27896
27377
|
}] });
|
|
27897
27378
|
|
|
27379
|
+
const DEFAULT_GEOCODING_PROVIDER = [
|
|
27380
|
+
'geonames',
|
|
27381
|
+
{ maxRows: 5 },
|
|
27382
|
+
];
|
|
27383
|
+
const GEOCODING_PROVIDER = new InjectionToken('geocoding-provider', {
|
|
27384
|
+
providedIn: 'root',
|
|
27385
|
+
factory: () => DEFAULT_GEOCODING_PROVIDER,
|
|
27386
|
+
});
|
|
27387
|
+
// these options are arrays in the providers, but they can be configured
|
|
27388
|
+
// with a single value for simplicity
|
|
27389
|
+
const GEOCODING_PROVIDER_ARRAY_OPTIONS = {
|
|
27390
|
+
geoadmin: ['origins', 'features'],
|
|
27391
|
+
geoplateforme: [
|
|
27392
|
+
'index',
|
|
27393
|
+
'category',
|
|
27394
|
+
'type',
|
|
27395
|
+
'postCode',
|
|
27396
|
+
'cityCode',
|
|
27397
|
+
'depCode',
|
|
27398
|
+
],
|
|
27399
|
+
};
|
|
27400
|
+
function wrapArrayOptions(options, keys) {
|
|
27401
|
+
const wrapped = { ...options };
|
|
27402
|
+
for (const key of keys) {
|
|
27403
|
+
if (typeof wrapped[key] === 'string') {
|
|
27404
|
+
wrapped[key] = [wrapped[key]];
|
|
27405
|
+
}
|
|
27406
|
+
}
|
|
27407
|
+
return wrapped;
|
|
27408
|
+
}
|
|
27409
|
+
class GeocodingService {
|
|
27410
|
+
constructor() {
|
|
27411
|
+
this.provider = inject(GEOCODING_PROVIDER);
|
|
27412
|
+
}
|
|
27413
|
+
query(text) {
|
|
27414
|
+
let queryObservable;
|
|
27415
|
+
switch (this.provider[0]) {
|
|
27416
|
+
case 'geoadmin':
|
|
27417
|
+
queryObservable = from(queryGeoadmin(text, wrapArrayOptions(this.provider[1], GEOCODING_PROVIDER_ARRAY_OPTIONS.geoadmin)));
|
|
27418
|
+
break;
|
|
27419
|
+
case 'geonames':
|
|
27420
|
+
queryObservable = from(queryGeonames(text, this.provider[1]));
|
|
27421
|
+
break;
|
|
27422
|
+
case 'geoplateforme':
|
|
27423
|
+
queryObservable = from(queryGeoplateforme(text, {
|
|
27424
|
+
...wrapArrayOptions(this.provider[1], GEOCODING_PROVIDER_ARRAY_OPTIONS.geoplateforme),
|
|
27425
|
+
returnTrueGeometry: true,
|
|
27426
|
+
}));
|
|
27427
|
+
break;
|
|
27428
|
+
default:
|
|
27429
|
+
return throwError(() => new Error(`Unsupported geocoding provider: ${this.provider[0]}`));
|
|
27430
|
+
}
|
|
27431
|
+
return queryObservable.pipe(catchError((error) => throwError(error)));
|
|
27432
|
+
}
|
|
27433
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
27434
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, providedIn: 'root' }); }
|
|
27435
|
+
}
|
|
27436
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, decorators: [{
|
|
27437
|
+
type: Injectable,
|
|
27438
|
+
args: [{
|
|
27439
|
+
providedIn: 'root',
|
|
27440
|
+
}]
|
|
27441
|
+
}] });
|
|
27442
|
+
|
|
27443
|
+
const GEOCODING_PROVIDER_LABELS = new InjectionToken('geocodingProviderLabels', {
|
|
27444
|
+
factory: () => ({}),
|
|
27445
|
+
});
|
|
27446
|
+
class LocationSearchComponent {
|
|
27447
|
+
constructor() {
|
|
27448
|
+
this.geocodingService = inject(GeocodingService);
|
|
27449
|
+
this.labels = inject(GEOCODING_PROVIDER_LABELS);
|
|
27450
|
+
this.placeholder = '';
|
|
27451
|
+
this.resultSelected = new EventEmitter();
|
|
27452
|
+
this.bboxSelected = new EventEmitter();
|
|
27453
|
+
this.displayWithFn = (item) => item.label;
|
|
27454
|
+
this.searchAction = (text) => this.geocodingService.query(text);
|
|
27455
|
+
}
|
|
27456
|
+
getSecondaryLabel(result) {
|
|
27457
|
+
return this.resolveLabel(result, this.labels.secondary);
|
|
27458
|
+
}
|
|
27459
|
+
getMainLabel(result) {
|
|
27460
|
+
return this.resolveLabel(result, this.labels.main) ?? result.label;
|
|
27461
|
+
}
|
|
27462
|
+
getTertiaryLabel(result) {
|
|
27463
|
+
return this.resolveLabel(result, this.labels.tertiary);
|
|
27464
|
+
}
|
|
27465
|
+
getDisplayLabel(result) {
|
|
27466
|
+
const tertiary = this.getTertiaryLabel(result);
|
|
27467
|
+
return this.getMainLabel(result) + (tertiary ? ', ' + tertiary : '');
|
|
27468
|
+
}
|
|
27469
|
+
resolveLabel(result, path) {
|
|
27470
|
+
if (!path)
|
|
27471
|
+
return undefined;
|
|
27472
|
+
let value;
|
|
27473
|
+
try {
|
|
27474
|
+
value = pointer.get(result, path);
|
|
27475
|
+
}
|
|
27476
|
+
catch {
|
|
27477
|
+
return undefined;
|
|
27478
|
+
}
|
|
27479
|
+
const values = Array.isArray(value) ? value : [value];
|
|
27480
|
+
const label = values
|
|
27481
|
+
.filter((v) => typeof v === 'string' || typeof v === 'number')
|
|
27482
|
+
.join(', ');
|
|
27483
|
+
return label || undefined;
|
|
27484
|
+
}
|
|
27485
|
+
// geoplateforme keeps a simplified geometry in geom and puts the real one,
|
|
27486
|
+
// as a JSON string, in properties.truegeometry when returnTrueGeometry is set
|
|
27487
|
+
getGeometry(result) {
|
|
27488
|
+
const trueGeometry = result.properties?.['truegeometry'];
|
|
27489
|
+
if (typeof trueGeometry === 'string') {
|
|
27490
|
+
return JSON.parse(trueGeometry);
|
|
27491
|
+
}
|
|
27492
|
+
return trueGeometry ?? result.geom;
|
|
27493
|
+
}
|
|
27494
|
+
handleItemSelected(item) {
|
|
27495
|
+
const result = item;
|
|
27496
|
+
this.resultSelected.emit(result);
|
|
27497
|
+
const geometry = this.getGeometry(result);
|
|
27498
|
+
if (geometry) {
|
|
27499
|
+
this.bboxSelected.emit({
|
|
27500
|
+
bbox: getGeometryBoundingBox(geometry),
|
|
27501
|
+
label: this.getDisplayLabel(result),
|
|
27502
|
+
});
|
|
27503
|
+
}
|
|
27504
|
+
}
|
|
27505
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LocationSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
27506
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: LocationSearchComponent, isStandalone: true, selector: "gn-ui-location-search", inputs: { placeholder: "placeholder" }, outputs: { resultSelected: "resultSelected", bboxSelected: "bboxSelected" }, ngImport: i0, template: "<gn-ui-autocomplete\n [action]=\"searchAction\"\n [displayWithFn]=\"displayWithFn\"\n [placeholder]=\"placeholder\"\n [displayWithTemplate]=\"defaultItemTpl\"\n [clearOnSelection]=\"true\"\n (itemSelected)=\"handleItemSelected($event)\"\n>\n</gn-ui-autocomplete>\n\n<ng-template #defaultItemTpl let-result>\n <div class=\"py-2\">\n @if (getSecondaryLabel(result)) {\n <div class=\"gn-ui-card-detail\">{{ getSecondaryLabel(result) }}</div>\n }\n <div class=\"gn-ui-card-title\">{{ getDisplayLabel(result) }}</div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithTemplate", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
27507
|
+
}
|
|
27508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LocationSearchComponent, decorators: [{
|
|
27509
|
+
type: Component,
|
|
27510
|
+
args: [{ selector: 'gn-ui-location-search', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [AutocompleteComponent], template: "<gn-ui-autocomplete\n [action]=\"searchAction\"\n [displayWithFn]=\"displayWithFn\"\n [placeholder]=\"placeholder\"\n [displayWithTemplate]=\"defaultItemTpl\"\n [clearOnSelection]=\"true\"\n (itemSelected)=\"handleItemSelected($event)\"\n>\n</gn-ui-autocomplete>\n\n<ng-template #defaultItemTpl let-result>\n <div class=\"py-2\">\n @if (getSecondaryLabel(result)) {\n <div class=\"gn-ui-card-detail\">{{ getSecondaryLabel(result) }}</div>\n }\n <div class=\"gn-ui-card-title\">{{ getDisplayLabel(result) }}</div>\n </div>\n</ng-template>\n" }]
|
|
27511
|
+
}], propDecorators: { placeholder: [{
|
|
27512
|
+
type: Input
|
|
27513
|
+
}], resultSelected: [{
|
|
27514
|
+
type: Output
|
|
27515
|
+
}], bboxSelected: [{
|
|
27516
|
+
type: Output
|
|
27517
|
+
}] } });
|
|
27518
|
+
|
|
27898
27519
|
// expects the replacement key ${uuid}
|
|
27899
27520
|
const RECORD_DATASET_URL_TOKEN = new InjectionToken('record-dataset-url-token');
|
|
27900
27521
|
const RECORD_SERVICE_URL_TOKEN = new InjectionToken('record-service-url-token');
|
|
@@ -28053,6 +27674,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
28053
27674
|
class AbstractSearchField {
|
|
28054
27675
|
}
|
|
28055
27676
|
class SimpleSearchField {
|
|
27677
|
+
get fieldIdentifier() {
|
|
27678
|
+
return this.customIdentifier ?? this.esFieldName;
|
|
27679
|
+
}
|
|
28056
27680
|
constructor(esFieldName, injector, order = 'asc', orderType = 'key') {
|
|
28057
27681
|
this.esFieldName = esFieldName;
|
|
28058
27682
|
this.injector = injector;
|
|
@@ -28061,14 +27685,26 @@ class SimpleSearchField {
|
|
|
28061
27685
|
this.repository = this.injector.get(RecordsRepositoryInterface);
|
|
28062
27686
|
// FIXME: this is required to register runtime fields; abstract this as well
|
|
28063
27687
|
this.esService = this.injector.get(ElasticsearchService);
|
|
27688
|
+
this.includeValues = [];
|
|
27689
|
+
this.excludeValues = [];
|
|
27690
|
+
}
|
|
27691
|
+
setFieldIdentifier(fieldIdentifier) {
|
|
27692
|
+
this.customIdentifier = fieldIdentifier;
|
|
27693
|
+
this.esService.registerFieldAlias(fieldIdentifier, this.esFieldName);
|
|
28064
27694
|
}
|
|
28065
27695
|
getAggregations() {
|
|
28066
27696
|
return {
|
|
28067
|
-
[this.
|
|
27697
|
+
[this.fieldIdentifier]: {
|
|
28068
27698
|
type: 'terms',
|
|
28069
27699
|
field: this.esFieldName,
|
|
28070
27700
|
limit: 1000,
|
|
28071
27701
|
sort: [this.order, this.orderType],
|
|
27702
|
+
...(this.includeValues?.length && {
|
|
27703
|
+
includeValues: this.includeValues,
|
|
27704
|
+
}),
|
|
27705
|
+
...(this.excludeValues?.length && {
|
|
27706
|
+
excludeValues: this.excludeValues,
|
|
27707
|
+
}),
|
|
28072
27708
|
},
|
|
28073
27709
|
};
|
|
28074
27710
|
}
|
|
@@ -28076,7 +27712,7 @@ class SimpleSearchField {
|
|
|
28076
27712
|
return bucket.term.toString();
|
|
28077
27713
|
}
|
|
28078
27714
|
getAvailableValues() {
|
|
28079
|
-
return this.repository.aggregate(this.getAggregations()).pipe(map$1((response) => response[this.
|
|
27715
|
+
return this.repository.aggregate(this.getAggregations()).pipe(map$1((response) => response[this.fieldIdentifier].buckets || []), switchMap((buckets) => {
|
|
28080
27716
|
const bucketPromises = buckets.map(async (bucket) => ({
|
|
28081
27717
|
label: `${await this.getBucketLabel(bucket)} (${bucket.count})`,
|
|
28082
27718
|
value: bucket.term.toString(),
|
|
@@ -28089,7 +27725,7 @@ class SimpleSearchField {
|
|
|
28089
27725
|
// FieldValue[]
|
|
28090
27726
|
if (this.getType() === 'values') {
|
|
28091
27727
|
return of({
|
|
28092
|
-
[this.
|
|
27728
|
+
[this.fieldIdentifier]: values.reduce((acc, val) => {
|
|
28093
27729
|
const value = val.toString();
|
|
28094
27730
|
if (value !== '') {
|
|
28095
27731
|
return { ...acc, [value]: true };
|
|
@@ -28100,11 +27736,11 @@ class SimpleSearchField {
|
|
|
28100
27736
|
}
|
|
28101
27737
|
// DateRange
|
|
28102
27738
|
return of({
|
|
28103
|
-
[this.
|
|
27739
|
+
[this.fieldIdentifier]: values[0] !== '' ? values[0] : {},
|
|
28104
27740
|
});
|
|
28105
27741
|
}
|
|
28106
27742
|
getValuesForFilter(filters) {
|
|
28107
|
-
const filter = filters[this.
|
|
27743
|
+
const filter = filters[this.fieldIdentifier];
|
|
28108
27744
|
if (!filter)
|
|
28109
27745
|
return of([]);
|
|
28110
27746
|
// filter by expression
|
|
@@ -28122,6 +27758,9 @@ class SimpleSearchField {
|
|
|
28122
27758
|
getType() {
|
|
28123
27759
|
return 'values';
|
|
28124
27760
|
}
|
|
27761
|
+
clone() {
|
|
27762
|
+
return Object.create(this);
|
|
27763
|
+
}
|
|
28125
27764
|
}
|
|
28126
27765
|
class TranslatedSearchField extends SimpleSearchField {
|
|
28127
27766
|
constructor(esFieldName, injector, order = 'asc', orderType = 'key') {
|
|
@@ -28363,15 +28002,26 @@ class DateRangeSearchField extends SimpleSearchField {
|
|
|
28363
28002
|
return 'dateRange';
|
|
28364
28003
|
}
|
|
28365
28004
|
}
|
|
28005
|
+
// treats a resource's creation/revision dates as an interval (its min and max), so a record matches
|
|
28006
|
+
// when that interval intersects the filter range, not just when a single date falls inside it
|
|
28366
28007
|
class ResourceCreationRevisionDateSearchField extends DateRangeSearchField {
|
|
28367
28008
|
constructor(injector, order = 'desc') {
|
|
28368
28009
|
super('resourceCreationRevisionDate', injector, order);
|
|
28369
|
-
|
|
28370
|
-
|
|
28371
|
-
|
|
28372
|
-
|
|
28373
|
-
|
|
28374
|
-
|
|
28010
|
+
const dateSourceFields = [
|
|
28011
|
+
'creationDateForResource',
|
|
28012
|
+
'revisionDateForResource',
|
|
28013
|
+
];
|
|
28014
|
+
const collectSortedDates = dateSourceFields
|
|
28015
|
+
.map((field) => `if (doc.containsKey('${field}')) {
|
|
28016
|
+
for (def date : doc['${field}']) { dates.add(date.millis); }
|
|
28017
|
+
}`)
|
|
28018
|
+
.join('\n');
|
|
28019
|
+
this.esService.registerRuntimeField('resourceCreationRevisionDateMin', `def dates = [];
|
|
28020
|
+
${collectSortedDates}
|
|
28021
|
+
if (dates.length > 0) { dates.sort(null); emit(dates[0]); }`, 'date');
|
|
28022
|
+
this.esService.registerRuntimeField('resourceCreationRevisionDateMax', `def dates = [];
|
|
28023
|
+
${collectSortedDates}
|
|
28024
|
+
if (dates.length > 0) { dates.sort(null); emit(dates[dates.length - 1]); }`, 'date');
|
|
28375
28025
|
}
|
|
28376
28026
|
}
|
|
28377
28027
|
class BoundingBoxSearchField extends SimpleSearchField {
|
|
@@ -28380,11 +28030,11 @@ class BoundingBoxSearchField extends SimpleSearchField {
|
|
|
28380
28030
|
}
|
|
28381
28031
|
getFiltersForValues(values) {
|
|
28382
28032
|
return of({
|
|
28383
|
-
[this.
|
|
28033
|
+
[this.fieldIdentifier]: values.map(Number),
|
|
28384
28034
|
});
|
|
28385
28035
|
}
|
|
28386
28036
|
getValuesForFilter(filters) {
|
|
28387
|
-
const filter = filters[this.
|
|
28037
|
+
const filter = filters[this.fieldIdentifier];
|
|
28388
28038
|
return of(isBoundingBox(filter) ? filter : []);
|
|
28389
28039
|
}
|
|
28390
28040
|
getType() {
|
|
@@ -28483,7 +28133,7 @@ class RecordKindField extends SimpleSearchField {
|
|
|
28483
28133
|
}
|
|
28484
28134
|
getFiltersForValues(values) {
|
|
28485
28135
|
const filters = {
|
|
28486
|
-
[this.
|
|
28136
|
+
[this.fieldIdentifier]: values.reduce((acc, value) => {
|
|
28487
28137
|
if (value === '')
|
|
28488
28138
|
return { ...acc, [value]: true };
|
|
28489
28139
|
const keysToAdd = this.TYPE_MAPPING[value] || [value];
|
|
@@ -28506,7 +28156,7 @@ class RecordKindField extends SimpleSearchField {
|
|
|
28506
28156
|
return of(filters);
|
|
28507
28157
|
}
|
|
28508
28158
|
getValuesForFilter(filters) {
|
|
28509
|
-
const filter = filters[this.
|
|
28159
|
+
const filter = filters[this.fieldIdentifier];
|
|
28510
28160
|
if (!filter)
|
|
28511
28161
|
return of([]);
|
|
28512
28162
|
const activeValues = Object.keys(filter).filter((v) => filter[v]);
|
|
@@ -28536,11 +28186,15 @@ marker('search.filters.publisherOrg');
|
|
|
28536
28186
|
marker('search.filters.user');
|
|
28537
28187
|
marker('search.filters.changeDate');
|
|
28538
28188
|
marker('search.filters.resourceCreationRevisionDate');
|
|
28189
|
+
marker('search.filters.temporalExtent');
|
|
28539
28190
|
marker('search.filters.spatialExtent');
|
|
28191
|
+
marker('search.filters.documentStandard');
|
|
28192
|
+
const CUSTOM_FIELDS = new InjectionToken('custom-fields');
|
|
28540
28193
|
class FieldsService {
|
|
28541
28194
|
constructor() {
|
|
28542
28195
|
this.injector = inject(Injector);
|
|
28543
|
-
this.
|
|
28196
|
+
this.customFields = inject(CUSTOM_FIELDS, { optional: true }) ?? [];
|
|
28197
|
+
this.baseFields = {
|
|
28544
28198
|
organization: new OrganizationSearchField(this.injector),
|
|
28545
28199
|
format: new SimpleSearchField('format', this.injector, 'asc'),
|
|
28546
28200
|
resourceType: new ResourceTypeLegacyField(this.injector), // Deprecated, use `recordKind` instead
|
|
@@ -28560,9 +28214,31 @@ class FieldsService {
|
|
|
28560
28214
|
user: new UserSearchField(this.injector),
|
|
28561
28215
|
changeDate: new DateRangeSearchField('changeDate', this.injector, 'desc'),
|
|
28562
28216
|
resourceCreationRevisionDate: new ResourceCreationRevisionDateSearchField(this.injector, 'desc'),
|
|
28217
|
+
temporalExtent: new DateRangeSearchField('resourceTemporalExtentDateRange', this.injector, 'desc'),
|
|
28563
28218
|
availableServices: new AvailableServicesField(this.injector),
|
|
28564
28219
|
spatialExtent: new BoundingBoxSearchField('spatialExtent', this.injector),
|
|
28565
28220
|
};
|
|
28221
|
+
this.fields = { ...this.baseFields };
|
|
28222
|
+
for (const customField of this.customFields) {
|
|
28223
|
+
const baseField = this.baseFields[customField.baseFilter];
|
|
28224
|
+
if (!(baseField instanceof SimpleSearchField)) {
|
|
28225
|
+
console.warn(`The custom field '${customField.name}' relies on a base field '${customField.baseFilter}' that is not supported. This field will be ignored.`);
|
|
28226
|
+
continue;
|
|
28227
|
+
}
|
|
28228
|
+
if (!customField.name.includes(':')) {
|
|
28229
|
+
console.warn(`The custom field '${customField.name}' is not scoped with a prefix. Custom fields must have their names prefixed, for instance "myOrg:myKeywords". This field will be ignored.`);
|
|
28230
|
+
continue;
|
|
28231
|
+
}
|
|
28232
|
+
const newField = baseField.clone();
|
|
28233
|
+
newField.setFieldIdentifier(customField.name);
|
|
28234
|
+
if (customField.includeValues) {
|
|
28235
|
+
newField.includeValues = customField.includeValues;
|
|
28236
|
+
}
|
|
28237
|
+
if (customField.excludeValues) {
|
|
28238
|
+
newField.excludeValues = customField.excludeValues;
|
|
28239
|
+
}
|
|
28240
|
+
this.fields[customField.name] = newField;
|
|
28241
|
+
}
|
|
28566
28242
|
}
|
|
28567
28243
|
get supportedFields() {
|
|
28568
28244
|
return Object.keys(this.fields);
|
|
@@ -28610,7 +28286,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
28610
28286
|
args: [{
|
|
28611
28287
|
providedIn: 'root',
|
|
28612
28288
|
}]
|
|
28613
|
-
}] });
|
|
28289
|
+
}], ctorParameters: () => [] });
|
|
28614
28290
|
|
|
28615
28291
|
class ApiCardComponent {
|
|
28616
28292
|
constructor() {
|
|
@@ -30550,7 +30226,7 @@ class ServiceCapabilitiesComponent {
|
|
|
30550
30226
|
if (this.apiLinks.length > 0 &&
|
|
30551
30227
|
this.apiLinks[0].accessServiceProtocol !== 'ogcFeatures') {
|
|
30552
30228
|
this.loading = true;
|
|
30553
|
-
this.availableLayers = await getLayers(this.apiLinks[0].url.href, this.apiLinks[0].accessServiceProtocol);
|
|
30229
|
+
this.availableLayers = await getLayers(this.apiLinks[0].url.href, this.apiLinks[0].accessServiceProtocol, true);
|
|
30554
30230
|
this.loading = false;
|
|
30555
30231
|
this.cdr.detectChanges();
|
|
30556
30232
|
this.filteredLayers = this.availableLayers;
|
|
@@ -30636,14 +30312,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
30636
30312
|
marker('feature.catalog.attribute.type');
|
|
30637
30313
|
marker('feature.catalog.attribute.name');
|
|
30638
30314
|
marker('feature.catalog.attribute.code');
|
|
30639
|
-
marker('feature.catalog.attribute.
|
|
30315
|
+
marker('feature.catalog.attribute.description');
|
|
30640
30316
|
marker('feature.catalog.attribute.values');
|
|
30641
30317
|
class FeatureCatalogListComponent {
|
|
30642
30318
|
constructor() {
|
|
30643
30319
|
this.COLUMNS_DEFAULT = [
|
|
30644
30320
|
{ key: 'type', width: '25%' },
|
|
30645
30321
|
{ key: 'name', width: '40%' },
|
|
30646
|
-
{ key: '
|
|
30322
|
+
{ key: 'description', width: 'minmax(0px, 1fr)' },
|
|
30647
30323
|
];
|
|
30648
30324
|
this.COLUMN_VALUES = {
|
|
30649
30325
|
key: 'values',
|
|
@@ -30664,7 +30340,7 @@ class FeatureCatalogListComponent {
|
|
|
30664
30340
|
return col.key;
|
|
30665
30341
|
}
|
|
30666
30342
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureCatalogListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
30667
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FeatureCatalogListComponent, isStandalone: true, selector: "gn-ui-feature-catalog-list", inputs: { filteredFeatureCatalog: "filteredFeatureCatalog" }, providers: [provideIcons({ iconoirList })], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "scrollable", first: true, predicate: CdkScrollable, descendants: true, static: true }, { propertyName: "panelComponent", first: true, predicate: ["expanel"], descendants: true, read: ExpandablePanelComponent, static: true }], ngImport: i0, template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.
|
|
30343
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FeatureCatalogListComponent, isStandalone: true, selector: "gn-ui-feature-catalog-list", inputs: { filteredFeatureCatalog: "filteredFeatureCatalog" }, providers: [provideIcons({ iconoirList })], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "scrollable", first: true, predicate: CdkScrollable, descendants: true, static: true }, { propertyName: "panelComponent", first: true, predicate: ["expanel"], descendants: true, read: ExpandablePanelComponent, static: true }], ngImport: i0, template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.description) {\n <div class=\"text-sm\">\n {{ featureType.description }}\n </div>\n }\n </div>\n </ng-template>\n @if (expanel && !expanel.collapsed) {\n <div\n class=\"grid gap-0\"\n [style.grid-template-columns]=\"\n getGridTemplateColumns(featureType.attributes)\n \"\n data-cy=\"feature-type-content\"\n >\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"py-1 px-2 text-sm font-bold text-left border-t break-all\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n [ngClass]=\"col.class || ''\"\n data-test=\"column-label\"\n >\n {{ 'feature.catalog.attribute.' + col.key | translate }}\n </div>\n }\n @if (expanel && !expanel.collapsed) {\n @for (row of featureType.attributes; track row) {\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"bg-white text-sm font-normal text-left border-t\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n data-test=\"cell-content\"\n >\n @if (col.key === 'values') {\n @if (row.values?.length > 0) {\n <gn-ui-cell-popin\n #popinRef\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n >\n <div\n cellContent\n data-cy=\"values-cell-popin-trigger\"\n >\n <gn-ui-button\n type=\"light\"\n extraClass=\"bg-transparent border-none\"\n (buttonClick)=\"popinRef.openOverlay()\"\n >\n <ng-icon name=\"iconoirList\" size=\"24\"></ng-icon>\n </gn-ui-button>\n </div>\n <div\n popinContent\n class=\"max-h-60 overflow-y-auto min-w-64 py-4 px-6\"\n style=\"scrollbar-width: thin\"\n >\n <ul class=\"list-disc list-inside mr-4\">\n @for (v of row.values; track v) {\n <li>\n {{ v.label || v.value }}\n </li>\n }\n </ul>\n </div>\n </gn-ui-cell-popin>\n }\n } @else {\n <gn-ui-truncated-text\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n [text]=\"row[col.key]\"\n ></gn-ui-truncated-text>\n }\n </div>\n }\n }\n }\n </div>\n }\n </gn-ui-expandable-panel>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: CellPopinComponent, selector: "gn-ui-cell-popin", inputs: ["extraClass", "cdkScrollContainer", "scrollContainer", "activePopin"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: ["title", "iconColor", "collapsed"] }, { kind: "component", type: TruncatedTextComponent, selector: "gn-ui-truncated-text", inputs: ["text", "extraClass", "scrollContainer", "cdkScrollContainer"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2$3.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
30668
30344
|
}
|
|
30669
30345
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureCatalogListComponent, decorators: [{
|
|
30670
30346
|
type: Component,
|
|
@@ -30677,7 +30353,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
30677
30353
|
TruncatedTextComponent,
|
|
30678
30354
|
NgIconComponent,
|
|
30679
30355
|
ScrollingModule,
|
|
30680
|
-
], providers: [provideIcons({ iconoirList })], template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.
|
|
30356
|
+
], providers: [provideIcons({ iconoirList })], template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.description) {\n <div class=\"text-sm\">\n {{ featureType.description }}\n </div>\n }\n </div>\n </ng-template>\n @if (expanel && !expanel.collapsed) {\n <div\n class=\"grid gap-0\"\n [style.grid-template-columns]=\"\n getGridTemplateColumns(featureType.attributes)\n \"\n data-cy=\"feature-type-content\"\n >\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"py-1 px-2 text-sm font-bold text-left border-t break-all\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n [ngClass]=\"col.class || ''\"\n data-test=\"column-label\"\n >\n {{ 'feature.catalog.attribute.' + col.key | translate }}\n </div>\n }\n @if (expanel && !expanel.collapsed) {\n @for (row of featureType.attributes; track row) {\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"bg-white text-sm font-normal text-left border-t\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n data-test=\"cell-content\"\n >\n @if (col.key === 'values') {\n @if (row.values?.length > 0) {\n <gn-ui-cell-popin\n #popinRef\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n >\n <div\n cellContent\n data-cy=\"values-cell-popin-trigger\"\n >\n <gn-ui-button\n type=\"light\"\n extraClass=\"bg-transparent border-none\"\n (buttonClick)=\"popinRef.openOverlay()\"\n >\n <ng-icon name=\"iconoirList\" size=\"24\"></ng-icon>\n </gn-ui-button>\n </div>\n <div\n popinContent\n class=\"max-h-60 overflow-y-auto min-w-64 py-4 px-6\"\n style=\"scrollbar-width: thin\"\n >\n <ul class=\"list-disc list-inside mr-4\">\n @for (v of row.values; track v) {\n <li>\n {{ v.label || v.value }}\n </li>\n }\n </ul>\n </div>\n </gn-ui-cell-popin>\n }\n } @else {\n <gn-ui-truncated-text\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n [text]=\"row[col.key]\"\n ></gn-ui-truncated-text>\n }\n </div>\n }\n }\n }\n </div>\n }\n </gn-ui-expandable-panel>\n </div>\n }\n </div>\n</div>\n" }]
|
|
30681
30357
|
}], propDecorators: { filteredFeatureCatalog: [{
|
|
30682
30358
|
type: Input
|
|
30683
30359
|
}], scrollContainer: [{
|
|
@@ -31815,6 +31491,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
31815
31491
|
], template: "<div class=\"flex flex-col gap-6 p-6 items-start pointer-events-none\">\n @for (\n notification of notificationsService.notifications$ | async;\n track trackById($index, notification)\n ) {\n <gn-ui-notification\n class=\"max-w-full pointer-events-auto\"\n [text]=\"notification.text\"\n [type]=\"notification.type\"\n [title]=\"notification.title\"\n [closeMessage]=\"notification.closeMessage\"\n (notificationClose)=\"\n notificationsService.removeNotificationById(notification.id)\n \"\n [@enterExit]\n ></gn-ui-notification>\n }\n</div>\n" }]
|
|
31816
31492
|
}] });
|
|
31817
31493
|
|
|
31494
|
+
marker('search.filters.spatialExtent.searchLocation');
|
|
31495
|
+
// in MB, null means no limit
|
|
31496
|
+
const SPATIAL_EXTENT_MAX_FILE_SIZE = new InjectionToken('spatialExtentMaxFileSize', { factory: () => null });
|
|
31818
31497
|
class FilterDropdownComponent {
|
|
31819
31498
|
constructor() {
|
|
31820
31499
|
this.searchFacade = inject(SearchFacade);
|
|
@@ -31822,7 +31501,7 @@ class FilterDropdownComponent {
|
|
|
31822
31501
|
this.fieldsService = inject(FieldsService);
|
|
31823
31502
|
this.notificationsService = inject(NotificationsService);
|
|
31824
31503
|
this.translateService = inject(TranslateService);
|
|
31825
|
-
this.spatialExtentMaxFileSize =
|
|
31504
|
+
this.spatialExtentMaxFileSize = inject(SPATIAL_EXTENT_MAX_FILE_SIZE);
|
|
31826
31505
|
this.selected$ = this.searchFacade.searchFilters$.pipe(switchMap((filters) => this.fieldsService.readFieldValuesFromFilters(filters)), map$1((fieldValues) => fieldValues[this.fieldName]), filter$1((selected) => !!selected), startWith$1([]), catchError(() => of([])));
|
|
31827
31506
|
this.selectedDateRange$ = this.selected$.pipe(map$1((selected) => (Array.isArray(selected) ? {} : selected)));
|
|
31828
31507
|
this.selectedBoundingBox$ = this.selected$.pipe(map$1((selected) => Array.isArray(selected) && selected.length > 0
|
|
@@ -31843,6 +31522,9 @@ class FilterDropdownComponent {
|
|
|
31843
31522
|
.subscribe((filters) => this.searchService.updateFilters(filters));
|
|
31844
31523
|
this.clearSpatialExtentErrorNotification();
|
|
31845
31524
|
}
|
|
31525
|
+
onLocationSelected({ bbox, label }) {
|
|
31526
|
+
this.spatialExtentDropdown.setLocationBbox(bbox, label);
|
|
31527
|
+
}
|
|
31846
31528
|
onSpatialExtentError(error) {
|
|
31847
31529
|
this.clearSpatialExtentErrorNotification();
|
|
31848
31530
|
this.spatialExtentErrorNotificationId =
|
|
@@ -31873,7 +31555,7 @@ class FilterDropdownComponent {
|
|
|
31873
31555
|
.subscribe((filters) => this.searchService.updateFilters(filters));
|
|
31874
31556
|
}
|
|
31875
31557
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FilterDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
31876
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FilterDropdownComponent, isStandalone: true, selector: "gn-ui-filter-dropdown", inputs: { fieldName: "fieldName", title: "title" }, ngImport: i0, template: "@if (fieldType === 'dateRange') {\n <gn-ui-date-range-dropdown\n [title]=\"title\"\n [dateRange]=\"(selectedDateRange$ | async) ?? {}\"\n (dateRangeChange)=\"onDateRangeChange($event)\"\n [attr.data-cy-field]=\"fieldName\"\n ></gn-ui-date-range-dropdown>\n} @else if (fieldType === 'spatialExtent') {\n <gn-ui-spatial-extent-dropdown\n [title]=\"title\"\n [initialBbox]=\"(selectedBoundingBox$ | async) ?? null\"\n [maxFileSizeMb]=\"spatialExtentMaxFileSize\"\n (bboxChange)=\"onBboxChange($event)\"\n (errorChange)=\"onSpatialExtentError($event)\"\n [attr.data-cy-field]=\"fieldName\"\n ></gn-ui-spatial-extent-dropdown>\n} @else {\n <gn-ui-dropdown-multiselect\n class=\"w-full\"\n [title]=\"title\"\n [maxRows]=\"6\"\n [choices]=\"(choices$ | async) || []\"\n [selected]=\"selected$ | async\"\n [allowSearch]=\"true\"\n (selectValues)=\"onSelectedValues($event)\"\n [attr.data-cy-field]=\"fieldName\"\n >\n </gn-ui-dropdown-multiselect>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DateRangeDropdownComponent, selector: "gn-ui-date-range-dropdown", inputs: ["title", "dateRange"], outputs: ["dateRangeChange"] }, { kind: "component", type: DropdownMultiselectComponent, selector: "gn-ui-dropdown-multiselect", inputs: ["title", "choices", "selected", "allowSearch", "maxRows", "searchInputValue"], outputs: ["selectValues"] }, { kind: "component", type: SpatialExtentDropdownComponent, selector: "gn-ui-spatial-extent-dropdown", inputs: ["title", "maxFileSizeMb", "initialBbox"], outputs: ["bboxChange", "errorChange"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
31558
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FilterDropdownComponent, isStandalone: true, selector: "gn-ui-filter-dropdown", inputs: { fieldName: "fieldName", title: "title" }, viewQueries: [{ propertyName: "spatialExtentDropdown", first: true, predicate: SpatialExtentDropdownComponent, descendants: true }], ngImport: i0, template: "@if (fieldType === 'dateRange') {\n <gn-ui-date-range-dropdown\n [title]=\"title\"\n [dateRange]=\"(selectedDateRange$ | async) ?? {}\"\n (dateRangeChange)=\"onDateRangeChange($event)\"\n [attr.data-cy-field]=\"fieldName\"\n ></gn-ui-date-range-dropdown>\n} @else if (fieldType === 'spatialExtent') {\n <gn-ui-spatial-extent-dropdown\n [title]=\"title\"\n [initialBbox]=\"(selectedBoundingBox$ | async) ?? null\"\n [maxFileSizeMb]=\"spatialExtentMaxFileSize\"\n (bboxChange)=\"onBboxChange($event)\"\n (errorChange)=\"onSpatialExtentError($event)\"\n [attr.data-cy-field]=\"fieldName\"\n >\n <gn-ui-location-search\n [placeholder]=\"'search.filters.spatialExtent.searchLocation' | translate\"\n (bboxSelected)=\"onLocationSelected($event)\"\n data-cy=\"locationSearch\"\n ></gn-ui-location-search>\n </gn-ui-spatial-extent-dropdown>\n} @else {\n <gn-ui-dropdown-multiselect\n class=\"w-full\"\n [title]=\"title\"\n [maxRows]=\"6\"\n [choices]=\"(choices$ | async) || []\"\n [selected]=\"selected$ | async\"\n [allowSearch]=\"true\"\n (selectValues)=\"onSelectedValues($event)\"\n [attr.data-cy-field]=\"fieldName\"\n >\n </gn-ui-dropdown-multiselect>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DateRangeDropdownComponent, selector: "gn-ui-date-range-dropdown", inputs: ["title", "dateRange"], outputs: ["dateRangeChange"] }, { kind: "component", type: DropdownMultiselectComponent, selector: "gn-ui-dropdown-multiselect", inputs: ["title", "choices", "selected", "allowSearch", "maxRows", "searchInputValue"], outputs: ["selectValues"] }, { kind: "component", type: SpatialExtentDropdownComponent, selector: "gn-ui-spatial-extent-dropdown", inputs: ["title", "maxFileSizeMb", "initialBbox"], outputs: ["bboxChange", "errorChange"] }, { kind: "component", type: LocationSearchComponent, selector: "gn-ui-location-search", inputs: ["placeholder"], outputs: ["resultSelected", "bboxSelected"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
31877
31559
|
}
|
|
31878
31560
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FilterDropdownComponent, decorators: [{
|
|
31879
31561
|
type: Component,
|
|
@@ -31882,11 +31564,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
31882
31564
|
DateRangeDropdownComponent,
|
|
31883
31565
|
DropdownMultiselectComponent,
|
|
31884
31566
|
SpatialExtentDropdownComponent,
|
|
31885
|
-
|
|
31567
|
+
LocationSearchComponent,
|
|
31568
|
+
TranslatePipe,
|
|
31569
|
+
], template: "@if (fieldType === 'dateRange') {\n <gn-ui-date-range-dropdown\n [title]=\"title\"\n [dateRange]=\"(selectedDateRange$ | async) ?? {}\"\n (dateRangeChange)=\"onDateRangeChange($event)\"\n [attr.data-cy-field]=\"fieldName\"\n ></gn-ui-date-range-dropdown>\n} @else if (fieldType === 'spatialExtent') {\n <gn-ui-spatial-extent-dropdown\n [title]=\"title\"\n [initialBbox]=\"(selectedBoundingBox$ | async) ?? null\"\n [maxFileSizeMb]=\"spatialExtentMaxFileSize\"\n (bboxChange)=\"onBboxChange($event)\"\n (errorChange)=\"onSpatialExtentError($event)\"\n [attr.data-cy-field]=\"fieldName\"\n >\n <gn-ui-location-search\n [placeholder]=\"'search.filters.spatialExtent.searchLocation' | translate\"\n (bboxSelected)=\"onLocationSelected($event)\"\n data-cy=\"locationSearch\"\n ></gn-ui-location-search>\n </gn-ui-spatial-extent-dropdown>\n} @else {\n <gn-ui-dropdown-multiselect\n class=\"w-full\"\n [title]=\"title\"\n [maxRows]=\"6\"\n [choices]=\"(choices$ | async) || []\"\n [selected]=\"selected$ | async\"\n [allowSearch]=\"true\"\n (selectValues)=\"onSelectedValues($event)\"\n [attr.data-cy-field]=\"fieldName\"\n >\n </gn-ui-dropdown-multiselect>\n}\n" }]
|
|
31886
31570
|
}], propDecorators: { fieldName: [{
|
|
31887
31571
|
type: Input
|
|
31888
31572
|
}], title: [{
|
|
31889
31573
|
type: Input
|
|
31574
|
+
}], spatialExtentDropdown: [{
|
|
31575
|
+
type: ViewChild,
|
|
31576
|
+
args: [SpatialExtentDropdownComponent]
|
|
31890
31577
|
}] } });
|
|
31891
31578
|
|
|
31892
31579
|
class FuzzySearchComponent {
|
|
@@ -31943,7 +31630,7 @@ class FuzzySearchComponent {
|
|
|
31943
31630
|
this.isSearchActive.emit(event);
|
|
31944
31631
|
}
|
|
31945
31632
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FuzzySearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
31946
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: FuzzySearchComponent, isStandalone: true, selector: "gn-ui-fuzzy-search", inputs: { autoFocus: "autoFocus", forceTrackPosition: "forceTrackPosition", enterButton: "enterButton", placeholder: "placeholder" }, outputs: { itemSelected: "itemSelected", inputSubmitted: "inputSubmitted", isSearchActive: "isSearchActive" }, viewQueries: [{ propertyName: "autocomplete", first: true, predicate: AutocompleteComponent, descendants: true }], ngImport: i0, template: "<gn-ui-autocomplete\n [placeholder]=\"placeholder ?? ('search.field.any.placeholder' | translate)\"\n [displayWithFn]=\"displayWithFn\"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"handleItemSelection($event)\"\n (inputSubmitted)=\"handleInputSubmission($event)\"\n (inputCleared)=\"handleInputCleared()\"\n (isSearchActive)=\"handleSearchActive($event)\"\n [value]=\"searchInputValue$ | async\"\n [preventCompleteOnSelection]=\"true\"\n [autoFocus]=\"autoFocus\"\n [allowSubmit]=\"true\"\n [forceTrackPosition]=\"forceTrackPosition\"\n [enterButton]=\"enterButton\"\n></gn-ui-autocomplete>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
31633
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: FuzzySearchComponent, isStandalone: true, selector: "gn-ui-fuzzy-search", inputs: { autoFocus: "autoFocus", forceTrackPosition: "forceTrackPosition", enterButton: "enterButton", placeholder: "placeholder" }, outputs: { itemSelected: "itemSelected", inputSubmitted: "inputSubmitted", isSearchActive: "isSearchActive" }, viewQueries: [{ propertyName: "autocomplete", first: true, predicate: AutocompleteComponent, descendants: true }], ngImport: i0, template: "<gn-ui-autocomplete\n [placeholder]=\"placeholder ?? ('search.field.any.placeholder' | translate)\"\n [displayWithFn]=\"displayWithFn\"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"handleItemSelection($event)\"\n (inputSubmitted)=\"handleInputSubmission($event)\"\n (inputCleared)=\"handleInputCleared()\"\n (isSearchActive)=\"handleSearchActive($event)\"\n [value]=\"searchInputValue$ | async\"\n [preventCompleteOnSelection]=\"true\"\n [autoFocus]=\"autoFocus\"\n [allowSubmit]=\"true\"\n [forceTrackPosition]=\"forceTrackPosition\"\n [enterButton]=\"enterButton\"\n></gn-ui-autocomplete>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithTemplate", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
31947
31634
|
}
|
|
31948
31635
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FuzzySearchComponent, decorators: [{
|
|
31949
31636
|
type: Component,
|
|
@@ -32503,6 +32190,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
32503
32190
|
marker('search.filters.summaryLabel.user');
|
|
32504
32191
|
marker('search.filters.summaryLabel.changeDate');
|
|
32505
32192
|
marker('search.filters.summaryLabel.resourceCreationRevisionDate');
|
|
32193
|
+
marker('search.filters.summaryLabel.temporalExtent');
|
|
32506
32194
|
const OPEN_BOUND = '…';
|
|
32507
32195
|
class SearchFiltersSummaryItemComponent {
|
|
32508
32196
|
constructor() {
|
|
@@ -32884,95 +32572,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
32884
32572
|
], template: "<div\n class=\"bg-white rounded shadow shadow-lg relative h-full w-[400px] overflow-hidden\"\n>\n <div class=\"p-3 border-b border-gray-300 flex items-center\">\n <ng-icon class=\"mr-2\" name=\"matLayersOutline\"></ng-icon>\n <span translate>map.layers.list</span>\n </div>\n <div class=\"flex flex-col px-4 divide-y divide-y-gray-50\">\n @for (layer of layers$ | async; track layer; let index = $index) {\n <div class=\"flex flex-row py-3\">\n <ng-icon class=\"-ml-2 mr-2 shrink-0\" name=\"matChevronRight\"></ng-icon>\n <span class=\"mr-2 grow\">{{ layer.label }}</span>\n <a\n href\n class=\"underline text-sm text-red-700 hover:text-red-900\"\n (click)=\"deleteLayer(index); $event.preventDefault()\"\n >\n delete\n </a>\n </div>\n }\n </div>\n <gn-ui-expandable-panel-button [titleTemplate]=\"addLayerTitle\">\n <mat-tab-group animationDuration=\"200ms\" class=\"h-full\">\n <mat-tab [label]=\"'map.add.layer.catalog' | translate\">\n <div class=\"p-3\">\n <gn-ui-add-layer-from-catalog></gn-ui-add-layer-from-catalog>\n </div>\n </mat-tab>\n <mat-tab [label]=\"'map.add.layer.wms' | translate\" bodyClass=\"h-full\">\n <div class=\"p-3\">\n <gn-ui-add-layer-from-wms></gn-ui-add-layer-from-wms>\n </div>\n </mat-tab>\n <mat-tab [label]=\"'map.add.layer.wfs' | translate\" bodyClass=\"h-full\">\n <div class=\"p-3\">\n <gn-ui-add-layer-from-wfs></gn-ui-add-layer-from-wfs>\n </div>\n </mat-tab>\n <mat-tab [label]=\"'map.add.layer.ogc.api' | translate\" bodyClass=\"h-full\">\n <div class=\"p-3\">\n <gn-ui-add-layer-from-ogc-api\n [ogcUrl]=\"ogcUrl\"\n (layerAdded)=\"addLayer($event)\"\n ></gn-ui-add-layer-from-ogc-api>\n </div>\n </mat-tab>\n <mat-tab [label]=\"'map.add.layer.file' | translate\" bodyClass=\"h-full\">\n <div class=\"p-3\">\n <gn-ui-add-layer-from-file></gn-ui-add-layer-from-file>\n </div>\n </mat-tab>\n </mat-tab-group>\n </gn-ui-expandable-panel-button>\n</div>\n\n<ng-template #addLayerTitle>\n <ng-icon class=\"mr-4\" name=\"matAddCircleOutlineOutline\"> </ng-icon>\n <span translate>map.add.layer</span>\n</ng-template>\n" }]
|
|
32885
32573
|
}] });
|
|
32886
32574
|
|
|
32887
|
-
class GeocodingComponent {
|
|
32888
|
-
constructor() {
|
|
32889
|
-
this.mapFacade = inject(MapFacade);
|
|
32890
|
-
this.geocodingService = inject(GeocodingService);
|
|
32891
|
-
this.searchText = '';
|
|
32892
|
-
this.results = [];
|
|
32893
|
-
this.searchTextChanged = new Subject();
|
|
32894
|
-
this.destroy$ = new Subject();
|
|
32895
|
-
this.errorMessage = null;
|
|
32896
|
-
this.searchTextChanged
|
|
32897
|
-
.pipe(debounceTime(300), switchMap$1((searchText) => {
|
|
32898
|
-
return from(this.geocodingService.query(searchText)).pipe(catchError$1((error) => {
|
|
32899
|
-
this.errorMessage =
|
|
32900
|
-
'An error occurred while searching. Please try again.';
|
|
32901
|
-
console.error(error);
|
|
32902
|
-
return [];
|
|
32903
|
-
}));
|
|
32904
|
-
}), takeUntil(this.destroy$))
|
|
32905
|
-
.subscribe((results) => {
|
|
32906
|
-
this.results = results;
|
|
32907
|
-
});
|
|
32908
|
-
}
|
|
32909
|
-
ngOnDestroy() {
|
|
32910
|
-
this.destroy$.next();
|
|
32911
|
-
this.destroy$.complete();
|
|
32912
|
-
}
|
|
32913
|
-
onSearchChange(searchText) {
|
|
32914
|
-
if (!searchText) {
|
|
32915
|
-
this.clearSearch();
|
|
32916
|
-
return;
|
|
32917
|
-
}
|
|
32918
|
-
else {
|
|
32919
|
-
this.searchTextChanged.next(searchText);
|
|
32920
|
-
}
|
|
32921
|
-
}
|
|
32922
|
-
clearSearch() {
|
|
32923
|
-
this.searchText = '';
|
|
32924
|
-
this.results = [];
|
|
32925
|
-
this.errorMessage = null;
|
|
32926
|
-
}
|
|
32927
|
-
async zoomToLocation(result) {
|
|
32928
|
-
const geometry = result.geom;
|
|
32929
|
-
if (geometry.type === 'Point') {
|
|
32930
|
-
await this.zoomToPoint(geometry.coordinates);
|
|
32931
|
-
}
|
|
32932
|
-
else if (geometry.type === 'Polygon') {
|
|
32933
|
-
await this.zoomToPolygon(geometry.coordinates);
|
|
32934
|
-
}
|
|
32935
|
-
else {
|
|
32936
|
-
console.error(`Unsupported geometry type: ${geometry.type}`);
|
|
32937
|
-
}
|
|
32938
|
-
}
|
|
32939
|
-
async zoomToPoint(pointCoords) {
|
|
32940
|
-
const context = await firstValueFrom(this.mapFacade.context$);
|
|
32941
|
-
const view = {
|
|
32942
|
-
center: pointCoords,
|
|
32943
|
-
zoom: 10,
|
|
32944
|
-
};
|
|
32945
|
-
this.mapFacade.applyContext({
|
|
32946
|
-
...context,
|
|
32947
|
-
view,
|
|
32948
|
-
});
|
|
32949
|
-
}
|
|
32950
|
-
async zoomToPolygon(polygonCoords) {
|
|
32951
|
-
const context = await firstValueFrom(this.mapFacade.context$);
|
|
32952
|
-
const view = {
|
|
32953
|
-
geometry: {
|
|
32954
|
-
type: 'Polygon',
|
|
32955
|
-
coordinates: polygonCoords,
|
|
32956
|
-
},
|
|
32957
|
-
};
|
|
32958
|
-
this.mapFacade.applyContext({
|
|
32959
|
-
...context,
|
|
32960
|
-
view,
|
|
32961
|
-
});
|
|
32962
|
-
}
|
|
32963
|
-
onEnterPress() {
|
|
32964
|
-
if (this.results && this.results.length > 0) {
|
|
32965
|
-
this.zoomToLocation(this.results[0]);
|
|
32966
|
-
}
|
|
32967
|
-
}
|
|
32968
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
32969
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: GeocodingComponent, isStandalone: true, selector: "gn-ui-geocoding", ngImport: i0, template: "<gn-ui-search-input\n [(value)]=\"searchText\"\n (valueChange)=\"onSearchChange($event)\"\n (keyup.enter)=\"onEnterPress()\"\n [placeholder]=\"'map.geocoding.placeholder' | translate\"\n>\n</gn-ui-search-input>\n@if (results && results.length) {\n <ul\n class=\"bg-gray-50 border border-gray-200 w-full mt-2 shadow-sm rounded-lg\"\n >\n @for (result of results; track result) {\n <li\n (click)=\"zoomToLocation(result)\"\n class=\"flex items-center pl-8 pr-4 py-2 border-b border-gray-200 relative cursor-pointer hover:bg-blue-100 hover:text-gray-800 transition duration-300 ease-in-out\"\n >\n <svg\n class=\"stroke-current text-blue-500 absolute w-5 h-5 left-3 top-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z\"\n />\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15 11a3 3 0 11-6 0 3 3 0 016 0z\"\n />\n </svg>\n <span class=\"font-sans font-semibold ml-4\">{{ result.label }}</span>\n </li>\n }\n </ul>\n}\n", styles: [""], dependencies: [{ kind: "component", type: SearchInputComponent, selector: "gn-ui-search-input", inputs: ["value", "placeholder"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
32970
|
-
}
|
|
32971
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingComponent, decorators: [{
|
|
32972
|
-
type: Component,
|
|
32973
|
-
args: [{ selector: 'gn-ui-geocoding', standalone: true, imports: [SearchInputComponent, TranslatePipe], template: "<gn-ui-search-input\n [(value)]=\"searchText\"\n (valueChange)=\"onSearchChange($event)\"\n (keyup.enter)=\"onEnterPress()\"\n [placeholder]=\"'map.geocoding.placeholder' | translate\"\n>\n</gn-ui-search-input>\n@if (results && results.length) {\n <ul\n class=\"bg-gray-50 border border-gray-200 w-full mt-2 shadow-sm rounded-lg\"\n >\n @for (result of results; track result) {\n <li\n (click)=\"zoomToLocation(result)\"\n class=\"flex items-center pl-8 pr-4 py-2 border-b border-gray-200 relative cursor-pointer hover:bg-blue-100 hover:text-gray-800 transition duration-300 ease-in-out\"\n >\n <svg\n class=\"stroke-current text-blue-500 absolute w-5 h-5 left-3 top-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z\"\n />\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15 11a3 3 0 11-6 0 3 3 0 016 0z\"\n />\n </svg>\n <span class=\"font-sans font-semibold ml-4\">{{ result.label }}</span>\n </li>\n }\n </ul>\n}\n" }]
|
|
32974
|
-
}], ctorParameters: () => [] });
|
|
32975
|
-
|
|
32976
32575
|
/*
|
|
32977
32576
|
Metadata actions
|
|
32978
32577
|
*/
|
|
@@ -34155,7 +33754,7 @@ class DataService {
|
|
|
34155
33754
|
}));
|
|
34156
33755
|
}
|
|
34157
33756
|
async getDownloadLinksFromOgcApiFeatures(ogcApiLink) {
|
|
34158
|
-
const collectionInfo = await this.getDownloadUrlsFromOgcApi(ogcApiLink.url.href);
|
|
33757
|
+
const collectionInfo = await this.getDownloadUrlsFromOgcApi(ogcApiLink.url.href, ogcApiLink.name);
|
|
34159
33758
|
return Object.keys(collectionInfo.bulkDownloadLinks).map((mimeType) => {
|
|
34160
33759
|
const urlWithoutLimit = new URL(collectionInfo.bulkDownloadLinks[mimeType]);
|
|
34161
33760
|
urlWithoutLimit.searchParams.delete('limit');
|
|
@@ -34168,27 +33767,31 @@ class DataService {
|
|
|
34168
33767
|
};
|
|
34169
33768
|
});
|
|
34170
33769
|
}
|
|
34171
|
-
async
|
|
33770
|
+
async getTargetCollectionId(endpoint, collectionId) {
|
|
33771
|
+
const collections = await endpoint.featureCollections;
|
|
33772
|
+
return collections.length === 1 && !collectionId
|
|
33773
|
+
? collections[0]
|
|
33774
|
+
: collectionId;
|
|
33775
|
+
}
|
|
33776
|
+
async getDownloadUrlsFromOgcApi(url, collectionId) {
|
|
34172
33777
|
const endpoint = new OgcApiEndpoint(url);
|
|
34173
|
-
|
|
34174
|
-
.
|
|
34175
|
-
return endpoint.getCollectionInfo(
|
|
34176
|
-
}
|
|
34177
|
-
|
|
34178
|
-
throw new Error(
|
|
34179
|
-
}
|
|
33778
|
+
try {
|
|
33779
|
+
const id = await this.getTargetCollectionId(endpoint, collectionId);
|
|
33780
|
+
return await endpoint.getCollectionInfo(id);
|
|
33781
|
+
}
|
|
33782
|
+
catch {
|
|
33783
|
+
throw new Error('ogc.unreachable.unknown');
|
|
33784
|
+
}
|
|
34180
33785
|
}
|
|
34181
|
-
async getItemsFromOgcApi(url, limit) {
|
|
33786
|
+
async getItemsFromOgcApi(url, collectionId, limit) {
|
|
34182
33787
|
const endpoint = new OgcApiEndpoint(url);
|
|
34183
|
-
|
|
34184
|
-
.
|
|
34185
|
-
return
|
|
34186
|
-
|
|
34187
|
-
|
|
34188
|
-
|
|
34189
|
-
|
|
34190
|
-
throw new Error(`ogc.unreachable.unknown`);
|
|
34191
|
-
});
|
|
33788
|
+
try {
|
|
33789
|
+
const id = await this.getTargetCollectionId(endpoint, collectionId);
|
|
33790
|
+
return await endpoint.getCollectionItems(id, limit);
|
|
33791
|
+
}
|
|
33792
|
+
catch {
|
|
33793
|
+
throw new Error('ogc.unreachable.unknown');
|
|
33794
|
+
}
|
|
34192
33795
|
}
|
|
34193
33796
|
async getItemsFromStacApi(url, options) {
|
|
34194
33797
|
return await StacEndpoint.getItemsFromUrl(url, options)
|
|
@@ -34276,7 +33879,7 @@ class DataService {
|
|
|
34276
33879
|
}
|
|
34277
33880
|
else if (link.type === 'service' &&
|
|
34278
33881
|
link.accessServiceProtocol === 'ogcFeatures') {
|
|
34279
|
-
return from(this.getDownloadUrlsFromOgcApi(link.url.href)).pipe(switchMap$1((collectionInfo) => {
|
|
33882
|
+
return from(this.getDownloadUrlsFromOgcApi(link.url.href, link.name)).pipe(switchMap$1((collectionInfo) => {
|
|
34280
33883
|
const isMimeTypeJson = (mimeType) => {
|
|
34281
33884
|
return mimeType.toLowerCase().indexOf('json') > -1;
|
|
34282
33885
|
};
|
|
@@ -35220,7 +34823,7 @@ class MdViewFacade {
|
|
|
35220
34823
|
if (this.linkClassifier.hasUsage(link, LinkUsage.GEODATA)) {
|
|
35221
34824
|
if (link.type === 'service' &&
|
|
35222
34825
|
link.accessServiceProtocol === 'ogcFeatures') {
|
|
35223
|
-
return from(this.dataService.getItemsFromOgcApi(link.url.href, 1)).pipe(map$1((collectionRecords) => {
|
|
34826
|
+
return from(this.dataService.getItemsFromOgcApi(link.url.href, link.name, 1)).pipe(map$1((collectionRecords) => {
|
|
35224
34827
|
return collectionRecords &&
|
|
35225
34828
|
collectionRecords[0] &&
|
|
35226
34829
|
collectionRecords[0].geometry
|
|
@@ -35303,7 +34906,7 @@ class MdViewEffects {
|
|
|
35303
34906
|
}
|
|
35304
34907
|
return loadFullMetadataSuccess({ full: record });
|
|
35305
34908
|
}), catchError((error) => of(loadFullMetadataFailure({ otherError: error.message })))));
|
|
35306
|
-
this.loadFeatureCatalog$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), filter$1(({ full }) => full !== undefined), switchMap$1(({ full }) => this.recordsRepository.
|
|
34909
|
+
this.loadFeatureCatalog$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), filter$1(({ full }) => full !== undefined), switchMap$1(({ full }) => this.recordsRepository.queryLinkedFeatureCatalog(full)), map$1((featureCatalog) => loadFeatureCatalogSuccess({
|
|
35307
34910
|
datasetCatalog: featureCatalog,
|
|
35308
34911
|
})), catchError((error) => of(loadFeatureCatalogFailure({
|
|
35309
34912
|
error: error.message,
|
|
@@ -36962,6 +36565,15 @@ const DEFAULT_CONFIGURATION = {
|
|
|
36962
36565
|
labelKey: marker('editor.record.form.field.title'),
|
|
36963
36566
|
},
|
|
36964
36567
|
},
|
|
36568
|
+
{
|
|
36569
|
+
model: 'flags',
|
|
36570
|
+
modelSpecifier: 'flags:IS_REFERENCE_DATASET',
|
|
36571
|
+
formFieldConfig: {
|
|
36572
|
+
labelKey: marker('editor.record.form.field.flags.IS_REFERENCE_DATASET'),
|
|
36573
|
+
hintKey: marker('editor.record.form.field.hint.flags.IS_REFERENCE_DATASET'),
|
|
36574
|
+
},
|
|
36575
|
+
hidden: '${record.kind != "dataset" || !user.isAdmin}',
|
|
36576
|
+
},
|
|
36965
36577
|
{
|
|
36966
36578
|
model: 'abstract',
|
|
36967
36579
|
formFieldConfig: {
|
|
@@ -38017,7 +37629,7 @@ class GenericKeywordsComponent {
|
|
|
38017
37629
|
this.deletedKeyword.emit(keyword);
|
|
38018
37630
|
}
|
|
38019
37631
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GenericKeywordsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
38020
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: GenericKeywordsComponent, isStandalone: true, selector: "gn-ui-generic-keywords", inputs: { keywords: "keywords", keywordTypes: "keywordTypes", placeholder: "placeholder", allowSubmit: "allowSubmit" }, outputs: { changedKeywords: "changedKeywords", addedKeyword: "addedKeyword", deletedKeyword: "deletedKeyword" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\">\n <gn-ui-autocomplete\n [placeholder]=\"placeholder\"\n [displayWithFn]=\"displayWithFn\"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"handleItemSelection($event)\"\n [preventCompleteOnSelection]=\"false\"\n [minCharacterCount]=\"1\"\n [allowSubmit]=\"false\"\n [clearOnSelection]=\"true\"\n ></gn-ui-autocomplete>\n <div class=\"flex gap-2 flex-wrap\">\n @for (keyword of keywords; track keyword) {\n <gn-ui-keyword-badge\n [keyword]=\"keyword\"\n [editable]=\"true\"\n (keywordRemove)=\"removeKeyword($event)\"\n ></gn-ui-keyword-badge>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "component", type: KeywordBadgeComponent, selector: "gn-ui-keyword-badge", inputs: ["keyword", "editable"], outputs: ["keywordClick", "keywordRemove"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
37632
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: GenericKeywordsComponent, isStandalone: true, selector: "gn-ui-generic-keywords", inputs: { keywords: "keywords", keywordTypes: "keywordTypes", placeholder: "placeholder", allowSubmit: "allowSubmit" }, outputs: { changedKeywords: "changedKeywords", addedKeyword: "addedKeyword", deletedKeyword: "deletedKeyword" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\">\n <gn-ui-autocomplete\n [placeholder]=\"placeholder\"\n [displayWithFn]=\"displayWithFn\"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"handleItemSelection($event)\"\n [preventCompleteOnSelection]=\"false\"\n [minCharacterCount]=\"1\"\n [allowSubmit]=\"false\"\n [clearOnSelection]=\"true\"\n ></gn-ui-autocomplete>\n <div class=\"flex gap-2 flex-wrap\">\n @for (keyword of keywords; track keyword) {\n <gn-ui-keyword-badge\n [keyword]=\"keyword\"\n [editable]=\"true\"\n (keywordRemove)=\"removeKeyword($event)\"\n ></gn-ui-keyword-badge>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithTemplate", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "component", type: KeywordBadgeComponent, selector: "gn-ui-keyword-badge", inputs: ["keyword", "editable"], outputs: ["keywordClick", "keywordRemove"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
38021
37633
|
}
|
|
38022
37634
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GenericKeywordsComponent, decorators: [{
|
|
38023
37635
|
type: Component,
|
|
@@ -38609,7 +38221,7 @@ class FormFieldContactsForResourceComponent {
|
|
|
38609
38221
|
provideNgIconsConfig({
|
|
38610
38222
|
size: '1.5rem',
|
|
38611
38223
|
}),
|
|
38612
|
-
], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col gap-3\">\n <div class=\"flex flex-row flex-wrap gap-2\" data-test=\"rolesToPick\">\n @for (role of rolesToPick; track role) {\n <gn-ui-button type=\"gray\" (buttonClick)=\"addRoleToDisplay(role)\">\n <ng-icon name=\"iconoirPlus\" class=\"text-primary\"></ng-icon>\n \n <span translate>{{ roleToLabel(role) }}</span>\n </gn-ui-button>\n }\n </div>\n @if (value.length === 0) {\n <div\n class=\"p-4 border border-primary bg-primary-lightest rounded-lg\"\n translate\n >\n editor.record.form.field.contactsForResource.noContact\n </div>\n }\n @if (roleSectionsToDisplay && roleSectionsToDisplay.length > 0) {\n <div class=\"mt-8\" data-test=\"displayedRoles\">\n @for (\n role of roleSectionsToDisplay;\n track role;\n let index = $index;\n let isLast = $last\n ) {\n <div class=\"flex flex-col gap-4\">\n <div class=\"flex flex-row justify-between\">\n <span class=\"font-bold text-base\" translate>{{\n roleToLabel(role)\n }}</span>\n </div>\n @if (role !== 'unspecified' && role !== 'other') {\n <gn-ui-autocomplete\n [placeholder]=\"\n 'editor.record.form.field.contactsForResource.placeholder'\n | translate\n \"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"addContact($event, role)\"\n [displayWithFn]=\"displayWithFn\"\n [minCharacterCount]=\"1\"\n [clearOnSelection]=\"true\"\n [allowSubmit]=\"false\"\n >\n </gn-ui-autocomplete>\n }\n @if (contactsForRessourceByRole.get(role); as contacts) {\n <gn-ui-sortable-list\n [items]=\"contacts\"\n (itemsOrderChange)=\"handleContactsChanged($event, role)\"\n [elementTemplate]=\"contactTemplate\"\n ></gn-ui-sortable-list>\n <ng-template #contactTemplate let-contact>\n <gn-ui-contact-card [contact]=\"contact\"></gn-ui-contact-card>\n </ng-template>\n }\n @if (!isLast) {\n <hr class=\"border-t-[#D6D3D1] mt-4 mb-6\" />\n }\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{--gn-ui-button-padding: 8px 8px;--gn-ui-button-rounded: 8px}\n"], dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "component", type: ContactCardComponent, selector: "gn-ui-contact-card", inputs: ["contact"] }, { kind: "component", type: SortableListComponent, selector: "gn-ui-sortable-list", inputs: ["elementTemplate", "items"], outputs: ["itemsOrderChange"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
38224
|
+
], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col gap-3\">\n <div class=\"flex flex-row flex-wrap gap-2\" data-test=\"rolesToPick\">\n @for (role of rolesToPick; track role) {\n <gn-ui-button type=\"gray\" (buttonClick)=\"addRoleToDisplay(role)\">\n <ng-icon name=\"iconoirPlus\" class=\"text-primary\"></ng-icon>\n \n <span translate>{{ roleToLabel(role) }}</span>\n </gn-ui-button>\n }\n </div>\n @if (value.length === 0) {\n <div\n class=\"p-4 border border-primary bg-primary-lightest rounded-lg\"\n translate\n >\n editor.record.form.field.contactsForResource.noContact\n </div>\n }\n @if (roleSectionsToDisplay && roleSectionsToDisplay.length > 0) {\n <div class=\"mt-8\" data-test=\"displayedRoles\">\n @for (\n role of roleSectionsToDisplay;\n track role;\n let index = $index;\n let isLast = $last\n ) {\n <div class=\"flex flex-col gap-4\">\n <div class=\"flex flex-row justify-between\">\n <span class=\"font-bold text-base\" translate>{{\n roleToLabel(role)\n }}</span>\n </div>\n @if (role !== 'unspecified' && role !== 'other') {\n <gn-ui-autocomplete\n [placeholder]=\"\n 'editor.record.form.field.contactsForResource.placeholder'\n | translate\n \"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"addContact($event, role)\"\n [displayWithFn]=\"displayWithFn\"\n [minCharacterCount]=\"1\"\n [clearOnSelection]=\"true\"\n [allowSubmit]=\"false\"\n >\n </gn-ui-autocomplete>\n }\n @if (contactsForRessourceByRole.get(role); as contacts) {\n <gn-ui-sortable-list\n [items]=\"contacts\"\n (itemsOrderChange)=\"handleContactsChanged($event, role)\"\n [elementTemplate]=\"contactTemplate\"\n ></gn-ui-sortable-list>\n <ng-template #contactTemplate let-contact>\n <gn-ui-contact-card [contact]=\"contact\"></gn-ui-contact-card>\n </ng-template>\n }\n @if (!isLast) {\n <hr class=\"border-t-[#D6D3D1] mt-4 mb-6\" />\n }\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{--gn-ui-button-padding: 8px 8px;--gn-ui-button-rounded: 8px}\n"], dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithTemplate", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "component", type: ContactCardComponent, selector: "gn-ui-contact-card", inputs: ["contact"] }, { kind: "component", type: SortableListComponent, selector: "gn-ui-sortable-list", inputs: ["elementTemplate", "items"], outputs: ["itemsOrderChange"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
38613
38225
|
}
|
|
38614
38226
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldContactsForResourceComponent, decorators: [{
|
|
38615
38227
|
type: Component,
|
|
@@ -38709,7 +38321,7 @@ class FormFieldContactsComponent {
|
|
|
38709
38321
|
this.subscription.unsubscribe();
|
|
38710
38322
|
}
|
|
38711
38323
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldContactsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
38712
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FormFieldContactsComponent, isStandalone: true, selector: "gn-ui-form-field-contacts", inputs: { value: "value", modelSpecifier: "modelSpecifier" }, outputs: { valueChange: "valueChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col gap-3\">\n <gn-ui-autocomplete\n [placeholder]=\"'editor.record.form.field.contacts.placeholder' | translate\"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"addContact($event)\"\n [displayWithFn]=\"displayWithFn\"\n [minCharacterCount]=\"1\"\n [clearOnSelection]=\"true\"\n >\n </gn-ui-autocomplete>\n\n @if (contacts.length > 0) {\n <gn-ui-sortable-list\n [items]=\"contacts\"\n (itemsOrderChange)=\"handleContactsChanged($event)\"\n [elementTemplate]=\"contactTemplate\"\n ></gn-ui-sortable-list>\n <ng-template #contactTemplate let-contact let-index=\"index\">\n @if (modelSpecifier === 'contact:editableDetails') {\n <gn-ui-contact-details-form\n [contact]=\"contact\"\n (contactChange)=\"handleContactChanged($event, index)\"\n ></gn-ui-contact-details-form>\n } @else {\n <gn-ui-contact-card [contact]=\"contact\"></gn-ui-contact-card>\n }\n </ng-template>\n } @else {\n <div\n class=\"p-4 text-sm border border-primary bg-primary-lightest rounded-lg\"\n translate\n >\n editor.record.form.field.contacts.noContact\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ContactCardComponent, selector: "gn-ui-contact-card", inputs: ["contact"] }, { kind: "component", type: ContactDetailsFormComponent, selector: "gn-ui-contact-details-form", inputs: ["contact"], outputs: ["contactChange"] }, { kind: "component", type: SortableListComponent, selector: "gn-ui-sortable-list", inputs: ["elementTemplate", "items"], outputs: ["itemsOrderChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
38324
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FormFieldContactsComponent, isStandalone: true, selector: "gn-ui-form-field-contacts", inputs: { value: "value", modelSpecifier: "modelSpecifier" }, outputs: { valueChange: "valueChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col gap-3\">\n <gn-ui-autocomplete\n [placeholder]=\"'editor.record.form.field.contacts.placeholder' | translate\"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"addContact($event)\"\n [displayWithFn]=\"displayWithFn\"\n [minCharacterCount]=\"1\"\n [clearOnSelection]=\"true\"\n >\n </gn-ui-autocomplete>\n\n @if (contacts.length > 0) {\n <gn-ui-sortable-list\n [items]=\"contacts\"\n (itemsOrderChange)=\"handleContactsChanged($event)\"\n [elementTemplate]=\"contactTemplate\"\n ></gn-ui-sortable-list>\n <ng-template #contactTemplate let-contact let-index=\"index\">\n @if (modelSpecifier === 'contact:editableDetails') {\n <gn-ui-contact-details-form\n [contact]=\"contact\"\n (contactChange)=\"handleContactChanged($event, index)\"\n ></gn-ui-contact-details-form>\n } @else {\n <gn-ui-contact-card [contact]=\"contact\"></gn-ui-contact-card>\n }\n </ng-template>\n } @else {\n <div\n class=\"p-4 text-sm border border-primary bg-primary-lightest rounded-lg\"\n translate\n >\n editor.record.form.field.contacts.noContact\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithTemplate", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ContactCardComponent, selector: "gn-ui-contact-card", inputs: ["contact"] }, { kind: "component", type: ContactDetailsFormComponent, selector: "gn-ui-contact-details-form", inputs: ["contact"], outputs: ["contactChange"] }, { kind: "component", type: SortableListComponent, selector: "gn-ui-sortable-list", inputs: ["elementTemplate", "items"], outputs: ["itemsOrderChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
38713
38325
|
}
|
|
38714
38326
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldContactsComponent, decorators: [{
|
|
38715
38327
|
type: Component,
|
|
@@ -39062,7 +38674,7 @@ class OnlineServiceResourceInputComponent {
|
|
|
39062
38674
|
provideNgIconsConfig({
|
|
39063
38675
|
size: '1.5em',
|
|
39064
38676
|
}),
|
|
39065
|
-
], ngImport: i0, template: "<div class=\"flex flex-row justify-between\">\n <h3 class=\"text-[16px] font-bold text-main mb-[12px]\" translate>\n editor.record.form.field.onlineResource.edit.protocol\n </h3>\n @if (protocolHint) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"protocolHint\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n</div>\n<div class=\"flex flex-row items-center gap-4 h-[48px]\">\n <mat-radio-group\n aria-labelledby=\"example-radio-group-label\"\n class=\"flex flex-row gap-[8px]\"\n [(ngModel)]=\"_service.accessServiceProtocol\"\n [disabled]=\"disabled\"\n (change)=\"resetAllFormFields()\"\n >\n @for (protocolOption of availableProtocolOptions; track protocolOption) {\n <mat-radio-button [value]=\"protocolOption.value\">\n {{ protocolOption.label | translate }}\n </mat-radio-button>\n }\n </mat-radio-group>\n</div>\n\n<div class=\"flex flex-col gap-4\">\n <gn-ui-url-input\n class=\"w-full\"\n (uploadClick)=\"handleUploadClick($event)\"\n (valueChange)=\"handleUrlValueChange($event)\"\n [disabled]=\"disabled\"\n [value]=\"_service.url?.toString()\"\n [showValidateButton]=\"activeLayerSuggestion\"\n [resetUrlOnChange]=\"resetUrlOnChange\"\n >\n @if (activeLayerSuggestion) {\n <ng-content>\n <ng-icon name=\"iconoirRefresh\"></ng-icon>\n </ng-content>\n }\n </gn-ui-url-input>\n\n @if (loading) {\n <div class=\"flex justify-center w-full py-4\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n }\n @if (errorMessage) {\n <p class=\"text-sm text-red-500 pl-4\" translate>\n editor.record.form.field.onlineResource.edit.identifier.error\n </p>\n }\n\n @if (\n !activeLayerSuggestion ||\n (_service.url && errorMessage) ||\n (modifyMode && (layers$ | async).length === 0)\n ) {\n <gn-ui-text-input\n class=\"grow border-b border-gray-300 pb-4\"\n [(value)]=\"_service.identifierInService\"\n [placeholder]=\"getIdentifierPlaceholder() | translate\"\n data-cy=\"identifier-in-service\"\n [disabled]=\"disabled\"\n ></gn-ui-text-input>\n }\n @if (activeLayerSuggestion && (layers$ | async)?.length > 0) {\n <gn-ui-autocomplete\n class=\"border-b border-gray-300 pb-4\"\n [placeholder]=\"\n 'editor.record.form.field.onlineResource.edit.identifier.select.label'\n | translate\n \"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"handleSelectValue($event)\"\n [displayWithFn]=\"displayWithFn\"\n [minCharacterCount]=\"0\"\n [clearOnSelection]=\"false\"\n >\n </gn-ui-autocomplete>\n }\n @if (\n !modifyMode &&\n ((activeLayerSuggestion && (layers$ | async)) ||\n !activeLayerSuggestion ||\n (_service.url && errorMessage))\n ) {\n <gn-ui-button\n (buttonClick)=\"submit()\"\n [disabled]=\"disabled || !_service.identifierInService\"\n type=\"primary\"\n >\n <span class=\"text-white font-bold\" translate>\n editor.record.form.field.onlineResource.edit.identifier.submit</span\n >\n </gn-ui-button>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i3$1.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i3$1.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: SpinningLoaderComponent, selector: "gn-ui-spinning-loader" }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "placeholder", "required", "disabled", "type"], outputs: ["valueChange"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: UrlInputComponent, selector: "gn-ui-url-input", inputs: ["value", "extraClass", "placeholder", "disabled", "showValidateButton", "resetUrlOnChange"], outputs: ["valueChange", "uploadClick"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
38677
|
+
], ngImport: i0, template: "<div class=\"flex flex-row justify-between\">\n <h3 class=\"text-[16px] font-bold text-main mb-[12px]\" translate>\n editor.record.form.field.onlineResource.edit.protocol\n </h3>\n @if (protocolHint) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"protocolHint\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n</div>\n<div class=\"flex flex-row items-center gap-4 h-[48px]\">\n <mat-radio-group\n aria-labelledby=\"example-radio-group-label\"\n class=\"flex flex-row gap-[8px]\"\n [(ngModel)]=\"_service.accessServiceProtocol\"\n [disabled]=\"disabled\"\n (change)=\"resetAllFormFields()\"\n >\n @for (protocolOption of availableProtocolOptions; track protocolOption) {\n <mat-radio-button [value]=\"protocolOption.value\">\n {{ protocolOption.label | translate }}\n </mat-radio-button>\n }\n </mat-radio-group>\n</div>\n\n<div class=\"flex flex-col gap-4\">\n <gn-ui-url-input\n class=\"w-full\"\n (uploadClick)=\"handleUploadClick($event)\"\n (valueChange)=\"handleUrlValueChange($event)\"\n [disabled]=\"disabled\"\n [value]=\"_service.url?.toString()\"\n [showValidateButton]=\"activeLayerSuggestion\"\n [resetUrlOnChange]=\"resetUrlOnChange\"\n >\n @if (activeLayerSuggestion) {\n <ng-content>\n <ng-icon name=\"iconoirRefresh\"></ng-icon>\n </ng-content>\n }\n </gn-ui-url-input>\n\n @if (loading) {\n <div class=\"flex justify-center w-full py-4\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n }\n @if (errorMessage) {\n <p class=\"text-sm text-red-500 pl-4\" translate>\n editor.record.form.field.onlineResource.edit.identifier.error\n </p>\n }\n\n @if (\n !activeLayerSuggestion ||\n (_service.url && errorMessage) ||\n (modifyMode && (layers$ | async).length === 0)\n ) {\n <gn-ui-text-input\n class=\"grow border-b border-gray-300 pb-4\"\n [(value)]=\"_service.identifierInService\"\n [placeholder]=\"getIdentifierPlaceholder() | translate\"\n data-cy=\"identifier-in-service\"\n [disabled]=\"disabled\"\n ></gn-ui-text-input>\n }\n @if (activeLayerSuggestion && (layers$ | async)?.length > 0) {\n <gn-ui-autocomplete\n class=\"border-b border-gray-300 pb-4\"\n [placeholder]=\"\n 'editor.record.form.field.onlineResource.edit.identifier.select.label'\n | translate\n \"\n [action]=\"autoCompleteAction\"\n (itemSelected)=\"handleSelectValue($event)\"\n [displayWithFn]=\"displayWithFn\"\n [minCharacterCount]=\"0\"\n [clearOnSelection]=\"false\"\n >\n </gn-ui-autocomplete>\n }\n @if (\n !modifyMode &&\n ((activeLayerSuggestion && (layers$ | async)) ||\n !activeLayerSuggestion ||\n (_service.url && errorMessage))\n ) {\n <gn-ui-button\n (buttonClick)=\"submit()\"\n [disabled]=\"disabled || !_service.identifierInService\"\n type=\"primary\"\n >\n <span class=\"text-white font-bold\" translate>\n editor.record.form.field.onlineResource.edit.identifier.submit</span\n >\n </gn-ui-button>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "gn-ui-autocomplete", inputs: ["placeholder", "enterButton", "action", "value", "clearOnSelection", "preventCompleteOnSelection", "autoFocus", "minCharacterCount", "allowSubmit", "forceTrackPosition", "displayWithTemplate", "displayWithFn"], outputs: ["itemSelected", "inputSubmitted", "inputCleared", "isSearchActive"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i3$1.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i3$1.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: SpinningLoaderComponent, selector: "gn-ui-spinning-loader" }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "placeholder", "required", "disabled", "type"], outputs: ["valueChange"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: UrlInputComponent, selector: "gn-ui-url-input", inputs: ["value", "extraClass", "placeholder", "disabled", "showValidateButton", "resetUrlOnChange"], outputs: ["valueChange", "uploadClick"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
39066
38678
|
}
|
|
39067
38679
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: OnlineServiceResourceInputComponent, decorators: [{
|
|
39068
38680
|
type: Component,
|
|
@@ -39846,6 +39458,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
39846
39458
|
type: Output
|
|
39847
39459
|
}] } });
|
|
39848
39460
|
|
|
39461
|
+
class FormFieldRecordFlagComponent {
|
|
39462
|
+
constructor() {
|
|
39463
|
+
this.flagName = input(...(ngDevMode ? [undefined, { debugName: "flagName" }] : []));
|
|
39464
|
+
this.labelKey = input(...(ngDevMode ? [undefined, { debugName: "labelKey" }] : []));
|
|
39465
|
+
this.hintKey = input(...(ngDevMode ? [undefined, { debugName: "hintKey" }] : []));
|
|
39466
|
+
this.editorFacade = inject(EditorFacade);
|
|
39467
|
+
this.repository = inject(RecordsRepositoryInterface);
|
|
39468
|
+
this.notificationsService = inject(NotificationsService);
|
|
39469
|
+
this.translateService = inject(TranslateService);
|
|
39470
|
+
this.record = toSignal(this.editorFacade.record$);
|
|
39471
|
+
this.recordKind = toSignal(this.editorFacade.record$.pipe(map$1((record) => record.kind)));
|
|
39472
|
+
this.initialValue$ = this.editorFacade.record$.pipe(filter((record) => !!record), switchMap$1((record) => this.repository.getRecordFlag(record.uniqueIdentifier, this.flagName())));
|
|
39473
|
+
}
|
|
39474
|
+
onToggle(enabled) {
|
|
39475
|
+
if (this.record() === null) {
|
|
39476
|
+
return;
|
|
39477
|
+
}
|
|
39478
|
+
this.repository
|
|
39479
|
+
.setRecordFlag(this.record().uniqueIdentifier, this.flagName(), enabled)
|
|
39480
|
+
.subscribe({
|
|
39481
|
+
next: () => {
|
|
39482
|
+
// do nothing
|
|
39483
|
+
},
|
|
39484
|
+
error: (error) => {
|
|
39485
|
+
this.notificationsService.showNotification({
|
|
39486
|
+
type: 'error',
|
|
39487
|
+
title: this.translateService.instant('editor.record.flag.saveError.title'),
|
|
39488
|
+
text: `${this.translateService.instant('editor.record.flag.saveError.body', {
|
|
39489
|
+
recordKind: this.recordKind(),
|
|
39490
|
+
})} ${error.message}`,
|
|
39491
|
+
}, undefined, error);
|
|
39492
|
+
},
|
|
39493
|
+
});
|
|
39494
|
+
}
|
|
39495
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldRecordFlagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
39496
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FormFieldRecordFlagComponent, isStandalone: true, selector: "gn-ui-form-field-record-flag", inputs: { flagName: { classPropertyName: "flagName", publicName: "flagName", isSignal: true, isRequired: false, transformFunction: null }, labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, hintKey: { classPropertyName: "hintKey", publicName: "hintKey", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex-1 flex justify-between items-center\">\n <gn-ui-check-toggle\n [label]=\"labelKey() | translate\"\n [value]=\"initialValue$ | async\"\n (toggled)=\"onToggle($event)\"\n [attr.data-cy]=\"'record-flag-toggle-' + flagName()\"\n ></gn-ui-check-toggle>\n\n @if (hintKey()) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"hintKey() | translate\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: CheckToggleComponent, selector: "gn-ui-check-toggle", inputs: ["title", "label", "value", "color"], outputs: ["toggled"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
|
|
39497
|
+
provideIcons({
|
|
39498
|
+
matHelpOutline,
|
|
39499
|
+
}),
|
|
39500
|
+
], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
39501
|
+
}
|
|
39502
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldRecordFlagComponent, decorators: [{
|
|
39503
|
+
type: Component,
|
|
39504
|
+
args: [{ selector: 'gn-ui-form-field-record-flag', standalone: true, imports: [AsyncPipe, CheckToggleComponent, TranslatePipe, NgIcon, MatTooltip], viewProviders: [
|
|
39505
|
+
provideIcons({
|
|
39506
|
+
matHelpOutline,
|
|
39507
|
+
}),
|
|
39508
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex-1 flex justify-between items-center\">\n <gn-ui-check-toggle\n [label]=\"labelKey() | translate\"\n [value]=\"initialValue$ | async\"\n (toggled)=\"onToggle($event)\"\n [attr.data-cy]=\"'record-flag-toggle-' + flagName()\"\n ></gn-ui-check-toggle>\n\n @if (hintKey()) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"hintKey() | translate\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n</div>\n" }]
|
|
39509
|
+
}], propDecorators: { flagName: [{ type: i0.Input, args: [{ isSignal: true, alias: "flagName", required: false }] }], labelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelKey", required: false }] }], hintKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "hintKey", required: false }] }] } });
|
|
39510
|
+
|
|
39849
39511
|
class FormFieldComponent {
|
|
39850
39512
|
constructor() {
|
|
39851
39513
|
this.valueChange = new EventEmitter();
|
|
@@ -39864,6 +39526,7 @@ class FormFieldComponent {
|
|
|
39864
39526
|
this.model === 'legalConstraints' ||
|
|
39865
39527
|
this.model === 'securityConstraints' ||
|
|
39866
39528
|
this.model === 'otherConstraints' ||
|
|
39529
|
+
this.model === 'flags' ||
|
|
39867
39530
|
this.componentName === 'form-field-constraints-shortcuts');
|
|
39868
39531
|
}
|
|
39869
39532
|
get valueAsString() {
|
|
@@ -39903,6 +39566,9 @@ class FormFieldComponent {
|
|
|
39903
39566
|
const identifiers = this.value;
|
|
39904
39567
|
return identifiers?.[0]?.code || '';
|
|
39905
39568
|
}
|
|
39569
|
+
get recordFlag() {
|
|
39570
|
+
return this.modelSpecifier?.replace(/^flags:/, '');
|
|
39571
|
+
}
|
|
39906
39572
|
handleResourceIdentifierChange(code) {
|
|
39907
39573
|
const identifiers = this.value;
|
|
39908
39574
|
if (!code) {
|
|
@@ -39920,7 +39586,7 @@ class FormFieldComponent {
|
|
|
39920
39586
|
}
|
|
39921
39587
|
}
|
|
39922
39588
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
39923
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: FormFieldComponent, isStandalone: true, selector: "gn-ui-form-field", inputs: { uniqueIdentifier: "uniqueIdentifier", recordKind: "recordKind", model: "model", modelSpecifier: "modelSpecifier", componentName: "componentName", config: "config", value: "value" }, outputs: { valueChange: "valueChange" }, providers: [provideIcons({ matEditOutline, matHelpOutline })], viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }], hostDirectives: [{ directive: FieldFocusDirective }], ngImport: i0, template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container [ngSwitch]=\"model\">\n <ng-container *ngSwitchCase=\"'title'\">\n <div class=\"flex flex-row flex-start items-center gap-3 mb-[12px]\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder'\n | translate: { recordKind }\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <ng-icon\n name=\"matEditOutline\"\n size=\"16\"\n class=\"m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n ></ng-icon>\n <ng-icon\n *ngIf=\"config.hintKey\"\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"config.hintKey! | translate: { recordKind }\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'abstract'\">\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngSwitchCase=\"'overviews'\">\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [recordKind]=\"recordKind\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceIdentifiers'\">\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceCreated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceUpdated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'updateFrequency'\">\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n [recordKind]=\"recordKind\"\n ></gn-ui-form-field-update-frequency>\n </ng-container>\n <ng-container *ngSwitchCase=\"'associatedRecords'\">\n <gn-ui-form-field-associated-records\n [value]=\"valueAsAssociatedRecords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-associated-records>\n </ng-container>\n <ng-container *ngSwitchCase=\"'temporalExtents'\">\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spatialExtents'\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngSwitchCase=\"'keywords'\">\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n </ng-container>\n <ng-container *ngSwitchCase=\"'topics'\">\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n </ng-container>\n <ng-container *ngSwitchCase=\"'licenses'\">\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'legalConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'securityConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'otherConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container\n ></ng-container>\n <ng-template #formFieldConstraints>\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints\n ></ng-template>\n\n <ng-container *ngSwitchCase=\"'contactsForResource'\">\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'contacts'\">\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n [modelSpecifier]=\"modelSpecifier\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:!link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-link-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-single-link-resource\n *ngIf=\"modelSpecifier === 'onlineResourceType:singleLink'\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-single-link-resource>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!model\">\n <ng-container [ngSwitch]=\"componentName\">\n <ng-container *ngSwitchCase=\"'form-field-constraints-shortcuts'\">\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'form-field-spatial-toggle'\">\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n </ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n", styles: [":host{scroll-margin-top:90px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FormFieldWrapperComponent, selector: "gn-ui-form-field-wrapper", inputs: ["label", "hint"] }, { kind: "component", type: FormFieldLicenseComponent, selector: "gn-ui-form-field-license", inputs: ["label", "recordLicences"], outputs: ["recordLicencesChange"] }, { kind: "component", type: FormFieldDateComponent, selector: "gn-ui-form-field-date", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldUpdateFrequencyComponent, selector: "gn-ui-form-field-update-frequency", inputs: ["value", "recordKind"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldAssociatedRecordsComponent, selector: "gn-ui-form-field-associated-records", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldTemporalExtentsComponent, selector: "gn-ui-form-field-temporal-extents", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: ["type", "readonly", "invalid", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: ["label", "hint", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent" }, { kind: "component", type: FormFieldKeywordsComponent, selector: "gn-ui-form-field-keywords", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOverviewsComponent, selector: "gn-ui-form-field-overviews", inputs: ["metadataUuid", "recordKind", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsForResourceComponent, selector: "gn-ui-form-field-contacts-for-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineResourcesComponent, selector: "gn-ui-form-field-online-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineLinkResourcesComponent, selector: "gn-ui-form-field-online-link-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineSingleLinkResourceComponent, selector: "gn-ui-form-field-online-single-link-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsComponent, selector: "gn-ui-form-field-contacts", inputs: ["value", "modelSpecifier"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsComponent, selector: "gn-ui-form-field-constraints", inputs: ["label", "value", "constraintType"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsShortcutsComponent, selector: "gn-ui-form-field-constraints-shortcuts" }, { kind: "component", type: FormFieldSpatialToggleComponent, selector: "gn-ui-form-field-spatial-toggle" }, { kind: "component", type: FormFieldTopicsComponent, selector: "gn-ui-form-field-topics", inputs: ["value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "directive", type: i4$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
39589
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FormFieldComponent, isStandalone: true, selector: "gn-ui-form-field", inputs: { uniqueIdentifier: "uniqueIdentifier", recordKind: "recordKind", model: "model", modelSpecifier: "modelSpecifier", componentName: "componentName", config: "config", value: "value" }, outputs: { valueChange: "valueChange" }, providers: [provideIcons({ matEditOutline, matHelpOutline })], viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }], hostDirectives: [{ directive: FieldFocusDirective }], ngImport: i0, template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n @if (withoutWrapper) {\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n } @else {\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n }\n</div>\n\n<ng-template #fieldContent>\n @switch (model) {\n @case ('title') {\n <div class=\"flex flex-row flex-start items-center gap-3\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder'\n | translate: { recordKind }\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <ng-icon\n name=\"matEditOutline\"\n size=\"16\"\n class=\"m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n ></ng-icon>\n @if (config.hintKey) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"config.hintKey! | translate: { recordKind }\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n </div>\n </div>\n }\n @case ('abstract') {\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n }\n @case ('overviews') {\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [recordKind]=\"recordKind\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n }\n @case ('resourceIdentifiers') {\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n }\n @case ('resourceCreated') {\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n }\n @case ('resourceUpdated') {\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n }\n @case ('updateFrequency') {\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n [recordKind]=\"recordKind\"\n ></gn-ui-form-field-update-frequency>\n }\n @case ('associatedRecords') {\n <gn-ui-form-field-associated-records\n [value]=\"valueAsAssociatedRecords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-associated-records>\n }\n @case ('temporalExtents') {\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n }\n @case ('spatialExtents') {\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n }\n @case ('keywords') {\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n }\n @case ('topics') {\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n }\n @case ('licenses') {\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n }\n\n <!-- TODO: merge these cases together when migrated to angular 21 -->\n @case ('legalConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n @case ('securityConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n @case ('otherConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n\n @case ('contactsForResource') {\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n }\n @case ('contacts') {\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n [modelSpecifier]=\"modelSpecifier\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n }\n @case ('onlineResources') {\n @if (modelSpecifier === 'onlineResourceType:!link') {\n <gn-ui-form-field-online-resources\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n } @else if (modelSpecifier === 'onlineResourceType:link') {\n <gn-ui-form-field-online-link-resources\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n } @else if (modelSpecifier === 'onlineResourceType:singleLink') {\n <gn-ui-form-field-online-single-link-resource\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-single-link-resource>\n }\n }\n @case ('flags') {\n <gn-ui-form-field-record-flag\n [flagName]=\"recordFlag\"\n [labelKey]=\"config.labelKey\"\n [hintKey]=\"config.hintKey\"\n ></gn-ui-form-field-record-flag>\n }\n }\n\n @if (!model) {\n @switch (componentName) {\n @case ('form-field-constraints-shortcuts') {\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n }\n @case ('form-field-spatial-toggle') {\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n }\n }\n }\n</ng-template>\n", styles: [":host{scroll-margin-top:90px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FormFieldWrapperComponent, selector: "gn-ui-form-field-wrapper", inputs: ["label", "hint"] }, { kind: "component", type: FormFieldLicenseComponent, selector: "gn-ui-form-field-license", inputs: ["label", "recordLicences"], outputs: ["recordLicencesChange"] }, { kind: "component", type: FormFieldDateComponent, selector: "gn-ui-form-field-date", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldUpdateFrequencyComponent, selector: "gn-ui-form-field-update-frequency", inputs: ["value", "recordKind"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldAssociatedRecordsComponent, selector: "gn-ui-form-field-associated-records", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldTemporalExtentsComponent, selector: "gn-ui-form-field-temporal-extents", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: ["type", "readonly", "invalid", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: ["label", "hint", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent" }, { kind: "component", type: FormFieldKeywordsComponent, selector: "gn-ui-form-field-keywords", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOverviewsComponent, selector: "gn-ui-form-field-overviews", inputs: ["metadataUuid", "recordKind", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsForResourceComponent, selector: "gn-ui-form-field-contacts-for-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineResourcesComponent, selector: "gn-ui-form-field-online-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineLinkResourcesComponent, selector: "gn-ui-form-field-online-link-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineSingleLinkResourceComponent, selector: "gn-ui-form-field-online-single-link-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsComponent, selector: "gn-ui-form-field-contacts", inputs: ["value", "modelSpecifier"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsComponent, selector: "gn-ui-form-field-constraints", inputs: ["label", "value", "constraintType"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsShortcutsComponent, selector: "gn-ui-form-field-constraints-shortcuts" }, { kind: "component", type: FormFieldSpatialToggleComponent, selector: "gn-ui-form-field-spatial-toggle" }, { kind: "component", type: FormFieldTopicsComponent, selector: "gn-ui-form-field-topics", inputs: ["value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "directive", type: i4$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: FormFieldRecordFlagComponent, selector: "gn-ui-form-field-record-flag", inputs: ["flagName", "labelKey", "hintKey"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
39924
39590
|
}
|
|
39925
39591
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldComponent, decorators: [{
|
|
39926
39592
|
type: Component,
|
|
@@ -39950,7 +39616,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
39950
39616
|
FormFieldTopicsComponent,
|
|
39951
39617
|
TextFieldModule,
|
|
39952
39618
|
NgIconComponent,
|
|
39953
|
-
|
|
39619
|
+
FormFieldRecordFlagComponent,
|
|
39620
|
+
], providers: [provideIcons({ matEditOutline, matHelpOutline })], hostDirectives: [FieldFocusDirective], template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n @if (withoutWrapper) {\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n } @else {\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n }\n</div>\n\n<ng-template #fieldContent>\n @switch (model) {\n @case ('title') {\n <div class=\"flex flex-row flex-start items-center gap-3\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder'\n | translate: { recordKind }\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <ng-icon\n name=\"matEditOutline\"\n size=\"16\"\n class=\"m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n ></ng-icon>\n @if (config.hintKey) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"config.hintKey! | translate: { recordKind }\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n </div>\n </div>\n }\n @case ('abstract') {\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n }\n @case ('overviews') {\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [recordKind]=\"recordKind\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n }\n @case ('resourceIdentifiers') {\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n }\n @case ('resourceCreated') {\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n }\n @case ('resourceUpdated') {\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n }\n @case ('updateFrequency') {\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n [recordKind]=\"recordKind\"\n ></gn-ui-form-field-update-frequency>\n }\n @case ('associatedRecords') {\n <gn-ui-form-field-associated-records\n [value]=\"valueAsAssociatedRecords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-associated-records>\n }\n @case ('temporalExtents') {\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n }\n @case ('spatialExtents') {\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n }\n @case ('keywords') {\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n }\n @case ('topics') {\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n }\n @case ('licenses') {\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n }\n\n <!-- TODO: merge these cases together when migrated to angular 21 -->\n @case ('legalConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n @case ('securityConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n @case ('otherConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n\n @case ('contactsForResource') {\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n }\n @case ('contacts') {\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n [modelSpecifier]=\"modelSpecifier\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n }\n @case ('onlineResources') {\n @if (modelSpecifier === 'onlineResourceType:!link') {\n <gn-ui-form-field-online-resources\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n } @else if (modelSpecifier === 'onlineResourceType:link') {\n <gn-ui-form-field-online-link-resources\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n } @else if (modelSpecifier === 'onlineResourceType:singleLink') {\n <gn-ui-form-field-online-single-link-resource\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-single-link-resource>\n }\n }\n @case ('flags') {\n <gn-ui-form-field-record-flag\n [flagName]=\"recordFlag\"\n [labelKey]=\"config.labelKey\"\n [hintKey]=\"config.hintKey\"\n ></gn-ui-form-field-record-flag>\n }\n }\n\n @if (!model) {\n @switch (componentName) {\n @case ('form-field-constraints-shortcuts') {\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n }\n @case ('form-field-spatial-toggle') {\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n }\n }\n }\n</ng-template>\n", styles: [":host{scroll-margin-top:90px}\n"] }]
|
|
39954
39621
|
}], propDecorators: { uniqueIdentifier: [{
|
|
39955
39622
|
type: Input
|
|
39956
39623
|
}], recordKind: [{
|
|
@@ -39981,9 +39648,13 @@ const TOKEN_OPERATOR_LOGICAL = ['==', '!='];
|
|
|
39981
39648
|
const TOKEN_STRING_LITERAL = ["'", '"'];
|
|
39982
39649
|
const TOKEN_GROUP_START = '(';
|
|
39983
39650
|
const TOKEN_GROUP_END = ')';
|
|
39651
|
+
const TOKEN_OPERATOR_BOOLEAN = ['&&', '||'];
|
|
39652
|
+
const TOKEN_OPERATOR_NOT = '!';
|
|
39984
39653
|
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence
|
|
39985
39654
|
const OPERATORS_BY_PRECEDENCE = [
|
|
39986
39655
|
[TOKEN_OPERATOR_TERNARY_FIRST, TOKEN_OPERATOR_TERNARY_SECOND],
|
|
39656
|
+
TOKEN_OPERATOR_BOOLEAN,
|
|
39657
|
+
[TOKEN_OPERATOR_NOT],
|
|
39987
39658
|
TOKEN_OPERATOR_LOGICAL,
|
|
39988
39659
|
];
|
|
39989
39660
|
const ALL_OPERATORS = OPERATORS_BY_PRECEDENCE.flat();
|
|
@@ -40093,6 +39764,16 @@ function evaluateInternal(expression, currentContext) {
|
|
|
40093
39764
|
pos++;
|
|
40094
39765
|
continue;
|
|
40095
39766
|
}
|
|
39767
|
+
// BOOLEAN LITERAL
|
|
39768
|
+
const isBooleanLiteral = readNext(expression, pos, 4) === 'true' ||
|
|
39769
|
+
readNext(expression, pos, 5) === 'false';
|
|
39770
|
+
if (isBooleanLiteral) {
|
|
39771
|
+
const literal = readNext(expression, pos, 4) === 'true' ? 'true' : 'false';
|
|
39772
|
+
pos += literal.length;
|
|
39773
|
+
const booleanLiteral = literal === 'true';
|
|
39774
|
+
currentEvaluator = () => booleanLiteral;
|
|
39775
|
+
continue;
|
|
39776
|
+
}
|
|
40096
39777
|
// SYMBOL (NAME)
|
|
40097
39778
|
const isSymbol = /[a-zA-Z]/.test(readNext(expression, pos));
|
|
40098
39779
|
if (isSymbol) {
|
|
@@ -40183,6 +39864,35 @@ function evaluateInternal(expression, currentContext) {
|
|
|
40183
39864
|
};
|
|
40184
39865
|
continue;
|
|
40185
39866
|
}
|
|
39867
|
+
// BOOLEAN OPERATORS
|
|
39868
|
+
const isBooleanOperator = TOKEN_OPERATOR_BOOLEAN.some((token) => readNext(expression, pos, token.length) === token);
|
|
39869
|
+
if (isBooleanOperator) {
|
|
39870
|
+
const matchingOperator = TOKEN_OPERATOR_BOOLEAN.find((token) => readNext(expression, pos, token.length) === token);
|
|
39871
|
+
const isAnd = matchingOperator === '&&';
|
|
39872
|
+
pos += matchingOperator.length;
|
|
39873
|
+
const leftEvaluator = currentEvaluator;
|
|
39874
|
+
const rightExpression = readUntilNextOperator(expression, pos, matchingOperator);
|
|
39875
|
+
pos += rightExpression.length;
|
|
39876
|
+
const rightEvaluator = evaluateInternal(rightExpression, currentContext).evaluator;
|
|
39877
|
+
currentEvaluator = (context) => {
|
|
39878
|
+
return isAnd
|
|
39879
|
+
? Boolean(leftEvaluator(context) && rightEvaluator(context))
|
|
39880
|
+
: Boolean(leftEvaluator(context) || rightEvaluator(context));
|
|
39881
|
+
};
|
|
39882
|
+
continue;
|
|
39883
|
+
}
|
|
39884
|
+
// PREFIX OPERATORS
|
|
39885
|
+
const isNotOperator = readNext(expression, pos) === TOKEN_OPERATOR_NOT;
|
|
39886
|
+
if (isNotOperator) {
|
|
39887
|
+
pos++;
|
|
39888
|
+
const operandExpression = readUntilNextOperator(expression, pos, TOKEN_OPERATOR_NOT);
|
|
39889
|
+
pos += operandExpression.length;
|
|
39890
|
+
const operandEvaluator = evaluateInternal(operandExpression, currentContext).evaluator;
|
|
39891
|
+
currentEvaluator = (context) => {
|
|
39892
|
+
return !operandEvaluator(context);
|
|
39893
|
+
};
|
|
39894
|
+
continue;
|
|
39895
|
+
}
|
|
40186
39896
|
// TERNARY OPERATOR
|
|
40187
39897
|
const isTernary = readNext(expression, pos) === TOKEN_OPERATOR_TERNARY_FIRST;
|
|
40188
39898
|
if (isTernary) {
|
|
@@ -40253,6 +39963,7 @@ class RecordFormComponent {
|
|
|
40253
39963
|
constructor() {
|
|
40254
39964
|
this.facade = inject(EditorFacade);
|
|
40255
39965
|
this.notifications = inject(NotificationsService);
|
|
39966
|
+
this.platform = inject(PlatformServiceInterface);
|
|
40256
39967
|
this.subscription = new Subscription();
|
|
40257
39968
|
this.recordUniqueIdentifier$ = this.facade.record$.pipe(map$2((record) => record.uniqueIdentifier));
|
|
40258
39969
|
this.recordKind$ = this.facade.record$.pipe(map$2((record) => record.kind));
|
|
@@ -40263,6 +39974,8 @@ class RecordFormComponent {
|
|
|
40263
39974
|
this.formFields = viewChildren(FormFieldComponent, ...(ngDevMode ? [{ debugName: "formFields" }] : []));
|
|
40264
39975
|
this.sectionFocusDirectives = viewChildren('sectionFocus', ...(ngDevMode ? [{ debugName: "sectionFocusDirectives" }] : []));
|
|
40265
39976
|
this.recordSignal = toSignal(this.facade.record$, { requireSync: true });
|
|
39977
|
+
this.userSignal = toSignal(this.platform.getMe());
|
|
39978
|
+
this.isAdminSignal = toSignal(this.platform.isAdministrator());
|
|
40266
39979
|
this.expressionCache = new Map();
|
|
40267
39980
|
}
|
|
40268
39981
|
focusField(model, sectionIndex) {
|
|
@@ -40287,7 +40000,7 @@ class RecordFormComponent {
|
|
|
40287
40000
|
this.subscription.unsubscribe();
|
|
40288
40001
|
}
|
|
40289
40002
|
handleFieldValueChange(model, newValue) {
|
|
40290
|
-
if (!model) {
|
|
40003
|
+
if (!model || model === 'flags') {
|
|
40291
40004
|
return;
|
|
40292
40005
|
}
|
|
40293
40006
|
this.facade.updateRecordField(model, newValue);
|
|
@@ -40330,7 +40043,15 @@ ${errors.map((err) => `> ${err}`).join('\n')}`);
|
|
|
40330
40043
|
text: 'An error happened while evaluating an expression inside the editor configuration; open the developer console for more information',
|
|
40331
40044
|
});
|
|
40332
40045
|
}
|
|
40333
|
-
this.expressionCache.set(expression, computed(() => evaluator({
|
|
40046
|
+
this.expressionCache.set(expression, computed(() => evaluator({
|
|
40047
|
+
globals: {
|
|
40048
|
+
record: this.recordSignal(),
|
|
40049
|
+
user: {
|
|
40050
|
+
...this.userSignal(),
|
|
40051
|
+
isAdmin: this.isAdminSignal(),
|
|
40052
|
+
},
|
|
40053
|
+
},
|
|
40054
|
+
})));
|
|
40334
40055
|
return this.expressionCache.get(expression);
|
|
40335
40056
|
}
|
|
40336
40057
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RecordFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
@@ -40937,6 +40658,638 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
40937
40658
|
args: ['gnUiSearchRouterContainer']
|
|
40938
40659
|
}] } });
|
|
40939
40660
|
|
|
40661
|
+
const flatten = (base, obj, keepLevel = false) => Object.keys(obj).reduce((prev, curr) => {
|
|
40662
|
+
const path = base ? `${base}.${curr}` : curr;
|
|
40663
|
+
const val = obj[curr];
|
|
40664
|
+
if (keepLevel) {
|
|
40665
|
+
return { ...prev, [path]: flatten('', val) };
|
|
40666
|
+
}
|
|
40667
|
+
else if (typeof val === 'object' && !Array.isArray(val)) {
|
|
40668
|
+
return {
|
|
40669
|
+
...prev,
|
|
40670
|
+
...flatten(path, val),
|
|
40671
|
+
};
|
|
40672
|
+
}
|
|
40673
|
+
else {
|
|
40674
|
+
return { ...prev, [path]: val };
|
|
40675
|
+
}
|
|
40676
|
+
}, {});
|
|
40677
|
+
const checkKeys = (input, mandatory, optional) => {
|
|
40678
|
+
const keys = Object.keys(input);
|
|
40679
|
+
const missing = mandatory.filter((key) => keys.indexOf(key) === -1);
|
|
40680
|
+
const unrecognized = keys.filter((key) => mandatory.indexOf(key) === -1 && optional.indexOf(key) === -1);
|
|
40681
|
+
return {
|
|
40682
|
+
missing,
|
|
40683
|
+
unrecognized,
|
|
40684
|
+
};
|
|
40685
|
+
};
|
|
40686
|
+
/**
|
|
40687
|
+
* Only keeps recognized keys, flatten nested values (to allow having "." in keys),
|
|
40688
|
+
* pushes warnings and errors to the given arrays; returns null in case of error
|
|
40689
|
+
*/
|
|
40690
|
+
function parseConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
40691
|
+
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
40692
|
+
if (mandatoryKeys.length === 0)
|
|
40693
|
+
return null;
|
|
40694
|
+
outErrors.push(`The [${sectionName}] mandatory section is missing.`);
|
|
40695
|
+
return null;
|
|
40696
|
+
}
|
|
40697
|
+
const sectionConf = fullConfigObj[sectionName];
|
|
40698
|
+
const keysCheck = checkKeys(sectionConf, mandatoryKeys, optionalKeys);
|
|
40699
|
+
if (keysCheck.missing.length) {
|
|
40700
|
+
// note: this is not thrown to allow merging several Errors down the line
|
|
40701
|
+
outErrors.push(`In the [${sectionName}] section: ${keysCheck.missing.join(', ')}`);
|
|
40702
|
+
return null;
|
|
40703
|
+
}
|
|
40704
|
+
else if (keysCheck.unrecognized.length) {
|
|
40705
|
+
outWarnings.push(`In the [${sectionName}] section: ${keysCheck.unrecognized.join(', ')}`);
|
|
40706
|
+
keysCheck.unrecognized.forEach((key) => delete sectionConf[key]);
|
|
40707
|
+
}
|
|
40708
|
+
return sectionConf;
|
|
40709
|
+
}
|
|
40710
|
+
/**
|
|
40711
|
+
* Same as parseConfigSection but keeps all keys, recognized or not
|
|
40712
|
+
* Also the first level is the language code (e.g. 'en')
|
|
40713
|
+
* This is optional
|
|
40714
|
+
*/
|
|
40715
|
+
function parseTranslationsConfigSection(fullConfigObj, sectionName) {
|
|
40716
|
+
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
40717
|
+
return {};
|
|
40718
|
+
}
|
|
40719
|
+
return flatten('', fullConfigObj[sectionName], true);
|
|
40720
|
+
}
|
|
40721
|
+
/**
|
|
40722
|
+
* Same as parseConfigSection but handles an array of configs; this is
|
|
40723
|
+
* considered optional; returns null in case of error in at least one of
|
|
40724
|
+
* the sections
|
|
40725
|
+
*/
|
|
40726
|
+
function parseMultiConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
40727
|
+
const sections = fullConfigObj[sectionName];
|
|
40728
|
+
if (!sections) {
|
|
40729
|
+
return [];
|
|
40730
|
+
}
|
|
40731
|
+
if (!Array.isArray(sections)) {
|
|
40732
|
+
outErrors.push(`Expected [[${sectionName}]] to be an array of sections.`);
|
|
40733
|
+
return null;
|
|
40734
|
+
}
|
|
40735
|
+
const result = sections.map((section) => parseConfigSection({ [sectionName]: section }, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors));
|
|
40736
|
+
if (result.some((r) => r === null)) {
|
|
40737
|
+
return null;
|
|
40738
|
+
}
|
|
40739
|
+
return result;
|
|
40740
|
+
}
|
|
40741
|
+
function checkMetadataLanguage(parsedConfigSection, outWarnings) {
|
|
40742
|
+
const lang2 = toLang2(parsedConfigSection.metadata_language.toLowerCase());
|
|
40743
|
+
if (lang2?.length !== 2) {
|
|
40744
|
+
outWarnings.push(`In the [global] section: metadata_language = "${parsedConfigSection.metadata_language}" is not a recognized ISO 639 language code`);
|
|
40745
|
+
}
|
|
40746
|
+
return parsedConfigSection;
|
|
40747
|
+
}
|
|
40748
|
+
function checkNewRecordDefaultLanguage(parsedConfigSection, outWarnings) {
|
|
40749
|
+
const lang2 = toLang2(parsedConfigSection.new_record_default_language.toLowerCase());
|
|
40750
|
+
if (!(lang2 in LANG_2_TO_3_MAPPER)) {
|
|
40751
|
+
outWarnings.push(`In the [editing] section: new_record_default_language = "${parsedConfigSection.new_record_default_language}" is not a recognized ISO 639 language code`);
|
|
40752
|
+
return {
|
|
40753
|
+
...parsedConfigSection,
|
|
40754
|
+
new_record_default_language: undefined,
|
|
40755
|
+
};
|
|
40756
|
+
}
|
|
40757
|
+
return {
|
|
40758
|
+
...parsedConfigSection,
|
|
40759
|
+
new_record_default_language: lang2,
|
|
40760
|
+
};
|
|
40761
|
+
}
|
|
40762
|
+
function checkNewRecordStandard(parsedConfigSection, outWarnings) {
|
|
40763
|
+
const standard = parsedConfigSection.new_record_standard;
|
|
40764
|
+
const normalizedStandard = typeof standard === 'string' ? standard.trim().toLowerCase() : null;
|
|
40765
|
+
if (normalizedStandard === 'iso19139' ||
|
|
40766
|
+
normalizedStandard === 'iso19115-3') {
|
|
40767
|
+
return {
|
|
40768
|
+
...parsedConfigSection,
|
|
40769
|
+
new_record_standard: normalizedStandard,
|
|
40770
|
+
};
|
|
40771
|
+
}
|
|
40772
|
+
outWarnings.push(`In the [editing] section: new_record_standard = "${standard}" is not a supported metadata standard`);
|
|
40773
|
+
return {
|
|
40774
|
+
...parsedConfigSection,
|
|
40775
|
+
new_record_standard: undefined,
|
|
40776
|
+
};
|
|
40777
|
+
}
|
|
40778
|
+
|
|
40779
|
+
/**
|
|
40780
|
+
* This loader extends the default one based on JSON files but also loads custom translations
|
|
40781
|
+
* defined in the app configuration
|
|
40782
|
+
* Implements a fallback on default lang if translated labels are empty
|
|
40783
|
+
*/
|
|
40784
|
+
class FileWithOverridesTranslateLoader extends FileTranslateLoader {
|
|
40785
|
+
getTranslation(lang) {
|
|
40786
|
+
const baseLang = lang.substring(0, 2); // removing the right part of e.g. en_EN
|
|
40787
|
+
return super.getTranslation(baseLang).pipe(map$1((translations) => ({
|
|
40788
|
+
...translations,
|
|
40789
|
+
...getCustomTranslations(baseLang),
|
|
40790
|
+
})));
|
|
40791
|
+
}
|
|
40792
|
+
}
|
|
40793
|
+
|
|
40794
|
+
const MISSING_CONFIG_ERROR = `Application configuration was not initialized correctly.
|
|
40795
|
+
This error might show up in case of an invalid/malformed configuration file.
|
|
40796
|
+
|
|
40797
|
+
Note: make sure that you have called \`loadAppConfig\` from '../../../../../libs/util/app-config/src' before starting the Angular application.`;
|
|
40798
|
+
let globalConfig = null;
|
|
40799
|
+
function getGlobalConfig() {
|
|
40800
|
+
if (globalConfig === null)
|
|
40801
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40802
|
+
return globalConfig;
|
|
40803
|
+
}
|
|
40804
|
+
let themeConfig = null;
|
|
40805
|
+
function getThemeConfig() {
|
|
40806
|
+
if (themeConfig === null)
|
|
40807
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40808
|
+
return themeConfig;
|
|
40809
|
+
}
|
|
40810
|
+
let mapConfig = null;
|
|
40811
|
+
function getOptionalMapConfig() {
|
|
40812
|
+
return mapConfig;
|
|
40813
|
+
}
|
|
40814
|
+
let searchConfig = null;
|
|
40815
|
+
function getOptionalSearchConfig() {
|
|
40816
|
+
return searchConfig;
|
|
40817
|
+
}
|
|
40818
|
+
let editorConfig = null;
|
|
40819
|
+
function getOptionalEditorConfig() {
|
|
40820
|
+
return editorConfig;
|
|
40821
|
+
}
|
|
40822
|
+
let metadataQualityConfig = null;
|
|
40823
|
+
function getMetadataQualityConfig() {
|
|
40824
|
+
return (metadataQualityConfig ||
|
|
40825
|
+
{
|
|
40826
|
+
ENABLED: false,
|
|
40827
|
+
});
|
|
40828
|
+
}
|
|
40829
|
+
let customTranslations = null;
|
|
40830
|
+
function getCustomTranslations(langCode) {
|
|
40831
|
+
if (customTranslations === null)
|
|
40832
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40833
|
+
return langCode in customTranslations ? customTranslations[langCode] : {};
|
|
40834
|
+
}
|
|
40835
|
+
let appConfigLoaded = false;
|
|
40836
|
+
function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
|
|
40837
|
+
console.log(`[geonetwork-ui] Loading application configuration from ${configUrl}`);
|
|
40838
|
+
return fetch(configUrl)
|
|
40839
|
+
.then((resp) => {
|
|
40840
|
+
if (!resp.ok)
|
|
40841
|
+
throw new Error('Configuration file could not be loaded');
|
|
40842
|
+
return resp.text();
|
|
40843
|
+
})
|
|
40844
|
+
.then((conf) => {
|
|
40845
|
+
let parsed;
|
|
40846
|
+
try {
|
|
40847
|
+
parsed = TOML.parse(conf, { joiner: '\n', bigint: false });
|
|
40848
|
+
}
|
|
40849
|
+
catch (e) {
|
|
40850
|
+
throw new Error(`An error occurred when parsing the configuration file: ${e.message}`);
|
|
40851
|
+
}
|
|
40852
|
+
const errors = [];
|
|
40853
|
+
const warnings = [];
|
|
40854
|
+
let parsedGlobalSection = parseConfigSection(parsed, 'global', ['geonetwork4_api_url'], [
|
|
40855
|
+
'datahub_url',
|
|
40856
|
+
'edit_url_template',
|
|
40857
|
+
'proxy_path',
|
|
40858
|
+
'metadata_language',
|
|
40859
|
+
'login_url',
|
|
40860
|
+
'logout_url',
|
|
40861
|
+
'settings_url',
|
|
40862
|
+
'web_component_embedder_url',
|
|
40863
|
+
'languages',
|
|
40864
|
+
'contact_email',
|
|
40865
|
+
'reuse_form_url',
|
|
40866
|
+
], warnings, errors);
|
|
40867
|
+
if (parsedGlobalSection?.metadata_language) {
|
|
40868
|
+
parsedGlobalSection = checkMetadataLanguage(parsedGlobalSection, warnings);
|
|
40869
|
+
}
|
|
40870
|
+
globalConfig =
|
|
40871
|
+
parsedGlobalSection === null
|
|
40872
|
+
? null
|
|
40873
|
+
: {
|
|
40874
|
+
GN4_API_URL: parsedGlobalSection.geonetwork4_api_url,
|
|
40875
|
+
DATAHUB_URL: parsedGlobalSection.datahub_url,
|
|
40876
|
+
EDIT_URL_TEMPLATE: parsedGlobalSection.edit_url_template,
|
|
40877
|
+
PROXY_PATH: parsedGlobalSection.proxy_path,
|
|
40878
|
+
METADATA_LANGUAGE: parsedGlobalSection.metadata_language
|
|
40879
|
+
? parsedGlobalSection.metadata_language.toLowerCase()
|
|
40880
|
+
: undefined,
|
|
40881
|
+
LOGIN_URL: parsedGlobalSection.login_url,
|
|
40882
|
+
LOGOUT_URL: parsedGlobalSection.logout_url,
|
|
40883
|
+
SETTINGS_URL: parsedGlobalSection.settings_url,
|
|
40884
|
+
WEB_COMPONENT_EMBEDDER_URL: parsedGlobalSection.web_component_embedder_url,
|
|
40885
|
+
LANGUAGES: parsedGlobalSection.languages,
|
|
40886
|
+
CONTACT_EMAIL: parsedGlobalSection.contact_email,
|
|
40887
|
+
REUSE_FORM_URL: parsedGlobalSection.reuse_form_url,
|
|
40888
|
+
};
|
|
40889
|
+
const parsedLayersSections = parseMultiConfigSection(parsed, 'map_layer', ['type'], ['name', 'url', 'data', 'styleUrl', 'accessToken'], warnings, errors);
|
|
40890
|
+
const parsedMapSection = parseConfigSection(parsed, 'map', [], [
|
|
40891
|
+
'max_zoom',
|
|
40892
|
+
'do_not_tile_wms',
|
|
40893
|
+
'max_extent',
|
|
40894
|
+
'max_feature_count',
|
|
40895
|
+
'baselayer',
|
|
40896
|
+
'do_not_use_default_basemap',
|
|
40897
|
+
'external_viewer_url_template',
|
|
40898
|
+
'external_viewer_open_new_tab',
|
|
40899
|
+
], warnings, errors);
|
|
40900
|
+
mapConfig =
|
|
40901
|
+
parsedMapSection === null || parsedLayersSections === null
|
|
40902
|
+
? null
|
|
40903
|
+
: {
|
|
40904
|
+
MAX_ZOOM: parsedMapSection.max_zoom,
|
|
40905
|
+
DO_NOT_TILE_WMS: parsedMapSection.do_not_tile_wms,
|
|
40906
|
+
MAX_EXTENT: parsedMapSection.max_extent,
|
|
40907
|
+
MAX_FEATURE_COUNT: parsedMapSection.max_feature_count,
|
|
40908
|
+
EXTERNAL_VIEWER_URL_TEMPLATE: parsedMapSection.external_viewer_url_template,
|
|
40909
|
+
EXTERNAL_VIEWER_OPEN_NEW_TAB: parsedMapSection.external_viewer_open_new_tab,
|
|
40910
|
+
DO_NOT_USE_DEFAULT_BASEMAP: !!parsedMapSection.do_not_use_default_basemap,
|
|
40911
|
+
MAP_LAYERS: parsedLayersSections.map((map_layer) => ({
|
|
40912
|
+
TYPE: map_layer.type,
|
|
40913
|
+
URL: map_layer.url,
|
|
40914
|
+
NAME: map_layer.name,
|
|
40915
|
+
DATA: map_layer.data,
|
|
40916
|
+
STYLE_URL: map_layer.styleUrl,
|
|
40917
|
+
ACCESS_TOKEN: map_layer.accessToken,
|
|
40918
|
+
})),
|
|
40919
|
+
};
|
|
40920
|
+
const parsedThemeSection = parseConfigSection(parsed, 'theme', ['primary_color', 'secondary_color', 'main_color', 'background_color'], [
|
|
40921
|
+
'header_foreground_color',
|
|
40922
|
+
'main_font',
|
|
40923
|
+
'title_font',
|
|
40924
|
+
'fonts_stylesheet_url',
|
|
40925
|
+
'thumbnail_placeholder',
|
|
40926
|
+
'header_background',
|
|
40927
|
+
'favicon',
|
|
40928
|
+
], warnings, errors);
|
|
40929
|
+
themeConfig =
|
|
40930
|
+
parsedThemeSection === null
|
|
40931
|
+
? null
|
|
40932
|
+
: {
|
|
40933
|
+
PRIMARY_COLOR: parsedThemeSection.primary_color,
|
|
40934
|
+
SECONDARY_COLOR: parsedThemeSection.secondary_color,
|
|
40935
|
+
MAIN_COLOR: parsedThemeSection.main_color,
|
|
40936
|
+
BACKGROUND_COLOR: parsedThemeSection.background_color,
|
|
40937
|
+
HEADER_FOREGROUND_COLOR: parsedThemeSection.header_foreground_color,
|
|
40938
|
+
THUMBNAIL_PLACEHOLDER: parsedThemeSection.thumbnail_placeholder,
|
|
40939
|
+
HEADER_BACKGROUND: parsedThemeSection.header_background,
|
|
40940
|
+
TITLE_FONT: parsedThemeSection.title_font,
|
|
40941
|
+
MAIN_FONT: parsedThemeSection.main_font,
|
|
40942
|
+
FONTS_STYLESHEET_URL: parsedThemeSection.fonts_stylesheet_url,
|
|
40943
|
+
FAVICON: parsedThemeSection.favicon,
|
|
40944
|
+
};
|
|
40945
|
+
const parsedSearchSection = parseConfigSection(parsed, 'search', [], [
|
|
40946
|
+
'record_kind_quick_filter',
|
|
40947
|
+
'filter_geometry_data',
|
|
40948
|
+
'filter_geometry_url',
|
|
40949
|
+
'do_not_use_default_search_preset',
|
|
40950
|
+
'search_preset',
|
|
40951
|
+
'advanced_filters',
|
|
40952
|
+
'limit',
|
|
40953
|
+
'spatial_extent_max_file_size',
|
|
40954
|
+
'geocoding_provider',
|
|
40955
|
+
'geocoding_provider_options',
|
|
40956
|
+
'geocoding_provider_labels',
|
|
40957
|
+
], warnings, errors);
|
|
40958
|
+
const parsedSearchParams = parseMultiConfigSection(parsed, 'search_preset', ['name'], ['sort', 'filters'], warnings, errors);
|
|
40959
|
+
const parsedCustomFilters = parseMultiConfigSection(parsed, 'custom_filter', ['name', 'base_filter'], ['exclude_values', 'include_values', 'label_key'], warnings, errors);
|
|
40960
|
+
const parsedGeocodingProviderLabels = parsedSearchSection?.geocoding_provider_labels;
|
|
40961
|
+
searchConfig =
|
|
40962
|
+
parsedSearchSection === null
|
|
40963
|
+
? null
|
|
40964
|
+
: {
|
|
40965
|
+
RECORD_KIND_QUICK_FILTER: parsedSearchSection.record_kind_quick_filter,
|
|
40966
|
+
FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
|
|
40967
|
+
FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
|
|
40968
|
+
DO_NOT_USE_DEFAULT_SEARCH_PRESET: !!parsedSearchSection.do_not_use_default_search_preset,
|
|
40969
|
+
SEARCH_PRESET: parsedSearchParams.map((param) => ({
|
|
40970
|
+
sort: param.sort,
|
|
40971
|
+
name: param.name,
|
|
40972
|
+
filters: param.filters,
|
|
40973
|
+
})),
|
|
40974
|
+
ADVANCED_FILTERS: parsedSearchSection.advanced_filters,
|
|
40975
|
+
CUSTOM_FILTERS: (parsedCustomFilters ?? []).map((customFilter) => ({
|
|
40976
|
+
name: customFilter.name,
|
|
40977
|
+
baseFilter: customFilter.base_filter,
|
|
40978
|
+
excludeValues: customFilter.exclude_values,
|
|
40979
|
+
includeValues: customFilter.include_values,
|
|
40980
|
+
labelKey: customFilter.label_key,
|
|
40981
|
+
})),
|
|
40982
|
+
LIMIT: parsedSearchSection.limit,
|
|
40983
|
+
SPATIAL_EXTENT_MAX_FILE_SIZE: parsedSearchSection.spatial_extent_max_file_size,
|
|
40984
|
+
GEOCODING_PROVIDER: parsedSearchSection.geocoding_provider,
|
|
40985
|
+
GEOCODING_PROVIDER_OPTIONS: parsedSearchSection.geocoding_provider_options,
|
|
40986
|
+
GEOCODING_PROVIDER_LABELS: parsedGeocodingProviderLabels
|
|
40987
|
+
? {
|
|
40988
|
+
MAIN: parsedGeocodingProviderLabels.main,
|
|
40989
|
+
SECONDARY: parsedGeocodingProviderLabels.secondary,
|
|
40990
|
+
TERTIARY: parsedGeocodingProviderLabels.tertiary,
|
|
40991
|
+
}
|
|
40992
|
+
: undefined,
|
|
40993
|
+
};
|
|
40994
|
+
const parsedMetadataQualitySection = parseConfigSection(parsed, 'metadata-quality', [], ['enabled'], warnings, errors);
|
|
40995
|
+
metadataQualityConfig =
|
|
40996
|
+
parsedMetadataQualitySection === null
|
|
40997
|
+
? null
|
|
40998
|
+
: {
|
|
40999
|
+
ENABLED: parsedMetadataQualitySection.enabled,
|
|
41000
|
+
SORTABLE: parsedMetadataQualitySection.sortable,
|
|
41001
|
+
};
|
|
41002
|
+
let parsedEditingSection = parseConfigSection(parsed, 'editing', [], ['new_record_default_language', 'new_record_standard'], warnings, errors);
|
|
41003
|
+
if (parsedEditingSection !== null &&
|
|
41004
|
+
parsedEditingSection.new_record_default_language !== undefined) {
|
|
41005
|
+
parsedEditingSection = checkNewRecordDefaultLanguage(parsedEditingSection, warnings);
|
|
41006
|
+
}
|
|
41007
|
+
if (parsedEditingSection !== null &&
|
|
41008
|
+
parsedEditingSection.new_record_standard !== undefined) {
|
|
41009
|
+
parsedEditingSection = checkNewRecordStandard(parsedEditingSection, warnings);
|
|
41010
|
+
}
|
|
41011
|
+
editorConfig =
|
|
41012
|
+
parsedEditingSection === null
|
|
41013
|
+
? null
|
|
41014
|
+
: {
|
|
41015
|
+
NEW_RECORD_DEFAULT_LANGUAGE: parsedEditingSection.new_record_default_language,
|
|
41016
|
+
NEW_RECORD_STANDARD: parsedEditingSection.new_record_standard,
|
|
41017
|
+
};
|
|
41018
|
+
customTranslations = parseTranslationsConfigSection(parsed, 'translations');
|
|
41019
|
+
if (errors.length) {
|
|
41020
|
+
throw new Error(`One or more mandatory settings were missing from the configuration file.
|
|
41021
|
+
${errors.join('\n')}`);
|
|
41022
|
+
}
|
|
41023
|
+
else if (warnings.length) {
|
|
41024
|
+
console.warn(`One or more unexpected settings were encountered in the configuration file.
|
|
41025
|
+
${warnings.join('\n')}`);
|
|
41026
|
+
}
|
|
41027
|
+
appConfigLoaded = true;
|
|
41028
|
+
});
|
|
41029
|
+
}
|
|
41030
|
+
function isConfigLoaded() {
|
|
41031
|
+
return appConfigLoaded;
|
|
41032
|
+
}
|
|
41033
|
+
function _reset() {
|
|
41034
|
+
globalConfig = null;
|
|
41035
|
+
themeConfig = null;
|
|
41036
|
+
editorConfig = null;
|
|
41037
|
+
customTranslations = null;
|
|
41038
|
+
}
|
|
41039
|
+
const TRANSLATE_WITH_OVERRIDES_CONFIG = {
|
|
41040
|
+
compiler: {
|
|
41041
|
+
provide: TranslateCompiler,
|
|
41042
|
+
useClass: TranslateMessageFormatCompiler,
|
|
41043
|
+
},
|
|
41044
|
+
loader: [
|
|
41045
|
+
{
|
|
41046
|
+
provide: TRANSLATE_HTTP_LOADER_CONFIG,
|
|
41047
|
+
useValue: {
|
|
41048
|
+
prefix: './assets/i18n/',
|
|
41049
|
+
suffix: '.json',
|
|
41050
|
+
},
|
|
41051
|
+
},
|
|
41052
|
+
{
|
|
41053
|
+
provide: TranslateLoader,
|
|
41054
|
+
useClass: FileWithOverridesTranslateLoader,
|
|
41055
|
+
deps: [HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
|
|
41056
|
+
},
|
|
41057
|
+
],
|
|
41058
|
+
};
|
|
41059
|
+
|
|
41060
|
+
const okAppConfigFixture = () => `
|
|
41061
|
+
[global]
|
|
41062
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
41063
|
+
proxy_path = "/proxy/?url="
|
|
41064
|
+
metadata_language = "fre"
|
|
41065
|
+
login_url = "/cas/login?service="
|
|
41066
|
+
logout_url = "/geonetwork/signout"
|
|
41067
|
+
settings_url = "/geonetwork/settings"
|
|
41068
|
+
web_component_embedder_url = "/datahub/wc-embedder.html"
|
|
41069
|
+
|
|
41070
|
+
[map]
|
|
41071
|
+
max_zoom = 10
|
|
41072
|
+
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
41073
|
+
do_not_use_default_basemap = false
|
|
41074
|
+
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
41075
|
+
external_viewer_open_new_tab = true
|
|
41076
|
+
[[map_layer]]
|
|
41077
|
+
type = "wms"
|
|
41078
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
41079
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
41080
|
+
[[map_layer]]
|
|
41081
|
+
type = "wfs"
|
|
41082
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
41083
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
41084
|
+
|
|
41085
|
+
[theme]
|
|
41086
|
+
primary_color = "#093564"
|
|
41087
|
+
secondary_color = "#c2e9dc"
|
|
41088
|
+
main_color = "#212029" # All-purpose text color
|
|
41089
|
+
background_color = "#fdfbff"
|
|
41090
|
+
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
41091
|
+
header_background = 'teal'
|
|
41092
|
+
header_foreground_color = "#872e2e"
|
|
41093
|
+
main_font = 'sans-serif'
|
|
41094
|
+
title_font = 'serif'
|
|
41095
|
+
fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
|
|
41096
|
+
|
|
41097
|
+
[search]
|
|
41098
|
+
record_kind_quick_filter = false
|
|
41099
|
+
filter_geometry_url = 'https://my.domain.org/geom.json'
|
|
41100
|
+
do_not_use_default_search_preset = false
|
|
41101
|
+
geocoding_provider = "geoplateforme"
|
|
41102
|
+
geocoding_provider_options.index = "poi"
|
|
41103
|
+
geocoding_provider_options.category = "administratif"
|
|
41104
|
+
geocoding_provider_options.limit = 5
|
|
41105
|
+
geocoding_provider_labels.main = '/properties/name/0'
|
|
41106
|
+
geocoding_provider_labels.secondary = '/properties/citycode/0'
|
|
41107
|
+
geocoding_provider_labels.tertiary = '/properties/category/1'
|
|
41108
|
+
advanced_filters = ['publicationYear', 'documentStandard', 'inspireKeyword', 'topic', 'license', 'myOrg:firstCustomFilter', 'myOrg:secondCustomFilter']
|
|
41109
|
+
|
|
41110
|
+
[[custom_filter]]
|
|
41111
|
+
name = 'myOrg:firstCustomFilter'
|
|
41112
|
+
base_filter = 'keyword'
|
|
41113
|
+
exclude_values = ['my keyword 1', 'my keyword 2']
|
|
41114
|
+
label_key = 'myOrg.firstCustomFilter'
|
|
41115
|
+
|
|
41116
|
+
[[custom_filter]]
|
|
41117
|
+
name = 'myOrg:secondCustomFilter'
|
|
41118
|
+
base_filter = 'keyword'
|
|
41119
|
+
include_values = ['my keyword 3', 'my keyword 4']
|
|
41120
|
+
label_key = 'myOrg.secondCustomFilter'
|
|
41121
|
+
|
|
41122
|
+
[[search_preset]]
|
|
41123
|
+
sort = "-createDate"
|
|
41124
|
+
name = 'filterByOrgs'
|
|
41125
|
+
filters.q = 'Carto'
|
|
41126
|
+
filters.organisation = ['Org1', 'Org2']
|
|
41127
|
+
filters.format = ['ESRI Shapefile']
|
|
41128
|
+
filters.topic = ['boundaries']
|
|
41129
|
+
filters.publicationYear = ['2023', '2022']
|
|
41130
|
+
filters.spatial = ['yes']
|
|
41131
|
+
|
|
41132
|
+
[translations.en]
|
|
41133
|
+
"my.first.key" = 'First label.'
|
|
41134
|
+
"my.second.key" = """
|
|
41135
|
+
Second label,
|
|
41136
|
+
on two lines."""
|
|
41137
|
+
|
|
41138
|
+
[translations.de]
|
|
41139
|
+
my.first.key = 'Erste Etikett.'
|
|
41140
|
+
|
|
41141
|
+
[translations.fr]
|
|
41142
|
+
my.sample.text = "Un bon exemple de texte."
|
|
41143
|
+
"my.quoted.text" = 'du texte entre guillements.'
|
|
41144
|
+
`;
|
|
41145
|
+
const appConfigWithTranslationFixture = () => okAppConfigFixture();
|
|
41146
|
+
const minimalAppConfigFixture = () => `
|
|
41147
|
+
[global]
|
|
41148
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
41149
|
+
proxy_path = "/proxy/?url="
|
|
41150
|
+
|
|
41151
|
+
[theme]
|
|
41152
|
+
primary_color = "#093564"
|
|
41153
|
+
secondary_color = "#c2e9dc"
|
|
41154
|
+
main_color = "#212029" # All-purpose text color
|
|
41155
|
+
background_color = "#fdfbff"
|
|
41156
|
+
`;
|
|
41157
|
+
const customFilterMissingMandatoryConfigFixture = () => `
|
|
41158
|
+
[global]
|
|
41159
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
41160
|
+
|
|
41161
|
+
[theme]
|
|
41162
|
+
primary_color = "#093564"
|
|
41163
|
+
secondary_color = "#c2e9dc"
|
|
41164
|
+
main_color = "#212029" # All-purpose text color
|
|
41165
|
+
background_color = "#fdfbff"
|
|
41166
|
+
|
|
41167
|
+
[search]
|
|
41168
|
+
advanced_filters = ['myOrg:firstCustomFilter']
|
|
41169
|
+
|
|
41170
|
+
[[custom_filter]]
|
|
41171
|
+
name = 'myOrg:firstCustomFilter'
|
|
41172
|
+
`;
|
|
41173
|
+
const mapConfigFixture = () => ({
|
|
41174
|
+
MAX_ZOOM: 10,
|
|
41175
|
+
MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
|
|
41176
|
+
DO_NOT_USE_DEFAULT_BASEMAP: false,
|
|
41177
|
+
DO_NOT_TILE_WMS: false,
|
|
41178
|
+
EXTERNAL_VIEWER_URL_TEMPLATE: 'https://example.com/myviewer/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["${layer_name}"],"sources":[{"url":"${service_url}","type":"${service_type}"}]}]',
|
|
41179
|
+
EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
|
|
41180
|
+
MAP_LAYERS: [
|
|
41181
|
+
{
|
|
41182
|
+
TYPE: 'xyz',
|
|
41183
|
+
URL: 'https://some-basemap-server',
|
|
41184
|
+
},
|
|
41185
|
+
{
|
|
41186
|
+
TYPE: 'wms',
|
|
41187
|
+
URL: 'https://some-wms-server',
|
|
41188
|
+
NAME: 'some_layername',
|
|
41189
|
+
},
|
|
41190
|
+
{
|
|
41191
|
+
TYPE: 'wfs',
|
|
41192
|
+
URL: 'https://some-wfs-server',
|
|
41193
|
+
NAME: 'some_layername',
|
|
41194
|
+
},
|
|
41195
|
+
],
|
|
41196
|
+
});
|
|
41197
|
+
const malformedConfigFixture = () => `
|
|
41198
|
+
{
|
|
41199
|
+
"I thought": "we were still doing json"
|
|
41200
|
+
}
|
|
41201
|
+
`;
|
|
41202
|
+
const missingMandatoryConfigFixture = () => `
|
|
41203
|
+
[theme]
|
|
41204
|
+
primary_color = "#093564"
|
|
41205
|
+
secondary_color = "#c2e9dc"
|
|
41206
|
+
background_color = "#fdfbff"
|
|
41207
|
+
main_font = 'sans-serif'
|
|
41208
|
+
`;
|
|
41209
|
+
const wrongLanguageCodeConfigFixture = () => `
|
|
41210
|
+
[global]
|
|
41211
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
41212
|
+
proxy_path = "/proxy/?url="
|
|
41213
|
+
metadata_language = "abc"
|
|
41214
|
+
|
|
41215
|
+
[map]
|
|
41216
|
+
|
|
41217
|
+
[theme]
|
|
41218
|
+
primary_color = "#093564"
|
|
41219
|
+
secondary_color = "#c2e9dc"
|
|
41220
|
+
main_color = "#212029" # All-purpose text color
|
|
41221
|
+
background_color = "#fdfbff"
|
|
41222
|
+
`;
|
|
41223
|
+
const unrecognizedKeysConfigFixture = () => `
|
|
41224
|
+
[global]
|
|
41225
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
41226
|
+
proxy_path = "/proxy/?url="
|
|
41227
|
+
metadata_language = "fre"
|
|
41228
|
+
another_path = '/whatever'
|
|
41229
|
+
|
|
41230
|
+
[map]
|
|
41231
|
+
max_zoom = 10
|
|
41232
|
+
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
41233
|
+
do_not_use_default_basemap = false
|
|
41234
|
+
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
41235
|
+
external_viewer_open_new_tab = true
|
|
41236
|
+
another_zoom = 15
|
|
41237
|
+
[[map_layer]]
|
|
41238
|
+
type = "wms"
|
|
41239
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
41240
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
41241
|
+
[[map_layer]]
|
|
41242
|
+
type = "wfs"
|
|
41243
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
41244
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
41245
|
+
another_layer = "wrong layer definition"
|
|
41246
|
+
|
|
41247
|
+
[theme]
|
|
41248
|
+
primary_color = "#093564"
|
|
41249
|
+
secondary_color = "#c2e9dc"
|
|
41250
|
+
main_color = "#212029" # All-purpose text color
|
|
41251
|
+
background_color = "#fdfbff"
|
|
41252
|
+
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
41253
|
+
header_background = 'teal'
|
|
41254
|
+
header_foreground_color = "#872e2e"
|
|
41255
|
+
main_font = 'sans-serif'
|
|
41256
|
+
title_font = 'serif'
|
|
41257
|
+
another_color = 'red'
|
|
41258
|
+
`;
|
|
41259
|
+
|
|
41260
|
+
function getMapContextLayerFromConfig(config) {
|
|
41261
|
+
switch (config.TYPE) {
|
|
41262
|
+
case 'wms':
|
|
41263
|
+
return {
|
|
41264
|
+
type: 'wms',
|
|
41265
|
+
url: config.URL,
|
|
41266
|
+
name: config.NAME,
|
|
41267
|
+
};
|
|
41268
|
+
case 'wfs':
|
|
41269
|
+
return {
|
|
41270
|
+
type: 'wfs',
|
|
41271
|
+
url: config.URL,
|
|
41272
|
+
featureType: config.NAME,
|
|
41273
|
+
};
|
|
41274
|
+
case 'xyz':
|
|
41275
|
+
return {
|
|
41276
|
+
type: config.TYPE,
|
|
41277
|
+
url: config.URL,
|
|
41278
|
+
};
|
|
41279
|
+
case 'geojson':
|
|
41280
|
+
return {
|
|
41281
|
+
type: config.TYPE,
|
|
41282
|
+
...(config.DATA ? { data: config.DATA } : { url: config.URL }),
|
|
41283
|
+
};
|
|
41284
|
+
case 'maplibre-style':
|
|
41285
|
+
return {
|
|
41286
|
+
type: config.TYPE,
|
|
41287
|
+
styleUrl: config.STYLE_URL,
|
|
41288
|
+
accessToken: config.ACCESS_TOKEN,
|
|
41289
|
+
};
|
|
41290
|
+
}
|
|
41291
|
+
}
|
|
41292
|
+
|
|
40940
41293
|
const CHART_TYPE_VALUES = [
|
|
40941
41294
|
'bar',
|
|
40942
41295
|
'bar-horizontal',
|
|
@@ -40952,5 +41305,5 @@ const CHART_TYPE_VALUES = [
|
|
|
40952
41305
|
* Generated bundle index. Do not edit.
|
|
40953
41306
|
*/
|
|
40954
41307
|
|
|
40955
|
-
export { ADD_RESULTS, ADD_SEARCH, AVAILABLE_LICENSES, AbstractAction, AbstractSearchField, ActionMenuComponent, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, ApplicationBannerComponent, AuthService, AutocompleteComponent, AutofocusDirective, AvailableServicesField, AvatarComponent, AvatarServiceInterface, BASEMAP_LAYERS, BadgeComponent, BaseConverter, BaseFileReader, BaseReader, BlockListComponent, BoundingBoxSearchField, ButtonComponent, CHART_TYPE_VALUES, CLEAR_ERROR, CLEAR_RESULTS, CarouselComponent, CatalogTitleComponent, CellPopinComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ClearError, ClearResults, ColorScaleComponent, ConfirmationDialogComponent, ContactDetailsComponent, ContactDetailsFormComponent, ContactPillComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASEMAP_LAYER, DEFAULT_CONFIGURATION, DEFAULT_GN4_LOGIN_URL, DEFAULT_GN4_LOGOUT_URL, DEFAULT_GN4_SETTINGS_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RECORD_CONVERTER, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_SPATIAL_EXTENT_STYLE, DISABLE_AUTH, DISABLE_DRAFT, DO_NOT_USE_DEFAULT_BASEMAP, DataService, DataTableComponent, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DatePickerComponent, DateRangeDropdownComponent, DateRangeInputsComponent, DateRangePickerComponent, DateRangeSearchField, DateService, DcatApConverter, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EXTERNAL_VIEWER_OPEN_NEW_TAB, EXTERNAL_VIEWER_URL_TEMPLATE, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, ErrorComponent, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalLinkCardComponent, ExternalViewerButtonComponent, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FILTER_SUMMARY_IGNORE_LIST, FORMATS, FacetBlockComponent, FacetItemComponent, FacetListComponent, FacetsContainerComponent, FavoriteStarComponent, FavoritesService, FeatureCatalogListComponent, FeatureDetailComponent, FeatureEditorModule, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldFocusDirective, FieldsService, FigureComponent, FigureContainerComponent, FileInputComponent, FileTranslateLoader, FilesDropDirective, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldDateComponent, FormFieldFileComponent, FormFieldKeywordsComponent, FormFieldLicenseComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentsComponent, FormFieldTopicsComponent, FormFieldWrapperComponent, FullTextSearchField, FuzzySearchComponent, GEONETWORK_UI_TAG_NAME, GEONETWORK_UI_VERSION, GeoDataBadgeComponent, GeoTableViewComponent, GeocodingComponent, GeojsonReader, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GnUiHumanizeDateDirective, GpfApiDlComponent, GravatarService, I18nInterceptor, ISO_TOPICS, ImageFallbackDirective, ImageInputComponent, ImageOverlayPreviewComponent, ImportRecordComponent, InlineFilterComponent, InteractiveTableColumnComponent, InteractiveTableComponent, InternalLinkCardComponent, IsSpatialSearchField, Iso191153Converter, Iso19139Converter, KeywordBadgeComponent, KindBadgeComponent, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LOGIN_URL, LOGOUT_URL, LONLAT_CRS_CODES, LanguageSwitcherComponent, LayersPanelComponent, LicenseSearchField, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_FEATURE_KEY, MAP_VIEW_CONSTRAINTS, MAX_UPLOAD_SIZE_MB, METADATA_LANGUAGE, MapContainerComponent, MapFacade, MapLegendComponent, MapStateContainerComponent, MapStyleService, MapUtilsService, MapViewComponent, MarkdownEditorComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataDoiComponent, MetadataInfoComponent, MetadataLinkType, MetadataMapperContext, MetadataQualityComponent, MetadataQualityItemComponent, MetadataQualityPanelComponent, ModalDialogComponent, MultilingualPanelComponent, MultilingualSearchField, MyOrgService, NAMESPACES, NOT_APPLICABLE_CONSTRAINT, NOT_KNOWN_CONSTRAINT, NotificationComponent, NotificationsContainerComponent, NotificationsService, OPEN_DATA_LICENSE, ORGANIZATIONS_STRATEGY, ORGANIZATION_PAGE_URL_TOKEN, ORGANIZATION_URL_TOKEN, OnlineResourceCardComponent, OnlineServiceResourceInputComponent, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationSearchField, OrganizationsFromGroupsService, OrganizationsFromMetadataService, OrganizationsServiceInterface, OwnerSearchField, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PaginationDotsComponent, PatchResultsAggregations, PlatformServiceInterface, PopoverComponent, PopupAlertComponent, PossibleResourceTypes, PossibleResourceTypesDefinition, PreviousNextButtonsComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_DATASET_URL_TOKEN, RECORD_REUSE_URL_TOKEN, RECORD_SERVICE_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, REUSE_LIGHT_CONFIGURATION, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_ORGANIZATION, ROUTER_ROUTE_REUSE, ROUTER_ROUTE_SEARCH, ROUTER_ROUTE_SERVICE, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordKindField, RecordMetaComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordStatusValues, RecordsMetricsComponent, RecordsRepositoryInterface, RecordsService, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResourceCreationRevisionDateSearchField, ResourceTypeLegacyField, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsHitsSearchKindComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, ResultsTableContainerComponent, ReusePresentationForms, RoleLabels, RoleValues, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SETTINGS_URL, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SPATIAL_SCOPES, SearchEffects, SearchFacade, SearchFeatureCatalogComponent, SearchFiltersSummaryComponent, SearchFiltersSummaryItemComponent, SearchInputComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, ServiceCapabilitiesComponent, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SimpleSearchField, SiteTitleComponent, SortByComponent, SortByEnum, SortableListComponent, SourceLabelComponent, SourcesService, SpatialExtentComponent, SpatialExtentDropdownComponent, SpinningLoaderComponent, StacItemsResultGridComponent, StacViewComponent, StarToggleComponent, StickyHeaderComponent, SupportedTypes, SwitchToggleComponent, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEBUG_CONFIG, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, TranslatedSearchField, TruncatedTextComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UpdateConfigAggregations, UpdateFilters, UrlInputComponent, UserFeedbackItemComponent, UserPreviewComponent, UserSearchField, VECTOR_STYLE_DEFAULT, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, XmlParseError, _reset, allChildrenElement, appConfigWithTranslationFixture, appendChildTree, appendChildren, assertValidXml, associationTypeValues, bboxToPolygon, blockModelFixture, bytesToMegabytes, canEditRecord, checkFileFormat, clearSelectedFeatures, createChild, createDocument, createElement, createFuzzyFilter, createNestedChild, createNestedElement, createSpatialExtentLayer, currentPage, defaultMapStyleFixture, defaultMapStyleHlFixture, downgradeImage, downsizeImage, draftSaveSuccess, dragPanCondition, dropEmptyTranslations, editorReducer, emptyBlockModelFixture, findChildElement, findChildOrCreate, findChildrenElement, findConverterForDocument, findNestedChildOrCreate, findNestedElement, findNestedElements, findParent, firstChildElement, formatDate, formatUserInfo, getAddressLines, getAllKeysValidator, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryBoundingBox, getGeometryFromGeoJSON, getGlobalConfig, getIndividualDisplayName, getIsMobile, getJsonDataItemsProxy, getKeywordHierarchyPath, getLayers, getLinkId, getLinkLabel, getLinkPriority, getMapContext, getMapContextLayerFromConfig, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getNamespace, getOptionalEditorConfig, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getQualityValidators, getResourceType, getReusePresentationForm, getReuseType, getRootElement, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSelectedFeatures, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, handleScrollOnNavigation, hasRecordChangedSinceDraft, hasRecordChangedSinceDraftSuccess, initSearch, initialEditorState, initialMapState, initialState, isBoundingBox, isConfigLoaded, isDateRange, isFileExtensionValid, isFormatInQueryParam, isPublished, itemModelFixture, kindToCodeListValue, loadAppConfig, malformedConfigFixture, mapConfigFixture, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, matchesNoApplicableConstraint, matchesNoKnownConstraint, megabytesToBytes, mimeTypeToFormat, minimalAppConfigFixture, missingMandatoryConfigFixture, mouseWheelZoomCondition, noDuplicateFileName, okAppConfigFixture, openDataset, openRecord, organizationsServiceFactory, parse, parseXmlString, placeholder, prioritizePageScroll, propagateToDocumentOnly, provideGn4, provideI18n, provideLocalizedDateAdapter, provideRepositoryUrl, readAttribute, readDataset, readDatasetHeaders, readFileAsText, readText, reducer$2 as reducer, reducerSearch, removeAllChildren, removeChildren, removeChildrenByName, removeSearchParams, removeWhitespace, renameElements, saveRecord, saveRecordFailure, saveRecordSuccess, selectCanEditRecord, selectCurrentPage, selectEditorConfig, selectEditorState, selectFallback, selectFallbackFields, selectField, selectHasRecordChanged, selectIsPublished, selectRecord, selectRecordChangedSinceSave, selectRecordSaveError, selectRecordSaving, selectRecordSections, selectRecordSource, selectTranslatedField, selectTranslatedValue, setContext, setCurrentPage, setEditorConfiguration, setFieldVisibility, setFocusedField, setSelectedFeatures, setTextContent, sortByFromString, sortByToString, sortByToStrings, spatialExtentToGeometry, spatialExtentsToFeatureCollection, stripHtml, stripNamespace, toDate, toIndividual, toLang2, toLang3, totalPages, undoRecordDraft, unrecognizedKeysConfigFixture, updateFrequencyCodeValues, updateLanguages, updateRecordField, updateRecordLanguages, wmsLayerFlatten, writeAttribute, wrongLanguageCodeConfigFixture, xmlToString };
|
|
41308
|
+
export { ADD_RESULTS, ADD_SEARCH, AVAILABLE_LICENSES, AbstractAction, AbstractSearchField, ActionMenuComponent, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, ApplicationBannerComponent, AuthService, AutocompleteComponent, AutofocusDirective, AvailableServicesField, AvatarComponent, AvatarServiceInterface, BASEMAP_LAYERS, BadgeComponent, BaseConverter, BaseFileReader, BaseReader, BlockListComponent, BoundingBoxSearchField, ButtonComponent, CHART_TYPE_VALUES, CLEAR_ERROR, CLEAR_RESULTS, CUSTOM_FIELDS, CarouselComponent, CatalogTitleComponent, CellPopinComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ClearError, ClearResults, ColorScaleComponent, ConfirmationDialogComponent, ContactDetailsComponent, ContactDetailsFormComponent, ContactPillComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASEMAP_LAYER, DEFAULT_CONFIGURATION, DEFAULT_GEOCODING_PROVIDER, DEFAULT_GN4_LOGIN_URL, DEFAULT_GN4_LOGOUT_URL, DEFAULT_GN4_SETTINGS_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RECORD_CONVERTER, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_SPATIAL_EXTENT_STYLE, DISABLE_AUTH, DISABLE_DRAFT, DO_NOT_USE_DEFAULT_BASEMAP, DataService, DataTableComponent, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DatePickerComponent, DateRangeDropdownComponent, DateRangeInputsComponent, DateRangePickerComponent, DateRangeSearchField, DateService, DcatApConverter, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EXTERNAL_VIEWER_OPEN_NEW_TAB, EXTERNAL_VIEWER_URL_TEMPLATE, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, ErrorComponent, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalLinkCardComponent, ExternalViewerButtonComponent, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FILTER_SUMMARY_IGNORE_LIST, FORMATS, FacetBlockComponent, FacetItemComponent, FacetListComponent, FacetsContainerComponent, FavoriteStarComponent, FavoritesService, FeatureCatalogListComponent, FeatureDetailComponent, FeatureEditorModule, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldFocusDirective, FieldsService, FigureComponent, FigureContainerComponent, FileInputComponent, FileTranslateLoader, FilesDropDirective, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldDateComponent, FormFieldFileComponent, FormFieldKeywordsComponent, FormFieldLicenseComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentsComponent, FormFieldTopicsComponent, FormFieldWrapperComponent, FullTextSearchField, FuzzySearchComponent, GEOCODING_PROVIDER, GEOCODING_PROVIDER_LABELS, GEONETWORK_UI_TAG_NAME, GEONETWORK_UI_VERSION, GeoDataBadgeComponent, GeoTableViewComponent, GeocodingService, GeojsonReader, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GnUiHumanizeDateDirective, GpfApiDlComponent, GravatarService, I18nInterceptor, ISO_TOPICS, ImageFallbackDirective, ImageInputComponent, ImageOverlayPreviewComponent, ImportRecordComponent, InlineFilterComponent, InteractiveTableColumnComponent, InteractiveTableComponent, InternalLinkCardComponent, IsSpatialSearchField, Iso191153Converter, Iso19139Converter, KeywordBadgeComponent, KindBadgeComponent, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LOGIN_URL, LOGOUT_URL, LONLAT_CRS_CODES, LanguageSwitcherComponent, LayersPanelComponent, LicenseSearchField, LinkClassifierService, LinkUsage, LoadingMaskComponent, LocationSearchComponent, LogService, MAP_FEATURE_KEY, MAP_VIEW_CONSTRAINTS, MAX_UPLOAD_SIZE_MB, METADATA_LANGUAGE, MapContainerComponent, MapFacade, MapLegendComponent, MapStateContainerComponent, MapUtilsService, MapViewComponent, MarkdownEditorComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataDoiComponent, MetadataInfoComponent, MetadataLinkType, MetadataMapperContext, MetadataQualityComponent, MetadataQualityItemComponent, MetadataQualityPanelComponent, ModalDialogComponent, MultilingualPanelComponent, MultilingualSearchField, MyOrgService, NAMESPACES, NOT_APPLICABLE_CONSTRAINT, NOT_KNOWN_CONSTRAINT, NotificationComponent, NotificationsContainerComponent, NotificationsService, OPEN_DATA_LICENSE, ORGANIZATIONS_STRATEGY, ORGANIZATION_PAGE_URL_TOKEN, ORGANIZATION_URL_TOKEN, OnlineResourceCardComponent, OnlineServiceResourceInputComponent, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationSearchField, OrganizationsFromGroupsService, OrganizationsFromMetadataService, OrganizationsServiceInterface, OwnerSearchField, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PaginationDotsComponent, PatchResultsAggregations, PlatformServiceInterface, PopoverComponent, PopupAlertComponent, PossibleResourceTypes, PossibleResourceTypesDefinition, PreviousNextButtonsComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_DATASET_URL_TOKEN, RECORD_REUSE_URL_TOKEN, RECORD_SERVICE_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, REUSE_LIGHT_CONFIGURATION, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_ORGANIZATION, ROUTER_ROUTE_REUSE, ROUTER_ROUTE_SEARCH, ROUTER_ROUTE_SERVICE, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordKindField, RecordMetaComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordStatusValues, RecordsMetricsComponent, RecordsRepositoryInterface, RecordsService, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResourceCreationRevisionDateSearchField, ResourceTypeLegacyField, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsHitsSearchKindComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, ResultsTableContainerComponent, ReusePresentationForms, RoleLabels, RoleValues, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SETTINGS_URL, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SPATIAL_EXTENT_MAX_FILE_SIZE, SPATIAL_SCOPES, SearchEffects, SearchFacade, SearchFeatureCatalogComponent, SearchFiltersSummaryComponent, SearchFiltersSummaryItemComponent, SearchInputComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, ServiceCapabilitiesComponent, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SimpleSearchField, SiteTitleComponent, SortByComponent, SortByEnum, SortableListComponent, SourceLabelComponent, SourcesService, SpatialExtentComponent, SpatialExtentDropdownComponent, SpinningLoaderComponent, StacItemsResultGridComponent, StacViewComponent, StarToggleComponent, StickyHeaderComponent, SupportedTypes, SwitchToggleComponent, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEBUG_CONFIG, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, TranslatedSearchField, TruncatedTextComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UpdateConfigAggregations, UpdateFilters, UrlInputComponent, UserFeedbackItemComponent, UserPreviewComponent, UserSearchField, VECTOR_STYLE_DEFAULT, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, XmlParseError, _reset, allChildrenElement, appConfigWithTranslationFixture, appendChildTree, appendChildren, assertValidXml, associationTypeValues, bboxToPolygon, blockModelFixture, bytesToMegabytes, canEditRecord, checkFileFormat, clearSelectedFeatures, createChild, createDocument, createElement, createFuzzyFilter, createNestedChild, createNestedElement, createSpatialExtentLayer, currentPage, customFilterMissingMandatoryConfigFixture, downgradeImage, downsizeImage, draftSaveSuccess, dragPanCondition, dropEmptyTranslations, editorReducer, emptyBlockModelFixture, findChildElement, findChildOrCreate, findChildrenElement, findConverterForDocument, findNestedChildOrCreate, findNestedElement, findNestedElements, findParent, firstChildElement, formatDate, formatUserInfo, getAddressLines, getAllKeysValidator, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryBoundingBox, getGeometryFromGeoJSON, getGlobalConfig, getIndividualDisplayName, getIsMobile, getJsonDataItemsProxy, getKeywordHierarchyPath, getLayers, getLinkId, getLinkLabel, getLinkPriority, getMapContext, getMapContextLayerFromConfig, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getNamespace, getOptionalEditorConfig, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getQualityValidators, getResourceType, getReusePresentationForm, getReuseType, getRootElement, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSelectedFeatures, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, handleScrollOnNavigation, hasRecordChangedSinceDraft, hasRecordChangedSinceDraftSuccess, initSearch, initialEditorState, initialMapState, initialState, isBoundingBox, isBoundingBoxWithinWorldExtent, isConfigLoaded, isDateRange, isFileExtensionValid, isFormatInQueryParam, isPublished, itemModelFixture, kindToCodeListValue, loadAppConfig, malformedConfigFixture, mapConfigFixture, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, matchesNoApplicableConstraint, matchesNoKnownConstraint, megabytesToBytes, mimeTypeToFormat, minimalAppConfigFixture, missingMandatoryConfigFixture, mouseWheelZoomCondition, noDuplicateFileName, okAppConfigFixture, openDataset, openRecord, organizationsServiceFactory, parse, parseXmlString, placeholder, prioritizePageScroll, propagateToDocumentOnly, provideGn4, provideI18n, provideLocalizedDateAdapter, provideRepositoryUrl, readAttribute, readDataset, readDatasetHeaders, readFileAsText, readText, reducer$2 as reducer, reducerSearch, removeAllChildren, removeChildren, removeChildrenByName, removeSearchParams, removeWhitespace, renameElements, saveRecord, saveRecordFailure, saveRecordSuccess, selectCanEditRecord, selectCurrentPage, selectEditorConfig, selectEditorState, selectFallback, selectFallbackFields, selectField, selectHasRecordChanged, selectIsPublished, selectRecord, selectRecordChangedSinceSave, selectRecordSaveError, selectRecordSaving, selectRecordSections, selectRecordSource, selectTranslatedField, selectTranslatedValue, setContext, setCurrentPage, setEditorConfiguration, setFieldVisibility, setFocusedField, setSelectedFeatures, setTextContent, sortByFromString, sortByToString, sortByToStrings, spatialExtentToGeometry, spatialExtentsToFeatureCollection, stripHtml, stripNamespace, toDate, toIndividual, toLang2, toLang3, totalPages, undoRecordDraft, unrecognizedKeysConfigFixture, updateFrequencyCodeValues, updateLanguages, updateRecordField, updateRecordLanguages, wmsLayerFlatten, writeAttribute, wrongLanguageCodeConfigFixture, xmlToString };
|
|
40956
41309
|
//# sourceMappingURL=geonetwork-ui.mjs.map
|