geonetwork-ui 2.11.0-dev.bc1a6d4e2 → 2.11.0-dev.bc1acb627
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 +1446 -1300
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/index.d.ts +170 -100
- 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 +317 -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 +2 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +98 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +7 -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 +90 -31
- package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +5 -34
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +6 -13
- 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/repository/records-repository.interface.ts +1 -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/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 +8 -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 +2 -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 +62 -4
- package/src/libs/feature/search/src/lib/utils/service/fields.ts +67 -9
- package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.html +2 -2
- 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 +10 -2
- package/translations/en.json +12 -4
- package/translations/es.json +10 -2
- package/translations/fr.json +17 -9
- package/translations/it.json +10 -2
- package/translations/nl.json +10 -2
- package/translations/pt.json +10 -2
- package/translations/sk.json +10 -2
- package/src/libs/feature/map/src/lib/geocoding/geocoding.component.css +0 -0
- 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
|
@@ -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';
|
|
@@ -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';
|
|
@@ -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
|
}
|
|
@@ -2633,6 +2636,31 @@ function readDefaultLanguage$1(rootEl) {
|
|
|
2633
2636
|
function readOtherLanguages(rootEl) {
|
|
2634
2637
|
return pipe(findChildrenElement('mdb:otherLocale', false), mapArray(readLocaleElement()), map((languages) => languages.filter((lang) => lang !== null)))(rootEl);
|
|
2635
2638
|
}
|
|
2639
|
+
function extractCharacterStringOrText() {
|
|
2640
|
+
return fallback(extractCharacterString(), readText());
|
|
2641
|
+
}
|
|
2642
|
+
function extractListedValue() {
|
|
2643
|
+
return pipe(combine(pipe(findChildElement('gfc:code', false), extractCharacterString()), pipe(findChildElement('gfc:label', false), extractCharacterString())), map(([code, label]) => ({
|
|
2644
|
+
...(code && { code }),
|
|
2645
|
+
...(label && { label }),
|
|
2646
|
+
})));
|
|
2647
|
+
}
|
|
2648
|
+
function extractFeatureAttribute() {
|
|
2649
|
+
return pipe(combine(pipe(findChildElement('gfc:memberName', false), extractCharacterStringOrText()), 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.code || value.label)))), map(([name, description, code, type, values]) => ({
|
|
2650
|
+
name: name ?? '',
|
|
2651
|
+
...(description && { description }),
|
|
2652
|
+
...(code && { code }),
|
|
2653
|
+
...(type && { type }),
|
|
2654
|
+
...(values.length > 0 && { values }),
|
|
2655
|
+
})));
|
|
2656
|
+
}
|
|
2657
|
+
function readFeatureTypeDescriptions(rootEl) {
|
|
2658
|
+
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:definition', false), extractCharacterString()), pipe(findNestedElements('gfc:carrierOfCharacteristics', 'gfc:FC_FeatureAttribute'), mapArray(extractFeatureAttribute()))), map(([name, description, attributes]) => ({
|
|
2659
|
+
name: name ?? '',
|
|
2660
|
+
...(description && { description }),
|
|
2661
|
+
attributes,
|
|
2662
|
+
})))))(rootEl);
|
|
2663
|
+
}
|
|
2636
2664
|
|
|
2637
2665
|
function writeUniqueIdentifier$1(record, rootEl) {
|
|
2638
2666
|
pipe(findNestedChildOrCreate('mdb:metadataIdentifier', 'mcc:MD_Identifier', 'mcc:code'), writeCharacterString(record.uniqueIdentifier))(rootEl);
|
|
@@ -2803,6 +2831,7 @@ class Iso191153Converter extends Iso19139Converter {
|
|
|
2803
2831
|
this.readers['lineage'] = readLineage;
|
|
2804
2832
|
this.readers['sourceRecords'] = readSourceRecords;
|
|
2805
2833
|
this.readers['associatedRecords'] = readAssociatedRecords;
|
|
2834
|
+
this.readers['featureTypeDescriptions'] = readFeatureTypeDescriptions;
|
|
2806
2835
|
this.readers['onlineResources'] = readOnlineResources$1;
|
|
2807
2836
|
this.readers['defaultLanguage'] = readDefaultLanguage$1;
|
|
2808
2837
|
this.readers['otherLanguages'] = readOtherLanguages;
|
|
@@ -3459,6 +3488,7 @@ class DcatApConverter extends BaseConverter {
|
|
|
3459
3488
|
lineage: () => '',
|
|
3460
3489
|
sourceRecords: () => [],
|
|
3461
3490
|
associatedRecords: () => [],
|
|
3491
|
+
featureTypeDescriptions: () => undefined,
|
|
3462
3492
|
temporalExtents: () => [],
|
|
3463
3493
|
spatialRepresentation: () => undefined,
|
|
3464
3494
|
extras: () => undefined,
|
|
@@ -3494,6 +3524,7 @@ class DcatApConverter extends BaseConverter {
|
|
|
3494
3524
|
lineage: () => undefined,
|
|
3495
3525
|
sourceRecords: () => [],
|
|
3496
3526
|
associatedRecords: () => [],
|
|
3527
|
+
featureTypeDescriptions: () => undefined,
|
|
3497
3528
|
onlineResources: () => undefined,
|
|
3498
3529
|
temporalExtents: () => undefined,
|
|
3499
3530
|
spatialExtents: () => undefined,
|
|
@@ -18904,9 +18935,15 @@ class Gn4FieldMapper {
|
|
|
18904
18935
|
isOpenData: (output, source) => this.addExtra({
|
|
18905
18936
|
isOpenData: selectField(source, 'isOpenData') !== 'false',
|
|
18906
18937
|
}, output),
|
|
18907
|
-
featureTypes: (output, source) =>
|
|
18908
|
-
featureTypes
|
|
18909
|
-
|
|
18938
|
+
featureTypes: (output, source) => {
|
|
18939
|
+
const featureTypes = getAsArray(selectField(source, 'featureTypes'));
|
|
18940
|
+
if (!featureTypes.length)
|
|
18941
|
+
return output;
|
|
18942
|
+
return {
|
|
18943
|
+
...output,
|
|
18944
|
+
featureTypeDescriptions: this.featureTypesField(featureTypes),
|
|
18945
|
+
};
|
|
18946
|
+
},
|
|
18910
18947
|
related: (output, source) => {
|
|
18911
18948
|
const related = selectField(source, 'related');
|
|
18912
18949
|
const fcatSource = selectField(getFirstValue(selectField(related, 'fcats')) ?? {}, '_source');
|
|
@@ -19042,6 +19079,27 @@ class Gn4FieldMapper {
|
|
|
19042
19079
|
},
|
|
19043
19080
|
};
|
|
19044
19081
|
this.genericField = (output) => output;
|
|
19082
|
+
this.featureTypesField = (featureTypes) => featureTypes.map((featureType) => ({
|
|
19083
|
+
name: featureType.typeName ?? '',
|
|
19084
|
+
...(featureType.definition && {
|
|
19085
|
+
description: featureType.definition,
|
|
19086
|
+
}),
|
|
19087
|
+
attributes: getAsArray(featureType.attributeTable ?? []).map((attr) => {
|
|
19088
|
+
const values = (attr.values ?? [])
|
|
19089
|
+
.filter((value) => value.code || value.label)
|
|
19090
|
+
.map((value) => ({
|
|
19091
|
+
...(value.code && { code: value.code }),
|
|
19092
|
+
...(value.label && { label: value.label }),
|
|
19093
|
+
}));
|
|
19094
|
+
return {
|
|
19095
|
+
name: attr.name ?? '',
|
|
19096
|
+
...(attr.definition && { description: attr.definition }),
|
|
19097
|
+
...(attr.code && { code: attr.code }),
|
|
19098
|
+
...(attr.type && { type: attr.type }),
|
|
19099
|
+
...(values.length > 0 && { values }),
|
|
19100
|
+
};
|
|
19101
|
+
}),
|
|
19102
|
+
}));
|
|
19045
19103
|
this.constraintField = (type, output, constraintArray) => {
|
|
19046
19104
|
let outputField;
|
|
19047
19105
|
switch (type) {
|
|
@@ -19596,6 +19654,19 @@ function isBoundingBox(value) {
|
|
|
19596
19654
|
value.length === 4 &&
|
|
19597
19655
|
value.every((item) => typeof item === 'number'));
|
|
19598
19656
|
}
|
|
19657
|
+
/**
|
|
19658
|
+
* Checks that a bounding box's coordinates stay within the valid
|
|
19659
|
+
* longitude (-180/180) and latitude (-90/90) ranges.
|
|
19660
|
+
*/
|
|
19661
|
+
function isBoundingBoxWithinWorldExtent(bbox) {
|
|
19662
|
+
const [minX, minY, maxX, maxY] = bbox;
|
|
19663
|
+
return (minX >= -180 &&
|
|
19664
|
+
maxX <= 180 &&
|
|
19665
|
+
minY >= -90 &&
|
|
19666
|
+
maxY <= 90 &&
|
|
19667
|
+
minX <= maxX &&
|
|
19668
|
+
minY <= maxY);
|
|
19669
|
+
}
|
|
19599
19670
|
function getGeometryBoundingBox(geometry) {
|
|
19600
19671
|
// use the bounding box if specified in the GeoJSON object
|
|
19601
19672
|
if (geometry.bbox) {
|
|
@@ -20264,7 +20335,7 @@ function getLinkLabel(link) {
|
|
|
20264
20335
|
const label = link.description || ('name' in link ? link.name : '');
|
|
20265
20336
|
return format ? `${label} (${format})` : label;
|
|
20266
20337
|
}
|
|
20267
|
-
async function getLayers(url, serviceProtocol) {
|
|
20338
|
+
async function getLayers(url, serviceProtocol, deep = false) {
|
|
20268
20339
|
switch (serviceProtocol) {
|
|
20269
20340
|
case 'ogcFeatures': {
|
|
20270
20341
|
const layers = await new OgcApiEndpoint(url).allCollections;
|
|
@@ -20272,7 +20343,10 @@ async function getLayers(url, serviceProtocol) {
|
|
|
20272
20343
|
}
|
|
20273
20344
|
case 'wfs': {
|
|
20274
20345
|
const endpointWfs = await new WfsEndpoint(url).isReady();
|
|
20275
|
-
const featureTypes =
|
|
20346
|
+
const featureTypes = endpointWfs.getFeatureTypes();
|
|
20347
|
+
if (!deep) {
|
|
20348
|
+
return featureTypes;
|
|
20349
|
+
}
|
|
20276
20350
|
const layers = (await Promise.allSettled(featureTypes.map((collection) => {
|
|
20277
20351
|
return endpointWfs.getFeatureTypeFull(collection.name);
|
|
20278
20352
|
})))
|
|
@@ -20282,12 +20356,14 @@ async function getLayers(url, serviceProtocol) {
|
|
|
20282
20356
|
}
|
|
20283
20357
|
case 'wms': {
|
|
20284
20358
|
const endpointWms = await new WmsEndpoint(url).isReady();
|
|
20285
|
-
const
|
|
20359
|
+
const layersSummary = endpointWms
|
|
20286
20360
|
.getLayers()
|
|
20287
20361
|
.flatMap(wmsLayerFlatten)
|
|
20288
|
-
.filter((l) => l.name)
|
|
20289
|
-
|
|
20290
|
-
|
|
20362
|
+
.filter((l) => l.name);
|
|
20363
|
+
if (!deep) {
|
|
20364
|
+
return layersSummary;
|
|
20365
|
+
}
|
|
20366
|
+
const layers = layersSummary.map((collection) => endpointWms.getLayerByName(collection.name));
|
|
20291
20367
|
return layers;
|
|
20292
20368
|
}
|
|
20293
20369
|
case 'wmts': {
|
|
@@ -20434,7 +20510,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
20434
20510
|
}] } });
|
|
20435
20511
|
|
|
20436
20512
|
var name = "geonetwork-ui";
|
|
20437
|
-
var version = "2.11.0-dev.
|
|
20513
|
+
var version = "2.11.0-dev.bc1acb627";
|
|
20438
20514
|
var engines = {
|
|
20439
20515
|
node: ">=24"
|
|
20440
20516
|
};
|
|
@@ -20476,10 +20552,10 @@ var dependencies = {
|
|
|
20476
20552
|
"@biesbjerg/ngx-translate-extract-marker": "~1.0.0",
|
|
20477
20553
|
"@camptocamp/ogc-client": "1.3.1-dev.200c02a",
|
|
20478
20554
|
"@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.
|
|
20555
|
+
"@geospatial-sdk/core": "0.0.5-dev.86.sha-124eae3",
|
|
20556
|
+
"@geospatial-sdk/geocoding": "0.0.5-dev.86.sha-124eae3",
|
|
20557
|
+
"@geospatial-sdk/legend": "0.0.5-dev.86.sha-124eae3",
|
|
20558
|
+
"@geospatial-sdk/openlayers": "0.0.5-dev.86.sha-124eae3",
|
|
20483
20559
|
"@ltd/j-toml": "~1.38.0",
|
|
20484
20560
|
"@messageformat/core": "~3.4.0",
|
|
20485
20561
|
"@ng-icons/core": "~32.5.0",
|
|
@@ -20496,6 +20572,7 @@ var dependencies = {
|
|
|
20496
20572
|
"embla-carousel": "~8.6.0",
|
|
20497
20573
|
"flag-icons": "~7.5.0",
|
|
20498
20574
|
"geojson-validation": "~1.0.2",
|
|
20575
|
+
jsonpointer: "^5.0.1",
|
|
20499
20576
|
marked: "~17.0.4",
|
|
20500
20577
|
"ngx-dropzone": "~3.1.0",
|
|
20501
20578
|
"ngx-translate-messageformat-compiler": "~7.2.0",
|
|
@@ -20672,6 +20749,7 @@ class ElasticsearchService {
|
|
|
20672
20749
|
// runtime fields are computed using a Painless script
|
|
20673
20750
|
// see: https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-mapping-fields.html
|
|
20674
20751
|
this.runtimeFields = {};
|
|
20752
|
+
this.fieldAliases = {};
|
|
20675
20753
|
}
|
|
20676
20754
|
// we're using getters in case the defined languages change over time
|
|
20677
20755
|
get metadataLang() {
|
|
@@ -20697,8 +20775,8 @@ class ElasticsearchService {
|
|
|
20697
20775
|
if (!payload.runtime_mappings)
|
|
20698
20776
|
payload.runtime_mappings = {};
|
|
20699
20777
|
payload.runtime_mappings[fieldName] = {
|
|
20700
|
-
type:
|
|
20701
|
-
script: this.runtimeFields[fieldName],
|
|
20778
|
+
type: this.runtimeFields[fieldName].type,
|
|
20779
|
+
script: this.runtimeFields[fieldName].script,
|
|
20702
20780
|
};
|
|
20703
20781
|
};
|
|
20704
20782
|
const lookForField = (node) => {
|
|
@@ -20718,6 +20796,12 @@ class ElasticsearchService {
|
|
|
20718
20796
|
(node[runtimeField] === 'asc' || node[runtimeField] === 'desc')) {
|
|
20719
20797
|
addMapping(runtimeField);
|
|
20720
20798
|
}
|
|
20799
|
+
if (runtimeField in node &&
|
|
20800
|
+
typeof node[runtimeField] === 'object' &&
|
|
20801
|
+
node[runtimeField] !== null &&
|
|
20802
|
+
('gte' in node[runtimeField] || 'lte' in node[runtimeField])) {
|
|
20803
|
+
addMapping(runtimeField);
|
|
20804
|
+
}
|
|
20721
20805
|
if ('query' in node &&
|
|
20722
20806
|
typeof node.query === 'string' &&
|
|
20723
20807
|
node.query.indexOf(runtimeField + ':') > -1) {
|
|
@@ -20734,8 +20818,11 @@ class ElasticsearchService {
|
|
|
20734
20818
|
lookForField(payload.query);
|
|
20735
20819
|
return payload;
|
|
20736
20820
|
}
|
|
20737
|
-
registerRuntimeField(fieldName, expression) {
|
|
20738
|
-
this.runtimeFields[fieldName] = expression;
|
|
20821
|
+
registerRuntimeField(fieldName, expression, type = 'keyword') {
|
|
20822
|
+
this.runtimeFields[fieldName] = { script: expression, type };
|
|
20823
|
+
}
|
|
20824
|
+
registerFieldAlias(fieldIdentifier, esFieldName) {
|
|
20825
|
+
this.fieldAliases[fieldIdentifier] = esFieldName;
|
|
20739
20826
|
}
|
|
20740
20827
|
getMetadataByIdsPayload(uuids) {
|
|
20741
20828
|
return {
|
|
@@ -20858,6 +20945,55 @@ class ElasticsearchService {
|
|
|
20858
20945
|
}
|
|
20859
20946
|
return Object.values(filters).find(isBoundingBox);
|
|
20860
20947
|
}
|
|
20948
|
+
// builds a query matching records whose dates intersect the filter range
|
|
20949
|
+
buildDateRangeQuery(searchField, dateRange) {
|
|
20950
|
+
// fields ending with 'DateRange' maps as ES range type
|
|
20951
|
+
if (searchField.endsWith('DateRange')) {
|
|
20952
|
+
return {
|
|
20953
|
+
range: {
|
|
20954
|
+
[searchField]: {
|
|
20955
|
+
...(dateRange.start && { gte: formatDate(dateRange.start) }),
|
|
20956
|
+
...(dateRange.end && { lte: formatDate(dateRange.end) }),
|
|
20957
|
+
format: 'yyyy-MM-dd',
|
|
20958
|
+
relation: 'intersects',
|
|
20959
|
+
},
|
|
20960
|
+
},
|
|
20961
|
+
};
|
|
20962
|
+
}
|
|
20963
|
+
const minField = `${searchField}Min`;
|
|
20964
|
+
const maxField = `${searchField}Max`;
|
|
20965
|
+
if (minField in this.runtimeFields && maxField in this.runtimeFields) {
|
|
20966
|
+
// min/max runtime fields form an interval per record; match if it intersects the filter range
|
|
20967
|
+
const filter = [
|
|
20968
|
+
dateRange.start && {
|
|
20969
|
+
range: {
|
|
20970
|
+
[maxField]: {
|
|
20971
|
+
gte: formatDate(dateRange.start),
|
|
20972
|
+
format: 'yyyy-MM-dd',
|
|
20973
|
+
},
|
|
20974
|
+
},
|
|
20975
|
+
},
|
|
20976
|
+
dateRange.end && {
|
|
20977
|
+
range: {
|
|
20978
|
+
[minField]: {
|
|
20979
|
+
lte: formatDate(dateRange.end),
|
|
20980
|
+
format: 'yyyy-MM-dd',
|
|
20981
|
+
},
|
|
20982
|
+
},
|
|
20983
|
+
},
|
|
20984
|
+
].filter(Boolean);
|
|
20985
|
+
return { bool: { filter } };
|
|
20986
|
+
}
|
|
20987
|
+
return {
|
|
20988
|
+
range: {
|
|
20989
|
+
[searchField]: {
|
|
20990
|
+
...(dateRange.start && { gte: formatDate(dateRange.start) }),
|
|
20991
|
+
...(dateRange.end && { lte: formatDate(dateRange.end) }),
|
|
20992
|
+
format: 'yyyy-MM-dd',
|
|
20993
|
+
},
|
|
20994
|
+
},
|
|
20995
|
+
};
|
|
20996
|
+
}
|
|
20861
20997
|
filtersToQuery(filters, spatialFilterExtent = this.findSpatialFilterExtent(filters)) {
|
|
20862
20998
|
const addQuote = (key) => (/^\/.+\/$/.test(key) ? key : `"${key}"`);
|
|
20863
20999
|
const makeQuery = (filter) => {
|
|
@@ -20882,39 +21018,19 @@ class ElasticsearchService {
|
|
|
20882
21018
|
.filter((fieldname) => !Array.isArray(filters[fieldname]))
|
|
20883
21019
|
.filter((fieldname) => filters[fieldname] &&
|
|
20884
21020
|
JSON.stringify(filters[fieldname]) !== '{}')
|
|
20885
|
-
.map((fieldname) => `${fieldname}:(${makeQuery(filters[fieldname])})`)
|
|
21021
|
+
.map((fieldname) => `${this.fieldAliases[fieldname] ?? fieldname}:(${makeQuery(filters[fieldname])})`)
|
|
20886
21022
|
.join(' AND ');
|
|
20887
21023
|
if (filters['gn-ui-crossFieldFilter']) {
|
|
20888
21024
|
queryString = `${queryString} AND (${filters['gn-ui-crossFieldFilter']})`;
|
|
20889
21025
|
}
|
|
20890
|
-
const
|
|
20891
|
-
.filter(([, value]) => isDateRange(value))
|
|
20892
|
-
.map(([searchField, dateRange]) => {
|
|
20893
|
-
return {
|
|
20894
|
-
searchField,
|
|
20895
|
-
dateRange,
|
|
20896
|
-
};
|
|
20897
|
-
})[0];
|
|
21026
|
+
const queryRanges = Object.entries(filters).filter(([, value]) => isDateRange(value));
|
|
20898
21027
|
const queryParts = [
|
|
20899
21028
|
queryString && {
|
|
20900
21029
|
query_string: {
|
|
20901
21030
|
query: queryString,
|
|
20902
21031
|
},
|
|
20903
21032
|
},
|
|
20904
|
-
|
|
20905
|
-
queryRange.dateRange && {
|
|
20906
|
-
range: {
|
|
20907
|
-
[queryRange.searchField]: {
|
|
20908
|
-
...(queryRange.dateRange.start && {
|
|
20909
|
-
gte: formatDate(queryRange.dateRange.start),
|
|
20910
|
-
}),
|
|
20911
|
-
...(queryRange.dateRange.end && {
|
|
20912
|
-
lte: formatDate(queryRange.dateRange.end),
|
|
20913
|
-
}),
|
|
20914
|
-
format: 'yyyy-MM-dd',
|
|
20915
|
-
},
|
|
20916
|
-
},
|
|
20917
|
-
},
|
|
21033
|
+
...queryRanges.map(([searchField, dateRange]) => this.buildDateRangeQuery(searchField, dateRange)),
|
|
20918
21034
|
spatialFilterExtent && {
|
|
20919
21035
|
geo_shape: {
|
|
20920
21036
|
geom: {
|
|
@@ -21200,6 +21316,12 @@ class ElasticsearchService {
|
|
|
21200
21316
|
order: {
|
|
21201
21317
|
[`_${aggregation.sort[1]}`]: aggregation.sort[0],
|
|
21202
21318
|
},
|
|
21319
|
+
...(aggregation.includeValues && {
|
|
21320
|
+
include: aggregation.includeValues,
|
|
21321
|
+
}),
|
|
21322
|
+
...(aggregation.excludeValues && {
|
|
21323
|
+
exclude: aggregation.excludeValues,
|
|
21324
|
+
}),
|
|
21203
21325
|
},
|
|
21204
21326
|
};
|
|
21205
21327
|
case 'histogram':
|
|
@@ -21334,42 +21456,16 @@ class Gn4Repository {
|
|
|
21334
21456
|
? this.gn4Mapper.readRecords(records)
|
|
21335
21457
|
: of(null)));
|
|
21336
21458
|
}
|
|
21337
|
-
|
|
21338
|
-
return {
|
|
21339
|
-
featureTypes: featureTypes.map((featureType) => ({
|
|
21340
|
-
name: featureType.typeName || '',
|
|
21341
|
-
definition: featureType.definition || '',
|
|
21342
|
-
attributes: Array.isArray(featureType.attributeTable)
|
|
21343
|
-
? featureType.attributeTable.map((attr) => {
|
|
21344
|
-
const values = attr.values
|
|
21345
|
-
?.filter((v) => v.code || v.label)
|
|
21346
|
-
.map((v) => ({
|
|
21347
|
-
code: v.code,
|
|
21348
|
-
label: v.label,
|
|
21349
|
-
}));
|
|
21350
|
-
return {
|
|
21351
|
-
name: attr.name,
|
|
21352
|
-
code: attr.code,
|
|
21353
|
-
definition: attr.definition,
|
|
21354
|
-
type: attr.type,
|
|
21355
|
-
...(values?.length > 0 ? { values } : {}),
|
|
21356
|
-
};
|
|
21357
|
-
})
|
|
21358
|
-
: [],
|
|
21359
|
-
})),
|
|
21360
|
-
};
|
|
21361
|
-
}
|
|
21362
|
-
getFeatureCatalog(record, visited = new Set() // prevent looping
|
|
21459
|
+
queryLinkedFeatureCatalog(record, visited = new Set() // prevent looping
|
|
21363
21460
|
) {
|
|
21364
|
-
if (
|
|
21365
|
-
|
|
21366
|
-
record.
|
|
21367
|
-
return of(this.mapEmbeddedFeatureCatalog(record.extras['featureTypes']));
|
|
21461
|
+
if ('featureTypeDescriptions' in record &&
|
|
21462
|
+
record.featureTypeDescriptions?.length > 0) {
|
|
21463
|
+
return of({ featureTypes: record.featureTypeDescriptions });
|
|
21368
21464
|
}
|
|
21369
21465
|
const featureCatalogIdentifier = record.extras['featureCatalogIdentifier'];
|
|
21370
21466
|
if (featureCatalogIdentifier && !visited.has(featureCatalogIdentifier)) {
|
|
21371
21467
|
visited.add(featureCatalogIdentifier);
|
|
21372
|
-
return this.getRecord(featureCatalogIdentifier).pipe(switchMap((record) => record ? this.
|
|
21468
|
+
return this.getRecord(featureCatalogIdentifier).pipe(switchMap((record) => record ? this.queryLinkedFeatureCatalog(record, visited) : of(null)));
|
|
21373
21469
|
}
|
|
21374
21470
|
return of(null);
|
|
21375
21471
|
}
|
|
@@ -22588,48 +22684,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
22588
22684
|
type: Injectable
|
|
22589
22685
|
}] });
|
|
22590
22686
|
|
|
22591
|
-
const GEOCODING_PROVIDER = new InjectionToken('geocoding-provider');
|
|
22592
|
-
class GeocodingService {
|
|
22593
|
-
constructor() {
|
|
22594
|
-
this.provider = inject(GEOCODING_PROVIDER);
|
|
22595
|
-
}
|
|
22596
|
-
query(text) {
|
|
22597
|
-
let queryObservable;
|
|
22598
|
-
switch (this.provider[0]) {
|
|
22599
|
-
case 'geoadmin':
|
|
22600
|
-
queryObservable = from(queryGeoadmin(text, this.provider[1]));
|
|
22601
|
-
break;
|
|
22602
|
-
case 'geonames':
|
|
22603
|
-
queryObservable = from(queryGeonames(text, this.provider[1]));
|
|
22604
|
-
break;
|
|
22605
|
-
case 'data-gouv-fr':
|
|
22606
|
-
queryObservable = from(queryDataGouvFr(text, this.provider[1]));
|
|
22607
|
-
break;
|
|
22608
|
-
default:
|
|
22609
|
-
return throwError(() => new Error(`Unsupported geocoding provider: ${this.provider[0]}`));
|
|
22610
|
-
}
|
|
22611
|
-
return queryObservable.pipe(catchError((error) => throwError(error)));
|
|
22612
|
-
}
|
|
22613
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
22614
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, providedIn: 'root' }); }
|
|
22615
|
-
}
|
|
22616
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, decorators: [{
|
|
22617
|
-
type: Injectable,
|
|
22618
|
-
args: [{
|
|
22619
|
-
providedIn: 'root',
|
|
22620
|
-
}]
|
|
22621
|
-
}] });
|
|
22622
|
-
|
|
22623
22687
|
class FeatureMapModule {
|
|
22624
22688
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
22625
22689
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, imports: [i1.StoreFeatureModule] }); }
|
|
22626
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, providers: [
|
|
22627
|
-
MapFacade,
|
|
22628
|
-
{
|
|
22629
|
-
provide: GEOCODING_PROVIDER,
|
|
22630
|
-
useValue: ['geonames', { maxRows: 5 }],
|
|
22631
|
-
},
|
|
22632
|
-
], imports: [StoreModule.forFeature(MAP_FEATURE_KEY, mapReducer)] }); }
|
|
22690
|
+
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)] }); }
|
|
22633
22691
|
}
|
|
22634
22692
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureMapModule, decorators: [{
|
|
22635
22693
|
type: NgModule,
|
|
@@ -22637,13 +22695,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
22637
22695
|
imports: [
|
|
22638
22696
|
StoreModule.forFeature(MAP_FEATURE_KEY, mapReducer),
|
|
22639
22697
|
],
|
|
22640
|
-
providers: [
|
|
22641
|
-
MapFacade,
|
|
22642
|
-
{
|
|
22643
|
-
provide: GEOCODING_PROVIDER,
|
|
22644
|
-
useValue: ['geonames', { maxRows: 5 }],
|
|
22645
|
-
},
|
|
22646
|
-
],
|
|
22698
|
+
providers: [MapFacade],
|
|
22647
22699
|
}]
|
|
22648
22700
|
}] });
|
|
22649
22701
|
|
|
@@ -23086,1060 +23138,352 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
23086
23138
|
}]
|
|
23087
23139
|
}] });
|
|
23088
23140
|
|
|
23089
|
-
|
|
23090
|
-
|
|
23091
|
-
|
|
23092
|
-
|
|
23093
|
-
|
|
23141
|
+
class AnchorLinkDirective {
|
|
23142
|
+
constructor() {
|
|
23143
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
23144
|
+
this.disabled = false;
|
|
23145
|
+
this.observer = new MutationObserver(() => {
|
|
23146
|
+
this.refreshDisabledState();
|
|
23147
|
+
});
|
|
23148
|
+
this.inView = false;
|
|
23149
|
+
this.initialized = false;
|
|
23094
23150
|
}
|
|
23095
|
-
|
|
23096
|
-
|
|
23097
|
-
|
|
23098
|
-
|
|
23099
|
-
|
|
23151
|
+
get elementClass() {
|
|
23152
|
+
if (this.disabled) {
|
|
23153
|
+
return this.disabledClass;
|
|
23154
|
+
}
|
|
23155
|
+
if (this.inView) {
|
|
23156
|
+
return `${this.inViewClass} ${this.enabledClass}`;
|
|
23157
|
+
}
|
|
23158
|
+
else {
|
|
23159
|
+
return `${this.outOfViewClass} ${this.enabledClass}`;
|
|
23160
|
+
}
|
|
23100
23161
|
}
|
|
23101
|
-
|
|
23102
|
-
|
|
23162
|
+
ngOnInit() {
|
|
23163
|
+
this.observer.observe(document.body, {
|
|
23164
|
+
childList: true,
|
|
23165
|
+
subtree: true,
|
|
23166
|
+
});
|
|
23167
|
+
this.refreshDisabledState();
|
|
23103
23168
|
}
|
|
23104
|
-
|
|
23105
|
-
|
|
23106
|
-
|
|
23107
|
-
|
|
23108
|
-
|
|
23109
|
-
|
|
23110
|
-
|
|
23111
|
-
|
|
23112
|
-
};
|
|
23113
|
-
};
|
|
23114
|
-
/**
|
|
23115
|
-
* Only keeps recognized keys, flatten nested values (to allow having "." in keys),
|
|
23116
|
-
* pushes warnings and errors to the given arrays; returns null in case of error
|
|
23117
|
-
*/
|
|
23118
|
-
function parseConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
23119
|
-
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
23120
|
-
if (mandatoryKeys.length === 0)
|
|
23121
|
-
return null;
|
|
23122
|
-
outErrors.push(`The [${sectionName}] mandatory section is missing.`);
|
|
23123
|
-
return null;
|
|
23169
|
+
ngAfterViewChecked() {
|
|
23170
|
+
if (!this.initialized && !this.disabled) {
|
|
23171
|
+
const target = document.getElementById(this.targetId);
|
|
23172
|
+
if (target) {
|
|
23173
|
+
this.initializeIntersectionObserver(target);
|
|
23174
|
+
this.initialized = true;
|
|
23175
|
+
}
|
|
23176
|
+
}
|
|
23124
23177
|
}
|
|
23125
|
-
|
|
23126
|
-
|
|
23127
|
-
|
|
23128
|
-
|
|
23129
|
-
|
|
23130
|
-
|
|
23178
|
+
initializeIntersectionObserver(target) {
|
|
23179
|
+
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
23180
|
+
entries.forEach((entry) => {
|
|
23181
|
+
this.inView = entry.isIntersecting;
|
|
23182
|
+
this.changeDetector.detectChanges();
|
|
23183
|
+
});
|
|
23184
|
+
}, {
|
|
23185
|
+
root: null,
|
|
23186
|
+
rootMargin: '-30% 0% -60% 0%',
|
|
23187
|
+
});
|
|
23188
|
+
this.intersectionObserver.observe(target);
|
|
23131
23189
|
}
|
|
23132
|
-
|
|
23133
|
-
|
|
23134
|
-
|
|
23190
|
+
ngOnDestroy() {
|
|
23191
|
+
this.observer.disconnect();
|
|
23192
|
+
if (this.intersectionObserver) {
|
|
23193
|
+
this.intersectionObserver.disconnect();
|
|
23194
|
+
}
|
|
23135
23195
|
}
|
|
23136
|
-
|
|
23196
|
+
refreshDisabledState() {
|
|
23197
|
+
const targetNotPresent = !document.getElementById(this.targetId);
|
|
23198
|
+
if (targetNotPresent !== this.disabled) {
|
|
23199
|
+
this.disabled = targetNotPresent;
|
|
23200
|
+
this.changeDetector.detectChanges();
|
|
23201
|
+
}
|
|
23202
|
+
}
|
|
23203
|
+
scrollToTarget() {
|
|
23204
|
+
const target = document.getElementById(this.targetId);
|
|
23205
|
+
if (!target)
|
|
23206
|
+
return;
|
|
23207
|
+
target.scrollIntoView({
|
|
23208
|
+
behavior: 'smooth',
|
|
23209
|
+
block: 'start',
|
|
23210
|
+
});
|
|
23211
|
+
}
|
|
23212
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
23213
|
+
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 }); }
|
|
23137
23214
|
}
|
|
23138
|
-
|
|
23139
|
-
|
|
23140
|
-
|
|
23141
|
-
|
|
23142
|
-
|
|
23143
|
-
|
|
23144
|
-
|
|
23145
|
-
|
|
23215
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, decorators: [{
|
|
23216
|
+
type: Directive,
|
|
23217
|
+
args: [{
|
|
23218
|
+
selector: '[gnUiAnchorLink]',
|
|
23219
|
+
standalone: true,
|
|
23220
|
+
}]
|
|
23221
|
+
}], propDecorators: { targetId: [{
|
|
23222
|
+
type: Input,
|
|
23223
|
+
args: ['gnUiAnchorLink']
|
|
23224
|
+
}], disabledClass: [{
|
|
23225
|
+
type: Input,
|
|
23226
|
+
args: ['gnUiAnchorLinkDisabledClass']
|
|
23227
|
+
}], enabledClass: [{
|
|
23228
|
+
type: Input,
|
|
23229
|
+
args: ['gnUiAnchorLinkEnabledClass']
|
|
23230
|
+
}], inViewClass: [{
|
|
23231
|
+
type: Input,
|
|
23232
|
+
args: ['gnUiAnchorLinkInViewClass']
|
|
23233
|
+
}], outOfViewClass: [{
|
|
23234
|
+
type: Input,
|
|
23235
|
+
args: ['gnUiAnchorLinkOutOfViewClass']
|
|
23236
|
+
}], elementClass: [{
|
|
23237
|
+
type: HostBinding,
|
|
23238
|
+
args: ['class']
|
|
23239
|
+
}], scrollToTarget: [{
|
|
23240
|
+
type: HostListener,
|
|
23241
|
+
args: ['click']
|
|
23242
|
+
}] } });
|
|
23243
|
+
|
|
23244
|
+
class PaginationDotsComponent {
|
|
23245
|
+
constructor() {
|
|
23246
|
+
this.containerClass = '';
|
|
23146
23247
|
}
|
|
23147
|
-
|
|
23248
|
+
// 1-based
|
|
23249
|
+
get steps() {
|
|
23250
|
+
return Array.from({ length: this.listComponent.pagesCount }, (_, i) => i + 1);
|
|
23251
|
+
}
|
|
23252
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23253
|
+
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: [
|
|
23254
|
+
provideIcons({
|
|
23255
|
+
iconoirNavArrowRight,
|
|
23256
|
+
iconoirNavArrowLeft,
|
|
23257
|
+
}),
|
|
23258
|
+
] }); }
|
|
23148
23259
|
}
|
|
23149
|
-
|
|
23150
|
-
|
|
23151
|
-
|
|
23152
|
-
|
|
23153
|
-
|
|
23154
|
-
|
|
23155
|
-
|
|
23156
|
-
|
|
23157
|
-
|
|
23260
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, decorators: [{
|
|
23261
|
+
type: Component,
|
|
23262
|
+
args: [{ selector: 'gn-ui-pagination-dots', standalone: true, imports: [CommonModule], viewProviders: [
|
|
23263
|
+
provideIcons({
|
|
23264
|
+
iconoirNavArrowRight,
|
|
23265
|
+
iconoirNavArrowLeft,
|
|
23266
|
+
}),
|
|
23267
|
+
], 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"] }]
|
|
23268
|
+
}], propDecorators: { listComponent: [{
|
|
23269
|
+
type: Input
|
|
23270
|
+
}], containerClass: [{
|
|
23271
|
+
type: Input
|
|
23272
|
+
}] } });
|
|
23273
|
+
|
|
23274
|
+
class CarouselComponent {
|
|
23275
|
+
constructor() {
|
|
23276
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
23277
|
+
this.containerClass = '';
|
|
23278
|
+
this.stepsContainerClass = 'w-full bottom-0 top-auto';
|
|
23279
|
+
this.currentStepChange = new EventEmitter();
|
|
23280
|
+
this.steps = [];
|
|
23281
|
+
this.currentStep = 0;
|
|
23282
|
+
this.refreshSteps = () => {
|
|
23283
|
+
this.steps = this.emblaApi.scrollSnapList();
|
|
23284
|
+
this.currentStep = this.emblaApi.selectedScrollSnap();
|
|
23285
|
+
this.currentStepChange.emit(this.currentStep);
|
|
23286
|
+
this.changeDetector.detectChanges();
|
|
23287
|
+
};
|
|
23158
23288
|
}
|
|
23159
|
-
|
|
23160
|
-
|
|
23161
|
-
return
|
|
23289
|
+
// Paginable API
|
|
23290
|
+
get isFirstPage() {
|
|
23291
|
+
return this.currentStep === 0;
|
|
23162
23292
|
}
|
|
23163
|
-
|
|
23164
|
-
|
|
23165
|
-
return null;
|
|
23293
|
+
get isLastPage() {
|
|
23294
|
+
return this.currentStep === this.steps.length - 1;
|
|
23166
23295
|
}
|
|
23167
|
-
|
|
23168
|
-
|
|
23169
|
-
function checkMetadataLanguage(parsedConfigSection, outWarnings) {
|
|
23170
|
-
const lang2 = toLang2(parsedConfigSection.metadata_language.toLowerCase());
|
|
23171
|
-
if (lang2?.length !== 2) {
|
|
23172
|
-
outWarnings.push(`In the [global] section: metadata_language = "${parsedConfigSection.metadata_language}" is not a recognized ISO 639 language code`);
|
|
23296
|
+
get currentPage() {
|
|
23297
|
+
return this.currentStep + 1; // this is 1-based
|
|
23173
23298
|
}
|
|
23174
|
-
|
|
23175
|
-
|
|
23176
|
-
function checkNewRecordDefaultLanguage(parsedConfigSection, outWarnings) {
|
|
23177
|
-
const lang2 = toLang2(parsedConfigSection.new_record_default_language.toLowerCase());
|
|
23178
|
-
if (!(lang2 in LANG_2_TO_3_MAPPER)) {
|
|
23179
|
-
outWarnings.push(`In the [editing] section: new_record_default_language = "${parsedConfigSection.new_record_default_language}" is not a recognized ISO 639 language code`);
|
|
23180
|
-
return {
|
|
23181
|
-
...parsedConfigSection,
|
|
23182
|
-
new_record_default_language: undefined,
|
|
23183
|
-
};
|
|
23299
|
+
get pagesCount() {
|
|
23300
|
+
return this.steps.length;
|
|
23184
23301
|
}
|
|
23185
|
-
|
|
23186
|
-
|
|
23187
|
-
new_record_default_language: lang2,
|
|
23188
|
-
};
|
|
23189
|
-
}
|
|
23190
|
-
function checkNewRecordStandard(parsedConfigSection, outWarnings) {
|
|
23191
|
-
const standard = parsedConfigSection.new_record_standard;
|
|
23192
|
-
const normalizedStandard = typeof standard === 'string' ? standard.trim().toLowerCase() : null;
|
|
23193
|
-
if (normalizedStandard === 'iso19139' ||
|
|
23194
|
-
normalizedStandard === 'iso19115-3') {
|
|
23195
|
-
return {
|
|
23196
|
-
...parsedConfigSection,
|
|
23197
|
-
new_record_standard: normalizedStandard,
|
|
23198
|
-
};
|
|
23302
|
+
goToPage(stepIndex) {
|
|
23303
|
+
this.emblaApi.scrollTo(stepIndex - 1); // this is 0-based
|
|
23199
23304
|
}
|
|
23200
|
-
|
|
23201
|
-
|
|
23202
|
-
|
|
23203
|
-
|
|
23204
|
-
}
|
|
23305
|
+
goToPrevPage() {
|
|
23306
|
+
if (this.isFirstPage)
|
|
23307
|
+
return;
|
|
23308
|
+
this.emblaApi.scrollPrev();
|
|
23309
|
+
}
|
|
23310
|
+
goToNextPage() {
|
|
23311
|
+
if (this.isLastPage)
|
|
23312
|
+
return;
|
|
23313
|
+
this.emblaApi.scrollNext();
|
|
23314
|
+
}
|
|
23315
|
+
ngAfterViewInit() {
|
|
23316
|
+
this.emblaApi = EmblaCarousel(this.carouselOverflowContainer.nativeElement, {
|
|
23317
|
+
duration: 15,
|
|
23318
|
+
});
|
|
23319
|
+
this.emblaApi
|
|
23320
|
+
.on('init', this.refreshSteps)
|
|
23321
|
+
.on('reInit', this.refreshSteps)
|
|
23322
|
+
.on('select', this.refreshSteps);
|
|
23323
|
+
}
|
|
23324
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23325
|
+
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 }); }
|
|
23205
23326
|
}
|
|
23327
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, decorators: [{
|
|
23328
|
+
type: Component,
|
|
23329
|
+
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"] }]
|
|
23330
|
+
}], propDecorators: { carouselOverflowContainer: [{
|
|
23331
|
+
type: ViewChild,
|
|
23332
|
+
args: ['carouselOverflowContainer']
|
|
23333
|
+
}], containerClass: [{
|
|
23334
|
+
type: Input
|
|
23335
|
+
}], stepsContainerClass: [{
|
|
23336
|
+
type: Input
|
|
23337
|
+
}], currentStepChange: [{
|
|
23338
|
+
type: Output
|
|
23339
|
+
}] } });
|
|
23206
23340
|
|
|
23207
|
-
|
|
23208
|
-
|
|
23209
|
-
|
|
23210
|
-
|
|
23211
|
-
|
|
23212
|
-
|
|
23213
|
-
|
|
23214
|
-
|
|
23215
|
-
|
|
23216
|
-
|
|
23217
|
-
|
|
23218
|
-
|
|
23341
|
+
class ProgressBarComponent {
|
|
23342
|
+
constructor() {
|
|
23343
|
+
this.value = 0;
|
|
23344
|
+
this.type = 'default';
|
|
23345
|
+
}
|
|
23346
|
+
get progress() {
|
|
23347
|
+
return this.value > 0 ? (this.value < 100 ? this.value : 100) : 0;
|
|
23348
|
+
}
|
|
23349
|
+
get color() {
|
|
23350
|
+
switch (this.type) {
|
|
23351
|
+
case 'default':
|
|
23352
|
+
return {
|
|
23353
|
+
outerBar: 'bg-gray-200',
|
|
23354
|
+
innerBar: 'bg-gray-100',
|
|
23355
|
+
text: 'text-gray-900',
|
|
23356
|
+
};
|
|
23357
|
+
case 'primary':
|
|
23358
|
+
return {
|
|
23359
|
+
outerBar: 'bg-primary',
|
|
23360
|
+
innerBar: 'bg-primary-lighter',
|
|
23361
|
+
text: 'text-white',
|
|
23362
|
+
};
|
|
23363
|
+
case 'secondary':
|
|
23364
|
+
return {
|
|
23365
|
+
outerBar: 'bg-secondary',
|
|
23366
|
+
innerBar: 'bg-secondary-lighter',
|
|
23367
|
+
text: 'text-white',
|
|
23368
|
+
};
|
|
23369
|
+
case 'light':
|
|
23370
|
+
return {
|
|
23371
|
+
outerBar: 'bg-primary-white',
|
|
23372
|
+
innerBar: 'bg-primary',
|
|
23373
|
+
text: 'text-main',
|
|
23374
|
+
};
|
|
23375
|
+
}
|
|
23219
23376
|
}
|
|
23377
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23378
|
+
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"] }); }
|
|
23220
23379
|
}
|
|
23380
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, decorators: [{
|
|
23381
|
+
type: Component,
|
|
23382
|
+
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"] }]
|
|
23383
|
+
}], propDecorators: { value: [{
|
|
23384
|
+
type: Input
|
|
23385
|
+
}], type: [{
|
|
23386
|
+
type: Input
|
|
23387
|
+
}] } });
|
|
23221
23388
|
|
|
23222
|
-
|
|
23223
|
-
|
|
23224
|
-
|
|
23225
|
-
|
|
23226
|
-
|
|
23227
|
-
|
|
23228
|
-
|
|
23229
|
-
|
|
23230
|
-
|
|
23231
|
-
}
|
|
23232
|
-
|
|
23233
|
-
|
|
23234
|
-
|
|
23235
|
-
|
|
23236
|
-
|
|
23237
|
-
}
|
|
23238
|
-
|
|
23239
|
-
|
|
23240
|
-
|
|
23241
|
-
}
|
|
23242
|
-
|
|
23243
|
-
|
|
23244
|
-
|
|
23245
|
-
|
|
23246
|
-
|
|
23247
|
-
function getOptionalEditorConfig() {
|
|
23248
|
-
return editorConfig;
|
|
23249
|
-
}
|
|
23250
|
-
let metadataQualityConfig = null;
|
|
23251
|
-
function getMetadataQualityConfig() {
|
|
23252
|
-
return (metadataQualityConfig ||
|
|
23253
|
-
{
|
|
23254
|
-
ENABLED: false,
|
|
23389
|
+
class PopoverComponent {
|
|
23390
|
+
constructor() {
|
|
23391
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
23392
|
+
this.renderer = inject(Renderer2);
|
|
23393
|
+
}
|
|
23394
|
+
getContent() {
|
|
23395
|
+
if (this.content instanceof TemplateRef) {
|
|
23396
|
+
if (this.view) {
|
|
23397
|
+
this.view.destroy();
|
|
23398
|
+
}
|
|
23399
|
+
this.view = this.viewContainerRef.createEmbeddedView(this.content);
|
|
23400
|
+
this.view.detectChanges();
|
|
23401
|
+
const wrapper = this.renderer.createElement('div'); // Create a wrapper div
|
|
23402
|
+
this.view.rootNodes.forEach((node) => {
|
|
23403
|
+
this.renderer.appendChild(wrapper, node); // Append each root node to the wrapper
|
|
23404
|
+
});
|
|
23405
|
+
return wrapper;
|
|
23406
|
+
}
|
|
23407
|
+
return this.content;
|
|
23408
|
+
}
|
|
23409
|
+
ngAfterViewInit() {
|
|
23410
|
+
this.tippyInstance = tippy(this.popoverContent.nativeElement, {
|
|
23411
|
+
content: this.getContent(),
|
|
23412
|
+
allowHTML: true,
|
|
23413
|
+
theme: this.theme,
|
|
23255
23414
|
});
|
|
23256
|
-
}
|
|
23257
|
-
|
|
23258
|
-
|
|
23259
|
-
|
|
23260
|
-
|
|
23261
|
-
|
|
23262
|
-
}
|
|
23263
|
-
let appConfigLoaded = false;
|
|
23264
|
-
function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
|
|
23265
|
-
console.log(`[geonetwork-ui] Loading application configuration from ${configUrl}`);
|
|
23266
|
-
return fetch(configUrl)
|
|
23267
|
-
.then((resp) => {
|
|
23268
|
-
if (!resp.ok)
|
|
23269
|
-
throw new Error('Configuration file could not be loaded');
|
|
23270
|
-
return resp.text();
|
|
23271
|
-
})
|
|
23272
|
-
.then((conf) => {
|
|
23273
|
-
let parsed;
|
|
23274
|
-
try {
|
|
23275
|
-
parsed = TOML.parse(conf, { joiner: '\n', bigint: false });
|
|
23276
|
-
}
|
|
23277
|
-
catch (e) {
|
|
23278
|
-
throw new Error(`An error occurred when parsing the configuration file: ${e.message}`);
|
|
23279
|
-
}
|
|
23280
|
-
const errors = [];
|
|
23281
|
-
const warnings = [];
|
|
23282
|
-
let parsedGlobalSection = parseConfigSection(parsed, 'global', ['geonetwork4_api_url'], [
|
|
23283
|
-
'datahub_url',
|
|
23284
|
-
'edit_url_template',
|
|
23285
|
-
'proxy_path',
|
|
23286
|
-
'metadata_language',
|
|
23287
|
-
'login_url',
|
|
23288
|
-
'logout_url',
|
|
23289
|
-
'settings_url',
|
|
23290
|
-
'web_component_embedder_url',
|
|
23291
|
-
'languages',
|
|
23292
|
-
'contact_email',
|
|
23293
|
-
'reuse_form_url',
|
|
23294
|
-
], warnings, errors);
|
|
23295
|
-
if (parsedGlobalSection?.metadata_language) {
|
|
23296
|
-
parsedGlobalSection = checkMetadataLanguage(parsedGlobalSection, warnings);
|
|
23297
|
-
}
|
|
23298
|
-
globalConfig =
|
|
23299
|
-
parsedGlobalSection === null
|
|
23300
|
-
? null
|
|
23301
|
-
: {
|
|
23302
|
-
GN4_API_URL: parsedGlobalSection.geonetwork4_api_url,
|
|
23303
|
-
DATAHUB_URL: parsedGlobalSection.datahub_url,
|
|
23304
|
-
EDIT_URL_TEMPLATE: parsedGlobalSection.edit_url_template,
|
|
23305
|
-
PROXY_PATH: parsedGlobalSection.proxy_path,
|
|
23306
|
-
METADATA_LANGUAGE: parsedGlobalSection.metadata_language
|
|
23307
|
-
? parsedGlobalSection.metadata_language.toLowerCase()
|
|
23308
|
-
: undefined,
|
|
23309
|
-
LOGIN_URL: parsedGlobalSection.login_url,
|
|
23310
|
-
LOGOUT_URL: parsedGlobalSection.logout_url,
|
|
23311
|
-
SETTINGS_URL: parsedGlobalSection.settings_url,
|
|
23312
|
-
WEB_COMPONENT_EMBEDDER_URL: parsedGlobalSection.web_component_embedder_url,
|
|
23313
|
-
LANGUAGES: parsedGlobalSection.languages,
|
|
23314
|
-
CONTACT_EMAIL: parsedGlobalSection.contact_email,
|
|
23315
|
-
REUSE_FORM_URL: parsedGlobalSection.reuse_form_url,
|
|
23316
|
-
};
|
|
23317
|
-
const parsedLayersSections = parseMultiConfigSection(parsed, 'map_layer', ['type'], ['name', 'url', 'data', 'styleUrl', 'accessToken'], warnings, errors);
|
|
23318
|
-
const parsedMapSection = parseConfigSection(parsed, 'map', [], [
|
|
23319
|
-
'max_zoom',
|
|
23320
|
-
'do_not_tile_wms',
|
|
23321
|
-
'max_extent',
|
|
23322
|
-
'max_feature_count',
|
|
23323
|
-
'baselayer',
|
|
23324
|
-
'do_not_use_default_basemap',
|
|
23325
|
-
'external_viewer_url_template',
|
|
23326
|
-
'external_viewer_open_new_tab',
|
|
23327
|
-
], warnings, errors);
|
|
23328
|
-
mapConfig =
|
|
23329
|
-
parsedMapSection === null || parsedLayersSections === null
|
|
23330
|
-
? null
|
|
23331
|
-
: {
|
|
23332
|
-
MAX_ZOOM: parsedMapSection.max_zoom,
|
|
23333
|
-
DO_NOT_TILE_WMS: parsedMapSection.do_not_tile_wms,
|
|
23334
|
-
MAX_EXTENT: parsedMapSection.max_extent,
|
|
23335
|
-
MAX_FEATURE_COUNT: parsedMapSection.max_feature_count,
|
|
23336
|
-
EXTERNAL_VIEWER_URL_TEMPLATE: parsedMapSection.external_viewer_url_template,
|
|
23337
|
-
EXTERNAL_VIEWER_OPEN_NEW_TAB: parsedMapSection.external_viewer_open_new_tab,
|
|
23338
|
-
DO_NOT_USE_DEFAULT_BASEMAP: !!parsedMapSection.do_not_use_default_basemap,
|
|
23339
|
-
MAP_LAYERS: parsedLayersSections.map((map_layer) => ({
|
|
23340
|
-
TYPE: map_layer.type,
|
|
23341
|
-
URL: map_layer.url,
|
|
23342
|
-
NAME: map_layer.name,
|
|
23343
|
-
DATA: map_layer.data,
|
|
23344
|
-
STYLE_URL: map_layer.styleUrl,
|
|
23345
|
-
ACCESS_TOKEN: map_layer.accessToken,
|
|
23346
|
-
})),
|
|
23347
|
-
};
|
|
23348
|
-
const parsedThemeSection = parseConfigSection(parsed, 'theme', ['primary_color', 'secondary_color', 'main_color', 'background_color'], [
|
|
23349
|
-
'header_foreground_color',
|
|
23350
|
-
'main_font',
|
|
23351
|
-
'title_font',
|
|
23352
|
-
'fonts_stylesheet_url',
|
|
23353
|
-
'thumbnail_placeholder',
|
|
23354
|
-
'header_background',
|
|
23355
|
-
'favicon',
|
|
23356
|
-
], warnings, errors);
|
|
23357
|
-
themeConfig =
|
|
23358
|
-
parsedThemeSection === null
|
|
23359
|
-
? null
|
|
23360
|
-
: {
|
|
23361
|
-
PRIMARY_COLOR: parsedThemeSection.primary_color,
|
|
23362
|
-
SECONDARY_COLOR: parsedThemeSection.secondary_color,
|
|
23363
|
-
MAIN_COLOR: parsedThemeSection.main_color,
|
|
23364
|
-
BACKGROUND_COLOR: parsedThemeSection.background_color,
|
|
23365
|
-
HEADER_FOREGROUND_COLOR: parsedThemeSection.header_foreground_color,
|
|
23366
|
-
THUMBNAIL_PLACEHOLDER: parsedThemeSection.thumbnail_placeholder,
|
|
23367
|
-
HEADER_BACKGROUND: parsedThemeSection.header_background,
|
|
23368
|
-
TITLE_FONT: parsedThemeSection.title_font,
|
|
23369
|
-
MAIN_FONT: parsedThemeSection.main_font,
|
|
23370
|
-
FONTS_STYLESHEET_URL: parsedThemeSection.fonts_stylesheet_url,
|
|
23371
|
-
FAVICON: parsedThemeSection.favicon,
|
|
23372
|
-
};
|
|
23373
|
-
const parsedSearchSection = parseConfigSection(parsed, 'search', [], [
|
|
23374
|
-
'record_kind_quick_filter',
|
|
23375
|
-
'filter_geometry_data',
|
|
23376
|
-
'filter_geometry_url',
|
|
23377
|
-
'do_not_use_default_search_preset',
|
|
23378
|
-
'search_preset',
|
|
23379
|
-
'advanced_filters',
|
|
23380
|
-
'limit',
|
|
23381
|
-
'spatial_extent_max_file_size',
|
|
23382
|
-
], warnings, errors);
|
|
23383
|
-
const parsedSearchParams = parseMultiConfigSection(parsed, 'search_preset', ['name'], ['sort', 'filters'], warnings, errors);
|
|
23384
|
-
searchConfig =
|
|
23385
|
-
parsedSearchSection === null
|
|
23386
|
-
? null
|
|
23387
|
-
: {
|
|
23388
|
-
RECORD_KIND_QUICK_FILTER: parsedSearchSection.record_kind_quick_filter,
|
|
23389
|
-
FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
|
|
23390
|
-
FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
|
|
23391
|
-
DO_NOT_USE_DEFAULT_SEARCH_PRESET: !!parsedSearchSection.do_not_use_default_search_preset,
|
|
23392
|
-
SEARCH_PRESET: parsedSearchParams.map((param) => ({
|
|
23393
|
-
sort: param.sort,
|
|
23394
|
-
name: param.name,
|
|
23395
|
-
filters: param.filters,
|
|
23396
|
-
})),
|
|
23397
|
-
ADVANCED_FILTERS: parsedSearchSection.advanced_filters,
|
|
23398
|
-
LIMIT: parsedSearchSection.limit,
|
|
23399
|
-
SPATIAL_EXTENT_MAX_FILE_SIZE: parsedSearchSection.spatial_extent_max_file_size,
|
|
23400
|
-
};
|
|
23401
|
-
const parsedMetadataQualitySection = parseConfigSection(parsed, 'metadata-quality', [], ['enabled'], warnings, errors);
|
|
23402
|
-
metadataQualityConfig =
|
|
23403
|
-
parsedMetadataQualitySection === null
|
|
23404
|
-
? null
|
|
23405
|
-
: {
|
|
23406
|
-
ENABLED: parsedMetadataQualitySection.enabled,
|
|
23407
|
-
SORTABLE: parsedMetadataQualitySection.sortable,
|
|
23408
|
-
};
|
|
23409
|
-
let parsedEditingSection = parseConfigSection(parsed, 'editing', [], ['new_record_default_language', 'new_record_standard'], warnings, errors);
|
|
23410
|
-
if (parsedEditingSection !== null &&
|
|
23411
|
-
parsedEditingSection.new_record_default_language !== undefined) {
|
|
23412
|
-
parsedEditingSection = checkNewRecordDefaultLanguage(parsedEditingSection, warnings);
|
|
23415
|
+
}
|
|
23416
|
+
ngOnChanges(changes) {
|
|
23417
|
+
if (changes['theme']) {
|
|
23418
|
+
this.theme = changes['theme'].currentValue;
|
|
23419
|
+
if (this.tippyInstance) {
|
|
23420
|
+
this.tippyInstance.setProps({ theme: this.theme });
|
|
23421
|
+
}
|
|
23413
23422
|
}
|
|
23414
|
-
if (
|
|
23415
|
-
|
|
23416
|
-
|
|
23423
|
+
if (changes['content']) {
|
|
23424
|
+
this.content = changes['content'].currentValue;
|
|
23425
|
+
if (this.tippyInstance) {
|
|
23426
|
+
this.tippyInstance.setContent(this.getContent());
|
|
23427
|
+
}
|
|
23417
23428
|
}
|
|
23418
|
-
|
|
23419
|
-
|
|
23420
|
-
|
|
23421
|
-
|
|
23422
|
-
NEW_RECORD_DEFAULT_LANGUAGE: parsedEditingSection.new_record_default_language,
|
|
23423
|
-
NEW_RECORD_STANDARD: parsedEditingSection.new_record_standard,
|
|
23424
|
-
};
|
|
23425
|
-
customTranslations = parseTranslationsConfigSection(parsed, 'translations');
|
|
23426
|
-
if (errors.length) {
|
|
23427
|
-
throw new Error(`One or more mandatory settings were missing from the configuration file.
|
|
23428
|
-
${errors.join('\n')}`);
|
|
23429
|
+
}
|
|
23430
|
+
ngOnDestroy() {
|
|
23431
|
+
if (this.tippyInstance) {
|
|
23432
|
+
this.tippyInstance.destroy();
|
|
23429
23433
|
}
|
|
23430
|
-
|
|
23431
|
-
|
|
23432
|
-
${warnings.join('\n')}`);
|
|
23434
|
+
if (this.view) {
|
|
23435
|
+
this.view.destroy();
|
|
23433
23436
|
}
|
|
23434
|
-
|
|
23435
|
-
});
|
|
23436
|
-
}
|
|
23437
|
-
function isConfigLoaded() {
|
|
23438
|
-
return appConfigLoaded;
|
|
23439
|
-
}
|
|
23440
|
-
function _reset() {
|
|
23441
|
-
globalConfig = null;
|
|
23442
|
-
themeConfig = null;
|
|
23443
|
-
editorConfig = null;
|
|
23444
|
-
customTranslations = null;
|
|
23445
|
-
}
|
|
23446
|
-
const TRANSLATE_WITH_OVERRIDES_CONFIG = {
|
|
23447
|
-
compiler: {
|
|
23448
|
-
provide: TranslateCompiler,
|
|
23449
|
-
useClass: TranslateMessageFormatCompiler,
|
|
23450
|
-
},
|
|
23451
|
-
loader: [
|
|
23452
|
-
{
|
|
23453
|
-
provide: TRANSLATE_HTTP_LOADER_CONFIG,
|
|
23454
|
-
useValue: {
|
|
23455
|
-
prefix: './assets/i18n/',
|
|
23456
|
-
suffix: '.json',
|
|
23457
|
-
},
|
|
23458
|
-
},
|
|
23459
|
-
{
|
|
23460
|
-
provide: TranslateLoader,
|
|
23461
|
-
useClass: FileWithOverridesTranslateLoader,
|
|
23462
|
-
deps: [HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
|
|
23463
|
-
},
|
|
23464
|
-
],
|
|
23465
|
-
};
|
|
23466
|
-
|
|
23467
|
-
const okAppConfigFixture = () => `
|
|
23468
|
-
[global]
|
|
23469
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23470
|
-
proxy_path = "/proxy/?url="
|
|
23471
|
-
metadata_language = "fre"
|
|
23472
|
-
login_url = "/cas/login?service="
|
|
23473
|
-
logout_url = "/geonetwork/signout"
|
|
23474
|
-
settings_url = "/geonetwork/settings"
|
|
23475
|
-
web_component_embedder_url = "/datahub/wc-embedder.html"
|
|
23476
|
-
|
|
23477
|
-
[map]
|
|
23478
|
-
max_zoom = 10
|
|
23479
|
-
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
23480
|
-
do_not_use_default_basemap = false
|
|
23481
|
-
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
23482
|
-
external_viewer_open_new_tab = true
|
|
23483
|
-
[[map_layer]]
|
|
23484
|
-
type = "wms"
|
|
23485
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23486
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23487
|
-
[[map_layer]]
|
|
23488
|
-
type = "wfs"
|
|
23489
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23490
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23491
|
-
|
|
23492
|
-
[theme]
|
|
23493
|
-
primary_color = "#093564"
|
|
23494
|
-
secondary_color = "#c2e9dc"
|
|
23495
|
-
main_color = "#212029" # All-purpose text color
|
|
23496
|
-
background_color = "#fdfbff"
|
|
23497
|
-
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
23498
|
-
header_background = 'teal'
|
|
23499
|
-
header_foreground_color = "#872e2e"
|
|
23500
|
-
main_font = 'sans-serif'
|
|
23501
|
-
title_font = 'serif'
|
|
23502
|
-
fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
|
|
23503
|
-
|
|
23504
|
-
[search]
|
|
23505
|
-
record_kind_quick_filter = false
|
|
23506
|
-
filter_geometry_url = 'https://my.domain.org/geom.json'
|
|
23507
|
-
do_not_use_default_search_preset = false
|
|
23508
|
-
advanced_filters = ['publicationYear', 'documentStandard', 'inspireKeyword', 'topic', 'license']
|
|
23509
|
-
|
|
23510
|
-
[[search_preset]]
|
|
23511
|
-
sort = "-createDate"
|
|
23512
|
-
name = 'filterByOrgs'
|
|
23513
|
-
filters.q = 'Carto'
|
|
23514
|
-
filters.organisation = ['Org1', 'Org2']
|
|
23515
|
-
filters.format = ['ESRI Shapefile']
|
|
23516
|
-
filters.topic = ['boundaries']
|
|
23517
|
-
filters.publicationYear = ['2023', '2022']
|
|
23518
|
-
filters.spatial = ['yes']
|
|
23519
|
-
|
|
23520
|
-
[translations.en]
|
|
23521
|
-
"my.first.key" = 'First label.'
|
|
23522
|
-
"my.second.key" = """
|
|
23523
|
-
Second label,
|
|
23524
|
-
on two lines."""
|
|
23525
|
-
|
|
23526
|
-
[translations.de]
|
|
23527
|
-
my.first.key = 'Erste Etikett.'
|
|
23528
|
-
|
|
23529
|
-
[translations.fr]
|
|
23530
|
-
my.sample.text = "Un bon exemple de texte."
|
|
23531
|
-
"my.quoted.text" = 'du texte entre guillements.'
|
|
23532
|
-
`;
|
|
23533
|
-
const appConfigWithTranslationFixture = () => okAppConfigFixture();
|
|
23534
|
-
const minimalAppConfigFixture = () => `
|
|
23535
|
-
[global]
|
|
23536
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23537
|
-
proxy_path = "/proxy/?url="
|
|
23538
|
-
|
|
23539
|
-
[theme]
|
|
23540
|
-
primary_color = "#093564"
|
|
23541
|
-
secondary_color = "#c2e9dc"
|
|
23542
|
-
main_color = "#212029" # All-purpose text color
|
|
23543
|
-
background_color = "#fdfbff"
|
|
23544
|
-
`;
|
|
23545
|
-
const mapConfigFixture = () => ({
|
|
23546
|
-
MAX_ZOOM: 10,
|
|
23547
|
-
MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
|
|
23548
|
-
DO_NOT_USE_DEFAULT_BASEMAP: false,
|
|
23549
|
-
DO_NOT_TILE_WMS: false,
|
|
23550
|
-
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}"}]}]',
|
|
23551
|
-
EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
|
|
23552
|
-
MAP_LAYERS: [
|
|
23553
|
-
{
|
|
23554
|
-
TYPE: 'xyz',
|
|
23555
|
-
URL: 'https://some-basemap-server',
|
|
23556
|
-
},
|
|
23557
|
-
{
|
|
23558
|
-
TYPE: 'wms',
|
|
23559
|
-
URL: 'https://some-wms-server',
|
|
23560
|
-
NAME: 'some_layername',
|
|
23561
|
-
},
|
|
23562
|
-
{
|
|
23563
|
-
TYPE: 'wfs',
|
|
23564
|
-
URL: 'https://some-wfs-server',
|
|
23565
|
-
NAME: 'some_layername',
|
|
23566
|
-
},
|
|
23567
|
-
],
|
|
23568
|
-
});
|
|
23569
|
-
const malformedConfigFixture = () => `
|
|
23570
|
-
{
|
|
23571
|
-
"I thought": "we were still doing json"
|
|
23437
|
+
}
|
|
23438
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23439
|
+
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: [""] }); }
|
|
23572
23440
|
}
|
|
23573
|
-
|
|
23574
|
-
|
|
23575
|
-
[
|
|
23576
|
-
|
|
23577
|
-
|
|
23578
|
-
|
|
23579
|
-
|
|
23580
|
-
|
|
23581
|
-
|
|
23582
|
-
|
|
23583
|
-
|
|
23584
|
-
proxy_path = "/proxy/?url="
|
|
23585
|
-
metadata_language = "abc"
|
|
23586
|
-
|
|
23587
|
-
[map]
|
|
23588
|
-
|
|
23589
|
-
[theme]
|
|
23590
|
-
primary_color = "#093564"
|
|
23591
|
-
secondary_color = "#c2e9dc"
|
|
23592
|
-
main_color = "#212029" # All-purpose text color
|
|
23593
|
-
background_color = "#fdfbff"
|
|
23594
|
-
`;
|
|
23595
|
-
const unrecognizedKeysConfigFixture = () => `
|
|
23596
|
-
[global]
|
|
23597
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23598
|
-
proxy_path = "/proxy/?url="
|
|
23599
|
-
metadata_language = "fre"
|
|
23600
|
-
another_path = '/whatever'
|
|
23601
|
-
|
|
23602
|
-
[map]
|
|
23603
|
-
max_zoom = 10
|
|
23604
|
-
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
23605
|
-
do_not_use_default_basemap = false
|
|
23606
|
-
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
23607
|
-
external_viewer_open_new_tab = true
|
|
23608
|
-
another_zoom = 15
|
|
23609
|
-
[[map_layer]]
|
|
23610
|
-
type = "wms"
|
|
23611
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23612
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23613
|
-
[[map_layer]]
|
|
23614
|
-
type = "wfs"
|
|
23615
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23616
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23617
|
-
another_layer = "wrong layer definition"
|
|
23618
|
-
|
|
23619
|
-
[theme]
|
|
23620
|
-
primary_color = "#093564"
|
|
23621
|
-
secondary_color = "#c2e9dc"
|
|
23622
|
-
main_color = "#212029" # All-purpose text color
|
|
23623
|
-
background_color = "#fdfbff"
|
|
23624
|
-
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
23625
|
-
header_background = 'teal'
|
|
23626
|
-
header_foreground_color = "#872e2e"
|
|
23627
|
-
main_font = 'sans-serif'
|
|
23628
|
-
title_font = 'serif'
|
|
23629
|
-
another_color = 'red'
|
|
23630
|
-
`;
|
|
23441
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, decorators: [{
|
|
23442
|
+
type: Component,
|
|
23443
|
+
args: [{ selector: 'gn-ui-popover', standalone: true, imports: [], template: "<span #popoverContent>\n <ng-content></ng-content>\n</span>\n" }]
|
|
23444
|
+
}], propDecorators: { popoverContent: [{
|
|
23445
|
+
type: ViewChild,
|
|
23446
|
+
args: ['popoverContent', { static: false }]
|
|
23447
|
+
}], content: [{
|
|
23448
|
+
type: Input
|
|
23449
|
+
}], theme: [{
|
|
23450
|
+
type: Input
|
|
23451
|
+
}] } });
|
|
23631
23452
|
|
|
23632
|
-
|
|
23633
|
-
|
|
23634
|
-
|
|
23635
|
-
return {
|
|
23636
|
-
type: 'wms',
|
|
23637
|
-
url: config.URL,
|
|
23638
|
-
name: config.NAME,
|
|
23639
|
-
};
|
|
23640
|
-
case 'wfs':
|
|
23641
|
-
return {
|
|
23642
|
-
type: 'wfs',
|
|
23643
|
-
url: config.URL,
|
|
23644
|
-
featureType: config.NAME,
|
|
23645
|
-
};
|
|
23646
|
-
case 'xyz':
|
|
23647
|
-
return {
|
|
23648
|
-
type: config.TYPE,
|
|
23649
|
-
url: config.URL,
|
|
23650
|
-
};
|
|
23651
|
-
case 'geojson':
|
|
23652
|
-
return {
|
|
23653
|
-
type: config.TYPE,
|
|
23654
|
-
...(config.DATA ? { data: config.DATA } : { url: config.URL }),
|
|
23655
|
-
};
|
|
23656
|
-
case 'maplibre-style':
|
|
23657
|
-
return {
|
|
23658
|
-
type: config.TYPE,
|
|
23659
|
-
styleUrl: config.STYLE_URL,
|
|
23660
|
-
accessToken: config.ACCESS_TOKEN,
|
|
23661
|
-
};
|
|
23662
|
-
}
|
|
23453
|
+
class LoadingMaskComponent {
|
|
23454
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23455
|
+
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 }); }
|
|
23663
23456
|
}
|
|
23457
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, decorators: [{
|
|
23458
|
+
type: Component,
|
|
23459
|
+
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"] }]
|
|
23460
|
+
}], propDecorators: { message: [{
|
|
23461
|
+
type: Input
|
|
23462
|
+
}] } });
|
|
23664
23463
|
|
|
23665
|
-
class
|
|
23666
|
-
|
|
23667
|
-
|
|
23668
|
-
default: this.createStyleFunction(this.createGeometryStyles({
|
|
23669
|
-
color: isConfigLoaded() ? getThemeConfig().PRIMARY_COLOR : 'blue',
|
|
23670
|
-
})),
|
|
23671
|
-
defaultHL: this.createStyleFunction(this.createGeometryStyles({
|
|
23672
|
-
color: isConfigLoaded() ? getThemeConfig().SECONDARY_COLOR : 'red',
|
|
23673
|
-
isFocused: true,
|
|
23674
|
-
})),
|
|
23675
|
-
};
|
|
23676
|
-
}
|
|
23677
|
-
createGeometryStyles(options) {
|
|
23678
|
-
const { color, isFocused } = options;
|
|
23679
|
-
const zIndex = isFocused ? 10 : undefined;
|
|
23680
|
-
return {
|
|
23681
|
-
polygon: new Style({
|
|
23682
|
-
fill: new Fill({
|
|
23683
|
-
color: this.computeTransparentFillColor(color),
|
|
23684
|
-
}),
|
|
23685
|
-
stroke: new Stroke({
|
|
23686
|
-
color: 'white',
|
|
23687
|
-
width: 2,
|
|
23688
|
-
}),
|
|
23689
|
-
zIndex,
|
|
23690
|
-
}),
|
|
23691
|
-
point: new Style({
|
|
23692
|
-
image: new CircleStyle({
|
|
23693
|
-
fill: new Fill({
|
|
23694
|
-
color,
|
|
23695
|
-
}),
|
|
23696
|
-
stroke: new Stroke({
|
|
23697
|
-
color: 'white',
|
|
23698
|
-
width: isFocused ? 3 : 2,
|
|
23699
|
-
}),
|
|
23700
|
-
radius: isFocused ? 8 : 7,
|
|
23701
|
-
}),
|
|
23702
|
-
zIndex,
|
|
23703
|
-
}),
|
|
23704
|
-
line: [
|
|
23705
|
-
new Style({
|
|
23706
|
-
stroke: new Stroke({
|
|
23707
|
-
color: 'white',
|
|
23708
|
-
width: isFocused ? 8 : 6,
|
|
23709
|
-
}),
|
|
23710
|
-
zIndex,
|
|
23711
|
-
}),
|
|
23712
|
-
new Style({
|
|
23713
|
-
stroke: new Stroke({
|
|
23714
|
-
color,
|
|
23715
|
-
width: isFocused ? 3 : 2,
|
|
23716
|
-
}),
|
|
23717
|
-
zIndex,
|
|
23718
|
-
}),
|
|
23719
|
-
],
|
|
23720
|
-
};
|
|
23721
|
-
}
|
|
23722
|
-
createStyleFunction(styleByGeometryType) {
|
|
23723
|
-
return (feature) => {
|
|
23724
|
-
const geometryType = feature?.getGeometry()?.getType();
|
|
23725
|
-
switch (geometryType) {
|
|
23726
|
-
case 'LinearRing':
|
|
23727
|
-
case 'LineString':
|
|
23728
|
-
case 'MultiLineString':
|
|
23729
|
-
return styleByGeometryType.line;
|
|
23730
|
-
case 'Point':
|
|
23731
|
-
case 'MultiPoint':
|
|
23732
|
-
return styleByGeometryType.point;
|
|
23733
|
-
case 'Circle':
|
|
23734
|
-
case 'Polygon':
|
|
23735
|
-
case 'MultiPolygon':
|
|
23736
|
-
return styleByGeometryType.polygon;
|
|
23737
|
-
default:
|
|
23738
|
-
return styleByGeometryType.point;
|
|
23739
|
-
}
|
|
23740
|
-
};
|
|
23741
|
-
}
|
|
23742
|
-
computeTransparentFillColor(color, alpha = 0.25) {
|
|
23743
|
-
return chroma(color).alpha(alpha).css();
|
|
23744
|
-
}
|
|
23745
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: MapStyleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
23746
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: MapStyleService, providedIn: 'root' }); }
|
|
23464
|
+
class ColorScaleComponent {
|
|
23465
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23466
|
+
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: [""] }); }
|
|
23747
23467
|
}
|
|
23748
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type:
|
|
23749
|
-
type:
|
|
23750
|
-
args: [{
|
|
23751
|
-
providedIn: 'root',
|
|
23752
|
-
}]
|
|
23468
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, decorators: [{
|
|
23469
|
+
type: Component,
|
|
23470
|
+
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" }]
|
|
23753
23471
|
}] });
|
|
23754
23472
|
|
|
23755
|
-
|
|
23756
|
-
const colorSecondary = 'red';
|
|
23757
|
-
const colorStroke = 'white';
|
|
23758
|
-
const defaultMapStyleFixture = () => new Style({
|
|
23759
|
-
image: new Circle({
|
|
23760
|
-
fill: new Fill({
|
|
23761
|
-
color: colorPrimary,
|
|
23762
|
-
}),
|
|
23763
|
-
stroke: new Stroke({
|
|
23764
|
-
color: colorStroke,
|
|
23765
|
-
width: 2,
|
|
23766
|
-
}),
|
|
23767
|
-
radius: 5,
|
|
23768
|
-
}),
|
|
23769
|
-
fill: new Fill({
|
|
23770
|
-
color: 'rgba(0,0,255,0.25)',
|
|
23771
|
-
}),
|
|
23772
|
-
stroke: new Stroke({
|
|
23773
|
-
color: colorStroke,
|
|
23774
|
-
width: 2,
|
|
23775
|
-
}),
|
|
23776
|
-
});
|
|
23777
|
-
const defaultMapStyleHlFixture = () => new Style({
|
|
23778
|
-
image: new Circle({
|
|
23779
|
-
fill: new Fill({
|
|
23780
|
-
color: colorSecondary,
|
|
23781
|
-
}),
|
|
23782
|
-
stroke: new Stroke({
|
|
23783
|
-
color: colorStroke,
|
|
23784
|
-
width: 3,
|
|
23785
|
-
}),
|
|
23786
|
-
radius: 6,
|
|
23787
|
-
}),
|
|
23788
|
-
fill: new Fill({
|
|
23789
|
-
color: 'rgba(255,0,0,0.25)',
|
|
23790
|
-
}),
|
|
23791
|
-
stroke: new Stroke({
|
|
23792
|
-
color: colorSecondary,
|
|
23793
|
-
width: 3,
|
|
23794
|
-
}),
|
|
23795
|
-
});
|
|
23796
|
-
|
|
23797
|
-
class AnchorLinkDirective {
|
|
23473
|
+
class PopupAlertComponent {
|
|
23798
23474
|
constructor() {
|
|
23799
23475
|
this.changeDetector = inject(ChangeDetectorRef);
|
|
23800
|
-
this.
|
|
23801
|
-
this.
|
|
23802
|
-
|
|
23803
|
-
|
|
23804
|
-
this.inView = false;
|
|
23805
|
-
this.initialized = false;
|
|
23476
|
+
this.type = 'info';
|
|
23477
|
+
this.position = 'top';
|
|
23478
|
+
this.expanded = false;
|
|
23479
|
+
this.timeout = null;
|
|
23806
23480
|
}
|
|
23807
|
-
get
|
|
23808
|
-
|
|
23809
|
-
|
|
23810
|
-
}
|
|
23811
|
-
if (this.inView) {
|
|
23812
|
-
return `${this.inViewClass} ${this.enabledClass}`;
|
|
23813
|
-
}
|
|
23814
|
-
else {
|
|
23815
|
-
return `${this.outOfViewClass} ${this.enabledClass}`;
|
|
23816
|
-
}
|
|
23481
|
+
get showDuration() {
|
|
23482
|
+
const chars = this.content.nativeElement.innerHTML.length;
|
|
23483
|
+
return Math.max(3000, chars * 20);
|
|
23817
23484
|
}
|
|
23818
23485
|
ngOnInit() {
|
|
23819
|
-
this.
|
|
23820
|
-
childList: true,
|
|
23821
|
-
subtree: true,
|
|
23822
|
-
});
|
|
23823
|
-
this.refreshDisabledState();
|
|
23824
|
-
}
|
|
23825
|
-
ngAfterViewChecked() {
|
|
23826
|
-
if (!this.initialized && !this.disabled) {
|
|
23827
|
-
const target = document.getElementById(this.targetId);
|
|
23828
|
-
if (target) {
|
|
23829
|
-
this.initializeIntersectionObserver(target);
|
|
23830
|
-
this.initialized = true;
|
|
23831
|
-
}
|
|
23832
|
-
}
|
|
23833
|
-
}
|
|
23834
|
-
initializeIntersectionObserver(target) {
|
|
23835
|
-
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
23836
|
-
entries.forEach((entry) => {
|
|
23837
|
-
this.inView = entry.isIntersecting;
|
|
23838
|
-
this.changeDetector.detectChanges();
|
|
23839
|
-
});
|
|
23840
|
-
}, {
|
|
23841
|
-
root: null,
|
|
23842
|
-
rootMargin: '-30% 0% -60% 0%',
|
|
23843
|
-
});
|
|
23844
|
-
this.intersectionObserver.observe(target);
|
|
23845
|
-
}
|
|
23846
|
-
ngOnDestroy() {
|
|
23847
|
-
this.observer.disconnect();
|
|
23848
|
-
if (this.intersectionObserver) {
|
|
23849
|
-
this.intersectionObserver.disconnect();
|
|
23850
|
-
}
|
|
23851
|
-
}
|
|
23852
|
-
refreshDisabledState() {
|
|
23853
|
-
const targetNotPresent = !document.getElementById(this.targetId);
|
|
23854
|
-
if (targetNotPresent !== this.disabled) {
|
|
23855
|
-
this.disabled = targetNotPresent;
|
|
23856
|
-
this.changeDetector.detectChanges();
|
|
23857
|
-
}
|
|
23858
|
-
}
|
|
23859
|
-
scrollToTarget() {
|
|
23860
|
-
const target = document.getElementById(this.targetId);
|
|
23861
|
-
if (!target)
|
|
23862
|
-
return;
|
|
23863
|
-
target.scrollIntoView({
|
|
23864
|
-
behavior: 'smooth',
|
|
23865
|
-
block: 'start',
|
|
23866
|
-
});
|
|
23867
|
-
}
|
|
23868
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
23869
|
-
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 }); }
|
|
23870
|
-
}
|
|
23871
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, decorators: [{
|
|
23872
|
-
type: Directive,
|
|
23873
|
-
args: [{
|
|
23874
|
-
selector: '[gnUiAnchorLink]',
|
|
23875
|
-
standalone: true,
|
|
23876
|
-
}]
|
|
23877
|
-
}], propDecorators: { targetId: [{
|
|
23878
|
-
type: Input,
|
|
23879
|
-
args: ['gnUiAnchorLink']
|
|
23880
|
-
}], disabledClass: [{
|
|
23881
|
-
type: Input,
|
|
23882
|
-
args: ['gnUiAnchorLinkDisabledClass']
|
|
23883
|
-
}], enabledClass: [{
|
|
23884
|
-
type: Input,
|
|
23885
|
-
args: ['gnUiAnchorLinkEnabledClass']
|
|
23886
|
-
}], inViewClass: [{
|
|
23887
|
-
type: Input,
|
|
23888
|
-
args: ['gnUiAnchorLinkInViewClass']
|
|
23889
|
-
}], outOfViewClass: [{
|
|
23890
|
-
type: Input,
|
|
23891
|
-
args: ['gnUiAnchorLinkOutOfViewClass']
|
|
23892
|
-
}], elementClass: [{
|
|
23893
|
-
type: HostBinding,
|
|
23894
|
-
args: ['class']
|
|
23895
|
-
}], scrollToTarget: [{
|
|
23896
|
-
type: HostListener,
|
|
23897
|
-
args: ['click']
|
|
23898
|
-
}] } });
|
|
23899
|
-
|
|
23900
|
-
class PaginationDotsComponent {
|
|
23901
|
-
constructor() {
|
|
23902
|
-
this.containerClass = '';
|
|
23903
|
-
}
|
|
23904
|
-
// 1-based
|
|
23905
|
-
get steps() {
|
|
23906
|
-
return Array.from({ length: this.listComponent.pagesCount }, (_, i) => i + 1);
|
|
23907
|
-
}
|
|
23908
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23909
|
-
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: [
|
|
23910
|
-
provideIcons({
|
|
23911
|
-
iconoirNavArrowRight,
|
|
23912
|
-
iconoirNavArrowLeft,
|
|
23913
|
-
}),
|
|
23914
|
-
] }); }
|
|
23915
|
-
}
|
|
23916
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, decorators: [{
|
|
23917
|
-
type: Component,
|
|
23918
|
-
args: [{ selector: 'gn-ui-pagination-dots', standalone: true, imports: [CommonModule], viewProviders: [
|
|
23919
|
-
provideIcons({
|
|
23920
|
-
iconoirNavArrowRight,
|
|
23921
|
-
iconoirNavArrowLeft,
|
|
23922
|
-
}),
|
|
23923
|
-
], 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"] }]
|
|
23924
|
-
}], propDecorators: { listComponent: [{
|
|
23925
|
-
type: Input
|
|
23926
|
-
}], containerClass: [{
|
|
23927
|
-
type: Input
|
|
23928
|
-
}] } });
|
|
23929
|
-
|
|
23930
|
-
class CarouselComponent {
|
|
23931
|
-
constructor() {
|
|
23932
|
-
this.changeDetector = inject(ChangeDetectorRef);
|
|
23933
|
-
this.containerClass = '';
|
|
23934
|
-
this.stepsContainerClass = 'w-full bottom-0 top-auto';
|
|
23935
|
-
this.currentStepChange = new EventEmitter();
|
|
23936
|
-
this.steps = [];
|
|
23937
|
-
this.currentStep = 0;
|
|
23938
|
-
this.refreshSteps = () => {
|
|
23939
|
-
this.steps = this.emblaApi.scrollSnapList();
|
|
23940
|
-
this.currentStep = this.emblaApi.selectedScrollSnap();
|
|
23941
|
-
this.currentStepChange.emit(this.currentStep);
|
|
23942
|
-
this.changeDetector.detectChanges();
|
|
23943
|
-
};
|
|
23944
|
-
}
|
|
23945
|
-
// Paginable API
|
|
23946
|
-
get isFirstPage() {
|
|
23947
|
-
return this.currentStep === 0;
|
|
23948
|
-
}
|
|
23949
|
-
get isLastPage() {
|
|
23950
|
-
return this.currentStep === this.steps.length - 1;
|
|
23951
|
-
}
|
|
23952
|
-
get currentPage() {
|
|
23953
|
-
return this.currentStep + 1; // this is 1-based
|
|
23954
|
-
}
|
|
23955
|
-
get pagesCount() {
|
|
23956
|
-
return this.steps.length;
|
|
23957
|
-
}
|
|
23958
|
-
goToPage(stepIndex) {
|
|
23959
|
-
this.emblaApi.scrollTo(stepIndex - 1); // this is 0-based
|
|
23960
|
-
}
|
|
23961
|
-
goToPrevPage() {
|
|
23962
|
-
if (this.isFirstPage)
|
|
23963
|
-
return;
|
|
23964
|
-
this.emblaApi.scrollPrev();
|
|
23965
|
-
}
|
|
23966
|
-
goToNextPage() {
|
|
23967
|
-
if (this.isLastPage)
|
|
23968
|
-
return;
|
|
23969
|
-
this.emblaApi.scrollNext();
|
|
23970
|
-
}
|
|
23971
|
-
ngAfterViewInit() {
|
|
23972
|
-
this.emblaApi = EmblaCarousel(this.carouselOverflowContainer.nativeElement, {
|
|
23973
|
-
duration: 15,
|
|
23974
|
-
});
|
|
23975
|
-
this.emblaApi
|
|
23976
|
-
.on('init', this.refreshSteps)
|
|
23977
|
-
.on('reInit', this.refreshSteps)
|
|
23978
|
-
.on('select', this.refreshSteps);
|
|
23979
|
-
}
|
|
23980
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23981
|
-
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 }); }
|
|
23982
|
-
}
|
|
23983
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, decorators: [{
|
|
23984
|
-
type: Component,
|
|
23985
|
-
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"] }]
|
|
23986
|
-
}], propDecorators: { carouselOverflowContainer: [{
|
|
23987
|
-
type: ViewChild,
|
|
23988
|
-
args: ['carouselOverflowContainer']
|
|
23989
|
-
}], containerClass: [{
|
|
23990
|
-
type: Input
|
|
23991
|
-
}], stepsContainerClass: [{
|
|
23992
|
-
type: Input
|
|
23993
|
-
}], currentStepChange: [{
|
|
23994
|
-
type: Output
|
|
23995
|
-
}] } });
|
|
23996
|
-
|
|
23997
|
-
class ProgressBarComponent {
|
|
23998
|
-
constructor() {
|
|
23999
|
-
this.value = 0;
|
|
24000
|
-
this.type = 'default';
|
|
24001
|
-
}
|
|
24002
|
-
get progress() {
|
|
24003
|
-
return this.value > 0 ? (this.value < 100 ? this.value : 100) : 0;
|
|
24004
|
-
}
|
|
24005
|
-
get color() {
|
|
24006
|
-
switch (this.type) {
|
|
24007
|
-
case 'default':
|
|
24008
|
-
return {
|
|
24009
|
-
outerBar: 'bg-gray-200',
|
|
24010
|
-
innerBar: 'bg-gray-100',
|
|
24011
|
-
text: 'text-gray-900',
|
|
24012
|
-
};
|
|
24013
|
-
case 'primary':
|
|
24014
|
-
return {
|
|
24015
|
-
outerBar: 'bg-primary',
|
|
24016
|
-
innerBar: 'bg-primary-lighter',
|
|
24017
|
-
text: 'text-white',
|
|
24018
|
-
};
|
|
24019
|
-
case 'secondary':
|
|
24020
|
-
return {
|
|
24021
|
-
outerBar: 'bg-secondary',
|
|
24022
|
-
innerBar: 'bg-secondary-lighter',
|
|
24023
|
-
text: 'text-white',
|
|
24024
|
-
};
|
|
24025
|
-
case 'light':
|
|
24026
|
-
return {
|
|
24027
|
-
outerBar: 'bg-primary-white',
|
|
24028
|
-
innerBar: 'bg-primary',
|
|
24029
|
-
text: 'text-main',
|
|
24030
|
-
};
|
|
24031
|
-
}
|
|
24032
|
-
}
|
|
24033
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24034
|
-
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"] }); }
|
|
24035
|
-
}
|
|
24036
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, decorators: [{
|
|
24037
|
-
type: Component,
|
|
24038
|
-
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"] }]
|
|
24039
|
-
}], propDecorators: { value: [{
|
|
24040
|
-
type: Input
|
|
24041
|
-
}], type: [{
|
|
24042
|
-
type: Input
|
|
24043
|
-
}] } });
|
|
24044
|
-
|
|
24045
|
-
class PopoverComponent {
|
|
24046
|
-
constructor() {
|
|
24047
|
-
this.viewContainerRef = inject(ViewContainerRef);
|
|
24048
|
-
this.renderer = inject(Renderer2);
|
|
24049
|
-
}
|
|
24050
|
-
getContent() {
|
|
24051
|
-
if (this.content instanceof TemplateRef) {
|
|
24052
|
-
if (this.view) {
|
|
24053
|
-
this.view.destroy();
|
|
24054
|
-
}
|
|
24055
|
-
this.view = this.viewContainerRef.createEmbeddedView(this.content);
|
|
24056
|
-
this.view.detectChanges();
|
|
24057
|
-
const wrapper = this.renderer.createElement('div'); // Create a wrapper div
|
|
24058
|
-
this.view.rootNodes.forEach((node) => {
|
|
24059
|
-
this.renderer.appendChild(wrapper, node); // Append each root node to the wrapper
|
|
24060
|
-
});
|
|
24061
|
-
return wrapper;
|
|
24062
|
-
}
|
|
24063
|
-
return this.content;
|
|
24064
|
-
}
|
|
24065
|
-
ngAfterViewInit() {
|
|
24066
|
-
this.tippyInstance = tippy(this.popoverContent.nativeElement, {
|
|
24067
|
-
content: this.getContent(),
|
|
24068
|
-
allowHTML: true,
|
|
24069
|
-
theme: this.theme,
|
|
24070
|
-
});
|
|
24071
|
-
}
|
|
24072
|
-
ngOnChanges(changes) {
|
|
24073
|
-
if (changes['theme']) {
|
|
24074
|
-
this.theme = changes['theme'].currentValue;
|
|
24075
|
-
if (this.tippyInstance) {
|
|
24076
|
-
this.tippyInstance.setProps({ theme: this.theme });
|
|
24077
|
-
}
|
|
24078
|
-
}
|
|
24079
|
-
if (changes['content']) {
|
|
24080
|
-
this.content = changes['content'].currentValue;
|
|
24081
|
-
if (this.tippyInstance) {
|
|
24082
|
-
this.tippyInstance.setContent(this.getContent());
|
|
24083
|
-
}
|
|
24084
|
-
}
|
|
24085
|
-
}
|
|
24086
|
-
ngOnDestroy() {
|
|
24087
|
-
if (this.tippyInstance) {
|
|
24088
|
-
this.tippyInstance.destroy();
|
|
24089
|
-
}
|
|
24090
|
-
if (this.view) {
|
|
24091
|
-
this.view.destroy();
|
|
24092
|
-
}
|
|
24093
|
-
}
|
|
24094
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24095
|
-
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: [""] }); }
|
|
24096
|
-
}
|
|
24097
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, decorators: [{
|
|
24098
|
-
type: Component,
|
|
24099
|
-
args: [{ selector: 'gn-ui-popover', standalone: true, imports: [], template: "<span #popoverContent>\n <ng-content></ng-content>\n</span>\n" }]
|
|
24100
|
-
}], propDecorators: { popoverContent: [{
|
|
24101
|
-
type: ViewChild,
|
|
24102
|
-
args: ['popoverContent', { static: false }]
|
|
24103
|
-
}], content: [{
|
|
24104
|
-
type: Input
|
|
24105
|
-
}], theme: [{
|
|
24106
|
-
type: Input
|
|
24107
|
-
}] } });
|
|
24108
|
-
|
|
24109
|
-
class LoadingMaskComponent {
|
|
24110
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24111
|
-
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 }); }
|
|
24112
|
-
}
|
|
24113
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, decorators: [{
|
|
24114
|
-
type: Component,
|
|
24115
|
-
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"] }]
|
|
24116
|
-
}], propDecorators: { message: [{
|
|
24117
|
-
type: Input
|
|
24118
|
-
}] } });
|
|
24119
|
-
|
|
24120
|
-
class ColorScaleComponent {
|
|
24121
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24122
|
-
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: [""] }); }
|
|
24123
|
-
}
|
|
24124
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, decorators: [{
|
|
24125
|
-
type: Component,
|
|
24126
|
-
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" }]
|
|
24127
|
-
}] });
|
|
24128
|
-
|
|
24129
|
-
class PopupAlertComponent {
|
|
24130
|
-
constructor() {
|
|
24131
|
-
this.changeDetector = inject(ChangeDetectorRef);
|
|
24132
|
-
this.type = 'info';
|
|
24133
|
-
this.position = 'top';
|
|
24134
|
-
this.expanded = false;
|
|
24135
|
-
this.timeout = null;
|
|
24136
|
-
}
|
|
24137
|
-
get showDuration() {
|
|
24138
|
-
const chars = this.content.nativeElement.innerHTML.length;
|
|
24139
|
-
return Math.max(3000, chars * 20);
|
|
24140
|
-
}
|
|
24141
|
-
ngOnInit() {
|
|
24142
|
-
this.expandAndClose();
|
|
23486
|
+
this.expandAndClose();
|
|
24143
23487
|
}
|
|
24144
23488
|
expand() {
|
|
24145
23489
|
this.expanded = true;
|
|
@@ -24310,15 +23654,15 @@ class AutocompleteComponent {
|
|
|
24310
23654
|
getExtraClass() {
|
|
24311
23655
|
if (this.allowSubmit) {
|
|
24312
23656
|
if (this.enterButton) {
|
|
24313
|
-
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+var(--icon-padding))]
|
|
23657
|
+
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+var(--icon-padding))] top-1/2 -translate-y-1/2';
|
|
24314
23658
|
}
|
|
24315
23659
|
else {
|
|
24316
|
-
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+0.25*var(--icon-width))]
|
|
23660
|
+
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';
|
|
24317
23661
|
}
|
|
24318
23662
|
}
|
|
24319
23663
|
else {
|
|
24320
23664
|
if (!this.enterButton) {
|
|
24321
|
-
return 'border rounded-lg absolute w-8 h-8 right-2
|
|
23665
|
+
return 'border rounded-lg absolute w-8 h-8 right-2 top-1/2 -translate-y-1/2';
|
|
24322
23666
|
}
|
|
24323
23667
|
}
|
|
24324
23668
|
return 'border rounded-lg absolute w-8 h-8';
|
|
@@ -24454,7 +23798,7 @@ class AutocompleteComponent {
|
|
|
24454
23798
|
this.enterBtnPosition = event.target['value'].length * 8 + 80;
|
|
24455
23799
|
}
|
|
24456
23800
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24457
|
-
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: [
|
|
23801
|
+
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: [
|
|
24458
23802
|
provideIcons({
|
|
24459
23803
|
iconoirSearch,
|
|
24460
23804
|
matClose,
|
|
@@ -24463,7 +23807,7 @@ class AutocompleteComponent {
|
|
|
24463
23807
|
provideNgIconsConfig({
|
|
24464
23808
|
size: '1.75rem',
|
|
24465
23809
|
}),
|
|
24466
|
-
], 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
|
|
23810
|
+
], 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 }); }
|
|
24467
23811
|
}
|
|
24468
23812
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AutocompleteComponent, decorators: [{
|
|
24469
23813
|
type: Component,
|
|
@@ -24484,7 +23828,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
24484
23828
|
provideNgIconsConfig({
|
|
24485
23829
|
size: '1.75rem',
|
|
24486
23830
|
}),
|
|
24487
|
-
], 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
|
|
23831
|
+
], 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"] }]
|
|
24488
23832
|
}], propDecorators: { placeholder: [{
|
|
24489
23833
|
type: Input
|
|
24490
23834
|
}], enterButton: [{
|
|
@@ -24522,6 +23866,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
24522
23866
|
}], inputRef: [{
|
|
24523
23867
|
type: ViewChild,
|
|
24524
23868
|
args: ['searchInput']
|
|
23869
|
+
}], displayWithTemplate: [{
|
|
23870
|
+
type: Input
|
|
24525
23871
|
}], displayWithFn: [{
|
|
24526
23872
|
type: Input
|
|
24527
23873
|
}] } });
|
|
@@ -25006,7 +24352,7 @@ class DropdownMultiselectComponent {
|
|
|
25006
24352
|
}
|
|
25007
24353
|
setFocus() {
|
|
25008
24354
|
setTimeout(() => {
|
|
25009
|
-
this.searchFieldInput
|
|
24355
|
+
this.searchFieldInput?.nativeElement.focus();
|
|
25010
24356
|
}, 0);
|
|
25011
24357
|
}
|
|
25012
24358
|
openOverlay() {
|
|
@@ -25112,7 +24458,10 @@ class DropdownMultiselectComponent {
|
|
|
25112
24458
|
matExpandMore,
|
|
25113
24459
|
matExpandLess,
|
|
25114
24460
|
}),
|
|
25115
|
-
|
|
24461
|
+
provideNgIconsConfig({
|
|
24462
|
+
size: '1.5rem',
|
|
24463
|
+
}),
|
|
24464
|
+
], 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 }); }
|
|
25116
24465
|
}
|
|
25117
24466
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: DropdownMultiselectComponent, decorators: [{
|
|
25118
24467
|
type: Component,
|
|
@@ -25122,7 +24471,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
25122
24471
|
matExpandMore,
|
|
25123
24472
|
matExpandLess,
|
|
25124
24473
|
}),
|
|
25125
|
-
|
|
24474
|
+
provideNgIconsConfig({
|
|
24475
|
+
size: '1.5rem',
|
|
24476
|
+
}),
|
|
24477
|
+
], 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" }]
|
|
25126
24478
|
}], propDecorators: { title: [{
|
|
25127
24479
|
type: Input
|
|
25128
24480
|
}], choices: [{
|
|
@@ -25952,7 +25304,8 @@ class SearchFeatureCatalogComponent {
|
|
|
25952
25304
|
const filtered = (this.featureCatalog?.featureTypes || []).filter((featureType) => {
|
|
25953
25305
|
const fuzzyFilter = createFuzzyFilter(searchTerm);
|
|
25954
25306
|
return (fuzzyFilter(featureType.name) ||
|
|
25955
|
-
(featureType.
|
|
25307
|
+
(featureType.description &&
|
|
25308
|
+
fuzzyFilter(featureType.description)));
|
|
25956
25309
|
});
|
|
25957
25310
|
this.filteredFeatureCatalog = {
|
|
25958
25311
|
...this.featureCatalog,
|
|
@@ -26037,8 +25390,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
26037
25390
|
marker('search.filters.spatialExtent.import');
|
|
26038
25391
|
marker('search.filters.spatialExtent.helpText');
|
|
26039
25392
|
marker('search.filters.spatialExtent.error.title');
|
|
25393
|
+
marker('search.filters.spatialExtent.error.outOfBounds');
|
|
26040
25394
|
const LABEL_FROM_FILE = marker('search.filters.spatialExtent.bboxFromFile');
|
|
26041
25395
|
const LABEL_FROM_FILE_DELETE = marker('search.filters.spatialExtent.bboxFromFileDelete');
|
|
25396
|
+
const LABEL_FROM_LOCATION = marker('search.filters.spatialExtent.bboxFromLocation');
|
|
25397
|
+
const LABEL_FROM_LOCATION_DELETE = marker('search.filters.spatialExtent.bboxFromLocationDelete');
|
|
26042
25398
|
const LABEL_INITIAL = marker('search.filters.spatialExtent.bboxInitial');
|
|
26043
25399
|
const LABEL_INITIAL_DELETE = marker('search.filters.spatialExtent.bboxInitialDelete');
|
|
26044
25400
|
class SpatialExtentDropdownComponent {
|
|
@@ -26050,6 +25406,7 @@ class SpatialExtentDropdownComponent {
|
|
|
26050
25406
|
this.errorChange = new EventEmitter();
|
|
26051
25407
|
this.bbox = null;
|
|
26052
25408
|
this.fileName = '';
|
|
25409
|
+
this.locationName = '';
|
|
26053
25410
|
this.overlayPositions = [
|
|
26054
25411
|
{
|
|
26055
25412
|
originX: 'start',
|
|
@@ -26080,13 +25437,21 @@ class SpatialExtentDropdownComponent {
|
|
|
26080
25437
|
return !!this.bbox;
|
|
26081
25438
|
}
|
|
26082
25439
|
get selectionLabelKey() {
|
|
26083
|
-
|
|
25440
|
+
if (this.fileName)
|
|
25441
|
+
return LABEL_FROM_FILE;
|
|
25442
|
+
if (this.locationName)
|
|
25443
|
+
return LABEL_FROM_LOCATION;
|
|
25444
|
+
return LABEL_INITIAL;
|
|
26084
25445
|
}
|
|
26085
25446
|
get selectionDeleteLabelKey() {
|
|
26086
|
-
|
|
25447
|
+
if (this.fileName)
|
|
25448
|
+
return LABEL_FROM_FILE_DELETE;
|
|
25449
|
+
if (this.locationName)
|
|
25450
|
+
return LABEL_FROM_LOCATION_DELETE;
|
|
25451
|
+
return LABEL_INITIAL_DELETE;
|
|
26087
25452
|
}
|
|
26088
25453
|
get selectionLabelParams() {
|
|
26089
|
-
return { fileName: this.fileName };
|
|
25454
|
+
return { fileName: this.fileName, locationName: this.locationName };
|
|
26090
25455
|
}
|
|
26091
25456
|
openOverlay() {
|
|
26092
25457
|
this.overlayMinWidth =
|
|
@@ -26117,8 +25482,13 @@ class SpatialExtentDropdownComponent {
|
|
|
26117
25482
|
return;
|
|
26118
25483
|
}
|
|
26119
25484
|
const bbox = getGeometryBoundingBox(geometry);
|
|
25485
|
+
if (!isBoundingBoxWithinWorldExtent(bbox)) {
|
|
25486
|
+
this.setError(marker('search.filters.spatialExtent.error.outOfBounds'));
|
|
25487
|
+
return;
|
|
25488
|
+
}
|
|
26120
25489
|
this.bbox = bbox;
|
|
26121
25490
|
this.fileName = file.name;
|
|
25491
|
+
this.locationName = '';
|
|
26122
25492
|
this.bboxChange.emit(bbox);
|
|
26123
25493
|
this.cd.markForCheck();
|
|
26124
25494
|
}
|
|
@@ -26127,6 +25497,15 @@ class SpatialExtentDropdownComponent {
|
|
|
26127
25497
|
return;
|
|
26128
25498
|
}
|
|
26129
25499
|
}
|
|
25500
|
+
setLocationBbox(bbox, name) {
|
|
25501
|
+
this.errorKey = null;
|
|
25502
|
+
this.bbox = bbox;
|
|
25503
|
+
this.locationName = name;
|
|
25504
|
+
this.fileName = '';
|
|
25505
|
+
this.fileInput?.clear();
|
|
25506
|
+
this.bboxChange.emit(bbox);
|
|
25507
|
+
this.cd.markForCheck();
|
|
25508
|
+
}
|
|
26130
25509
|
handleFileError(error) {
|
|
26131
25510
|
if (error === 'file-too-large') {
|
|
26132
25511
|
this.setError(marker('search.filters.spatialExtent.error.fileTooLarge'), {
|
|
@@ -26145,6 +25524,7 @@ class SpatialExtentDropdownComponent {
|
|
|
26145
25524
|
removeSelection(event) {
|
|
26146
25525
|
this.bbox = null;
|
|
26147
25526
|
this.fileName = '';
|
|
25527
|
+
this.locationName = '';
|
|
26148
25528
|
this.errorKey = null;
|
|
26149
25529
|
this.fileInput?.clear();
|
|
26150
25530
|
this.bboxChange.emit(null);
|
|
@@ -26154,14 +25534,14 @@ class SpatialExtentDropdownComponent {
|
|
|
26154
25534
|
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: [
|
|
26155
25535
|
provideIcons({
|
|
26156
25536
|
iconoirCheckCircle,
|
|
26157
|
-
iconoirImport,
|
|
26158
25537
|
iconoirSquareDashed,
|
|
26159
25538
|
iconoirTrash,
|
|
25539
|
+
iconoirUpload,
|
|
26160
25540
|
matClose,
|
|
26161
25541
|
matExpandLess,
|
|
26162
25542
|
matExpandMore,
|
|
26163
25543
|
}),
|
|
26164
|
-
], 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-[
|
|
25544
|
+
], 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 }); }
|
|
26165
25545
|
}
|
|
26166
25546
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SpatialExtentDropdownComponent, decorators: [{
|
|
26167
25547
|
type: Component,
|
|
@@ -26174,14 +25554,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
26174
25554
|
], providers: [
|
|
26175
25555
|
provideIcons({
|
|
26176
25556
|
iconoirCheckCircle,
|
|
26177
|
-
iconoirImport,
|
|
26178
25557
|
iconoirSquareDashed,
|
|
26179
25558
|
iconoirTrash,
|
|
25559
|
+
iconoirUpload,
|
|
26180
25560
|
matClose,
|
|
26181
25561
|
matExpandLess,
|
|
26182
25562
|
matExpandMore,
|
|
26183
25563
|
}),
|
|
26184
|
-
], 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-[
|
|
25564
|
+
], 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" }]
|
|
26185
25565
|
}], propDecorators: { title: [{
|
|
26186
25566
|
type: Input
|
|
26187
25567
|
}], maxFileSizeMb: [{
|
|
@@ -26707,11 +26087,11 @@ class BlockListComponent {
|
|
|
26707
26087
|
this.goToPage(this.currentPage + 1);
|
|
26708
26088
|
}
|
|
26709
26089
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BlockListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
26710
|
-
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 }); }
|
|
26090
|
+
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 }); }
|
|
26711
26091
|
}
|
|
26712
26092
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BlockListComponent, decorators: [{
|
|
26713
26093
|
type: Component,
|
|
26714
|
-
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"] }]
|
|
26094
|
+
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"] }]
|
|
26715
26095
|
}], propDecorators: { containerClass: [{
|
|
26716
26096
|
type: Input
|
|
26717
26097
|
}], paginationContainerClass: [{
|
|
@@ -27450,9 +26830,7 @@ const initSearch = () => {
|
|
|
27450
26830
|
},
|
|
27451
26831
|
params: {
|
|
27452
26832
|
filters: {},
|
|
27453
|
-
pageSize:
|
|
27454
|
-
? getOptionalSearchConfig().LIMIT
|
|
27455
|
-
: DEFAULT_PAGE_SIZE,
|
|
26833
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
27456
26834
|
currentPage: 0,
|
|
27457
26835
|
favoritesOnly: false,
|
|
27458
26836
|
useSpatialFilter: true,
|
|
@@ -27901,6 +27279,146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
27901
27279
|
}]
|
|
27902
27280
|
}] });
|
|
27903
27281
|
|
|
27282
|
+
const DEFAULT_GEOCODING_PROVIDER = [
|
|
27283
|
+
'geonames',
|
|
27284
|
+
{ maxRows: 5 },
|
|
27285
|
+
];
|
|
27286
|
+
const GEOCODING_PROVIDER = new InjectionToken('geocoding-provider', {
|
|
27287
|
+
providedIn: 'root',
|
|
27288
|
+
factory: () => DEFAULT_GEOCODING_PROVIDER,
|
|
27289
|
+
});
|
|
27290
|
+
// these options are arrays in the providers, but they can be configured
|
|
27291
|
+
// with a single value for simplicity
|
|
27292
|
+
const GEOCODING_PROVIDER_ARRAY_OPTIONS = {
|
|
27293
|
+
geoadmin: ['origins', 'features'],
|
|
27294
|
+
geoplateforme: [
|
|
27295
|
+
'index',
|
|
27296
|
+
'category',
|
|
27297
|
+
'type',
|
|
27298
|
+
'postCode',
|
|
27299
|
+
'cityCode',
|
|
27300
|
+
'depCode',
|
|
27301
|
+
],
|
|
27302
|
+
};
|
|
27303
|
+
function wrapArrayOptions(options, keys) {
|
|
27304
|
+
const wrapped = { ...options };
|
|
27305
|
+
for (const key of keys) {
|
|
27306
|
+
if (typeof wrapped[key] === 'string') {
|
|
27307
|
+
wrapped[key] = [wrapped[key]];
|
|
27308
|
+
}
|
|
27309
|
+
}
|
|
27310
|
+
return wrapped;
|
|
27311
|
+
}
|
|
27312
|
+
class GeocodingService {
|
|
27313
|
+
constructor() {
|
|
27314
|
+
this.provider = inject(GEOCODING_PROVIDER);
|
|
27315
|
+
}
|
|
27316
|
+
query(text) {
|
|
27317
|
+
let queryObservable;
|
|
27318
|
+
switch (this.provider[0]) {
|
|
27319
|
+
case 'geoadmin':
|
|
27320
|
+
queryObservable = from(queryGeoadmin(text, wrapArrayOptions(this.provider[1], GEOCODING_PROVIDER_ARRAY_OPTIONS.geoadmin)));
|
|
27321
|
+
break;
|
|
27322
|
+
case 'geonames':
|
|
27323
|
+
queryObservable = from(queryGeonames(text, this.provider[1]));
|
|
27324
|
+
break;
|
|
27325
|
+
case 'geoplateforme':
|
|
27326
|
+
queryObservable = from(queryGeoplateforme(text, {
|
|
27327
|
+
...wrapArrayOptions(this.provider[1], GEOCODING_PROVIDER_ARRAY_OPTIONS.geoplateforme),
|
|
27328
|
+
returnTrueGeometry: true,
|
|
27329
|
+
}));
|
|
27330
|
+
break;
|
|
27331
|
+
default:
|
|
27332
|
+
return throwError(() => new Error(`Unsupported geocoding provider: ${this.provider[0]}`));
|
|
27333
|
+
}
|
|
27334
|
+
return queryObservable.pipe(catchError((error) => throwError(error)));
|
|
27335
|
+
}
|
|
27336
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
27337
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, providedIn: 'root' }); }
|
|
27338
|
+
}
|
|
27339
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingService, decorators: [{
|
|
27340
|
+
type: Injectable,
|
|
27341
|
+
args: [{
|
|
27342
|
+
providedIn: 'root',
|
|
27343
|
+
}]
|
|
27344
|
+
}] });
|
|
27345
|
+
|
|
27346
|
+
const GEOCODING_PROVIDER_LABELS = new InjectionToken('geocodingProviderLabels', {
|
|
27347
|
+
factory: () => ({}),
|
|
27348
|
+
});
|
|
27349
|
+
class LocationSearchComponent {
|
|
27350
|
+
constructor() {
|
|
27351
|
+
this.geocodingService = inject(GeocodingService);
|
|
27352
|
+
this.labels = inject(GEOCODING_PROVIDER_LABELS);
|
|
27353
|
+
this.placeholder = '';
|
|
27354
|
+
this.resultSelected = new EventEmitter();
|
|
27355
|
+
this.bboxSelected = new EventEmitter();
|
|
27356
|
+
this.displayWithFn = (item) => item.label;
|
|
27357
|
+
this.searchAction = (text) => this.geocodingService.query(text);
|
|
27358
|
+
}
|
|
27359
|
+
getSecondaryLabel(result) {
|
|
27360
|
+
return this.resolveLabel(result, this.labels.secondary);
|
|
27361
|
+
}
|
|
27362
|
+
getMainLabel(result) {
|
|
27363
|
+
return this.resolveLabel(result, this.labels.main) ?? result.label;
|
|
27364
|
+
}
|
|
27365
|
+
getTertiaryLabel(result) {
|
|
27366
|
+
return this.resolveLabel(result, this.labels.tertiary);
|
|
27367
|
+
}
|
|
27368
|
+
getDisplayLabel(result) {
|
|
27369
|
+
const tertiary = this.getTertiaryLabel(result);
|
|
27370
|
+
return this.getMainLabel(result) + (tertiary ? ', ' + tertiary : '');
|
|
27371
|
+
}
|
|
27372
|
+
resolveLabel(result, path) {
|
|
27373
|
+
if (!path)
|
|
27374
|
+
return undefined;
|
|
27375
|
+
let value;
|
|
27376
|
+
try {
|
|
27377
|
+
value = pointer.get(result, path);
|
|
27378
|
+
}
|
|
27379
|
+
catch {
|
|
27380
|
+
return undefined;
|
|
27381
|
+
}
|
|
27382
|
+
const values = Array.isArray(value) ? value : [value];
|
|
27383
|
+
const label = values
|
|
27384
|
+
.filter((v) => typeof v === 'string' || typeof v === 'number')
|
|
27385
|
+
.join(', ');
|
|
27386
|
+
return label || undefined;
|
|
27387
|
+
}
|
|
27388
|
+
// geoplateforme keeps a simplified geometry in geom and puts the real one,
|
|
27389
|
+
// as a JSON string, in properties.truegeometry when returnTrueGeometry is set
|
|
27390
|
+
getGeometry(result) {
|
|
27391
|
+
const trueGeometry = result.properties?.['truegeometry'];
|
|
27392
|
+
if (typeof trueGeometry === 'string') {
|
|
27393
|
+
return JSON.parse(trueGeometry);
|
|
27394
|
+
}
|
|
27395
|
+
return trueGeometry ?? result.geom;
|
|
27396
|
+
}
|
|
27397
|
+
handleItemSelected(item) {
|
|
27398
|
+
const result = item;
|
|
27399
|
+
this.resultSelected.emit(result);
|
|
27400
|
+
const geometry = this.getGeometry(result);
|
|
27401
|
+
if (geometry) {
|
|
27402
|
+
this.bboxSelected.emit({
|
|
27403
|
+
bbox: getGeometryBoundingBox(geometry),
|
|
27404
|
+
label: this.getDisplayLabel(result),
|
|
27405
|
+
});
|
|
27406
|
+
}
|
|
27407
|
+
}
|
|
27408
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LocationSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
27409
|
+
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 }); }
|
|
27410
|
+
}
|
|
27411
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LocationSearchComponent, decorators: [{
|
|
27412
|
+
type: Component,
|
|
27413
|
+
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" }]
|
|
27414
|
+
}], propDecorators: { placeholder: [{
|
|
27415
|
+
type: Input
|
|
27416
|
+
}], resultSelected: [{
|
|
27417
|
+
type: Output
|
|
27418
|
+
}], bboxSelected: [{
|
|
27419
|
+
type: Output
|
|
27420
|
+
}] } });
|
|
27421
|
+
|
|
27904
27422
|
// expects the replacement key ${uuid}
|
|
27905
27423
|
const RECORD_DATASET_URL_TOKEN = new InjectionToken('record-dataset-url-token');
|
|
27906
27424
|
const RECORD_SERVICE_URL_TOKEN = new InjectionToken('record-service-url-token');
|
|
@@ -28059,6 +27577,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
28059
27577
|
class AbstractSearchField {
|
|
28060
27578
|
}
|
|
28061
27579
|
class SimpleSearchField {
|
|
27580
|
+
get fieldIdentifier() {
|
|
27581
|
+
return this.customIdentifier ?? this.esFieldName;
|
|
27582
|
+
}
|
|
28062
27583
|
constructor(esFieldName, injector, order = 'asc', orderType = 'key') {
|
|
28063
27584
|
this.esFieldName = esFieldName;
|
|
28064
27585
|
this.injector = injector;
|
|
@@ -28067,14 +27588,26 @@ class SimpleSearchField {
|
|
|
28067
27588
|
this.repository = this.injector.get(RecordsRepositoryInterface);
|
|
28068
27589
|
// FIXME: this is required to register runtime fields; abstract this as well
|
|
28069
27590
|
this.esService = this.injector.get(ElasticsearchService);
|
|
27591
|
+
this.includeValues = [];
|
|
27592
|
+
this.excludeValues = [];
|
|
27593
|
+
}
|
|
27594
|
+
setFieldIdentifier(fieldIdentifier) {
|
|
27595
|
+
this.customIdentifier = fieldIdentifier;
|
|
27596
|
+
this.esService.registerFieldAlias(fieldIdentifier, this.esFieldName);
|
|
28070
27597
|
}
|
|
28071
27598
|
getAggregations() {
|
|
28072
27599
|
return {
|
|
28073
|
-
[this.
|
|
27600
|
+
[this.fieldIdentifier]: {
|
|
28074
27601
|
type: 'terms',
|
|
28075
27602
|
field: this.esFieldName,
|
|
28076
27603
|
limit: 1000,
|
|
28077
27604
|
sort: [this.order, this.orderType],
|
|
27605
|
+
...(this.includeValues?.length && {
|
|
27606
|
+
includeValues: this.includeValues,
|
|
27607
|
+
}),
|
|
27608
|
+
...(this.excludeValues?.length && {
|
|
27609
|
+
excludeValues: this.excludeValues,
|
|
27610
|
+
}),
|
|
28078
27611
|
},
|
|
28079
27612
|
};
|
|
28080
27613
|
}
|
|
@@ -28082,7 +27615,7 @@ class SimpleSearchField {
|
|
|
28082
27615
|
return bucket.term.toString();
|
|
28083
27616
|
}
|
|
28084
27617
|
getAvailableValues() {
|
|
28085
|
-
return this.repository.aggregate(this.getAggregations()).pipe(map$1((response) => response[this.
|
|
27618
|
+
return this.repository.aggregate(this.getAggregations()).pipe(map$1((response) => response[this.fieldIdentifier].buckets || []), switchMap((buckets) => {
|
|
28086
27619
|
const bucketPromises = buckets.map(async (bucket) => ({
|
|
28087
27620
|
label: `${await this.getBucketLabel(bucket)} (${bucket.count})`,
|
|
28088
27621
|
value: bucket.term.toString(),
|
|
@@ -28095,7 +27628,7 @@ class SimpleSearchField {
|
|
|
28095
27628
|
// FieldValue[]
|
|
28096
27629
|
if (this.getType() === 'values') {
|
|
28097
27630
|
return of({
|
|
28098
|
-
[this.
|
|
27631
|
+
[this.fieldIdentifier]: values.reduce((acc, val) => {
|
|
28099
27632
|
const value = val.toString();
|
|
28100
27633
|
if (value !== '') {
|
|
28101
27634
|
return { ...acc, [value]: true };
|
|
@@ -28106,11 +27639,11 @@ class SimpleSearchField {
|
|
|
28106
27639
|
}
|
|
28107
27640
|
// DateRange
|
|
28108
27641
|
return of({
|
|
28109
|
-
[this.
|
|
27642
|
+
[this.fieldIdentifier]: values[0] !== '' ? values[0] : {},
|
|
28110
27643
|
});
|
|
28111
27644
|
}
|
|
28112
27645
|
getValuesForFilter(filters) {
|
|
28113
|
-
const filter = filters[this.
|
|
27646
|
+
const filter = filters[this.fieldIdentifier];
|
|
28114
27647
|
if (!filter)
|
|
28115
27648
|
return of([]);
|
|
28116
27649
|
// filter by expression
|
|
@@ -28128,6 +27661,9 @@ class SimpleSearchField {
|
|
|
28128
27661
|
getType() {
|
|
28129
27662
|
return 'values';
|
|
28130
27663
|
}
|
|
27664
|
+
clone() {
|
|
27665
|
+
return Object.create(this);
|
|
27666
|
+
}
|
|
28131
27667
|
}
|
|
28132
27668
|
class TranslatedSearchField extends SimpleSearchField {
|
|
28133
27669
|
constructor(esFieldName, injector, order = 'asc', orderType = 'key') {
|
|
@@ -28369,17 +27905,39 @@ class DateRangeSearchField extends SimpleSearchField {
|
|
|
28369
27905
|
return 'dateRange';
|
|
28370
27906
|
}
|
|
28371
27907
|
}
|
|
27908
|
+
// treats a resource's creation/revision dates as an interval (its min and max), so a record matches
|
|
27909
|
+
// when that interval intersects the filter range, not just when a single date falls inside it
|
|
27910
|
+
class ResourceCreationRevisionDateSearchField extends DateRangeSearchField {
|
|
27911
|
+
constructor(injector, order = 'desc') {
|
|
27912
|
+
super('resourceCreationRevisionDate', injector, order);
|
|
27913
|
+
const dateSourceFields = [
|
|
27914
|
+
'creationDateForResource',
|
|
27915
|
+
'revisionDateForResource',
|
|
27916
|
+
];
|
|
27917
|
+
const collectSortedDates = dateSourceFields
|
|
27918
|
+
.map((field) => `if (doc.containsKey('${field}')) {
|
|
27919
|
+
for (def date : doc['${field}']) { dates.add(date.millis); }
|
|
27920
|
+
}`)
|
|
27921
|
+
.join('\n');
|
|
27922
|
+
this.esService.registerRuntimeField('resourceCreationRevisionDateMin', `def dates = [];
|
|
27923
|
+
${collectSortedDates}
|
|
27924
|
+
if (dates.length > 0) { dates.sort(null); emit(dates[0]); }`, 'date');
|
|
27925
|
+
this.esService.registerRuntimeField('resourceCreationRevisionDateMax', `def dates = [];
|
|
27926
|
+
${collectSortedDates}
|
|
27927
|
+
if (dates.length > 0) { dates.sort(null); emit(dates[dates.length - 1]); }`, 'date');
|
|
27928
|
+
}
|
|
27929
|
+
}
|
|
28372
27930
|
class BoundingBoxSearchField extends SimpleSearchField {
|
|
28373
27931
|
getAvailableValues() {
|
|
28374
27932
|
return of([]);
|
|
28375
27933
|
}
|
|
28376
27934
|
getFiltersForValues(values) {
|
|
28377
27935
|
return of({
|
|
28378
|
-
[this.
|
|
27936
|
+
[this.fieldIdentifier]: values.map(Number),
|
|
28379
27937
|
});
|
|
28380
27938
|
}
|
|
28381
27939
|
getValuesForFilter(filters) {
|
|
28382
|
-
const filter = filters[this.
|
|
27940
|
+
const filter = filters[this.fieldIdentifier];
|
|
28383
27941
|
return of(isBoundingBox(filter) ? filter : []);
|
|
28384
27942
|
}
|
|
28385
27943
|
getType() {
|
|
@@ -28478,7 +28036,7 @@ class RecordKindField extends SimpleSearchField {
|
|
|
28478
28036
|
}
|
|
28479
28037
|
getFiltersForValues(values) {
|
|
28480
28038
|
const filters = {
|
|
28481
|
-
[this.
|
|
28039
|
+
[this.fieldIdentifier]: values.reduce((acc, value) => {
|
|
28482
28040
|
if (value === '')
|
|
28483
28041
|
return { ...acc, [value]: true };
|
|
28484
28042
|
const keysToAdd = this.TYPE_MAPPING[value] || [value];
|
|
@@ -28501,7 +28059,7 @@ class RecordKindField extends SimpleSearchField {
|
|
|
28501
28059
|
return of(filters);
|
|
28502
28060
|
}
|
|
28503
28061
|
getValuesForFilter(filters) {
|
|
28504
|
-
const filter = filters[this.
|
|
28062
|
+
const filter = filters[this.fieldIdentifier];
|
|
28505
28063
|
if (!filter)
|
|
28506
28064
|
return of([]);
|
|
28507
28065
|
const activeValues = Object.keys(filter).filter((v) => filter[v]);
|
|
@@ -28530,11 +28088,16 @@ marker('search.filters.producerOrg');
|
|
|
28530
28088
|
marker('search.filters.publisherOrg');
|
|
28531
28089
|
marker('search.filters.user');
|
|
28532
28090
|
marker('search.filters.changeDate');
|
|
28091
|
+
marker('search.filters.resourceCreationRevisionDate');
|
|
28092
|
+
marker('search.filters.temporalExtent');
|
|
28533
28093
|
marker('search.filters.spatialExtent');
|
|
28094
|
+
marker('search.filters.documentStandard');
|
|
28095
|
+
const CUSTOM_FIELDS = new InjectionToken('custom-fields');
|
|
28534
28096
|
class FieldsService {
|
|
28535
28097
|
constructor() {
|
|
28536
28098
|
this.injector = inject(Injector);
|
|
28537
|
-
this.
|
|
28099
|
+
this.customFields = inject(CUSTOM_FIELDS, { optional: true }) ?? [];
|
|
28100
|
+
this.baseFields = {
|
|
28538
28101
|
organization: new OrganizationSearchField(this.injector),
|
|
28539
28102
|
format: new SimpleSearchField('format', this.injector, 'asc'),
|
|
28540
28103
|
resourceType: new ResourceTypeLegacyField(this.injector), // Deprecated, use `recordKind` instead
|
|
@@ -28553,9 +28116,32 @@ class FieldsService {
|
|
|
28553
28116
|
publisherOrg: new MultilingualSearchField('distributorOrgForResourceObject', this.injector, 'asc', 'key'),
|
|
28554
28117
|
user: new UserSearchField(this.injector),
|
|
28555
28118
|
changeDate: new DateRangeSearchField('changeDate', this.injector, 'desc'),
|
|
28119
|
+
resourceCreationRevisionDate: new ResourceCreationRevisionDateSearchField(this.injector, 'desc'),
|
|
28120
|
+
temporalExtent: new DateRangeSearchField('resourceTemporalExtentDateRange', this.injector, 'desc'),
|
|
28556
28121
|
availableServices: new AvailableServicesField(this.injector),
|
|
28557
28122
|
spatialExtent: new BoundingBoxSearchField('spatialExtent', this.injector),
|
|
28558
28123
|
};
|
|
28124
|
+
this.fields = { ...this.baseFields };
|
|
28125
|
+
for (const customField of this.customFields) {
|
|
28126
|
+
const baseField = this.baseFields[customField.baseFilter];
|
|
28127
|
+
if (!(baseField instanceof SimpleSearchField)) {
|
|
28128
|
+
console.warn(`The custom field '${customField.name}' relies on a base field '${customField.baseFilter}' that is not supported. This field will be ignored.`);
|
|
28129
|
+
continue;
|
|
28130
|
+
}
|
|
28131
|
+
if (!customField.name.includes(':')) {
|
|
28132
|
+
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.`);
|
|
28133
|
+
continue;
|
|
28134
|
+
}
|
|
28135
|
+
const newField = baseField.clone();
|
|
28136
|
+
newField.setFieldIdentifier(customField.name);
|
|
28137
|
+
if (customField.includeValues) {
|
|
28138
|
+
newField.includeValues = customField.includeValues;
|
|
28139
|
+
}
|
|
28140
|
+
if (customField.excludeValues) {
|
|
28141
|
+
newField.excludeValues = customField.excludeValues;
|
|
28142
|
+
}
|
|
28143
|
+
this.fields[customField.name] = newField;
|
|
28144
|
+
}
|
|
28559
28145
|
}
|
|
28560
28146
|
get supportedFields() {
|
|
28561
28147
|
return Object.keys(this.fields);
|
|
@@ -28603,7 +28189,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
28603
28189
|
args: [{
|
|
28604
28190
|
providedIn: 'root',
|
|
28605
28191
|
}]
|
|
28606
|
-
}] });
|
|
28192
|
+
}], ctorParameters: () => [] });
|
|
28607
28193
|
|
|
28608
28194
|
class ApiCardComponent {
|
|
28609
28195
|
constructor() {
|
|
@@ -30543,7 +30129,7 @@ class ServiceCapabilitiesComponent {
|
|
|
30543
30129
|
if (this.apiLinks.length > 0 &&
|
|
30544
30130
|
this.apiLinks[0].accessServiceProtocol !== 'ogcFeatures') {
|
|
30545
30131
|
this.loading = true;
|
|
30546
|
-
this.availableLayers = await getLayers(this.apiLinks[0].url.href, this.apiLinks[0].accessServiceProtocol);
|
|
30132
|
+
this.availableLayers = await getLayers(this.apiLinks[0].url.href, this.apiLinks[0].accessServiceProtocol, true);
|
|
30547
30133
|
this.loading = false;
|
|
30548
30134
|
this.cdr.detectChanges();
|
|
30549
30135
|
this.filteredLayers = this.availableLayers;
|
|
@@ -30629,14 +30215,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
30629
30215
|
marker('feature.catalog.attribute.type');
|
|
30630
30216
|
marker('feature.catalog.attribute.name');
|
|
30631
30217
|
marker('feature.catalog.attribute.code');
|
|
30632
|
-
marker('feature.catalog.attribute.
|
|
30218
|
+
marker('feature.catalog.attribute.description');
|
|
30633
30219
|
marker('feature.catalog.attribute.values');
|
|
30634
30220
|
class FeatureCatalogListComponent {
|
|
30635
30221
|
constructor() {
|
|
30636
30222
|
this.COLUMNS_DEFAULT = [
|
|
30637
30223
|
{ key: 'type', width: '25%' },
|
|
30638
30224
|
{ key: 'name', width: '40%' },
|
|
30639
|
-
{ key: '
|
|
30225
|
+
{ key: 'description', width: 'minmax(0px, 1fr)' },
|
|
30640
30226
|
];
|
|
30641
30227
|
this.COLUMN_VALUES = {
|
|
30642
30228
|
key: 'values',
|
|
@@ -30657,7 +30243,7 @@ class FeatureCatalogListComponent {
|
|
|
30657
30243
|
return col.key;
|
|
30658
30244
|
}
|
|
30659
30245
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureCatalogListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
30660
|
-
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.
|
|
30246
|
+
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.code }}\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" }] }); }
|
|
30661
30247
|
}
|
|
30662
30248
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureCatalogListComponent, decorators: [{
|
|
30663
30249
|
type: Component,
|
|
@@ -30670,7 +30256,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
30670
30256
|
TruncatedTextComponent,
|
|
30671
30257
|
NgIconComponent,
|
|
30672
30258
|
ScrollingModule,
|
|
30673
|
-
], 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.
|
|
30259
|
+
], 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.code }}\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" }]
|
|
30674
30260
|
}], propDecorators: { filteredFeatureCatalog: [{
|
|
30675
30261
|
type: Input
|
|
30676
30262
|
}], scrollContainer: [{
|
|
@@ -31808,6 +31394,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
31808
31394
|
], 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" }]
|
|
31809
31395
|
}] });
|
|
31810
31396
|
|
|
31397
|
+
marker('search.filters.spatialExtent.searchLocation');
|
|
31398
|
+
// in MB, null means no limit
|
|
31399
|
+
const SPATIAL_EXTENT_MAX_FILE_SIZE = new InjectionToken('spatialExtentMaxFileSize', { factory: () => null });
|
|
31811
31400
|
class FilterDropdownComponent {
|
|
31812
31401
|
constructor() {
|
|
31813
31402
|
this.searchFacade = inject(SearchFacade);
|
|
@@ -31815,7 +31404,7 @@ class FilterDropdownComponent {
|
|
|
31815
31404
|
this.fieldsService = inject(FieldsService);
|
|
31816
31405
|
this.notificationsService = inject(NotificationsService);
|
|
31817
31406
|
this.translateService = inject(TranslateService);
|
|
31818
|
-
this.spatialExtentMaxFileSize =
|
|
31407
|
+
this.spatialExtentMaxFileSize = inject(SPATIAL_EXTENT_MAX_FILE_SIZE);
|
|
31819
31408
|
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([])));
|
|
31820
31409
|
this.selectedDateRange$ = this.selected$.pipe(map$1((selected) => (Array.isArray(selected) ? {} : selected)));
|
|
31821
31410
|
this.selectedBoundingBox$ = this.selected$.pipe(map$1((selected) => Array.isArray(selected) && selected.length > 0
|
|
@@ -31836,6 +31425,9 @@ class FilterDropdownComponent {
|
|
|
31836
31425
|
.subscribe((filters) => this.searchService.updateFilters(filters));
|
|
31837
31426
|
this.clearSpatialExtentErrorNotification();
|
|
31838
31427
|
}
|
|
31428
|
+
onLocationSelected({ bbox, label }) {
|
|
31429
|
+
this.spatialExtentDropdown.setLocationBbox(bbox, label);
|
|
31430
|
+
}
|
|
31839
31431
|
onSpatialExtentError(error) {
|
|
31840
31432
|
this.clearSpatialExtentErrorNotification();
|
|
31841
31433
|
this.spatialExtentErrorNotificationId =
|
|
@@ -31866,7 +31458,7 @@ class FilterDropdownComponent {
|
|
|
31866
31458
|
.subscribe((filters) => this.searchService.updateFilters(filters));
|
|
31867
31459
|
}
|
|
31868
31460
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FilterDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
31869
|
-
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 ></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 }); }
|
|
31461
|
+
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 }); }
|
|
31870
31462
|
}
|
|
31871
31463
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FilterDropdownComponent, decorators: [{
|
|
31872
31464
|
type: Component,
|
|
@@ -31875,11 +31467,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
31875
31467
|
DateRangeDropdownComponent,
|
|
31876
31468
|
DropdownMultiselectComponent,
|
|
31877
31469
|
SpatialExtentDropdownComponent,
|
|
31878
|
-
|
|
31470
|
+
LocationSearchComponent,
|
|
31471
|
+
TranslatePipe,
|
|
31472
|
+
], 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" }]
|
|
31879
31473
|
}], propDecorators: { fieldName: [{
|
|
31880
31474
|
type: Input
|
|
31881
31475
|
}], title: [{
|
|
31882
31476
|
type: Input
|
|
31477
|
+
}], spatialExtentDropdown: [{
|
|
31478
|
+
type: ViewChild,
|
|
31479
|
+
args: [SpatialExtentDropdownComponent]
|
|
31883
31480
|
}] } });
|
|
31884
31481
|
|
|
31885
31482
|
class FuzzySearchComponent {
|
|
@@ -31936,7 +31533,7 @@ class FuzzySearchComponent {
|
|
|
31936
31533
|
this.isSearchActive.emit(event);
|
|
31937
31534
|
}
|
|
31938
31535
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FuzzySearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
31939
|
-
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 }); }
|
|
31536
|
+
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 }); }
|
|
31940
31537
|
}
|
|
31941
31538
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FuzzySearchComponent, decorators: [{
|
|
31942
31539
|
type: Component,
|
|
@@ -32495,6 +32092,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
32495
32092
|
|
|
32496
32093
|
marker('search.filters.summaryLabel.user');
|
|
32497
32094
|
marker('search.filters.summaryLabel.changeDate');
|
|
32095
|
+
marker('search.filters.summaryLabel.resourceCreationRevisionDate');
|
|
32096
|
+
marker('search.filters.summaryLabel.temporalExtent');
|
|
32498
32097
|
const OPEN_BOUND = '…';
|
|
32499
32098
|
class SearchFiltersSummaryItemComponent {
|
|
32500
32099
|
constructor() {
|
|
@@ -32876,95 +32475,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
32876
32475
|
], 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" }]
|
|
32877
32476
|
}] });
|
|
32878
32477
|
|
|
32879
|
-
class GeocodingComponent {
|
|
32880
|
-
constructor() {
|
|
32881
|
-
this.mapFacade = inject(MapFacade);
|
|
32882
|
-
this.geocodingService = inject(GeocodingService);
|
|
32883
|
-
this.searchText = '';
|
|
32884
|
-
this.results = [];
|
|
32885
|
-
this.searchTextChanged = new Subject();
|
|
32886
|
-
this.destroy$ = new Subject();
|
|
32887
|
-
this.errorMessage = null;
|
|
32888
|
-
this.searchTextChanged
|
|
32889
|
-
.pipe(debounceTime(300), switchMap$1((searchText) => {
|
|
32890
|
-
return from(this.geocodingService.query(searchText)).pipe(catchError$1((error) => {
|
|
32891
|
-
this.errorMessage =
|
|
32892
|
-
'An error occurred while searching. Please try again.';
|
|
32893
|
-
console.error(error);
|
|
32894
|
-
return [];
|
|
32895
|
-
}));
|
|
32896
|
-
}), takeUntil(this.destroy$))
|
|
32897
|
-
.subscribe((results) => {
|
|
32898
|
-
this.results = results;
|
|
32899
|
-
});
|
|
32900
|
-
}
|
|
32901
|
-
ngOnDestroy() {
|
|
32902
|
-
this.destroy$.next();
|
|
32903
|
-
this.destroy$.complete();
|
|
32904
|
-
}
|
|
32905
|
-
onSearchChange(searchText) {
|
|
32906
|
-
if (!searchText) {
|
|
32907
|
-
this.clearSearch();
|
|
32908
|
-
return;
|
|
32909
|
-
}
|
|
32910
|
-
else {
|
|
32911
|
-
this.searchTextChanged.next(searchText);
|
|
32912
|
-
}
|
|
32913
|
-
}
|
|
32914
|
-
clearSearch() {
|
|
32915
|
-
this.searchText = '';
|
|
32916
|
-
this.results = [];
|
|
32917
|
-
this.errorMessage = null;
|
|
32918
|
-
}
|
|
32919
|
-
async zoomToLocation(result) {
|
|
32920
|
-
const geometry = result.geom;
|
|
32921
|
-
if (geometry.type === 'Point') {
|
|
32922
|
-
await this.zoomToPoint(geometry.coordinates);
|
|
32923
|
-
}
|
|
32924
|
-
else if (geometry.type === 'Polygon') {
|
|
32925
|
-
await this.zoomToPolygon(geometry.coordinates);
|
|
32926
|
-
}
|
|
32927
|
-
else {
|
|
32928
|
-
console.error(`Unsupported geometry type: ${geometry.type}`);
|
|
32929
|
-
}
|
|
32930
|
-
}
|
|
32931
|
-
async zoomToPoint(pointCoords) {
|
|
32932
|
-
const context = await firstValueFrom(this.mapFacade.context$);
|
|
32933
|
-
const view = {
|
|
32934
|
-
center: pointCoords,
|
|
32935
|
-
zoom: 10,
|
|
32936
|
-
};
|
|
32937
|
-
this.mapFacade.applyContext({
|
|
32938
|
-
...context,
|
|
32939
|
-
view,
|
|
32940
|
-
});
|
|
32941
|
-
}
|
|
32942
|
-
async zoomToPolygon(polygonCoords) {
|
|
32943
|
-
const context = await firstValueFrom(this.mapFacade.context$);
|
|
32944
|
-
const view = {
|
|
32945
|
-
geometry: {
|
|
32946
|
-
type: 'Polygon',
|
|
32947
|
-
coordinates: polygonCoords,
|
|
32948
|
-
},
|
|
32949
|
-
};
|
|
32950
|
-
this.mapFacade.applyContext({
|
|
32951
|
-
...context,
|
|
32952
|
-
view,
|
|
32953
|
-
});
|
|
32954
|
-
}
|
|
32955
|
-
onEnterPress() {
|
|
32956
|
-
if (this.results && this.results.length > 0) {
|
|
32957
|
-
this.zoomToLocation(this.results[0]);
|
|
32958
|
-
}
|
|
32959
|
-
}
|
|
32960
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
32961
|
-
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" }] }); }
|
|
32962
|
-
}
|
|
32963
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GeocodingComponent, decorators: [{
|
|
32964
|
-
type: Component,
|
|
32965
|
-
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" }]
|
|
32966
|
-
}], ctorParameters: () => [] });
|
|
32967
|
-
|
|
32968
32478
|
/*
|
|
32969
32479
|
Metadata actions
|
|
32970
32480
|
*/
|
|
@@ -34147,7 +33657,7 @@ class DataService {
|
|
|
34147
33657
|
}));
|
|
34148
33658
|
}
|
|
34149
33659
|
async getDownloadLinksFromOgcApiFeatures(ogcApiLink) {
|
|
34150
|
-
const collectionInfo = await this.getDownloadUrlsFromOgcApi(ogcApiLink.url.href);
|
|
33660
|
+
const collectionInfo = await this.getDownloadUrlsFromOgcApi(ogcApiLink.url.href, ogcApiLink.name);
|
|
34151
33661
|
return Object.keys(collectionInfo.bulkDownloadLinks).map((mimeType) => {
|
|
34152
33662
|
const urlWithoutLimit = new URL(collectionInfo.bulkDownloadLinks[mimeType]);
|
|
34153
33663
|
urlWithoutLimit.searchParams.delete('limit');
|
|
@@ -34160,27 +33670,31 @@ class DataService {
|
|
|
34160
33670
|
};
|
|
34161
33671
|
});
|
|
34162
33672
|
}
|
|
34163
|
-
async
|
|
33673
|
+
async getTargetCollectionId(endpoint, collectionId) {
|
|
33674
|
+
const collections = await endpoint.featureCollections;
|
|
33675
|
+
return collections.length === 1 && !collectionId
|
|
33676
|
+
? collections[0]
|
|
33677
|
+
: collectionId;
|
|
33678
|
+
}
|
|
33679
|
+
async getDownloadUrlsFromOgcApi(url, collectionId) {
|
|
34164
33680
|
const endpoint = new OgcApiEndpoint(url);
|
|
34165
|
-
|
|
34166
|
-
.
|
|
34167
|
-
return endpoint.getCollectionInfo(
|
|
34168
|
-
}
|
|
34169
|
-
|
|
34170
|
-
throw new Error(
|
|
34171
|
-
}
|
|
33681
|
+
try {
|
|
33682
|
+
const id = await this.getTargetCollectionId(endpoint, collectionId);
|
|
33683
|
+
return await endpoint.getCollectionInfo(id);
|
|
33684
|
+
}
|
|
33685
|
+
catch {
|
|
33686
|
+
throw new Error('ogc.unreachable.unknown');
|
|
33687
|
+
}
|
|
34172
33688
|
}
|
|
34173
|
-
async getItemsFromOgcApi(url, limit) {
|
|
33689
|
+
async getItemsFromOgcApi(url, collectionId, limit) {
|
|
34174
33690
|
const endpoint = new OgcApiEndpoint(url);
|
|
34175
|
-
|
|
34176
|
-
.
|
|
34177
|
-
return
|
|
34178
|
-
|
|
34179
|
-
|
|
34180
|
-
|
|
34181
|
-
|
|
34182
|
-
throw new Error(`ogc.unreachable.unknown`);
|
|
34183
|
-
});
|
|
33691
|
+
try {
|
|
33692
|
+
const id = await this.getTargetCollectionId(endpoint, collectionId);
|
|
33693
|
+
return await endpoint.getCollectionItems(id, limit);
|
|
33694
|
+
}
|
|
33695
|
+
catch {
|
|
33696
|
+
throw new Error('ogc.unreachable.unknown');
|
|
33697
|
+
}
|
|
34184
33698
|
}
|
|
34185
33699
|
async getItemsFromStacApi(url, options) {
|
|
34186
33700
|
return await StacEndpoint.getItemsFromUrl(url, options)
|
|
@@ -34268,7 +33782,7 @@ class DataService {
|
|
|
34268
33782
|
}
|
|
34269
33783
|
else if (link.type === 'service' &&
|
|
34270
33784
|
link.accessServiceProtocol === 'ogcFeatures') {
|
|
34271
|
-
return from(this.getDownloadUrlsFromOgcApi(link.url.href)).pipe(switchMap$1((collectionInfo) => {
|
|
33785
|
+
return from(this.getDownloadUrlsFromOgcApi(link.url.href, link.name)).pipe(switchMap$1((collectionInfo) => {
|
|
34272
33786
|
const isMimeTypeJson = (mimeType) => {
|
|
34273
33787
|
return mimeType.toLowerCase().indexOf('json') > -1;
|
|
34274
33788
|
};
|
|
@@ -35212,7 +34726,7 @@ class MdViewFacade {
|
|
|
35212
34726
|
if (this.linkClassifier.hasUsage(link, LinkUsage.GEODATA)) {
|
|
35213
34727
|
if (link.type === 'service' &&
|
|
35214
34728
|
link.accessServiceProtocol === 'ogcFeatures') {
|
|
35215
|
-
return from(this.dataService.getItemsFromOgcApi(link.url.href, 1)).pipe(map$1((collectionRecords) => {
|
|
34729
|
+
return from(this.dataService.getItemsFromOgcApi(link.url.href, link.name, 1)).pipe(map$1((collectionRecords) => {
|
|
35216
34730
|
return collectionRecords &&
|
|
35217
34731
|
collectionRecords[0] &&
|
|
35218
34732
|
collectionRecords[0].geometry
|
|
@@ -35295,7 +34809,7 @@ class MdViewEffects {
|
|
|
35295
34809
|
}
|
|
35296
34810
|
return loadFullMetadataSuccess({ full: record });
|
|
35297
34811
|
}), catchError((error) => of(loadFullMetadataFailure({ otherError: error.message })))));
|
|
35298
|
-
this.loadFeatureCatalog$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), filter$1(({ full }) => full !== undefined), switchMap$1(({ full }) => this.recordsRepository.
|
|
34812
|
+
this.loadFeatureCatalog$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), filter$1(({ full }) => full !== undefined), switchMap$1(({ full }) => this.recordsRepository.queryLinkedFeatureCatalog(full)), map$1((featureCatalog) => loadFeatureCatalogSuccess({
|
|
35299
34813
|
datasetCatalog: featureCatalog,
|
|
35300
34814
|
})), catchError((error) => of(loadFeatureCatalogFailure({
|
|
35301
34815
|
error: error.message,
|
|
@@ -38009,7 +37523,7 @@ class GenericKeywordsComponent {
|
|
|
38009
37523
|
this.deletedKeyword.emit(keyword);
|
|
38010
37524
|
}
|
|
38011
37525
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GenericKeywordsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
38012
|
-
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 }); }
|
|
37526
|
+
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 }); }
|
|
38013
37527
|
}
|
|
38014
37528
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GenericKeywordsComponent, decorators: [{
|
|
38015
37529
|
type: Component,
|
|
@@ -38601,7 +38115,7 @@ class FormFieldContactsForResourceComponent {
|
|
|
38601
38115
|
provideNgIconsConfig({
|
|
38602
38116
|
size: '1.5rem',
|
|
38603
38117
|
}),
|
|
38604
|
-
], 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 }); }
|
|
38118
|
+
], 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 }); }
|
|
38605
38119
|
}
|
|
38606
38120
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldContactsForResourceComponent, decorators: [{
|
|
38607
38121
|
type: Component,
|
|
@@ -38701,7 +38215,7 @@ class FormFieldContactsComponent {
|
|
|
38701
38215
|
this.subscription.unsubscribe();
|
|
38702
38216
|
}
|
|
38703
38217
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldContactsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
38704
|
-
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 }); }
|
|
38218
|
+
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 }); }
|
|
38705
38219
|
}
|
|
38706
38220
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldContactsComponent, decorators: [{
|
|
38707
38221
|
type: Component,
|
|
@@ -39054,7 +38568,7 @@ class OnlineServiceResourceInputComponent {
|
|
|
39054
38568
|
provideNgIconsConfig({
|
|
39055
38569
|
size: '1.5em',
|
|
39056
38570
|
}),
|
|
39057
|
-
], 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 }); }
|
|
38571
|
+
], 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 }); }
|
|
39058
38572
|
}
|
|
39059
38573
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: OnlineServiceResourceInputComponent, decorators: [{
|
|
39060
38574
|
type: Component,
|
|
@@ -40929,6 +40443,638 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
40929
40443
|
args: ['gnUiSearchRouterContainer']
|
|
40930
40444
|
}] } });
|
|
40931
40445
|
|
|
40446
|
+
const flatten = (base, obj, keepLevel = false) => Object.keys(obj).reduce((prev, curr) => {
|
|
40447
|
+
const path = base ? `${base}.${curr}` : curr;
|
|
40448
|
+
const val = obj[curr];
|
|
40449
|
+
if (keepLevel) {
|
|
40450
|
+
return { ...prev, [path]: flatten('', val) };
|
|
40451
|
+
}
|
|
40452
|
+
else if (typeof val === 'object' && !Array.isArray(val)) {
|
|
40453
|
+
return {
|
|
40454
|
+
...prev,
|
|
40455
|
+
...flatten(path, val),
|
|
40456
|
+
};
|
|
40457
|
+
}
|
|
40458
|
+
else {
|
|
40459
|
+
return { ...prev, [path]: val };
|
|
40460
|
+
}
|
|
40461
|
+
}, {});
|
|
40462
|
+
const checkKeys = (input, mandatory, optional) => {
|
|
40463
|
+
const keys = Object.keys(input);
|
|
40464
|
+
const missing = mandatory.filter((key) => keys.indexOf(key) === -1);
|
|
40465
|
+
const unrecognized = keys.filter((key) => mandatory.indexOf(key) === -1 && optional.indexOf(key) === -1);
|
|
40466
|
+
return {
|
|
40467
|
+
missing,
|
|
40468
|
+
unrecognized,
|
|
40469
|
+
};
|
|
40470
|
+
};
|
|
40471
|
+
/**
|
|
40472
|
+
* Only keeps recognized keys, flatten nested values (to allow having "." in keys),
|
|
40473
|
+
* pushes warnings and errors to the given arrays; returns null in case of error
|
|
40474
|
+
*/
|
|
40475
|
+
function parseConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
40476
|
+
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
40477
|
+
if (mandatoryKeys.length === 0)
|
|
40478
|
+
return null;
|
|
40479
|
+
outErrors.push(`The [${sectionName}] mandatory section is missing.`);
|
|
40480
|
+
return null;
|
|
40481
|
+
}
|
|
40482
|
+
const sectionConf = fullConfigObj[sectionName];
|
|
40483
|
+
const keysCheck = checkKeys(sectionConf, mandatoryKeys, optionalKeys);
|
|
40484
|
+
if (keysCheck.missing.length) {
|
|
40485
|
+
// note: this is not thrown to allow merging several Errors down the line
|
|
40486
|
+
outErrors.push(`In the [${sectionName}] section: ${keysCheck.missing.join(', ')}`);
|
|
40487
|
+
return null;
|
|
40488
|
+
}
|
|
40489
|
+
else if (keysCheck.unrecognized.length) {
|
|
40490
|
+
outWarnings.push(`In the [${sectionName}] section: ${keysCheck.unrecognized.join(', ')}`);
|
|
40491
|
+
keysCheck.unrecognized.forEach((key) => delete sectionConf[key]);
|
|
40492
|
+
}
|
|
40493
|
+
return sectionConf;
|
|
40494
|
+
}
|
|
40495
|
+
/**
|
|
40496
|
+
* Same as parseConfigSection but keeps all keys, recognized or not
|
|
40497
|
+
* Also the first level is the language code (e.g. 'en')
|
|
40498
|
+
* This is optional
|
|
40499
|
+
*/
|
|
40500
|
+
function parseTranslationsConfigSection(fullConfigObj, sectionName) {
|
|
40501
|
+
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
40502
|
+
return {};
|
|
40503
|
+
}
|
|
40504
|
+
return flatten('', fullConfigObj[sectionName], true);
|
|
40505
|
+
}
|
|
40506
|
+
/**
|
|
40507
|
+
* Same as parseConfigSection but handles an array of configs; this is
|
|
40508
|
+
* considered optional; returns null in case of error in at least one of
|
|
40509
|
+
* the sections
|
|
40510
|
+
*/
|
|
40511
|
+
function parseMultiConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
40512
|
+
const sections = fullConfigObj[sectionName];
|
|
40513
|
+
if (!sections) {
|
|
40514
|
+
return [];
|
|
40515
|
+
}
|
|
40516
|
+
if (!Array.isArray(sections)) {
|
|
40517
|
+
outErrors.push(`Expected [[${sectionName}]] to be an array of sections.`);
|
|
40518
|
+
return null;
|
|
40519
|
+
}
|
|
40520
|
+
const result = sections.map((section) => parseConfigSection({ [sectionName]: section }, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors));
|
|
40521
|
+
if (result.some((r) => r === null)) {
|
|
40522
|
+
return null;
|
|
40523
|
+
}
|
|
40524
|
+
return result;
|
|
40525
|
+
}
|
|
40526
|
+
function checkMetadataLanguage(parsedConfigSection, outWarnings) {
|
|
40527
|
+
const lang2 = toLang2(parsedConfigSection.metadata_language.toLowerCase());
|
|
40528
|
+
if (lang2?.length !== 2) {
|
|
40529
|
+
outWarnings.push(`In the [global] section: metadata_language = "${parsedConfigSection.metadata_language}" is not a recognized ISO 639 language code`);
|
|
40530
|
+
}
|
|
40531
|
+
return parsedConfigSection;
|
|
40532
|
+
}
|
|
40533
|
+
function checkNewRecordDefaultLanguage(parsedConfigSection, outWarnings) {
|
|
40534
|
+
const lang2 = toLang2(parsedConfigSection.new_record_default_language.toLowerCase());
|
|
40535
|
+
if (!(lang2 in LANG_2_TO_3_MAPPER)) {
|
|
40536
|
+
outWarnings.push(`In the [editing] section: new_record_default_language = "${parsedConfigSection.new_record_default_language}" is not a recognized ISO 639 language code`);
|
|
40537
|
+
return {
|
|
40538
|
+
...parsedConfigSection,
|
|
40539
|
+
new_record_default_language: undefined,
|
|
40540
|
+
};
|
|
40541
|
+
}
|
|
40542
|
+
return {
|
|
40543
|
+
...parsedConfigSection,
|
|
40544
|
+
new_record_default_language: lang2,
|
|
40545
|
+
};
|
|
40546
|
+
}
|
|
40547
|
+
function checkNewRecordStandard(parsedConfigSection, outWarnings) {
|
|
40548
|
+
const standard = parsedConfigSection.new_record_standard;
|
|
40549
|
+
const normalizedStandard = typeof standard === 'string' ? standard.trim().toLowerCase() : null;
|
|
40550
|
+
if (normalizedStandard === 'iso19139' ||
|
|
40551
|
+
normalizedStandard === 'iso19115-3') {
|
|
40552
|
+
return {
|
|
40553
|
+
...parsedConfigSection,
|
|
40554
|
+
new_record_standard: normalizedStandard,
|
|
40555
|
+
};
|
|
40556
|
+
}
|
|
40557
|
+
outWarnings.push(`In the [editing] section: new_record_standard = "${standard}" is not a supported metadata standard`);
|
|
40558
|
+
return {
|
|
40559
|
+
...parsedConfigSection,
|
|
40560
|
+
new_record_standard: undefined,
|
|
40561
|
+
};
|
|
40562
|
+
}
|
|
40563
|
+
|
|
40564
|
+
/**
|
|
40565
|
+
* This loader extends the default one based on JSON files but also loads custom translations
|
|
40566
|
+
* defined in the app configuration
|
|
40567
|
+
* Implements a fallback on default lang if translated labels are empty
|
|
40568
|
+
*/
|
|
40569
|
+
class FileWithOverridesTranslateLoader extends FileTranslateLoader {
|
|
40570
|
+
getTranslation(lang) {
|
|
40571
|
+
const baseLang = lang.substring(0, 2); // removing the right part of e.g. en_EN
|
|
40572
|
+
return super.getTranslation(baseLang).pipe(map$1((translations) => ({
|
|
40573
|
+
...translations,
|
|
40574
|
+
...getCustomTranslations(baseLang),
|
|
40575
|
+
})));
|
|
40576
|
+
}
|
|
40577
|
+
}
|
|
40578
|
+
|
|
40579
|
+
const MISSING_CONFIG_ERROR = `Application configuration was not initialized correctly.
|
|
40580
|
+
This error might show up in case of an invalid/malformed configuration file.
|
|
40581
|
+
|
|
40582
|
+
Note: make sure that you have called \`loadAppConfig\` from '../../../../../libs/util/app-config/src' before starting the Angular application.`;
|
|
40583
|
+
let globalConfig = null;
|
|
40584
|
+
function getGlobalConfig() {
|
|
40585
|
+
if (globalConfig === null)
|
|
40586
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40587
|
+
return globalConfig;
|
|
40588
|
+
}
|
|
40589
|
+
let themeConfig = null;
|
|
40590
|
+
function getThemeConfig() {
|
|
40591
|
+
if (themeConfig === null)
|
|
40592
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40593
|
+
return themeConfig;
|
|
40594
|
+
}
|
|
40595
|
+
let mapConfig = null;
|
|
40596
|
+
function getOptionalMapConfig() {
|
|
40597
|
+
return mapConfig;
|
|
40598
|
+
}
|
|
40599
|
+
let searchConfig = null;
|
|
40600
|
+
function getOptionalSearchConfig() {
|
|
40601
|
+
return searchConfig;
|
|
40602
|
+
}
|
|
40603
|
+
let editorConfig = null;
|
|
40604
|
+
function getOptionalEditorConfig() {
|
|
40605
|
+
return editorConfig;
|
|
40606
|
+
}
|
|
40607
|
+
let metadataQualityConfig = null;
|
|
40608
|
+
function getMetadataQualityConfig() {
|
|
40609
|
+
return (metadataQualityConfig ||
|
|
40610
|
+
{
|
|
40611
|
+
ENABLED: false,
|
|
40612
|
+
});
|
|
40613
|
+
}
|
|
40614
|
+
let customTranslations = null;
|
|
40615
|
+
function getCustomTranslations(langCode) {
|
|
40616
|
+
if (customTranslations === null)
|
|
40617
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40618
|
+
return langCode in customTranslations ? customTranslations[langCode] : {};
|
|
40619
|
+
}
|
|
40620
|
+
let appConfigLoaded = false;
|
|
40621
|
+
function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
|
|
40622
|
+
console.log(`[geonetwork-ui] Loading application configuration from ${configUrl}`);
|
|
40623
|
+
return fetch(configUrl)
|
|
40624
|
+
.then((resp) => {
|
|
40625
|
+
if (!resp.ok)
|
|
40626
|
+
throw new Error('Configuration file could not be loaded');
|
|
40627
|
+
return resp.text();
|
|
40628
|
+
})
|
|
40629
|
+
.then((conf) => {
|
|
40630
|
+
let parsed;
|
|
40631
|
+
try {
|
|
40632
|
+
parsed = TOML.parse(conf, { joiner: '\n', bigint: false });
|
|
40633
|
+
}
|
|
40634
|
+
catch (e) {
|
|
40635
|
+
throw new Error(`An error occurred when parsing the configuration file: ${e.message}`);
|
|
40636
|
+
}
|
|
40637
|
+
const errors = [];
|
|
40638
|
+
const warnings = [];
|
|
40639
|
+
let parsedGlobalSection = parseConfigSection(parsed, 'global', ['geonetwork4_api_url'], [
|
|
40640
|
+
'datahub_url',
|
|
40641
|
+
'edit_url_template',
|
|
40642
|
+
'proxy_path',
|
|
40643
|
+
'metadata_language',
|
|
40644
|
+
'login_url',
|
|
40645
|
+
'logout_url',
|
|
40646
|
+
'settings_url',
|
|
40647
|
+
'web_component_embedder_url',
|
|
40648
|
+
'languages',
|
|
40649
|
+
'contact_email',
|
|
40650
|
+
'reuse_form_url',
|
|
40651
|
+
], warnings, errors);
|
|
40652
|
+
if (parsedGlobalSection?.metadata_language) {
|
|
40653
|
+
parsedGlobalSection = checkMetadataLanguage(parsedGlobalSection, warnings);
|
|
40654
|
+
}
|
|
40655
|
+
globalConfig =
|
|
40656
|
+
parsedGlobalSection === null
|
|
40657
|
+
? null
|
|
40658
|
+
: {
|
|
40659
|
+
GN4_API_URL: parsedGlobalSection.geonetwork4_api_url,
|
|
40660
|
+
DATAHUB_URL: parsedGlobalSection.datahub_url,
|
|
40661
|
+
EDIT_URL_TEMPLATE: parsedGlobalSection.edit_url_template,
|
|
40662
|
+
PROXY_PATH: parsedGlobalSection.proxy_path,
|
|
40663
|
+
METADATA_LANGUAGE: parsedGlobalSection.metadata_language
|
|
40664
|
+
? parsedGlobalSection.metadata_language.toLowerCase()
|
|
40665
|
+
: undefined,
|
|
40666
|
+
LOGIN_URL: parsedGlobalSection.login_url,
|
|
40667
|
+
LOGOUT_URL: parsedGlobalSection.logout_url,
|
|
40668
|
+
SETTINGS_URL: parsedGlobalSection.settings_url,
|
|
40669
|
+
WEB_COMPONENT_EMBEDDER_URL: parsedGlobalSection.web_component_embedder_url,
|
|
40670
|
+
LANGUAGES: parsedGlobalSection.languages,
|
|
40671
|
+
CONTACT_EMAIL: parsedGlobalSection.contact_email,
|
|
40672
|
+
REUSE_FORM_URL: parsedGlobalSection.reuse_form_url,
|
|
40673
|
+
};
|
|
40674
|
+
const parsedLayersSections = parseMultiConfigSection(parsed, 'map_layer', ['type'], ['name', 'url', 'data', 'styleUrl', 'accessToken'], warnings, errors);
|
|
40675
|
+
const parsedMapSection = parseConfigSection(parsed, 'map', [], [
|
|
40676
|
+
'max_zoom',
|
|
40677
|
+
'do_not_tile_wms',
|
|
40678
|
+
'max_extent',
|
|
40679
|
+
'max_feature_count',
|
|
40680
|
+
'baselayer',
|
|
40681
|
+
'do_not_use_default_basemap',
|
|
40682
|
+
'external_viewer_url_template',
|
|
40683
|
+
'external_viewer_open_new_tab',
|
|
40684
|
+
], warnings, errors);
|
|
40685
|
+
mapConfig =
|
|
40686
|
+
parsedMapSection === null || parsedLayersSections === null
|
|
40687
|
+
? null
|
|
40688
|
+
: {
|
|
40689
|
+
MAX_ZOOM: parsedMapSection.max_zoom,
|
|
40690
|
+
DO_NOT_TILE_WMS: parsedMapSection.do_not_tile_wms,
|
|
40691
|
+
MAX_EXTENT: parsedMapSection.max_extent,
|
|
40692
|
+
MAX_FEATURE_COUNT: parsedMapSection.max_feature_count,
|
|
40693
|
+
EXTERNAL_VIEWER_URL_TEMPLATE: parsedMapSection.external_viewer_url_template,
|
|
40694
|
+
EXTERNAL_VIEWER_OPEN_NEW_TAB: parsedMapSection.external_viewer_open_new_tab,
|
|
40695
|
+
DO_NOT_USE_DEFAULT_BASEMAP: !!parsedMapSection.do_not_use_default_basemap,
|
|
40696
|
+
MAP_LAYERS: parsedLayersSections.map((map_layer) => ({
|
|
40697
|
+
TYPE: map_layer.type,
|
|
40698
|
+
URL: map_layer.url,
|
|
40699
|
+
NAME: map_layer.name,
|
|
40700
|
+
DATA: map_layer.data,
|
|
40701
|
+
STYLE_URL: map_layer.styleUrl,
|
|
40702
|
+
ACCESS_TOKEN: map_layer.accessToken,
|
|
40703
|
+
})),
|
|
40704
|
+
};
|
|
40705
|
+
const parsedThemeSection = parseConfigSection(parsed, 'theme', ['primary_color', 'secondary_color', 'main_color', 'background_color'], [
|
|
40706
|
+
'header_foreground_color',
|
|
40707
|
+
'main_font',
|
|
40708
|
+
'title_font',
|
|
40709
|
+
'fonts_stylesheet_url',
|
|
40710
|
+
'thumbnail_placeholder',
|
|
40711
|
+
'header_background',
|
|
40712
|
+
'favicon',
|
|
40713
|
+
], warnings, errors);
|
|
40714
|
+
themeConfig =
|
|
40715
|
+
parsedThemeSection === null
|
|
40716
|
+
? null
|
|
40717
|
+
: {
|
|
40718
|
+
PRIMARY_COLOR: parsedThemeSection.primary_color,
|
|
40719
|
+
SECONDARY_COLOR: parsedThemeSection.secondary_color,
|
|
40720
|
+
MAIN_COLOR: parsedThemeSection.main_color,
|
|
40721
|
+
BACKGROUND_COLOR: parsedThemeSection.background_color,
|
|
40722
|
+
HEADER_FOREGROUND_COLOR: parsedThemeSection.header_foreground_color,
|
|
40723
|
+
THUMBNAIL_PLACEHOLDER: parsedThemeSection.thumbnail_placeholder,
|
|
40724
|
+
HEADER_BACKGROUND: parsedThemeSection.header_background,
|
|
40725
|
+
TITLE_FONT: parsedThemeSection.title_font,
|
|
40726
|
+
MAIN_FONT: parsedThemeSection.main_font,
|
|
40727
|
+
FONTS_STYLESHEET_URL: parsedThemeSection.fonts_stylesheet_url,
|
|
40728
|
+
FAVICON: parsedThemeSection.favicon,
|
|
40729
|
+
};
|
|
40730
|
+
const parsedSearchSection = parseConfigSection(parsed, 'search', [], [
|
|
40731
|
+
'record_kind_quick_filter',
|
|
40732
|
+
'filter_geometry_data',
|
|
40733
|
+
'filter_geometry_url',
|
|
40734
|
+
'do_not_use_default_search_preset',
|
|
40735
|
+
'search_preset',
|
|
40736
|
+
'advanced_filters',
|
|
40737
|
+
'limit',
|
|
40738
|
+
'spatial_extent_max_file_size',
|
|
40739
|
+
'geocoding_provider',
|
|
40740
|
+
'geocoding_provider_options',
|
|
40741
|
+
'geocoding_provider_labels',
|
|
40742
|
+
], warnings, errors);
|
|
40743
|
+
const parsedSearchParams = parseMultiConfigSection(parsed, 'search_preset', ['name'], ['sort', 'filters'], warnings, errors);
|
|
40744
|
+
const parsedCustomFilters = parseMultiConfigSection(parsed, 'custom_filter', ['name', 'base_filter'], ['exclude_values', 'include_values', 'label_key'], warnings, errors);
|
|
40745
|
+
const parsedGeocodingProviderLabels = parsedSearchSection?.geocoding_provider_labels;
|
|
40746
|
+
searchConfig =
|
|
40747
|
+
parsedSearchSection === null
|
|
40748
|
+
? null
|
|
40749
|
+
: {
|
|
40750
|
+
RECORD_KIND_QUICK_FILTER: parsedSearchSection.record_kind_quick_filter,
|
|
40751
|
+
FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
|
|
40752
|
+
FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
|
|
40753
|
+
DO_NOT_USE_DEFAULT_SEARCH_PRESET: !!parsedSearchSection.do_not_use_default_search_preset,
|
|
40754
|
+
SEARCH_PRESET: parsedSearchParams.map((param) => ({
|
|
40755
|
+
sort: param.sort,
|
|
40756
|
+
name: param.name,
|
|
40757
|
+
filters: param.filters,
|
|
40758
|
+
})),
|
|
40759
|
+
ADVANCED_FILTERS: parsedSearchSection.advanced_filters,
|
|
40760
|
+
CUSTOM_FILTERS: (parsedCustomFilters ?? []).map((customFilter) => ({
|
|
40761
|
+
name: customFilter.name,
|
|
40762
|
+
baseFilter: customFilter.base_filter,
|
|
40763
|
+
excludeValues: customFilter.exclude_values,
|
|
40764
|
+
includeValues: customFilter.include_values,
|
|
40765
|
+
labelKey: customFilter.label_key,
|
|
40766
|
+
})),
|
|
40767
|
+
LIMIT: parsedSearchSection.limit,
|
|
40768
|
+
SPATIAL_EXTENT_MAX_FILE_SIZE: parsedSearchSection.spatial_extent_max_file_size,
|
|
40769
|
+
GEOCODING_PROVIDER: parsedSearchSection.geocoding_provider,
|
|
40770
|
+
GEOCODING_PROVIDER_OPTIONS: parsedSearchSection.geocoding_provider_options,
|
|
40771
|
+
GEOCODING_PROVIDER_LABELS: parsedGeocodingProviderLabels
|
|
40772
|
+
? {
|
|
40773
|
+
MAIN: parsedGeocodingProviderLabels.main,
|
|
40774
|
+
SECONDARY: parsedGeocodingProviderLabels.secondary,
|
|
40775
|
+
TERTIARY: parsedGeocodingProviderLabels.tertiary,
|
|
40776
|
+
}
|
|
40777
|
+
: undefined,
|
|
40778
|
+
};
|
|
40779
|
+
const parsedMetadataQualitySection = parseConfigSection(parsed, 'metadata-quality', [], ['enabled'], warnings, errors);
|
|
40780
|
+
metadataQualityConfig =
|
|
40781
|
+
parsedMetadataQualitySection === null
|
|
40782
|
+
? null
|
|
40783
|
+
: {
|
|
40784
|
+
ENABLED: parsedMetadataQualitySection.enabled,
|
|
40785
|
+
SORTABLE: parsedMetadataQualitySection.sortable,
|
|
40786
|
+
};
|
|
40787
|
+
let parsedEditingSection = parseConfigSection(parsed, 'editing', [], ['new_record_default_language', 'new_record_standard'], warnings, errors);
|
|
40788
|
+
if (parsedEditingSection !== null &&
|
|
40789
|
+
parsedEditingSection.new_record_default_language !== undefined) {
|
|
40790
|
+
parsedEditingSection = checkNewRecordDefaultLanguage(parsedEditingSection, warnings);
|
|
40791
|
+
}
|
|
40792
|
+
if (parsedEditingSection !== null &&
|
|
40793
|
+
parsedEditingSection.new_record_standard !== undefined) {
|
|
40794
|
+
parsedEditingSection = checkNewRecordStandard(parsedEditingSection, warnings);
|
|
40795
|
+
}
|
|
40796
|
+
editorConfig =
|
|
40797
|
+
parsedEditingSection === null
|
|
40798
|
+
? null
|
|
40799
|
+
: {
|
|
40800
|
+
NEW_RECORD_DEFAULT_LANGUAGE: parsedEditingSection.new_record_default_language,
|
|
40801
|
+
NEW_RECORD_STANDARD: parsedEditingSection.new_record_standard,
|
|
40802
|
+
};
|
|
40803
|
+
customTranslations = parseTranslationsConfigSection(parsed, 'translations');
|
|
40804
|
+
if (errors.length) {
|
|
40805
|
+
throw new Error(`One or more mandatory settings were missing from the configuration file.
|
|
40806
|
+
${errors.join('\n')}`);
|
|
40807
|
+
}
|
|
40808
|
+
else if (warnings.length) {
|
|
40809
|
+
console.warn(`One or more unexpected settings were encountered in the configuration file.
|
|
40810
|
+
${warnings.join('\n')}`);
|
|
40811
|
+
}
|
|
40812
|
+
appConfigLoaded = true;
|
|
40813
|
+
});
|
|
40814
|
+
}
|
|
40815
|
+
function isConfigLoaded() {
|
|
40816
|
+
return appConfigLoaded;
|
|
40817
|
+
}
|
|
40818
|
+
function _reset() {
|
|
40819
|
+
globalConfig = null;
|
|
40820
|
+
themeConfig = null;
|
|
40821
|
+
editorConfig = null;
|
|
40822
|
+
customTranslations = null;
|
|
40823
|
+
}
|
|
40824
|
+
const TRANSLATE_WITH_OVERRIDES_CONFIG = {
|
|
40825
|
+
compiler: {
|
|
40826
|
+
provide: TranslateCompiler,
|
|
40827
|
+
useClass: TranslateMessageFormatCompiler,
|
|
40828
|
+
},
|
|
40829
|
+
loader: [
|
|
40830
|
+
{
|
|
40831
|
+
provide: TRANSLATE_HTTP_LOADER_CONFIG,
|
|
40832
|
+
useValue: {
|
|
40833
|
+
prefix: './assets/i18n/',
|
|
40834
|
+
suffix: '.json',
|
|
40835
|
+
},
|
|
40836
|
+
},
|
|
40837
|
+
{
|
|
40838
|
+
provide: TranslateLoader,
|
|
40839
|
+
useClass: FileWithOverridesTranslateLoader,
|
|
40840
|
+
deps: [HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
|
|
40841
|
+
},
|
|
40842
|
+
],
|
|
40843
|
+
};
|
|
40844
|
+
|
|
40845
|
+
const okAppConfigFixture = () => `
|
|
40846
|
+
[global]
|
|
40847
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
40848
|
+
proxy_path = "/proxy/?url="
|
|
40849
|
+
metadata_language = "fre"
|
|
40850
|
+
login_url = "/cas/login?service="
|
|
40851
|
+
logout_url = "/geonetwork/signout"
|
|
40852
|
+
settings_url = "/geonetwork/settings"
|
|
40853
|
+
web_component_embedder_url = "/datahub/wc-embedder.html"
|
|
40854
|
+
|
|
40855
|
+
[map]
|
|
40856
|
+
max_zoom = 10
|
|
40857
|
+
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
40858
|
+
do_not_use_default_basemap = false
|
|
40859
|
+
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
40860
|
+
external_viewer_open_new_tab = true
|
|
40861
|
+
[[map_layer]]
|
|
40862
|
+
type = "wms"
|
|
40863
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
40864
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
40865
|
+
[[map_layer]]
|
|
40866
|
+
type = "wfs"
|
|
40867
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
40868
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
40869
|
+
|
|
40870
|
+
[theme]
|
|
40871
|
+
primary_color = "#093564"
|
|
40872
|
+
secondary_color = "#c2e9dc"
|
|
40873
|
+
main_color = "#212029" # All-purpose text color
|
|
40874
|
+
background_color = "#fdfbff"
|
|
40875
|
+
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
40876
|
+
header_background = 'teal'
|
|
40877
|
+
header_foreground_color = "#872e2e"
|
|
40878
|
+
main_font = 'sans-serif'
|
|
40879
|
+
title_font = 'serif'
|
|
40880
|
+
fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
|
|
40881
|
+
|
|
40882
|
+
[search]
|
|
40883
|
+
record_kind_quick_filter = false
|
|
40884
|
+
filter_geometry_url = 'https://my.domain.org/geom.json'
|
|
40885
|
+
do_not_use_default_search_preset = false
|
|
40886
|
+
geocoding_provider = "geoplateforme"
|
|
40887
|
+
geocoding_provider_options.index = "poi"
|
|
40888
|
+
geocoding_provider_options.category = "administratif"
|
|
40889
|
+
geocoding_provider_options.limit = 5
|
|
40890
|
+
geocoding_provider_labels.main = '/properties/name/0'
|
|
40891
|
+
geocoding_provider_labels.secondary = '/properties/citycode/0'
|
|
40892
|
+
geocoding_provider_labels.tertiary = '/properties/category/1'
|
|
40893
|
+
advanced_filters = ['publicationYear', 'documentStandard', 'inspireKeyword', 'topic', 'license', 'myOrg:firstCustomFilter', 'myOrg:secondCustomFilter']
|
|
40894
|
+
|
|
40895
|
+
[[custom_filter]]
|
|
40896
|
+
name = 'myOrg:firstCustomFilter'
|
|
40897
|
+
base_filter = 'keyword'
|
|
40898
|
+
exclude_values = ['my keyword 1', 'my keyword 2']
|
|
40899
|
+
label_key = 'myOrg.firstCustomFilter'
|
|
40900
|
+
|
|
40901
|
+
[[custom_filter]]
|
|
40902
|
+
name = 'myOrg:secondCustomFilter'
|
|
40903
|
+
base_filter = 'keyword'
|
|
40904
|
+
include_values = ['my keyword 3', 'my keyword 4']
|
|
40905
|
+
label_key = 'myOrg.secondCustomFilter'
|
|
40906
|
+
|
|
40907
|
+
[[search_preset]]
|
|
40908
|
+
sort = "-createDate"
|
|
40909
|
+
name = 'filterByOrgs'
|
|
40910
|
+
filters.q = 'Carto'
|
|
40911
|
+
filters.organisation = ['Org1', 'Org2']
|
|
40912
|
+
filters.format = ['ESRI Shapefile']
|
|
40913
|
+
filters.topic = ['boundaries']
|
|
40914
|
+
filters.publicationYear = ['2023', '2022']
|
|
40915
|
+
filters.spatial = ['yes']
|
|
40916
|
+
|
|
40917
|
+
[translations.en]
|
|
40918
|
+
"my.first.key" = 'First label.'
|
|
40919
|
+
"my.second.key" = """
|
|
40920
|
+
Second label,
|
|
40921
|
+
on two lines."""
|
|
40922
|
+
|
|
40923
|
+
[translations.de]
|
|
40924
|
+
my.first.key = 'Erste Etikett.'
|
|
40925
|
+
|
|
40926
|
+
[translations.fr]
|
|
40927
|
+
my.sample.text = "Un bon exemple de texte."
|
|
40928
|
+
"my.quoted.text" = 'du texte entre guillements.'
|
|
40929
|
+
`;
|
|
40930
|
+
const appConfigWithTranslationFixture = () => okAppConfigFixture();
|
|
40931
|
+
const minimalAppConfigFixture = () => `
|
|
40932
|
+
[global]
|
|
40933
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
40934
|
+
proxy_path = "/proxy/?url="
|
|
40935
|
+
|
|
40936
|
+
[theme]
|
|
40937
|
+
primary_color = "#093564"
|
|
40938
|
+
secondary_color = "#c2e9dc"
|
|
40939
|
+
main_color = "#212029" # All-purpose text color
|
|
40940
|
+
background_color = "#fdfbff"
|
|
40941
|
+
`;
|
|
40942
|
+
const customFilterMissingMandatoryConfigFixture = () => `
|
|
40943
|
+
[global]
|
|
40944
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
40945
|
+
|
|
40946
|
+
[theme]
|
|
40947
|
+
primary_color = "#093564"
|
|
40948
|
+
secondary_color = "#c2e9dc"
|
|
40949
|
+
main_color = "#212029" # All-purpose text color
|
|
40950
|
+
background_color = "#fdfbff"
|
|
40951
|
+
|
|
40952
|
+
[search]
|
|
40953
|
+
advanced_filters = ['myOrg:firstCustomFilter']
|
|
40954
|
+
|
|
40955
|
+
[[custom_filter]]
|
|
40956
|
+
name = 'myOrg:firstCustomFilter'
|
|
40957
|
+
`;
|
|
40958
|
+
const mapConfigFixture = () => ({
|
|
40959
|
+
MAX_ZOOM: 10,
|
|
40960
|
+
MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
|
|
40961
|
+
DO_NOT_USE_DEFAULT_BASEMAP: false,
|
|
40962
|
+
DO_NOT_TILE_WMS: false,
|
|
40963
|
+
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}"}]}]',
|
|
40964
|
+
EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
|
|
40965
|
+
MAP_LAYERS: [
|
|
40966
|
+
{
|
|
40967
|
+
TYPE: 'xyz',
|
|
40968
|
+
URL: 'https://some-basemap-server',
|
|
40969
|
+
},
|
|
40970
|
+
{
|
|
40971
|
+
TYPE: 'wms',
|
|
40972
|
+
URL: 'https://some-wms-server',
|
|
40973
|
+
NAME: 'some_layername',
|
|
40974
|
+
},
|
|
40975
|
+
{
|
|
40976
|
+
TYPE: 'wfs',
|
|
40977
|
+
URL: 'https://some-wfs-server',
|
|
40978
|
+
NAME: 'some_layername',
|
|
40979
|
+
},
|
|
40980
|
+
],
|
|
40981
|
+
});
|
|
40982
|
+
const malformedConfigFixture = () => `
|
|
40983
|
+
{
|
|
40984
|
+
"I thought": "we were still doing json"
|
|
40985
|
+
}
|
|
40986
|
+
`;
|
|
40987
|
+
const missingMandatoryConfigFixture = () => `
|
|
40988
|
+
[theme]
|
|
40989
|
+
primary_color = "#093564"
|
|
40990
|
+
secondary_color = "#c2e9dc"
|
|
40991
|
+
background_color = "#fdfbff"
|
|
40992
|
+
main_font = 'sans-serif'
|
|
40993
|
+
`;
|
|
40994
|
+
const wrongLanguageCodeConfigFixture = () => `
|
|
40995
|
+
[global]
|
|
40996
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
40997
|
+
proxy_path = "/proxy/?url="
|
|
40998
|
+
metadata_language = "abc"
|
|
40999
|
+
|
|
41000
|
+
[map]
|
|
41001
|
+
|
|
41002
|
+
[theme]
|
|
41003
|
+
primary_color = "#093564"
|
|
41004
|
+
secondary_color = "#c2e9dc"
|
|
41005
|
+
main_color = "#212029" # All-purpose text color
|
|
41006
|
+
background_color = "#fdfbff"
|
|
41007
|
+
`;
|
|
41008
|
+
const unrecognizedKeysConfigFixture = () => `
|
|
41009
|
+
[global]
|
|
41010
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
41011
|
+
proxy_path = "/proxy/?url="
|
|
41012
|
+
metadata_language = "fre"
|
|
41013
|
+
another_path = '/whatever'
|
|
41014
|
+
|
|
41015
|
+
[map]
|
|
41016
|
+
max_zoom = 10
|
|
41017
|
+
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
41018
|
+
do_not_use_default_basemap = false
|
|
41019
|
+
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
41020
|
+
external_viewer_open_new_tab = true
|
|
41021
|
+
another_zoom = 15
|
|
41022
|
+
[[map_layer]]
|
|
41023
|
+
type = "wms"
|
|
41024
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
41025
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
41026
|
+
[[map_layer]]
|
|
41027
|
+
type = "wfs"
|
|
41028
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
41029
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
41030
|
+
another_layer = "wrong layer definition"
|
|
41031
|
+
|
|
41032
|
+
[theme]
|
|
41033
|
+
primary_color = "#093564"
|
|
41034
|
+
secondary_color = "#c2e9dc"
|
|
41035
|
+
main_color = "#212029" # All-purpose text color
|
|
41036
|
+
background_color = "#fdfbff"
|
|
41037
|
+
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
41038
|
+
header_background = 'teal'
|
|
41039
|
+
header_foreground_color = "#872e2e"
|
|
41040
|
+
main_font = 'sans-serif'
|
|
41041
|
+
title_font = 'serif'
|
|
41042
|
+
another_color = 'red'
|
|
41043
|
+
`;
|
|
41044
|
+
|
|
41045
|
+
function getMapContextLayerFromConfig(config) {
|
|
41046
|
+
switch (config.TYPE) {
|
|
41047
|
+
case 'wms':
|
|
41048
|
+
return {
|
|
41049
|
+
type: 'wms',
|
|
41050
|
+
url: config.URL,
|
|
41051
|
+
name: config.NAME,
|
|
41052
|
+
};
|
|
41053
|
+
case 'wfs':
|
|
41054
|
+
return {
|
|
41055
|
+
type: 'wfs',
|
|
41056
|
+
url: config.URL,
|
|
41057
|
+
featureType: config.NAME,
|
|
41058
|
+
};
|
|
41059
|
+
case 'xyz':
|
|
41060
|
+
return {
|
|
41061
|
+
type: config.TYPE,
|
|
41062
|
+
url: config.URL,
|
|
41063
|
+
};
|
|
41064
|
+
case 'geojson':
|
|
41065
|
+
return {
|
|
41066
|
+
type: config.TYPE,
|
|
41067
|
+
...(config.DATA ? { data: config.DATA } : { url: config.URL }),
|
|
41068
|
+
};
|
|
41069
|
+
case 'maplibre-style':
|
|
41070
|
+
return {
|
|
41071
|
+
type: config.TYPE,
|
|
41072
|
+
styleUrl: config.STYLE_URL,
|
|
41073
|
+
accessToken: config.ACCESS_TOKEN,
|
|
41074
|
+
};
|
|
41075
|
+
}
|
|
41076
|
+
}
|
|
41077
|
+
|
|
40932
41078
|
const CHART_TYPE_VALUES = [
|
|
40933
41079
|
'bar',
|
|
40934
41080
|
'bar-horizontal',
|
|
@@ -40944,5 +41090,5 @@ const CHART_TYPE_VALUES = [
|
|
|
40944
41090
|
* Generated bundle index. Do not edit.
|
|
40945
41091
|
*/
|
|
40946
41092
|
|
|
40947
|
-
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, 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 };
|
|
41093
|
+
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 };
|
|
40948
41094
|
//# sourceMappingURL=geonetwork-ui.mjs.map
|