geonetwork-ui 2.11.0-dev.0504d85cc → 2.11.0-dev.0559cfd9d
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 +1347 -1152
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/index.d.ts +117 -64
- package/index.d.ts.map +1 -1
- package/package.json +6 -5
- package/src/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts +2 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/mel.records.dataset+featurecatalog.ts +395 -0
- package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +35 -8
- package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +19 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +17 -6
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +110 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +131 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +9 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +2 -1
- package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +29 -3
- 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 +14 -18
- package/src/libs/common/domain/src/lib/model/search/aggregation.model.ts +2 -0
- package/src/libs/common/domain/src/lib/model/search/filter.model.ts +4 -1
- 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 -1
- 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/lib/filter-dropdown/filter-dropdown.component.html +7 -1
- package/src/libs/feature/search/src/lib/filter-dropdown/filter-dropdown.component.ts +26 -4
- package/src/libs/feature/search/src/lib/geocoding/geocoding.service.ts +52 -8
- package/src/libs/feature/search/src/lib/location-search/location-search.component.html +11 -1
- package/src/libs/feature/search/src/lib/location-search/location-search.component.ts +77 -3
- package/src/libs/feature/search/src/lib/search-filters-summary-item/search-filters-summary-item.component.ts +1 -0
- package/src/libs/feature/search/src/lib/state/reducer.ts +1 -4
- package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +56 -4
- package/src/libs/feature/search/src/lib/utils/service/fields.ts +33 -9
- package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.html +3 -3
- package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.ts +2 -2
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.css +0 -4
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.html +2 -2
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +3 -3
- 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 +7 -1
- package/src/libs/ui/inputs/src/lib/spatial-extent-dropdown/spatial-extent-dropdown.component.ts +26 -3
- 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/translations/de.json +8 -2
- package/translations/en.json +8 -2
- package/translations/es.json +8 -2
- package/translations/fr.json +12 -6
- package/translations/it.json +8 -2
- package/translations/nl.json +8 -2
- package/translations/pt.json +8 -2
- package/translations/sk.json +8 -2
- 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
|
@@ -36,9 +36,6 @@ import { createLegendFromLayer } from '@geospatial-sdk/legend';
|
|
|
36
36
|
import { mouseOnly, noModifierKeys, primaryAction, platformModifierKeyOnly } from 'ol/events/condition.js';
|
|
37
37
|
import { defaults, DragPan, MouseWheelZoom } from 'ol/interaction.js';
|
|
38
38
|
import { extend } from 'ol/extent.js';
|
|
39
|
-
import * as TOML from '@ltd/j-toml';
|
|
40
|
-
import { Style, Stroke, Fill, Circle } from 'ol/style.js';
|
|
41
|
-
import CircleStyle from 'ol/style/Circle.js';
|
|
42
39
|
import EmblaCarousel from 'embla-carousel';
|
|
43
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';
|
|
44
41
|
import { MatButtonModule } from '@angular/material/button';
|
|
@@ -73,7 +70,8 @@ import { MatTabsModule } from '@angular/material/tabs';
|
|
|
73
70
|
import * as i2$2 from '@ngrx/effects';
|
|
74
71
|
import { Actions, createEffect, ofType, EffectsModule } from '@ngrx/effects';
|
|
75
72
|
import { valid as valid$1 } from 'geojson-validation';
|
|
76
|
-
import {
|
|
73
|
+
import { queryGeoplateforme, queryGeonames, queryGeoadmin } from '@geospatial-sdk/geocoding';
|
|
74
|
+
import pointer from 'jsonpointer';
|
|
77
75
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
78
76
|
import { parse as parse$3 } from 'marked';
|
|
79
77
|
import * as i2$3 from '@angular/cdk/scrolling';
|
|
@@ -101,6 +99,7 @@ import { TextFieldModule } from '@angular/cdk/text-field';
|
|
|
101
99
|
import * as i2$5 from '@ngrx/router-store';
|
|
102
100
|
import { getRouterSelectors, routerReducer, StoreRouterConnectingModule, FullRouterStateSerializer } from '@ngrx/router-store';
|
|
103
101
|
import { navigation } from '@ngrx/router-store/data-persistence';
|
|
102
|
+
import * as TOML from '@ltd/j-toml';
|
|
104
103
|
|
|
105
104
|
class MetadataMapperContext {
|
|
106
105
|
}
|
|
@@ -1139,7 +1138,7 @@ function kindToCodeListValue(record) {
|
|
|
1139
1138
|
}
|
|
1140
1139
|
|
|
1141
1140
|
function extractCharacterString() {
|
|
1142
|
-
return pipe(fallback(findChildElement('gco:CharacterString', false), findChildElement('gmx:Anchor', false), findChildElement('gmx:MimeFileType', false)), readText());
|
|
1141
|
+
return pipe(fallback(findChildElement('gco:CharacterString', false), findChildElement('gmx:Anchor', false), findChildElement('gmx:MimeFileType', false), findChildElement('gco:LocalName', false)), readText());
|
|
1143
1142
|
}
|
|
1144
1143
|
/**
|
|
1145
1144
|
* Translated values will also be collected in the translations object
|
|
@@ -2202,6 +2201,7 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2202
2201
|
lineage: readLineage$1,
|
|
2203
2202
|
sourceRecords: readSourceRecords$1,
|
|
2204
2203
|
associatedRecords: readAssociatedRecords$1,
|
|
2204
|
+
featureTypeDescriptions: () => undefined,
|
|
2205
2205
|
onlineResources: readOnlineResources$2,
|
|
2206
2206
|
temporalExtents: readTemporalExtents,
|
|
2207
2207
|
spatialExtents: readSpatialExtents$1,
|
|
@@ -2241,6 +2241,7 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2241
2241
|
lineage: writeLineage$1,
|
|
2242
2242
|
sourceRecords: writeSourceRecords$1,
|
|
2243
2243
|
associatedRecords: writeAssociatedRecords$1,
|
|
2244
|
+
featureTypeDescriptions: () => undefined,
|
|
2244
2245
|
onlineResources: writeOnlineResources$1,
|
|
2245
2246
|
temporalExtents: writeTemporalExtents,
|
|
2246
2247
|
spatialExtents: writeSpatialExtents,
|
|
@@ -2367,6 +2368,7 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2367
2368
|
const sourceRecords = this.readers['sourceRecords'](rootEl, tr);
|
|
2368
2369
|
const associatedRecords = this.readers['associatedRecords'](rootEl, tr);
|
|
2369
2370
|
const updateFrequency = this.readers['updateFrequency'](rootEl, tr);
|
|
2371
|
+
const featureTypeDescriptions = this.readers['featureTypeDescriptions'](rootEl, tr);
|
|
2370
2372
|
return this.afterRecordRead({
|
|
2371
2373
|
...this.readBaseRecord(rootEl, tr),
|
|
2372
2374
|
kind,
|
|
@@ -2377,6 +2379,7 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2377
2379
|
...(spatialRepresentation && { spatialRepresentation }),
|
|
2378
2380
|
temporalExtents,
|
|
2379
2381
|
updateFrequency,
|
|
2382
|
+
...(featureTypeDescriptions?.length && { featureTypeDescriptions }),
|
|
2380
2383
|
translations: tr,
|
|
2381
2384
|
});
|
|
2382
2385
|
}
|
|
@@ -2466,6 +2469,8 @@ class Iso19139Converter extends BaseConverter {
|
|
|
2466
2469
|
this.writers['resourceIdentifiers'](record, rootEl);
|
|
2467
2470
|
if (record.kind === 'dataset') {
|
|
2468
2471
|
fieldChanged('status') && this.writers['status'](record, rootEl);
|
|
2472
|
+
fieldChanged('featureTypeDescriptions') &&
|
|
2473
|
+
this.writers['featureTypeDescriptions'](record, rootEl);
|
|
2469
2474
|
}
|
|
2470
2475
|
if (record.kind === 'dataset' || record.kind === 'reuse') {
|
|
2471
2476
|
fieldChanged('updateFrequency') &&
|
|
@@ -2633,6 +2638,34 @@ function readDefaultLanguage$1(rootEl) {
|
|
|
2633
2638
|
function readOtherLanguages(rootEl) {
|
|
2634
2639
|
return pipe(findChildrenElement('mdb:otherLocale', false), mapArray(readLocaleElement()), map((languages) => languages.filter((lang) => lang !== null)))(rootEl);
|
|
2635
2640
|
}
|
|
2641
|
+
function extractCharacterStringOrText() {
|
|
2642
|
+
return fallback(extractCharacterString(), readText());
|
|
2643
|
+
}
|
|
2644
|
+
function extractListedValue() {
|
|
2645
|
+
return pipe(combine(pipe(findChildElement('gfc:code', false), extractCharacterString()), pipe(findChildElement('gfc:label', false), extractCharacterString()), pipe(findChildElement('gfc:definition', false), extractCharacterString())), map(([code, label, description]) => ({
|
|
2646
|
+
value: code ?? '',
|
|
2647
|
+
...(label && { label }),
|
|
2648
|
+
...(description && { description }),
|
|
2649
|
+
})));
|
|
2650
|
+
}
|
|
2651
|
+
function extractFeatureAttribute() {
|
|
2652
|
+
return pipe(combine(pipe(findChildElement('gfc:memberName', false), extractCharacterStringOrText()), pipe(findChildElement('gfc:designation', false), extractCharacterString()), pipe(findChildElement('gfc:definition', false), extractCharacterString()), pipe(findChildElement('gfc:code', false), extractCharacterString()), pipe(findNestedElement('gfc:valueType', 'gco:TypeName', 'gco:aName'), extractCharacterString()), pipe(findNestedElements('gfc:listedValue', 'gfc:FC_ListedValue'), mapArray(extractListedValue()), filterArray((value) => !!(value.value || value.label)))), map(([name, label, description, code, type, values]) => ({
|
|
2653
|
+
name: name ?? '',
|
|
2654
|
+
...(label && { label }),
|
|
2655
|
+
...(description && { description }),
|
|
2656
|
+
...(code && { code }),
|
|
2657
|
+
...(type && { type }),
|
|
2658
|
+
...(values.length > 0 && { values }),
|
|
2659
|
+
})));
|
|
2660
|
+
}
|
|
2661
|
+
function readFeatureTypeDescriptions(rootEl) {
|
|
2662
|
+
return pipe(findNestedElements('mdb:contentInfo', 'mrc:MD_FeatureCatalogue', 'mrc:featureCatalogue', 'gfc:FC_FeatureCatalogue', 'gfc:featureType', 'gfc:FC_FeatureType'), mapArray(pipe(combine(pipe(findChildElement('gfc:typeName', false), extractCharacterStringOrText()), pipe(findChildElement('gfc:designation', false), extractCharacterString()), pipe(findChildElement('gfc:definition', false), extractCharacterString()), pipe(findNestedElements('gfc:carrierOfCharacteristics', 'gfc:FC_FeatureAttribute'), mapArray(extractFeatureAttribute()))), map(([name, label, description, attributes]) => ({
|
|
2663
|
+
name: name ?? '',
|
|
2664
|
+
...(label && { label }),
|
|
2665
|
+
...(description && { description }),
|
|
2666
|
+
attributes,
|
|
2667
|
+
})))))(rootEl);
|
|
2668
|
+
}
|
|
2636
2669
|
|
|
2637
2670
|
function writeUniqueIdentifier$1(record, rootEl) {
|
|
2638
2671
|
pipe(findNestedChildOrCreate('mdb:metadataIdentifier', 'mcc:MD_Identifier', 'mcc:code'), writeCharacterString(record.uniqueIdentifier))(rootEl);
|
|
@@ -2787,6 +2820,52 @@ function writeAssociatedRecords(record, rootEl) {
|
|
|
2787
2820
|
.filter((assoc) => assoc.uniqueIdentifier && assoc.associationType)
|
|
2788
2821
|
.map((assoc) => pipe(createNestedElement('mri:associatedResource', 'mri:MD_AssociatedResource'), appendChildren(pipe(createNestedElement('mri:associationType', 'mri:DS_AssociationTypeCode'), writeAttribute('codeList', 'http://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#DS_AssociationTypeCode'), writeAttribute('codeListValue', assoc.associationType)), pipe(createElement('mri:metadataReference'), writeAttribute('uuidref', assoc.uniqueIdentifier)))))))(rootEl);
|
|
2789
2822
|
}
|
|
2823
|
+
function createNilElement(name, nilReason) {
|
|
2824
|
+
return pipe(createElement(name), writeAttribute('gco:nilReason', nilReason));
|
|
2825
|
+
}
|
|
2826
|
+
function createFeatureCatalogueShell() {
|
|
2827
|
+
return pipe(createNestedElement('mdb:contentInfo', 'mrc:MD_FeatureCatalogue', 'mrc:featureCatalogue', 'gfc:FC_FeatureCatalogue'),
|
|
2828
|
+
// create mandatory elements which are not part of the model yet
|
|
2829
|
+
appendChildren(createNilElement('cat:name', 'missing'), createNilElement('cat:scope', 'missing'), createNilElement('cat:versionNumber', 'missing'), createNilElement('cat:versionDate', 'missing'), createNilElement('gfc:producer', 'missing')));
|
|
2830
|
+
}
|
|
2831
|
+
function createListedValue(value) {
|
|
2832
|
+
return pipe(createNestedElement('gfc:listedValue', 'gfc:FC_ListedValue'), appendChildren(value.label
|
|
2833
|
+
? pipe(createElement('gfc:label'), writeCharacterString(value.label))
|
|
2834
|
+
: createNilElement('gfc:label', 'missing'), value.value
|
|
2835
|
+
? pipe(createElement('gfc:code'), writeCharacterString(value.value))
|
|
2836
|
+
: null, value.description
|
|
2837
|
+
? pipe(createElement('gfc:definition'), writeCharacterString(value.description))
|
|
2838
|
+
: null));
|
|
2839
|
+
}
|
|
2840
|
+
function createFeatureAttribute(attribute) {
|
|
2841
|
+
return pipe(createNestedElement('gfc:carrierOfCharacteristics', 'gfc:FC_FeatureAttribute'), appendChildren(pipe(createElement('gfc:memberName'), setTextContent(attribute.name)), attribute.description
|
|
2842
|
+
? pipe(createElement('gfc:definition'), writeCharacterString(attribute.description))
|
|
2843
|
+
: null, createNilElement('gfc:cardinality', 'missing'), attribute.label
|
|
2844
|
+
? pipe(createElement('gfc:designation'), writeCharacterString(attribute.label))
|
|
2845
|
+
: null, attribute.code
|
|
2846
|
+
? pipe(createElement('gfc:code'), writeCharacterString(attribute.code))
|
|
2847
|
+
: null, attribute.type
|
|
2848
|
+
? pipe(createNestedElement('gfc:valueType', 'gco:TypeName', 'gco:aName'), writeCharacterString(attribute.type))
|
|
2849
|
+
: null, ...(attribute.values ?? [])
|
|
2850
|
+
.filter((value) => value.value || value.label)
|
|
2851
|
+
.map(createListedValue)));
|
|
2852
|
+
}
|
|
2853
|
+
function createFeatureType(featureType) {
|
|
2854
|
+
return pipe(createNestedElement('gfc:featureType', 'gfc:FC_FeatureType'), appendChildren(pipe(createElement('gfc:typeName'), setTextContent(featureType.name)), featureType.description
|
|
2855
|
+
? pipe(createElement('gfc:definition'), writeCharacterString(featureType.description))
|
|
2856
|
+
: null, pipe(createNestedElement('gfc:isAbstract', 'gco:Boolean'), setTextContent('false')), featureType.label
|
|
2857
|
+
? pipe(createElement('gfc:designation'), writeCharacterString(featureType.label))
|
|
2858
|
+
: null, ...featureType.attributes.map(createFeatureAttribute), createNilElement('gfc:featureCatalogue', 'missing')));
|
|
2859
|
+
}
|
|
2860
|
+
function writeFeatureTypeDescriptions(record, rootEl) {
|
|
2861
|
+
const featureTypes = record.featureTypeDescriptions ?? [];
|
|
2862
|
+
const catalogues = findNestedElements('mdb:contentInfo', 'mrc:MD_FeatureCatalogue', 'mrc:featureCatalogue', 'gfc:FC_FeatureCatalogue')(rootEl);
|
|
2863
|
+
catalogues.forEach((catalogue) => removeChildrenByName('gfc:featureType')(catalogue));
|
|
2864
|
+
if (!featureTypes.length)
|
|
2865
|
+
return;
|
|
2866
|
+
const catalogue = catalogues[0] ?? appendChildTree(createFeatureCatalogueShell())(rootEl);
|
|
2867
|
+
appendChildren(...featureTypes.map(createFeatureType))(catalogue);
|
|
2868
|
+
}
|
|
2790
2869
|
|
|
2791
2870
|
class Iso191153Converter extends Iso19139Converter {
|
|
2792
2871
|
constructor() {
|
|
@@ -2803,6 +2882,7 @@ class Iso191153Converter extends Iso19139Converter {
|
|
|
2803
2882
|
this.readers['lineage'] = readLineage;
|
|
2804
2883
|
this.readers['sourceRecords'] = readSourceRecords;
|
|
2805
2884
|
this.readers['associatedRecords'] = readAssociatedRecords;
|
|
2885
|
+
this.readers['featureTypeDescriptions'] = readFeatureTypeDescriptions;
|
|
2806
2886
|
this.readers['onlineResources'] = readOnlineResources$1;
|
|
2807
2887
|
this.readers['defaultLanguage'] = readDefaultLanguage$1;
|
|
2808
2888
|
this.readers['otherLanguages'] = readOtherLanguages;
|
|
@@ -2823,6 +2903,7 @@ class Iso191153Converter extends Iso19139Converter {
|
|
|
2823
2903
|
this.writers['lineage'] = writeLineage;
|
|
2824
2904
|
this.writers['sourceRecords'] = writeSourceRecords;
|
|
2825
2905
|
this.writers['associatedRecords'] = writeAssociatedRecords;
|
|
2906
|
+
this.writers['featureTypeDescriptions'] = writeFeatureTypeDescriptions;
|
|
2826
2907
|
this.writers['onlineResources'] = writeOnlineResources;
|
|
2827
2908
|
this.writers['status'] = writeStatus;
|
|
2828
2909
|
this.writers['spatialRepresentation'] = writeSpatialRepresentation;
|
|
@@ -2912,10 +2993,12 @@ class Iso191153Converter extends Iso19139Converter {
|
|
|
2912
2993
|
});
|
|
2913
2994
|
}
|
|
2914
2995
|
async writeRecord(record, reference) {
|
|
2915
|
-
|
|
2916
|
-
// fix gco namespace
|
|
2917
|
-
|
|
2918
|
-
return result
|
|
2996
|
+
const result = await super.writeRecord(record, reference);
|
|
2997
|
+
// fix the gco and gfc namespace definitions (they change between iso19139 and iso19115-3);
|
|
2998
|
+
// only on the root element, where they are declared, so that nested declarations stay untouched
|
|
2999
|
+
return result.replace(/<mdb:MD_Metadata[^>]*>/, (rootTag) => rootTag
|
|
3000
|
+
.replace('"http://www.isotc211.org/2005/gco"', '"http://standards.iso.org/iso/19115/-3/gco/1.0"')
|
|
3001
|
+
.replace('"http://www.isotc211.org/2005/gfc"', '"http://standards.iso.org/iso/19110/gfc/1.1"'));
|
|
2919
3002
|
}
|
|
2920
3003
|
}
|
|
2921
3004
|
|
|
@@ -3459,6 +3542,7 @@ class DcatApConverter extends BaseConverter {
|
|
|
3459
3542
|
lineage: () => '',
|
|
3460
3543
|
sourceRecords: () => [],
|
|
3461
3544
|
associatedRecords: () => [],
|
|
3545
|
+
featureTypeDescriptions: () => undefined,
|
|
3462
3546
|
temporalExtents: () => [],
|
|
3463
3547
|
spatialRepresentation: () => undefined,
|
|
3464
3548
|
extras: () => undefined,
|
|
@@ -3494,6 +3578,7 @@ class DcatApConverter extends BaseConverter {
|
|
|
3494
3578
|
lineage: () => undefined,
|
|
3495
3579
|
sourceRecords: () => [],
|
|
3496
3580
|
associatedRecords: () => [],
|
|
3581
|
+
featureTypeDescriptions: () => undefined,
|
|
3497
3582
|
onlineResources: () => undefined,
|
|
3498
3583
|
temporalExtents: () => undefined,
|
|
3499
3584
|
spatialExtents: () => undefined,
|
|
@@ -18904,9 +18989,15 @@ class Gn4FieldMapper {
|
|
|
18904
18989
|
isOpenData: (output, source) => this.addExtra({
|
|
18905
18990
|
isOpenData: selectField(source, 'isOpenData') !== 'false',
|
|
18906
18991
|
}, output),
|
|
18907
|
-
featureTypes: (output, source) =>
|
|
18908
|
-
featureTypes
|
|
18909
|
-
|
|
18992
|
+
featureTypes: (output, source) => {
|
|
18993
|
+
const featureTypes = getAsArray(selectField(source, 'featureTypes'));
|
|
18994
|
+
if (!featureTypes.length)
|
|
18995
|
+
return output;
|
|
18996
|
+
return {
|
|
18997
|
+
...output,
|
|
18998
|
+
featureTypeDescriptions: this.featureTypesField(featureTypes),
|
|
18999
|
+
};
|
|
19000
|
+
},
|
|
18910
19001
|
related: (output, source) => {
|
|
18911
19002
|
const related = selectField(source, 'related');
|
|
18912
19003
|
const fcatSource = selectField(getFirstValue(selectField(related, 'fcats')) ?? {}, '_source');
|
|
@@ -19042,6 +19133,27 @@ class Gn4FieldMapper {
|
|
|
19042
19133
|
},
|
|
19043
19134
|
};
|
|
19044
19135
|
this.genericField = (output) => output;
|
|
19136
|
+
this.featureTypesField = (featureTypes) => featureTypes.map((featureType) => ({
|
|
19137
|
+
name: featureType.typeName ?? '',
|
|
19138
|
+
...(featureType.definition && {
|
|
19139
|
+
description: featureType.definition,
|
|
19140
|
+
}),
|
|
19141
|
+
attributes: getAsArray(featureType.attributeTable ?? []).map((attr) => {
|
|
19142
|
+
const values = (attr.values ?? [])
|
|
19143
|
+
.filter((value) => value.code || value.label)
|
|
19144
|
+
.map((value) => ({
|
|
19145
|
+
value: value.code || '',
|
|
19146
|
+
...(value.label && { label: value.label }),
|
|
19147
|
+
}));
|
|
19148
|
+
return {
|
|
19149
|
+
name: attr.name ?? '',
|
|
19150
|
+
...(attr.definition && { description: attr.definition }),
|
|
19151
|
+
...(attr.code && { code: attr.code }),
|
|
19152
|
+
...(attr.type && { type: attr.type }),
|
|
19153
|
+
...(values.length > 0 && { values }),
|
|
19154
|
+
};
|
|
19155
|
+
}),
|
|
19156
|
+
}));
|
|
19045
19157
|
this.constraintField = (type, output, constraintArray) => {
|
|
19046
19158
|
let outputField;
|
|
19047
19159
|
switch (type) {
|
|
@@ -20452,7 +20564,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
20452
20564
|
}] } });
|
|
20453
20565
|
|
|
20454
20566
|
var name = "geonetwork-ui";
|
|
20455
|
-
var version = "2.11.0-dev.
|
|
20567
|
+
var version = "2.11.0-dev.0559cfd9d";
|
|
20456
20568
|
var engines = {
|
|
20457
20569
|
node: ">=24"
|
|
20458
20570
|
};
|
|
@@ -20494,10 +20606,10 @@ var dependencies = {
|
|
|
20494
20606
|
"@biesbjerg/ngx-translate-extract-marker": "~1.0.0",
|
|
20495
20607
|
"@camptocamp/ogc-client": "1.3.1-dev.200c02a",
|
|
20496
20608
|
"@duckdb/duckdb-wasm": "~1.32.0",
|
|
20497
|
-
"@geospatial-sdk/core": "0.0.5-dev.
|
|
20498
|
-
"@geospatial-sdk/geocoding": "0.0.5-dev.
|
|
20499
|
-
"@geospatial-sdk/legend": "0.0.5-dev.
|
|
20500
|
-
"@geospatial-sdk/openlayers": "0.0.5-dev.
|
|
20609
|
+
"@geospatial-sdk/core": "0.0.5-dev.86.sha-124eae3",
|
|
20610
|
+
"@geospatial-sdk/geocoding": "0.0.5-dev.86.sha-124eae3",
|
|
20611
|
+
"@geospatial-sdk/legend": "0.0.5-dev.86.sha-124eae3",
|
|
20612
|
+
"@geospatial-sdk/openlayers": "0.0.5-dev.86.sha-124eae3",
|
|
20501
20613
|
"@ltd/j-toml": "~1.38.0",
|
|
20502
20614
|
"@messageformat/core": "~3.4.0",
|
|
20503
20615
|
"@ng-icons/core": "~32.5.0",
|
|
@@ -20514,6 +20626,7 @@ var dependencies = {
|
|
|
20514
20626
|
"embla-carousel": "~8.6.0",
|
|
20515
20627
|
"flag-icons": "~7.5.0",
|
|
20516
20628
|
"geojson-validation": "~1.0.2",
|
|
20629
|
+
jsonpointer: "^5.0.1",
|
|
20517
20630
|
marked: "~17.0.4",
|
|
20518
20631
|
"ngx-dropzone": "~3.1.0",
|
|
20519
20632
|
"ngx-translate-messageformat-compiler": "~7.2.0",
|
|
@@ -20690,6 +20803,7 @@ class ElasticsearchService {
|
|
|
20690
20803
|
// runtime fields are computed using a Painless script
|
|
20691
20804
|
// see: https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-mapping-fields.html
|
|
20692
20805
|
this.runtimeFields = {};
|
|
20806
|
+
this.fieldAliases = {};
|
|
20693
20807
|
}
|
|
20694
20808
|
// we're using getters in case the defined languages change over time
|
|
20695
20809
|
get metadataLang() {
|
|
@@ -20761,6 +20875,9 @@ class ElasticsearchService {
|
|
|
20761
20875
|
registerRuntimeField(fieldName, expression, type = 'keyword') {
|
|
20762
20876
|
this.runtimeFields[fieldName] = { script: expression, type };
|
|
20763
20877
|
}
|
|
20878
|
+
registerFieldAlias(fieldIdentifier, esFieldName) {
|
|
20879
|
+
this.fieldAliases[fieldIdentifier] = esFieldName;
|
|
20880
|
+
}
|
|
20764
20881
|
getMetadataByIdsPayload(uuids) {
|
|
20765
20882
|
return {
|
|
20766
20883
|
query: {
|
|
@@ -20882,12 +20999,25 @@ class ElasticsearchService {
|
|
|
20882
20999
|
}
|
|
20883
21000
|
return Object.values(filters).find(isBoundingBox);
|
|
20884
21001
|
}
|
|
20885
|
-
//
|
|
20886
|
-
// the record matches if that interval intersects the filter range
|
|
21002
|
+
// builds a query matching records whose dates intersect the filter range
|
|
20887
21003
|
buildDateRangeQuery(searchField, dateRange) {
|
|
21004
|
+
// fields ending with 'DateRange' maps as ES range type
|
|
21005
|
+
if (searchField.endsWith('DateRange')) {
|
|
21006
|
+
return {
|
|
21007
|
+
range: {
|
|
21008
|
+
[searchField]: {
|
|
21009
|
+
...(dateRange.start && { gte: formatDate(dateRange.start) }),
|
|
21010
|
+
...(dateRange.end && { lte: formatDate(dateRange.end) }),
|
|
21011
|
+
format: 'yyyy-MM-dd',
|
|
21012
|
+
relation: 'intersects',
|
|
21013
|
+
},
|
|
21014
|
+
},
|
|
21015
|
+
};
|
|
21016
|
+
}
|
|
20888
21017
|
const minField = `${searchField}Min`;
|
|
20889
21018
|
const maxField = `${searchField}Max`;
|
|
20890
21019
|
if (minField in this.runtimeFields && maxField in this.runtimeFields) {
|
|
21020
|
+
// min/max runtime fields form an interval per record; match if it intersects the filter range
|
|
20891
21021
|
const filter = [
|
|
20892
21022
|
dateRange.start && {
|
|
20893
21023
|
range: {
|
|
@@ -20942,7 +21072,7 @@ class ElasticsearchService {
|
|
|
20942
21072
|
.filter((fieldname) => !Array.isArray(filters[fieldname]))
|
|
20943
21073
|
.filter((fieldname) => filters[fieldname] &&
|
|
20944
21074
|
JSON.stringify(filters[fieldname]) !== '{}')
|
|
20945
|
-
.map((fieldname) => `${fieldname}:(${makeQuery(filters[fieldname])})`)
|
|
21075
|
+
.map((fieldname) => `${this.fieldAliases[fieldname] ?? fieldname}:(${makeQuery(filters[fieldname])})`)
|
|
20946
21076
|
.join(' AND ');
|
|
20947
21077
|
if (filters['gn-ui-crossFieldFilter']) {
|
|
20948
21078
|
queryString = `${queryString} AND (${filters['gn-ui-crossFieldFilter']})`;
|
|
@@ -21240,6 +21370,12 @@ class ElasticsearchService {
|
|
|
21240
21370
|
order: {
|
|
21241
21371
|
[`_${aggregation.sort[1]}`]: aggregation.sort[0],
|
|
21242
21372
|
},
|
|
21373
|
+
...(aggregation.includeValues && {
|
|
21374
|
+
include: aggregation.includeValues,
|
|
21375
|
+
}),
|
|
21376
|
+
...(aggregation.excludeValues && {
|
|
21377
|
+
exclude: aggregation.excludeValues,
|
|
21378
|
+
}),
|
|
21243
21379
|
},
|
|
21244
21380
|
};
|
|
21245
21381
|
case 'histogram':
|
|
@@ -21374,42 +21510,16 @@ class Gn4Repository {
|
|
|
21374
21510
|
? this.gn4Mapper.readRecords(records)
|
|
21375
21511
|
: of(null)));
|
|
21376
21512
|
}
|
|
21377
|
-
|
|
21378
|
-
return {
|
|
21379
|
-
featureTypes: featureTypes.map((featureType) => ({
|
|
21380
|
-
name: featureType.typeName || '',
|
|
21381
|
-
definition: featureType.definition || '',
|
|
21382
|
-
attributes: Array.isArray(featureType.attributeTable)
|
|
21383
|
-
? featureType.attributeTable.map((attr) => {
|
|
21384
|
-
const values = attr.values
|
|
21385
|
-
?.filter((v) => v.code || v.label)
|
|
21386
|
-
.map((v) => ({
|
|
21387
|
-
code: v.code,
|
|
21388
|
-
label: v.label,
|
|
21389
|
-
}));
|
|
21390
|
-
return {
|
|
21391
|
-
name: attr.name,
|
|
21392
|
-
code: attr.code,
|
|
21393
|
-
definition: attr.definition,
|
|
21394
|
-
type: attr.type,
|
|
21395
|
-
...(values?.length > 0 ? { values } : {}),
|
|
21396
|
-
};
|
|
21397
|
-
})
|
|
21398
|
-
: [],
|
|
21399
|
-
})),
|
|
21400
|
-
};
|
|
21401
|
-
}
|
|
21402
|
-
getFeatureCatalog(record, visited = new Set() // prevent looping
|
|
21513
|
+
queryLinkedFeatureCatalog(record, visited = new Set() // prevent looping
|
|
21403
21514
|
) {
|
|
21404
|
-
if (
|
|
21405
|
-
|
|
21406
|
-
record.
|
|
21407
|
-
return of(this.mapEmbeddedFeatureCatalog(record.extras['featureTypes']));
|
|
21515
|
+
if ('featureTypeDescriptions' in record &&
|
|
21516
|
+
record.featureTypeDescriptions?.length > 0) {
|
|
21517
|
+
return of({ featureTypes: record.featureTypeDescriptions });
|
|
21408
21518
|
}
|
|
21409
21519
|
const featureCatalogIdentifier = record.extras['featureCatalogIdentifier'];
|
|
21410
21520
|
if (featureCatalogIdentifier && !visited.has(featureCatalogIdentifier)) {
|
|
21411
21521
|
visited.add(featureCatalogIdentifier);
|
|
21412
|
-
return this.getRecord(featureCatalogIdentifier).pipe(switchMap((record) => record ? this.
|
|
21522
|
+
return this.getRecord(featureCatalogIdentifier).pipe(switchMap((record) => record ? this.queryLinkedFeatureCatalog(record, visited) : of(null)));
|
|
21413
21523
|
}
|
|
21414
21524
|
return of(null);
|
|
21415
21525
|
}
|
|
@@ -23082,1082 +23192,374 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
23082
23192
|
}]
|
|
23083
23193
|
}] });
|
|
23084
23194
|
|
|
23085
|
-
|
|
23086
|
-
|
|
23087
|
-
|
|
23088
|
-
|
|
23089
|
-
|
|
23195
|
+
class AnchorLinkDirective {
|
|
23196
|
+
constructor() {
|
|
23197
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
23198
|
+
this.disabled = false;
|
|
23199
|
+
this.observer = new MutationObserver(() => {
|
|
23200
|
+
this.refreshDisabledState();
|
|
23201
|
+
});
|
|
23202
|
+
this.inView = false;
|
|
23203
|
+
this.initialized = false;
|
|
23090
23204
|
}
|
|
23091
|
-
|
|
23092
|
-
|
|
23093
|
-
|
|
23094
|
-
|
|
23095
|
-
|
|
23205
|
+
get elementClass() {
|
|
23206
|
+
if (this.disabled) {
|
|
23207
|
+
return this.disabledClass;
|
|
23208
|
+
}
|
|
23209
|
+
if (this.inView) {
|
|
23210
|
+
return `${this.inViewClass} ${this.enabledClass}`;
|
|
23211
|
+
}
|
|
23212
|
+
else {
|
|
23213
|
+
return `${this.outOfViewClass} ${this.enabledClass}`;
|
|
23214
|
+
}
|
|
23096
23215
|
}
|
|
23097
|
-
|
|
23098
|
-
|
|
23216
|
+
ngOnInit() {
|
|
23217
|
+
this.observer.observe(document.body, {
|
|
23218
|
+
childList: true,
|
|
23219
|
+
subtree: true,
|
|
23220
|
+
});
|
|
23221
|
+
this.refreshDisabledState();
|
|
23099
23222
|
}
|
|
23100
|
-
|
|
23101
|
-
|
|
23102
|
-
|
|
23103
|
-
|
|
23104
|
-
|
|
23105
|
-
|
|
23106
|
-
|
|
23107
|
-
|
|
23108
|
-
};
|
|
23109
|
-
};
|
|
23110
|
-
/**
|
|
23111
|
-
* Only keeps recognized keys, flatten nested values (to allow having "." in keys),
|
|
23112
|
-
* pushes warnings and errors to the given arrays; returns null in case of error
|
|
23113
|
-
*/
|
|
23114
|
-
function parseConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
23115
|
-
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
23116
|
-
if (mandatoryKeys.length === 0)
|
|
23117
|
-
return null;
|
|
23118
|
-
outErrors.push(`The [${sectionName}] mandatory section is missing.`);
|
|
23119
|
-
return null;
|
|
23223
|
+
ngAfterViewChecked() {
|
|
23224
|
+
if (!this.initialized && !this.disabled) {
|
|
23225
|
+
const target = document.getElementById(this.targetId);
|
|
23226
|
+
if (target) {
|
|
23227
|
+
this.initializeIntersectionObserver(target);
|
|
23228
|
+
this.initialized = true;
|
|
23229
|
+
}
|
|
23230
|
+
}
|
|
23120
23231
|
}
|
|
23121
|
-
|
|
23122
|
-
|
|
23123
|
-
|
|
23124
|
-
|
|
23125
|
-
|
|
23126
|
-
|
|
23232
|
+
initializeIntersectionObserver(target) {
|
|
23233
|
+
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
23234
|
+
entries.forEach((entry) => {
|
|
23235
|
+
this.inView = entry.isIntersecting;
|
|
23236
|
+
this.changeDetector.detectChanges();
|
|
23237
|
+
});
|
|
23238
|
+
}, {
|
|
23239
|
+
root: null,
|
|
23240
|
+
rootMargin: '-30% 0% -60% 0%',
|
|
23241
|
+
});
|
|
23242
|
+
this.intersectionObserver.observe(target);
|
|
23127
23243
|
}
|
|
23128
|
-
|
|
23129
|
-
|
|
23130
|
-
|
|
23244
|
+
ngOnDestroy() {
|
|
23245
|
+
this.observer.disconnect();
|
|
23246
|
+
if (this.intersectionObserver) {
|
|
23247
|
+
this.intersectionObserver.disconnect();
|
|
23248
|
+
}
|
|
23131
23249
|
}
|
|
23132
|
-
|
|
23250
|
+
refreshDisabledState() {
|
|
23251
|
+
const targetNotPresent = !document.getElementById(this.targetId);
|
|
23252
|
+
if (targetNotPresent !== this.disabled) {
|
|
23253
|
+
this.disabled = targetNotPresent;
|
|
23254
|
+
this.changeDetector.detectChanges();
|
|
23255
|
+
}
|
|
23256
|
+
}
|
|
23257
|
+
scrollToTarget() {
|
|
23258
|
+
const target = document.getElementById(this.targetId);
|
|
23259
|
+
if (!target)
|
|
23260
|
+
return;
|
|
23261
|
+
target.scrollIntoView({
|
|
23262
|
+
behavior: 'smooth',
|
|
23263
|
+
block: 'start',
|
|
23264
|
+
});
|
|
23265
|
+
}
|
|
23266
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
23267
|
+
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 }); }
|
|
23133
23268
|
}
|
|
23134
|
-
|
|
23135
|
-
|
|
23136
|
-
|
|
23137
|
-
|
|
23138
|
-
|
|
23139
|
-
|
|
23140
|
-
|
|
23141
|
-
|
|
23269
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AnchorLinkDirective, decorators: [{
|
|
23270
|
+
type: Directive,
|
|
23271
|
+
args: [{
|
|
23272
|
+
selector: '[gnUiAnchorLink]',
|
|
23273
|
+
standalone: true,
|
|
23274
|
+
}]
|
|
23275
|
+
}], propDecorators: { targetId: [{
|
|
23276
|
+
type: Input,
|
|
23277
|
+
args: ['gnUiAnchorLink']
|
|
23278
|
+
}], disabledClass: [{
|
|
23279
|
+
type: Input,
|
|
23280
|
+
args: ['gnUiAnchorLinkDisabledClass']
|
|
23281
|
+
}], enabledClass: [{
|
|
23282
|
+
type: Input,
|
|
23283
|
+
args: ['gnUiAnchorLinkEnabledClass']
|
|
23284
|
+
}], inViewClass: [{
|
|
23285
|
+
type: Input,
|
|
23286
|
+
args: ['gnUiAnchorLinkInViewClass']
|
|
23287
|
+
}], outOfViewClass: [{
|
|
23288
|
+
type: Input,
|
|
23289
|
+
args: ['gnUiAnchorLinkOutOfViewClass']
|
|
23290
|
+
}], elementClass: [{
|
|
23291
|
+
type: HostBinding,
|
|
23292
|
+
args: ['class']
|
|
23293
|
+
}], scrollToTarget: [{
|
|
23294
|
+
type: HostListener,
|
|
23295
|
+
args: ['click']
|
|
23296
|
+
}] } });
|
|
23297
|
+
|
|
23298
|
+
class PaginationDotsComponent {
|
|
23299
|
+
constructor() {
|
|
23300
|
+
this.containerClass = '';
|
|
23142
23301
|
}
|
|
23143
|
-
|
|
23302
|
+
// 1-based
|
|
23303
|
+
get steps() {
|
|
23304
|
+
return Array.from({ length: this.listComponent.pagesCount }, (_, i) => i + 1);
|
|
23305
|
+
}
|
|
23306
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23307
|
+
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: [
|
|
23308
|
+
provideIcons({
|
|
23309
|
+
iconoirNavArrowRight,
|
|
23310
|
+
iconoirNavArrowLeft,
|
|
23311
|
+
}),
|
|
23312
|
+
] }); }
|
|
23144
23313
|
}
|
|
23145
|
-
|
|
23146
|
-
|
|
23147
|
-
|
|
23148
|
-
|
|
23149
|
-
|
|
23150
|
-
|
|
23151
|
-
|
|
23152
|
-
|
|
23153
|
-
|
|
23314
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, decorators: [{
|
|
23315
|
+
type: Component,
|
|
23316
|
+
args: [{ selector: 'gn-ui-pagination-dots', standalone: true, imports: [CommonModule], viewProviders: [
|
|
23317
|
+
provideIcons({
|
|
23318
|
+
iconoirNavArrowRight,
|
|
23319
|
+
iconoirNavArrowLeft,
|
|
23320
|
+
}),
|
|
23321
|
+
], 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"] }]
|
|
23322
|
+
}], propDecorators: { listComponent: [{
|
|
23323
|
+
type: Input
|
|
23324
|
+
}], containerClass: [{
|
|
23325
|
+
type: Input
|
|
23326
|
+
}] } });
|
|
23327
|
+
|
|
23328
|
+
class CarouselComponent {
|
|
23329
|
+
constructor() {
|
|
23330
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
23331
|
+
this.containerClass = '';
|
|
23332
|
+
this.stepsContainerClass = 'w-full bottom-0 top-auto';
|
|
23333
|
+
this.currentStepChange = new EventEmitter();
|
|
23334
|
+
this.steps = [];
|
|
23335
|
+
this.currentStep = 0;
|
|
23336
|
+
this.refreshSteps = () => {
|
|
23337
|
+
this.steps = this.emblaApi.scrollSnapList();
|
|
23338
|
+
this.currentStep = this.emblaApi.selectedScrollSnap();
|
|
23339
|
+
this.currentStepChange.emit(this.currentStep);
|
|
23340
|
+
this.changeDetector.detectChanges();
|
|
23341
|
+
};
|
|
23154
23342
|
}
|
|
23155
|
-
|
|
23156
|
-
|
|
23157
|
-
return
|
|
23343
|
+
// Paginable API
|
|
23344
|
+
get isFirstPage() {
|
|
23345
|
+
return this.currentStep === 0;
|
|
23158
23346
|
}
|
|
23159
|
-
|
|
23160
|
-
|
|
23161
|
-
return null;
|
|
23347
|
+
get isLastPage() {
|
|
23348
|
+
return this.currentStep === this.steps.length - 1;
|
|
23162
23349
|
}
|
|
23163
|
-
|
|
23164
|
-
|
|
23165
|
-
function checkMetadataLanguage(parsedConfigSection, outWarnings) {
|
|
23166
|
-
const lang2 = toLang2(parsedConfigSection.metadata_language.toLowerCase());
|
|
23167
|
-
if (lang2?.length !== 2) {
|
|
23168
|
-
outWarnings.push(`In the [global] section: metadata_language = "${parsedConfigSection.metadata_language}" is not a recognized ISO 639 language code`);
|
|
23350
|
+
get currentPage() {
|
|
23351
|
+
return this.currentStep + 1; // this is 1-based
|
|
23169
23352
|
}
|
|
23170
|
-
|
|
23171
|
-
|
|
23172
|
-
function checkNewRecordDefaultLanguage(parsedConfigSection, outWarnings) {
|
|
23173
|
-
const lang2 = toLang2(parsedConfigSection.new_record_default_language.toLowerCase());
|
|
23174
|
-
if (!(lang2 in LANG_2_TO_3_MAPPER)) {
|
|
23175
|
-
outWarnings.push(`In the [editing] section: new_record_default_language = "${parsedConfigSection.new_record_default_language}" is not a recognized ISO 639 language code`);
|
|
23176
|
-
return {
|
|
23177
|
-
...parsedConfigSection,
|
|
23178
|
-
new_record_default_language: undefined,
|
|
23179
|
-
};
|
|
23353
|
+
get pagesCount() {
|
|
23354
|
+
return this.steps.length;
|
|
23180
23355
|
}
|
|
23181
|
-
|
|
23182
|
-
|
|
23183
|
-
new_record_default_language: lang2,
|
|
23184
|
-
};
|
|
23185
|
-
}
|
|
23186
|
-
function checkNewRecordStandard(parsedConfigSection, outWarnings) {
|
|
23187
|
-
const standard = parsedConfigSection.new_record_standard;
|
|
23188
|
-
const normalizedStandard = typeof standard === 'string' ? standard.trim().toLowerCase() : null;
|
|
23189
|
-
if (normalizedStandard === 'iso19139' ||
|
|
23190
|
-
normalizedStandard === 'iso19115-3') {
|
|
23191
|
-
return {
|
|
23192
|
-
...parsedConfigSection,
|
|
23193
|
-
new_record_standard: normalizedStandard,
|
|
23194
|
-
};
|
|
23356
|
+
goToPage(stepIndex) {
|
|
23357
|
+
this.emblaApi.scrollTo(stepIndex - 1); // this is 0-based
|
|
23195
23358
|
}
|
|
23196
|
-
|
|
23197
|
-
|
|
23198
|
-
|
|
23199
|
-
|
|
23200
|
-
}
|
|
23359
|
+
goToPrevPage() {
|
|
23360
|
+
if (this.isFirstPage)
|
|
23361
|
+
return;
|
|
23362
|
+
this.emblaApi.scrollPrev();
|
|
23363
|
+
}
|
|
23364
|
+
goToNextPage() {
|
|
23365
|
+
if (this.isLastPage)
|
|
23366
|
+
return;
|
|
23367
|
+
this.emblaApi.scrollNext();
|
|
23368
|
+
}
|
|
23369
|
+
ngAfterViewInit() {
|
|
23370
|
+
this.emblaApi = EmblaCarousel(this.carouselOverflowContainer.nativeElement, {
|
|
23371
|
+
duration: 15,
|
|
23372
|
+
});
|
|
23373
|
+
this.emblaApi
|
|
23374
|
+
.on('init', this.refreshSteps)
|
|
23375
|
+
.on('reInit', this.refreshSteps)
|
|
23376
|
+
.on('select', this.refreshSteps);
|
|
23377
|
+
}
|
|
23378
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23379
|
+
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 }); }
|
|
23201
23380
|
}
|
|
23381
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, decorators: [{
|
|
23382
|
+
type: Component,
|
|
23383
|
+
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"] }]
|
|
23384
|
+
}], propDecorators: { carouselOverflowContainer: [{
|
|
23385
|
+
type: ViewChild,
|
|
23386
|
+
args: ['carouselOverflowContainer']
|
|
23387
|
+
}], containerClass: [{
|
|
23388
|
+
type: Input
|
|
23389
|
+
}], stepsContainerClass: [{
|
|
23390
|
+
type: Input
|
|
23391
|
+
}], currentStepChange: [{
|
|
23392
|
+
type: Output
|
|
23393
|
+
}] } });
|
|
23202
23394
|
|
|
23203
|
-
|
|
23204
|
-
|
|
23205
|
-
|
|
23206
|
-
|
|
23207
|
-
|
|
23208
|
-
|
|
23209
|
-
|
|
23210
|
-
|
|
23211
|
-
|
|
23212
|
-
|
|
23213
|
-
|
|
23214
|
-
|
|
23395
|
+
class ProgressBarComponent {
|
|
23396
|
+
constructor() {
|
|
23397
|
+
this.value = 0;
|
|
23398
|
+
this.type = 'default';
|
|
23399
|
+
}
|
|
23400
|
+
get progress() {
|
|
23401
|
+
return this.value > 0 ? (this.value < 100 ? this.value : 100) : 0;
|
|
23402
|
+
}
|
|
23403
|
+
get color() {
|
|
23404
|
+
switch (this.type) {
|
|
23405
|
+
case 'default':
|
|
23406
|
+
return {
|
|
23407
|
+
outerBar: 'bg-gray-200',
|
|
23408
|
+
innerBar: 'bg-gray-100',
|
|
23409
|
+
text: 'text-gray-900',
|
|
23410
|
+
};
|
|
23411
|
+
case 'primary':
|
|
23412
|
+
return {
|
|
23413
|
+
outerBar: 'bg-primary',
|
|
23414
|
+
innerBar: 'bg-primary-lighter',
|
|
23415
|
+
text: 'text-white',
|
|
23416
|
+
};
|
|
23417
|
+
case 'secondary':
|
|
23418
|
+
return {
|
|
23419
|
+
outerBar: 'bg-secondary',
|
|
23420
|
+
innerBar: 'bg-secondary-lighter',
|
|
23421
|
+
text: 'text-white',
|
|
23422
|
+
};
|
|
23423
|
+
case 'light':
|
|
23424
|
+
return {
|
|
23425
|
+
outerBar: 'bg-primary-white',
|
|
23426
|
+
innerBar: 'bg-primary',
|
|
23427
|
+
text: 'text-main',
|
|
23428
|
+
};
|
|
23429
|
+
}
|
|
23215
23430
|
}
|
|
23431
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23432
|
+
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"] }); }
|
|
23216
23433
|
}
|
|
23434
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, decorators: [{
|
|
23435
|
+
type: Component,
|
|
23436
|
+
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"] }]
|
|
23437
|
+
}], propDecorators: { value: [{
|
|
23438
|
+
type: Input
|
|
23439
|
+
}], type: [{
|
|
23440
|
+
type: Input
|
|
23441
|
+
}] } });
|
|
23217
23442
|
|
|
23218
|
-
|
|
23219
|
-
|
|
23220
|
-
|
|
23221
|
-
|
|
23222
|
-
|
|
23223
|
-
|
|
23224
|
-
|
|
23225
|
-
|
|
23226
|
-
|
|
23227
|
-
}
|
|
23228
|
-
|
|
23229
|
-
|
|
23230
|
-
|
|
23231
|
-
|
|
23232
|
-
|
|
23233
|
-
}
|
|
23234
|
-
|
|
23235
|
-
|
|
23236
|
-
|
|
23237
|
-
}
|
|
23238
|
-
|
|
23239
|
-
|
|
23240
|
-
|
|
23241
|
-
|
|
23242
|
-
|
|
23243
|
-
function getOptionalEditorConfig() {
|
|
23244
|
-
return editorConfig;
|
|
23245
|
-
}
|
|
23246
|
-
let metadataQualityConfig = null;
|
|
23247
|
-
function getMetadataQualityConfig() {
|
|
23248
|
-
return (metadataQualityConfig ||
|
|
23249
|
-
{
|
|
23250
|
-
ENABLED: false,
|
|
23443
|
+
class PopoverComponent {
|
|
23444
|
+
constructor() {
|
|
23445
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
23446
|
+
this.renderer = inject(Renderer2);
|
|
23447
|
+
}
|
|
23448
|
+
getContent() {
|
|
23449
|
+
if (this.content instanceof TemplateRef) {
|
|
23450
|
+
if (this.view) {
|
|
23451
|
+
this.view.destroy();
|
|
23452
|
+
}
|
|
23453
|
+
this.view = this.viewContainerRef.createEmbeddedView(this.content);
|
|
23454
|
+
this.view.detectChanges();
|
|
23455
|
+
const wrapper = this.renderer.createElement('div'); // Create a wrapper div
|
|
23456
|
+
this.view.rootNodes.forEach((node) => {
|
|
23457
|
+
this.renderer.appendChild(wrapper, node); // Append each root node to the wrapper
|
|
23458
|
+
});
|
|
23459
|
+
return wrapper;
|
|
23460
|
+
}
|
|
23461
|
+
return this.content;
|
|
23462
|
+
}
|
|
23463
|
+
ngAfterViewInit() {
|
|
23464
|
+
this.tippyInstance = tippy(this.popoverContent.nativeElement, {
|
|
23465
|
+
content: this.getContent(),
|
|
23466
|
+
allowHTML: true,
|
|
23467
|
+
theme: this.theme,
|
|
23251
23468
|
});
|
|
23252
|
-
}
|
|
23253
|
-
|
|
23254
|
-
|
|
23255
|
-
|
|
23256
|
-
|
|
23257
|
-
|
|
23258
|
-
}
|
|
23259
|
-
let appConfigLoaded = false;
|
|
23260
|
-
function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
|
|
23261
|
-
console.log(`[geonetwork-ui] Loading application configuration from ${configUrl}`);
|
|
23262
|
-
return fetch(configUrl)
|
|
23263
|
-
.then((resp) => {
|
|
23264
|
-
if (!resp.ok)
|
|
23265
|
-
throw new Error('Configuration file could not be loaded');
|
|
23266
|
-
return resp.text();
|
|
23267
|
-
})
|
|
23268
|
-
.then((conf) => {
|
|
23269
|
-
let parsed;
|
|
23270
|
-
try {
|
|
23271
|
-
parsed = TOML.parse(conf, { joiner: '\n', bigint: false });
|
|
23469
|
+
}
|
|
23470
|
+
ngOnChanges(changes) {
|
|
23471
|
+
if (changes['theme']) {
|
|
23472
|
+
this.theme = changes['theme'].currentValue;
|
|
23473
|
+
if (this.tippyInstance) {
|
|
23474
|
+
this.tippyInstance.setProps({ theme: this.theme });
|
|
23475
|
+
}
|
|
23272
23476
|
}
|
|
23273
|
-
|
|
23274
|
-
|
|
23477
|
+
if (changes['content']) {
|
|
23478
|
+
this.content = changes['content'].currentValue;
|
|
23479
|
+
if (this.tippyInstance) {
|
|
23480
|
+
this.tippyInstance.setContent(this.getContent());
|
|
23481
|
+
}
|
|
23275
23482
|
}
|
|
23276
|
-
|
|
23277
|
-
|
|
23278
|
-
|
|
23279
|
-
|
|
23280
|
-
'edit_url_template',
|
|
23281
|
-
'proxy_path',
|
|
23282
|
-
'metadata_language',
|
|
23283
|
-
'login_url',
|
|
23284
|
-
'logout_url',
|
|
23285
|
-
'settings_url',
|
|
23286
|
-
'web_component_embedder_url',
|
|
23287
|
-
'languages',
|
|
23288
|
-
'contact_email',
|
|
23289
|
-
'reuse_form_url',
|
|
23290
|
-
], warnings, errors);
|
|
23291
|
-
if (parsedGlobalSection?.metadata_language) {
|
|
23292
|
-
parsedGlobalSection = checkMetadataLanguage(parsedGlobalSection, warnings);
|
|
23483
|
+
}
|
|
23484
|
+
ngOnDestroy() {
|
|
23485
|
+
if (this.tippyInstance) {
|
|
23486
|
+
this.tippyInstance.destroy();
|
|
23293
23487
|
}
|
|
23294
|
-
|
|
23295
|
-
|
|
23296
|
-
? null
|
|
23297
|
-
: {
|
|
23298
|
-
GN4_API_URL: parsedGlobalSection.geonetwork4_api_url,
|
|
23299
|
-
DATAHUB_URL: parsedGlobalSection.datahub_url,
|
|
23300
|
-
EDIT_URL_TEMPLATE: parsedGlobalSection.edit_url_template,
|
|
23301
|
-
PROXY_PATH: parsedGlobalSection.proxy_path,
|
|
23302
|
-
METADATA_LANGUAGE: parsedGlobalSection.metadata_language
|
|
23303
|
-
? parsedGlobalSection.metadata_language.toLowerCase()
|
|
23304
|
-
: undefined,
|
|
23305
|
-
LOGIN_URL: parsedGlobalSection.login_url,
|
|
23306
|
-
LOGOUT_URL: parsedGlobalSection.logout_url,
|
|
23307
|
-
SETTINGS_URL: parsedGlobalSection.settings_url,
|
|
23308
|
-
WEB_COMPONENT_EMBEDDER_URL: parsedGlobalSection.web_component_embedder_url,
|
|
23309
|
-
LANGUAGES: parsedGlobalSection.languages,
|
|
23310
|
-
CONTACT_EMAIL: parsedGlobalSection.contact_email,
|
|
23311
|
-
REUSE_FORM_URL: parsedGlobalSection.reuse_form_url,
|
|
23312
|
-
};
|
|
23313
|
-
const parsedLayersSections = parseMultiConfigSection(parsed, 'map_layer', ['type'], ['name', 'url', 'data', 'styleUrl', 'accessToken'], warnings, errors);
|
|
23314
|
-
const parsedMapSection = parseConfigSection(parsed, 'map', [], [
|
|
23315
|
-
'max_zoom',
|
|
23316
|
-
'do_not_tile_wms',
|
|
23317
|
-
'max_extent',
|
|
23318
|
-
'max_feature_count',
|
|
23319
|
-
'baselayer',
|
|
23320
|
-
'do_not_use_default_basemap',
|
|
23321
|
-
'external_viewer_url_template',
|
|
23322
|
-
'external_viewer_open_new_tab',
|
|
23323
|
-
], warnings, errors);
|
|
23324
|
-
mapConfig =
|
|
23325
|
-
parsedMapSection === null || parsedLayersSections === null
|
|
23326
|
-
? null
|
|
23327
|
-
: {
|
|
23328
|
-
MAX_ZOOM: parsedMapSection.max_zoom,
|
|
23329
|
-
DO_NOT_TILE_WMS: parsedMapSection.do_not_tile_wms,
|
|
23330
|
-
MAX_EXTENT: parsedMapSection.max_extent,
|
|
23331
|
-
MAX_FEATURE_COUNT: parsedMapSection.max_feature_count,
|
|
23332
|
-
EXTERNAL_VIEWER_URL_TEMPLATE: parsedMapSection.external_viewer_url_template,
|
|
23333
|
-
EXTERNAL_VIEWER_OPEN_NEW_TAB: parsedMapSection.external_viewer_open_new_tab,
|
|
23334
|
-
DO_NOT_USE_DEFAULT_BASEMAP: !!parsedMapSection.do_not_use_default_basemap,
|
|
23335
|
-
MAP_LAYERS: parsedLayersSections.map((map_layer) => ({
|
|
23336
|
-
TYPE: map_layer.type,
|
|
23337
|
-
URL: map_layer.url,
|
|
23338
|
-
NAME: map_layer.name,
|
|
23339
|
-
DATA: map_layer.data,
|
|
23340
|
-
STYLE_URL: map_layer.styleUrl,
|
|
23341
|
-
ACCESS_TOKEN: map_layer.accessToken,
|
|
23342
|
-
})),
|
|
23343
|
-
};
|
|
23344
|
-
const parsedThemeSection = parseConfigSection(parsed, 'theme', ['primary_color', 'secondary_color', 'main_color', 'background_color'], [
|
|
23345
|
-
'header_foreground_color',
|
|
23346
|
-
'main_font',
|
|
23347
|
-
'title_font',
|
|
23348
|
-
'fonts_stylesheet_url',
|
|
23349
|
-
'thumbnail_placeholder',
|
|
23350
|
-
'header_background',
|
|
23351
|
-
'favicon',
|
|
23352
|
-
], warnings, errors);
|
|
23353
|
-
themeConfig =
|
|
23354
|
-
parsedThemeSection === null
|
|
23355
|
-
? null
|
|
23356
|
-
: {
|
|
23357
|
-
PRIMARY_COLOR: parsedThemeSection.primary_color,
|
|
23358
|
-
SECONDARY_COLOR: parsedThemeSection.secondary_color,
|
|
23359
|
-
MAIN_COLOR: parsedThemeSection.main_color,
|
|
23360
|
-
BACKGROUND_COLOR: parsedThemeSection.background_color,
|
|
23361
|
-
HEADER_FOREGROUND_COLOR: parsedThemeSection.header_foreground_color,
|
|
23362
|
-
THUMBNAIL_PLACEHOLDER: parsedThemeSection.thumbnail_placeholder,
|
|
23363
|
-
HEADER_BACKGROUND: parsedThemeSection.header_background,
|
|
23364
|
-
TITLE_FONT: parsedThemeSection.title_font,
|
|
23365
|
-
MAIN_FONT: parsedThemeSection.main_font,
|
|
23366
|
-
FONTS_STYLESHEET_URL: parsedThemeSection.fonts_stylesheet_url,
|
|
23367
|
-
FAVICON: parsedThemeSection.favicon,
|
|
23368
|
-
};
|
|
23369
|
-
const parsedSearchSection = parseConfigSection(parsed, 'search', [], [
|
|
23370
|
-
'record_kind_quick_filter',
|
|
23371
|
-
'filter_geometry_data',
|
|
23372
|
-
'filter_geometry_url',
|
|
23373
|
-
'do_not_use_default_search_preset',
|
|
23374
|
-
'search_preset',
|
|
23375
|
-
'advanced_filters',
|
|
23376
|
-
'limit',
|
|
23377
|
-
'spatial_extent_max_file_size',
|
|
23378
|
-
], warnings, errors);
|
|
23379
|
-
const parsedSearchParams = parseMultiConfigSection(parsed, 'search_preset', ['name'], ['sort', 'filters'], warnings, errors);
|
|
23380
|
-
searchConfig =
|
|
23381
|
-
parsedSearchSection === null
|
|
23382
|
-
? null
|
|
23383
|
-
: {
|
|
23384
|
-
RECORD_KIND_QUICK_FILTER: parsedSearchSection.record_kind_quick_filter,
|
|
23385
|
-
FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
|
|
23386
|
-
FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
|
|
23387
|
-
DO_NOT_USE_DEFAULT_SEARCH_PRESET: !!parsedSearchSection.do_not_use_default_search_preset,
|
|
23388
|
-
SEARCH_PRESET: parsedSearchParams.map((param) => ({
|
|
23389
|
-
sort: param.sort,
|
|
23390
|
-
name: param.name,
|
|
23391
|
-
filters: param.filters,
|
|
23392
|
-
})),
|
|
23393
|
-
ADVANCED_FILTERS: parsedSearchSection.advanced_filters,
|
|
23394
|
-
LIMIT: parsedSearchSection.limit,
|
|
23395
|
-
SPATIAL_EXTENT_MAX_FILE_SIZE: parsedSearchSection.spatial_extent_max_file_size,
|
|
23396
|
-
};
|
|
23397
|
-
const parsedMetadataQualitySection = parseConfigSection(parsed, 'metadata-quality', [], ['enabled'], warnings, errors);
|
|
23398
|
-
metadataQualityConfig =
|
|
23399
|
-
parsedMetadataQualitySection === null
|
|
23400
|
-
? null
|
|
23401
|
-
: {
|
|
23402
|
-
ENABLED: parsedMetadataQualitySection.enabled,
|
|
23403
|
-
SORTABLE: parsedMetadataQualitySection.sortable,
|
|
23404
|
-
};
|
|
23405
|
-
let parsedEditingSection = parseConfigSection(parsed, 'editing', [], ['new_record_default_language', 'new_record_standard'], warnings, errors);
|
|
23406
|
-
if (parsedEditingSection !== null &&
|
|
23407
|
-
parsedEditingSection.new_record_default_language !== undefined) {
|
|
23408
|
-
parsedEditingSection = checkNewRecordDefaultLanguage(parsedEditingSection, warnings);
|
|
23409
|
-
}
|
|
23410
|
-
if (parsedEditingSection !== null &&
|
|
23411
|
-
parsedEditingSection.new_record_standard !== undefined) {
|
|
23412
|
-
parsedEditingSection = checkNewRecordStandard(parsedEditingSection, warnings);
|
|
23413
|
-
}
|
|
23414
|
-
editorConfig =
|
|
23415
|
-
parsedEditingSection === null
|
|
23416
|
-
? null
|
|
23417
|
-
: {
|
|
23418
|
-
NEW_RECORD_DEFAULT_LANGUAGE: parsedEditingSection.new_record_default_language,
|
|
23419
|
-
NEW_RECORD_STANDARD: parsedEditingSection.new_record_standard,
|
|
23420
|
-
};
|
|
23421
|
-
customTranslations = parseTranslationsConfigSection(parsed, 'translations');
|
|
23422
|
-
if (errors.length) {
|
|
23423
|
-
throw new Error(`One or more mandatory settings were missing from the configuration file.
|
|
23424
|
-
${errors.join('\n')}`);
|
|
23425
|
-
}
|
|
23426
|
-
else if (warnings.length) {
|
|
23427
|
-
console.warn(`One or more unexpected settings were encountered in the configuration file.
|
|
23428
|
-
${warnings.join('\n')}`);
|
|
23488
|
+
if (this.view) {
|
|
23489
|
+
this.view.destroy();
|
|
23429
23490
|
}
|
|
23430
|
-
|
|
23431
|
-
});
|
|
23432
|
-
}
|
|
23433
|
-
function isConfigLoaded() {
|
|
23434
|
-
return appConfigLoaded;
|
|
23435
|
-
}
|
|
23436
|
-
function _reset() {
|
|
23437
|
-
globalConfig = null;
|
|
23438
|
-
themeConfig = null;
|
|
23439
|
-
editorConfig = null;
|
|
23440
|
-
customTranslations = null;
|
|
23441
|
-
}
|
|
23442
|
-
const TRANSLATE_WITH_OVERRIDES_CONFIG = {
|
|
23443
|
-
compiler: {
|
|
23444
|
-
provide: TranslateCompiler,
|
|
23445
|
-
useClass: TranslateMessageFormatCompiler,
|
|
23446
|
-
},
|
|
23447
|
-
loader: [
|
|
23448
|
-
{
|
|
23449
|
-
provide: TRANSLATE_HTTP_LOADER_CONFIG,
|
|
23450
|
-
useValue: {
|
|
23451
|
-
prefix: './assets/i18n/',
|
|
23452
|
-
suffix: '.json',
|
|
23453
|
-
},
|
|
23454
|
-
},
|
|
23455
|
-
{
|
|
23456
|
-
provide: TranslateLoader,
|
|
23457
|
-
useClass: FileWithOverridesTranslateLoader,
|
|
23458
|
-
deps: [HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
|
|
23459
|
-
},
|
|
23460
|
-
],
|
|
23461
|
-
};
|
|
23462
|
-
|
|
23463
|
-
const okAppConfigFixture = () => `
|
|
23464
|
-
[global]
|
|
23465
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23466
|
-
proxy_path = "/proxy/?url="
|
|
23467
|
-
metadata_language = "fre"
|
|
23468
|
-
login_url = "/cas/login?service="
|
|
23469
|
-
logout_url = "/geonetwork/signout"
|
|
23470
|
-
settings_url = "/geonetwork/settings"
|
|
23471
|
-
web_component_embedder_url = "/datahub/wc-embedder.html"
|
|
23472
|
-
|
|
23473
|
-
[map]
|
|
23474
|
-
max_zoom = 10
|
|
23475
|
-
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
23476
|
-
do_not_use_default_basemap = false
|
|
23477
|
-
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
23478
|
-
external_viewer_open_new_tab = true
|
|
23479
|
-
[[map_layer]]
|
|
23480
|
-
type = "wms"
|
|
23481
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23482
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23483
|
-
[[map_layer]]
|
|
23484
|
-
type = "wfs"
|
|
23485
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23486
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23487
|
-
|
|
23488
|
-
[theme]
|
|
23489
|
-
primary_color = "#093564"
|
|
23490
|
-
secondary_color = "#c2e9dc"
|
|
23491
|
-
main_color = "#212029" # All-purpose text color
|
|
23492
|
-
background_color = "#fdfbff"
|
|
23493
|
-
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
23494
|
-
header_background = 'teal'
|
|
23495
|
-
header_foreground_color = "#872e2e"
|
|
23496
|
-
main_font = 'sans-serif'
|
|
23497
|
-
title_font = 'serif'
|
|
23498
|
-
fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
|
|
23499
|
-
|
|
23500
|
-
[search]
|
|
23501
|
-
record_kind_quick_filter = false
|
|
23502
|
-
filter_geometry_url = 'https://my.domain.org/geom.json'
|
|
23503
|
-
do_not_use_default_search_preset = false
|
|
23504
|
-
advanced_filters = ['publicationYear', 'documentStandard', 'inspireKeyword', 'topic', 'license']
|
|
23505
|
-
|
|
23506
|
-
[[search_preset]]
|
|
23507
|
-
sort = "-createDate"
|
|
23508
|
-
name = 'filterByOrgs'
|
|
23509
|
-
filters.q = 'Carto'
|
|
23510
|
-
filters.organisation = ['Org1', 'Org2']
|
|
23511
|
-
filters.format = ['ESRI Shapefile']
|
|
23512
|
-
filters.topic = ['boundaries']
|
|
23513
|
-
filters.publicationYear = ['2023', '2022']
|
|
23514
|
-
filters.spatial = ['yes']
|
|
23515
|
-
|
|
23516
|
-
[translations.en]
|
|
23517
|
-
"my.first.key" = 'First label.'
|
|
23518
|
-
"my.second.key" = """
|
|
23519
|
-
Second label,
|
|
23520
|
-
on two lines."""
|
|
23521
|
-
|
|
23522
|
-
[translations.de]
|
|
23523
|
-
my.first.key = 'Erste Etikett.'
|
|
23524
|
-
|
|
23525
|
-
[translations.fr]
|
|
23526
|
-
my.sample.text = "Un bon exemple de texte."
|
|
23527
|
-
"my.quoted.text" = 'du texte entre guillements.'
|
|
23528
|
-
`;
|
|
23529
|
-
const appConfigWithTranslationFixture = () => okAppConfigFixture();
|
|
23530
|
-
const minimalAppConfigFixture = () => `
|
|
23531
|
-
[global]
|
|
23532
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23533
|
-
proxy_path = "/proxy/?url="
|
|
23534
|
-
|
|
23535
|
-
[theme]
|
|
23536
|
-
primary_color = "#093564"
|
|
23537
|
-
secondary_color = "#c2e9dc"
|
|
23538
|
-
main_color = "#212029" # All-purpose text color
|
|
23539
|
-
background_color = "#fdfbff"
|
|
23540
|
-
`;
|
|
23541
|
-
const mapConfigFixture = () => ({
|
|
23542
|
-
MAX_ZOOM: 10,
|
|
23543
|
-
MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
|
|
23544
|
-
DO_NOT_USE_DEFAULT_BASEMAP: false,
|
|
23545
|
-
DO_NOT_TILE_WMS: false,
|
|
23546
|
-
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}"}]}]',
|
|
23547
|
-
EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
|
|
23548
|
-
MAP_LAYERS: [
|
|
23549
|
-
{
|
|
23550
|
-
TYPE: 'xyz',
|
|
23551
|
-
URL: 'https://some-basemap-server',
|
|
23552
|
-
},
|
|
23553
|
-
{
|
|
23554
|
-
TYPE: 'wms',
|
|
23555
|
-
URL: 'https://some-wms-server',
|
|
23556
|
-
NAME: 'some_layername',
|
|
23557
|
-
},
|
|
23558
|
-
{
|
|
23559
|
-
TYPE: 'wfs',
|
|
23560
|
-
URL: 'https://some-wfs-server',
|
|
23561
|
-
NAME: 'some_layername',
|
|
23562
|
-
},
|
|
23563
|
-
],
|
|
23564
|
-
});
|
|
23565
|
-
const malformedConfigFixture = () => `
|
|
23566
|
-
{
|
|
23567
|
-
"I thought": "we were still doing json"
|
|
23491
|
+
}
|
|
23492
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23493
|
+
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: [""] }); }
|
|
23568
23494
|
}
|
|
23569
|
-
|
|
23570
|
-
|
|
23571
|
-
[
|
|
23572
|
-
|
|
23573
|
-
|
|
23574
|
-
|
|
23575
|
-
|
|
23576
|
-
|
|
23577
|
-
|
|
23578
|
-
|
|
23579
|
-
|
|
23580
|
-
proxy_path = "/proxy/?url="
|
|
23581
|
-
metadata_language = "abc"
|
|
23582
|
-
|
|
23583
|
-
[map]
|
|
23584
|
-
|
|
23585
|
-
[theme]
|
|
23586
|
-
primary_color = "#093564"
|
|
23587
|
-
secondary_color = "#c2e9dc"
|
|
23588
|
-
main_color = "#212029" # All-purpose text color
|
|
23589
|
-
background_color = "#fdfbff"
|
|
23590
|
-
`;
|
|
23591
|
-
const unrecognizedKeysConfigFixture = () => `
|
|
23592
|
-
[global]
|
|
23593
|
-
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
23594
|
-
proxy_path = "/proxy/?url="
|
|
23595
|
-
metadata_language = "fre"
|
|
23596
|
-
another_path = '/whatever'
|
|
23597
|
-
|
|
23598
|
-
[map]
|
|
23599
|
-
max_zoom = 10
|
|
23600
|
-
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
23601
|
-
do_not_use_default_basemap = false
|
|
23602
|
-
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
23603
|
-
external_viewer_open_new_tab = true
|
|
23604
|
-
another_zoom = 15
|
|
23605
|
-
[[map_layer]]
|
|
23606
|
-
type = "wms"
|
|
23607
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23608
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23609
|
-
[[map_layer]]
|
|
23610
|
-
type = "wfs"
|
|
23611
|
-
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
23612
|
-
name = "masque_hdf_ign_carto_latin1"
|
|
23613
|
-
another_layer = "wrong layer definition"
|
|
23614
|
-
|
|
23615
|
-
[theme]
|
|
23616
|
-
primary_color = "#093564"
|
|
23617
|
-
secondary_color = "#c2e9dc"
|
|
23618
|
-
main_color = "#212029" # All-purpose text color
|
|
23619
|
-
background_color = "#fdfbff"
|
|
23620
|
-
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
23621
|
-
header_background = 'teal'
|
|
23622
|
-
header_foreground_color = "#872e2e"
|
|
23623
|
-
main_font = 'sans-serif'
|
|
23624
|
-
title_font = 'serif'
|
|
23625
|
-
another_color = 'red'
|
|
23626
|
-
`;
|
|
23495
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, decorators: [{
|
|
23496
|
+
type: Component,
|
|
23497
|
+
args: [{ selector: 'gn-ui-popover', standalone: true, imports: [], template: "<span #popoverContent>\n <ng-content></ng-content>\n</span>\n" }]
|
|
23498
|
+
}], propDecorators: { popoverContent: [{
|
|
23499
|
+
type: ViewChild,
|
|
23500
|
+
args: ['popoverContent', { static: false }]
|
|
23501
|
+
}], content: [{
|
|
23502
|
+
type: Input
|
|
23503
|
+
}], theme: [{
|
|
23504
|
+
type: Input
|
|
23505
|
+
}] } });
|
|
23627
23506
|
|
|
23628
|
-
|
|
23629
|
-
|
|
23630
|
-
|
|
23631
|
-
return {
|
|
23632
|
-
type: 'wms',
|
|
23633
|
-
url: config.URL,
|
|
23634
|
-
name: config.NAME,
|
|
23635
|
-
};
|
|
23636
|
-
case 'wfs':
|
|
23637
|
-
return {
|
|
23638
|
-
type: 'wfs',
|
|
23639
|
-
url: config.URL,
|
|
23640
|
-
featureType: config.NAME,
|
|
23641
|
-
};
|
|
23642
|
-
case 'xyz':
|
|
23643
|
-
return {
|
|
23644
|
-
type: config.TYPE,
|
|
23645
|
-
url: config.URL,
|
|
23646
|
-
};
|
|
23647
|
-
case 'geojson':
|
|
23648
|
-
return {
|
|
23649
|
-
type: config.TYPE,
|
|
23650
|
-
...(config.DATA ? { data: config.DATA } : { url: config.URL }),
|
|
23651
|
-
};
|
|
23652
|
-
case 'maplibre-style':
|
|
23653
|
-
return {
|
|
23654
|
-
type: config.TYPE,
|
|
23655
|
-
styleUrl: config.STYLE_URL,
|
|
23656
|
-
accessToken: config.ACCESS_TOKEN,
|
|
23657
|
-
};
|
|
23658
|
-
}
|
|
23507
|
+
class LoadingMaskComponent {
|
|
23508
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23509
|
+
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 }); }
|
|
23659
23510
|
}
|
|
23511
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, decorators: [{
|
|
23512
|
+
type: Component,
|
|
23513
|
+
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"] }]
|
|
23514
|
+
}], propDecorators: { message: [{
|
|
23515
|
+
type: Input
|
|
23516
|
+
}] } });
|
|
23660
23517
|
|
|
23661
|
-
class
|
|
23662
|
-
|
|
23663
|
-
|
|
23664
|
-
default: this.createStyleFunction(this.createGeometryStyles({
|
|
23665
|
-
color: isConfigLoaded() ? getThemeConfig().PRIMARY_COLOR : 'blue',
|
|
23666
|
-
})),
|
|
23667
|
-
defaultHL: this.createStyleFunction(this.createGeometryStyles({
|
|
23668
|
-
color: isConfigLoaded() ? getThemeConfig().SECONDARY_COLOR : 'red',
|
|
23669
|
-
isFocused: true,
|
|
23670
|
-
})),
|
|
23671
|
-
};
|
|
23672
|
-
}
|
|
23673
|
-
createGeometryStyles(options) {
|
|
23674
|
-
const { color, isFocused } = options;
|
|
23675
|
-
const zIndex = isFocused ? 10 : undefined;
|
|
23676
|
-
return {
|
|
23677
|
-
polygon: new Style({
|
|
23678
|
-
fill: new Fill({
|
|
23679
|
-
color: this.computeTransparentFillColor(color),
|
|
23680
|
-
}),
|
|
23681
|
-
stroke: new Stroke({
|
|
23682
|
-
color: 'white',
|
|
23683
|
-
width: 2,
|
|
23684
|
-
}),
|
|
23685
|
-
zIndex,
|
|
23686
|
-
}),
|
|
23687
|
-
point: new Style({
|
|
23688
|
-
image: new CircleStyle({
|
|
23689
|
-
fill: new Fill({
|
|
23690
|
-
color,
|
|
23691
|
-
}),
|
|
23692
|
-
stroke: new Stroke({
|
|
23693
|
-
color: 'white',
|
|
23694
|
-
width: isFocused ? 3 : 2,
|
|
23695
|
-
}),
|
|
23696
|
-
radius: isFocused ? 8 : 7,
|
|
23697
|
-
}),
|
|
23698
|
-
zIndex,
|
|
23699
|
-
}),
|
|
23700
|
-
line: [
|
|
23701
|
-
new Style({
|
|
23702
|
-
stroke: new Stroke({
|
|
23703
|
-
color: 'white',
|
|
23704
|
-
width: isFocused ? 8 : 6,
|
|
23705
|
-
}),
|
|
23706
|
-
zIndex,
|
|
23707
|
-
}),
|
|
23708
|
-
new Style({
|
|
23709
|
-
stroke: new Stroke({
|
|
23710
|
-
color,
|
|
23711
|
-
width: isFocused ? 3 : 2,
|
|
23712
|
-
}),
|
|
23713
|
-
zIndex,
|
|
23714
|
-
}),
|
|
23715
|
-
],
|
|
23716
|
-
};
|
|
23717
|
-
}
|
|
23718
|
-
createStyleFunction(styleByGeometryType) {
|
|
23719
|
-
return (feature) => {
|
|
23720
|
-
const geometryType = feature?.getGeometry()?.getType();
|
|
23721
|
-
switch (geometryType) {
|
|
23722
|
-
case 'LinearRing':
|
|
23723
|
-
case 'LineString':
|
|
23724
|
-
case 'MultiLineString':
|
|
23725
|
-
return styleByGeometryType.line;
|
|
23726
|
-
case 'Point':
|
|
23727
|
-
case 'MultiPoint':
|
|
23728
|
-
return styleByGeometryType.point;
|
|
23729
|
-
case 'Circle':
|
|
23730
|
-
case 'Polygon':
|
|
23731
|
-
case 'MultiPolygon':
|
|
23732
|
-
return styleByGeometryType.polygon;
|
|
23733
|
-
default:
|
|
23734
|
-
return styleByGeometryType.point;
|
|
23735
|
-
}
|
|
23736
|
-
};
|
|
23737
|
-
}
|
|
23738
|
-
computeTransparentFillColor(color, alpha = 0.25) {
|
|
23739
|
-
return chroma(color).alpha(alpha).css();
|
|
23740
|
-
}
|
|
23741
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: MapStyleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
23742
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: MapStyleService, providedIn: 'root' }); }
|
|
23518
|
+
class ColorScaleComponent {
|
|
23519
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23520
|
+
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: [""] }); }
|
|
23743
23521
|
}
|
|
23744
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type:
|
|
23745
|
-
type:
|
|
23746
|
-
args: [{
|
|
23747
|
-
providedIn: 'root',
|
|
23748
|
-
}]
|
|
23522
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, decorators: [{
|
|
23523
|
+
type: Component,
|
|
23524
|
+
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" }]
|
|
23749
23525
|
}] });
|
|
23750
23526
|
|
|
23751
|
-
|
|
23752
|
-
const colorSecondary = 'red';
|
|
23753
|
-
const colorStroke = 'white';
|
|
23754
|
-
const defaultMapStyleFixture = () => new Style({
|
|
23755
|
-
image: new Circle({
|
|
23756
|
-
fill: new Fill({
|
|
23757
|
-
color: colorPrimary,
|
|
23758
|
-
}),
|
|
23759
|
-
stroke: new Stroke({
|
|
23760
|
-
color: colorStroke,
|
|
23761
|
-
width: 2,
|
|
23762
|
-
}),
|
|
23763
|
-
radius: 5,
|
|
23764
|
-
}),
|
|
23765
|
-
fill: new Fill({
|
|
23766
|
-
color: 'rgba(0,0,255,0.25)',
|
|
23767
|
-
}),
|
|
23768
|
-
stroke: new Stroke({
|
|
23769
|
-
color: colorStroke,
|
|
23770
|
-
width: 2,
|
|
23771
|
-
}),
|
|
23772
|
-
});
|
|
23773
|
-
const defaultMapStyleHlFixture = () => new Style({
|
|
23774
|
-
image: new Circle({
|
|
23775
|
-
fill: new Fill({
|
|
23776
|
-
color: colorSecondary,
|
|
23777
|
-
}),
|
|
23778
|
-
stroke: new Stroke({
|
|
23779
|
-
color: colorStroke,
|
|
23780
|
-
width: 3,
|
|
23781
|
-
}),
|
|
23782
|
-
radius: 6,
|
|
23783
|
-
}),
|
|
23784
|
-
fill: new Fill({
|
|
23785
|
-
color: 'rgba(255,0,0,0.25)',
|
|
23786
|
-
}),
|
|
23787
|
-
stroke: new Stroke({
|
|
23788
|
-
color: colorSecondary,
|
|
23789
|
-
width: 3,
|
|
23790
|
-
}),
|
|
23791
|
-
});
|
|
23792
|
-
|
|
23793
|
-
class AnchorLinkDirective {
|
|
23527
|
+
class PopupAlertComponent {
|
|
23794
23528
|
constructor() {
|
|
23795
23529
|
this.changeDetector = inject(ChangeDetectorRef);
|
|
23796
|
-
this.
|
|
23797
|
-
this.
|
|
23798
|
-
|
|
23799
|
-
|
|
23800
|
-
this.inView = false;
|
|
23801
|
-
this.initialized = false;
|
|
23530
|
+
this.type = 'info';
|
|
23531
|
+
this.position = 'top';
|
|
23532
|
+
this.expanded = false;
|
|
23533
|
+
this.timeout = null;
|
|
23802
23534
|
}
|
|
23803
|
-
get
|
|
23804
|
-
|
|
23805
|
-
|
|
23806
|
-
}
|
|
23807
|
-
if (this.inView) {
|
|
23808
|
-
return `${this.inViewClass} ${this.enabledClass}`;
|
|
23809
|
-
}
|
|
23810
|
-
else {
|
|
23811
|
-
return `${this.outOfViewClass} ${this.enabledClass}`;
|
|
23812
|
-
}
|
|
23535
|
+
get showDuration() {
|
|
23536
|
+
const chars = this.content.nativeElement.innerHTML.length;
|
|
23537
|
+
return Math.max(3000, chars * 20);
|
|
23813
23538
|
}
|
|
23814
23539
|
ngOnInit() {
|
|
23815
|
-
this.
|
|
23816
|
-
childList: true,
|
|
23817
|
-
subtree: true,
|
|
23818
|
-
});
|
|
23819
|
-
this.refreshDisabledState();
|
|
23820
|
-
}
|
|
23821
|
-
ngAfterViewChecked() {
|
|
23822
|
-
if (!this.initialized && !this.disabled) {
|
|
23823
|
-
const target = document.getElementById(this.targetId);
|
|
23824
|
-
if (target) {
|
|
23825
|
-
this.initializeIntersectionObserver(target);
|
|
23826
|
-
this.initialized = true;
|
|
23827
|
-
}
|
|
23828
|
-
}
|
|
23829
|
-
}
|
|
23830
|
-
initializeIntersectionObserver(target) {
|
|
23831
|
-
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
23832
|
-
entries.forEach((entry) => {
|
|
23833
|
-
this.inView = entry.isIntersecting;
|
|
23834
|
-
this.changeDetector.detectChanges();
|
|
23835
|
-
});
|
|
23836
|
-
}, {
|
|
23837
|
-
root: null,
|
|
23838
|
-
rootMargin: '-30% 0% -60% 0%',
|
|
23839
|
-
});
|
|
23840
|
-
this.intersectionObserver.observe(target);
|
|
23540
|
+
this.expandAndClose();
|
|
23841
23541
|
}
|
|
23842
|
-
|
|
23843
|
-
this.
|
|
23844
|
-
|
|
23845
|
-
|
|
23846
|
-
}
|
|
23542
|
+
expand() {
|
|
23543
|
+
this.expanded = true;
|
|
23544
|
+
this.changeDetector.detectChanges();
|
|
23545
|
+
clearTimeout(this.timeout);
|
|
23847
23546
|
}
|
|
23848
|
-
|
|
23849
|
-
|
|
23850
|
-
|
|
23851
|
-
|
|
23547
|
+
expandAndClose() {
|
|
23548
|
+
this.expanded = true;
|
|
23549
|
+
this.changeDetector.detectChanges();
|
|
23550
|
+
clearTimeout(this.timeout);
|
|
23551
|
+
this.timeout = setTimeout(() => {
|
|
23552
|
+
this.expanded = false;
|
|
23852
23553
|
this.changeDetector.detectChanges();
|
|
23853
|
-
}
|
|
23854
|
-
}
|
|
23855
|
-
scrollToTarget() {
|
|
23856
|
-
const target = document.getElementById(this.targetId);
|
|
23857
|
-
if (!target)
|
|
23858
|
-
return;
|
|
23859
|
-
target.scrollIntoView({
|
|
23860
|
-
behavior: 'smooth',
|
|
23861
|
-
block: 'start',
|
|
23862
|
-
});
|
|
23554
|
+
}, this.showDuration);
|
|
23863
23555
|
}
|
|
23864
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type:
|
|
23865
|
-
static { this.ɵ
|
|
23866
|
-
}
|
|
23867
|
-
|
|
23868
|
-
|
|
23869
|
-
|
|
23870
|
-
|
|
23871
|
-
standalone: true,
|
|
23872
|
-
}]
|
|
23873
|
-
}], propDecorators: { targetId: [{
|
|
23874
|
-
type: Input,
|
|
23875
|
-
args: ['gnUiAnchorLink']
|
|
23876
|
-
}], disabledClass: [{
|
|
23877
|
-
type: Input,
|
|
23878
|
-
args: ['gnUiAnchorLinkDisabledClass']
|
|
23879
|
-
}], enabledClass: [{
|
|
23880
|
-
type: Input,
|
|
23881
|
-
args: ['gnUiAnchorLinkEnabledClass']
|
|
23882
|
-
}], inViewClass: [{
|
|
23883
|
-
type: Input,
|
|
23884
|
-
args: ['gnUiAnchorLinkInViewClass']
|
|
23885
|
-
}], outOfViewClass: [{
|
|
23886
|
-
type: Input,
|
|
23887
|
-
args: ['gnUiAnchorLinkOutOfViewClass']
|
|
23888
|
-
}], elementClass: [{
|
|
23889
|
-
type: HostBinding,
|
|
23890
|
-
args: ['class']
|
|
23891
|
-
}], scrollToTarget: [{
|
|
23892
|
-
type: HostListener,
|
|
23893
|
-
args: ['click']
|
|
23894
|
-
}] } });
|
|
23895
|
-
|
|
23896
|
-
class PaginationDotsComponent {
|
|
23897
|
-
constructor() {
|
|
23898
|
-
this.containerClass = '';
|
|
23899
|
-
}
|
|
23900
|
-
// 1-based
|
|
23901
|
-
get steps() {
|
|
23902
|
-
return Array.from({ length: this.listComponent.pagesCount }, (_, i) => i + 1);
|
|
23903
|
-
}
|
|
23904
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23905
|
-
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: [
|
|
23906
|
-
provideIcons({
|
|
23907
|
-
iconoirNavArrowRight,
|
|
23908
|
-
iconoirNavArrowLeft,
|
|
23909
|
-
}),
|
|
23910
|
-
] }); }
|
|
23911
|
-
}
|
|
23912
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationDotsComponent, decorators: [{
|
|
23913
|
-
type: Component,
|
|
23914
|
-
args: [{ selector: 'gn-ui-pagination-dots', standalone: true, imports: [CommonModule], viewProviders: [
|
|
23915
|
-
provideIcons({
|
|
23916
|
-
iconoirNavArrowRight,
|
|
23917
|
-
iconoirNavArrowLeft,
|
|
23918
|
-
}),
|
|
23919
|
-
], 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"] }]
|
|
23920
|
-
}], propDecorators: { listComponent: [{
|
|
23921
|
-
type: Input
|
|
23922
|
-
}], containerClass: [{
|
|
23923
|
-
type: Input
|
|
23924
|
-
}] } });
|
|
23925
|
-
|
|
23926
|
-
class CarouselComponent {
|
|
23927
|
-
constructor() {
|
|
23928
|
-
this.changeDetector = inject(ChangeDetectorRef);
|
|
23929
|
-
this.containerClass = '';
|
|
23930
|
-
this.stepsContainerClass = 'w-full bottom-0 top-auto';
|
|
23931
|
-
this.currentStepChange = new EventEmitter();
|
|
23932
|
-
this.steps = [];
|
|
23933
|
-
this.currentStep = 0;
|
|
23934
|
-
this.refreshSteps = () => {
|
|
23935
|
-
this.steps = this.emblaApi.scrollSnapList();
|
|
23936
|
-
this.currentStep = this.emblaApi.selectedScrollSnap();
|
|
23937
|
-
this.currentStepChange.emit(this.currentStep);
|
|
23938
|
-
this.changeDetector.detectChanges();
|
|
23939
|
-
};
|
|
23940
|
-
}
|
|
23941
|
-
// Paginable API
|
|
23942
|
-
get isFirstPage() {
|
|
23943
|
-
return this.currentStep === 0;
|
|
23944
|
-
}
|
|
23945
|
-
get isLastPage() {
|
|
23946
|
-
return this.currentStep === this.steps.length - 1;
|
|
23947
|
-
}
|
|
23948
|
-
get currentPage() {
|
|
23949
|
-
return this.currentStep + 1; // this is 1-based
|
|
23950
|
-
}
|
|
23951
|
-
get pagesCount() {
|
|
23952
|
-
return this.steps.length;
|
|
23953
|
-
}
|
|
23954
|
-
goToPage(stepIndex) {
|
|
23955
|
-
this.emblaApi.scrollTo(stepIndex - 1); // this is 0-based
|
|
23956
|
-
}
|
|
23957
|
-
goToPrevPage() {
|
|
23958
|
-
if (this.isFirstPage)
|
|
23959
|
-
return;
|
|
23960
|
-
this.emblaApi.scrollPrev();
|
|
23961
|
-
}
|
|
23962
|
-
goToNextPage() {
|
|
23963
|
-
if (this.isLastPage)
|
|
23964
|
-
return;
|
|
23965
|
-
this.emblaApi.scrollNext();
|
|
23966
|
-
}
|
|
23967
|
-
ngAfterViewInit() {
|
|
23968
|
-
this.emblaApi = EmblaCarousel(this.carouselOverflowContainer.nativeElement, {
|
|
23969
|
-
duration: 15,
|
|
23970
|
-
});
|
|
23971
|
-
this.emblaApi
|
|
23972
|
-
.on('init', this.refreshSteps)
|
|
23973
|
-
.on('reInit', this.refreshSteps)
|
|
23974
|
-
.on('select', this.refreshSteps);
|
|
23975
|
-
}
|
|
23976
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23977
|
-
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 }); }
|
|
23978
|
-
}
|
|
23979
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CarouselComponent, decorators: [{
|
|
23980
|
-
type: Component,
|
|
23981
|
-
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"] }]
|
|
23982
|
-
}], propDecorators: { carouselOverflowContainer: [{
|
|
23983
|
-
type: ViewChild,
|
|
23984
|
-
args: ['carouselOverflowContainer']
|
|
23985
|
-
}], containerClass: [{
|
|
23986
|
-
type: Input
|
|
23987
|
-
}], stepsContainerClass: [{
|
|
23988
|
-
type: Input
|
|
23989
|
-
}], currentStepChange: [{
|
|
23990
|
-
type: Output
|
|
23991
|
-
}] } });
|
|
23992
|
-
|
|
23993
|
-
class ProgressBarComponent {
|
|
23994
|
-
constructor() {
|
|
23995
|
-
this.value = 0;
|
|
23996
|
-
this.type = 'default';
|
|
23997
|
-
}
|
|
23998
|
-
get progress() {
|
|
23999
|
-
return this.value > 0 ? (this.value < 100 ? this.value : 100) : 0;
|
|
24000
|
-
}
|
|
24001
|
-
get color() {
|
|
24002
|
-
switch (this.type) {
|
|
24003
|
-
case 'default':
|
|
24004
|
-
return {
|
|
24005
|
-
outerBar: 'bg-gray-200',
|
|
24006
|
-
innerBar: 'bg-gray-100',
|
|
24007
|
-
text: 'text-gray-900',
|
|
24008
|
-
};
|
|
24009
|
-
case 'primary':
|
|
24010
|
-
return {
|
|
24011
|
-
outerBar: 'bg-primary',
|
|
24012
|
-
innerBar: 'bg-primary-lighter',
|
|
24013
|
-
text: 'text-white',
|
|
24014
|
-
};
|
|
24015
|
-
case 'secondary':
|
|
24016
|
-
return {
|
|
24017
|
-
outerBar: 'bg-secondary',
|
|
24018
|
-
innerBar: 'bg-secondary-lighter',
|
|
24019
|
-
text: 'text-white',
|
|
24020
|
-
};
|
|
24021
|
-
case 'light':
|
|
24022
|
-
return {
|
|
24023
|
-
outerBar: 'bg-primary-white',
|
|
24024
|
-
innerBar: 'bg-primary',
|
|
24025
|
-
text: 'text-main',
|
|
24026
|
-
};
|
|
24027
|
-
}
|
|
24028
|
-
}
|
|
24029
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24030
|
-
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"] }); }
|
|
24031
|
-
}
|
|
24032
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ProgressBarComponent, decorators: [{
|
|
24033
|
-
type: Component,
|
|
24034
|
-
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"] }]
|
|
24035
|
-
}], propDecorators: { value: [{
|
|
24036
|
-
type: Input
|
|
24037
|
-
}], type: [{
|
|
24038
|
-
type: Input
|
|
24039
|
-
}] } });
|
|
24040
|
-
|
|
24041
|
-
class PopoverComponent {
|
|
24042
|
-
constructor() {
|
|
24043
|
-
this.viewContainerRef = inject(ViewContainerRef);
|
|
24044
|
-
this.renderer = inject(Renderer2);
|
|
24045
|
-
}
|
|
24046
|
-
getContent() {
|
|
24047
|
-
if (this.content instanceof TemplateRef) {
|
|
24048
|
-
if (this.view) {
|
|
24049
|
-
this.view.destroy();
|
|
24050
|
-
}
|
|
24051
|
-
this.view = this.viewContainerRef.createEmbeddedView(this.content);
|
|
24052
|
-
this.view.detectChanges();
|
|
24053
|
-
const wrapper = this.renderer.createElement('div'); // Create a wrapper div
|
|
24054
|
-
this.view.rootNodes.forEach((node) => {
|
|
24055
|
-
this.renderer.appendChild(wrapper, node); // Append each root node to the wrapper
|
|
24056
|
-
});
|
|
24057
|
-
return wrapper;
|
|
24058
|
-
}
|
|
24059
|
-
return this.content;
|
|
24060
|
-
}
|
|
24061
|
-
ngAfterViewInit() {
|
|
24062
|
-
this.tippyInstance = tippy(this.popoverContent.nativeElement, {
|
|
24063
|
-
content: this.getContent(),
|
|
24064
|
-
allowHTML: true,
|
|
24065
|
-
theme: this.theme,
|
|
24066
|
-
});
|
|
24067
|
-
}
|
|
24068
|
-
ngOnChanges(changes) {
|
|
24069
|
-
if (changes['theme']) {
|
|
24070
|
-
this.theme = changes['theme'].currentValue;
|
|
24071
|
-
if (this.tippyInstance) {
|
|
24072
|
-
this.tippyInstance.setProps({ theme: this.theme });
|
|
24073
|
-
}
|
|
24074
|
-
}
|
|
24075
|
-
if (changes['content']) {
|
|
24076
|
-
this.content = changes['content'].currentValue;
|
|
24077
|
-
if (this.tippyInstance) {
|
|
24078
|
-
this.tippyInstance.setContent(this.getContent());
|
|
24079
|
-
}
|
|
24080
|
-
}
|
|
24081
|
-
}
|
|
24082
|
-
ngOnDestroy() {
|
|
24083
|
-
if (this.tippyInstance) {
|
|
24084
|
-
this.tippyInstance.destroy();
|
|
24085
|
-
}
|
|
24086
|
-
if (this.view) {
|
|
24087
|
-
this.view.destroy();
|
|
24088
|
-
}
|
|
24089
|
-
}
|
|
24090
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24091
|
-
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: [""] }); }
|
|
24092
|
-
}
|
|
24093
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopoverComponent, decorators: [{
|
|
24094
|
-
type: Component,
|
|
24095
|
-
args: [{ selector: 'gn-ui-popover', standalone: true, imports: [], template: "<span #popoverContent>\n <ng-content></ng-content>\n</span>\n" }]
|
|
24096
|
-
}], propDecorators: { popoverContent: [{
|
|
24097
|
-
type: ViewChild,
|
|
24098
|
-
args: ['popoverContent', { static: false }]
|
|
24099
|
-
}], content: [{
|
|
24100
|
-
type: Input
|
|
24101
|
-
}], theme: [{
|
|
24102
|
-
type: Input
|
|
24103
|
-
}] } });
|
|
24104
|
-
|
|
24105
|
-
class LoadingMaskComponent {
|
|
24106
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24107
|
-
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 }); }
|
|
24108
|
-
}
|
|
24109
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LoadingMaskComponent, decorators: [{
|
|
24110
|
-
type: Component,
|
|
24111
|
-
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"] }]
|
|
24112
|
-
}], propDecorators: { message: [{
|
|
24113
|
-
type: Input
|
|
24114
|
-
}] } });
|
|
24115
|
-
|
|
24116
|
-
class ColorScaleComponent {
|
|
24117
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24118
|
-
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: [""] }); }
|
|
24119
|
-
}
|
|
24120
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ColorScaleComponent, decorators: [{
|
|
24121
|
-
type: Component,
|
|
24122
|
-
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" }]
|
|
24123
|
-
}] });
|
|
24124
|
-
|
|
24125
|
-
class PopupAlertComponent {
|
|
24126
|
-
constructor() {
|
|
24127
|
-
this.changeDetector = inject(ChangeDetectorRef);
|
|
24128
|
-
this.type = 'info';
|
|
24129
|
-
this.position = 'top';
|
|
24130
|
-
this.expanded = false;
|
|
24131
|
-
this.timeout = null;
|
|
24132
|
-
}
|
|
24133
|
-
get showDuration() {
|
|
24134
|
-
const chars = this.content.nativeElement.innerHTML.length;
|
|
24135
|
-
return Math.max(3000, chars * 20);
|
|
24136
|
-
}
|
|
24137
|
-
ngOnInit() {
|
|
24138
|
-
this.expandAndClose();
|
|
24139
|
-
}
|
|
24140
|
-
expand() {
|
|
24141
|
-
this.expanded = true;
|
|
24142
|
-
this.changeDetector.detectChanges();
|
|
24143
|
-
clearTimeout(this.timeout);
|
|
24144
|
-
}
|
|
24145
|
-
expandAndClose() {
|
|
24146
|
-
this.expanded = true;
|
|
24147
|
-
this.changeDetector.detectChanges();
|
|
24148
|
-
clearTimeout(this.timeout);
|
|
24149
|
-
this.timeout = setTimeout(() => {
|
|
24150
|
-
this.expanded = false;
|
|
24151
|
-
this.changeDetector.detectChanges();
|
|
24152
|
-
}, this.showDuration);
|
|
24153
|
-
}
|
|
24154
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopupAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
24155
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: PopupAlertComponent, isStandalone: true, selector: "gn-ui-popup-alert", inputs: { icon: "icon", type: "type", position: "position" }, providers: [
|
|
24156
|
-
provideIcons({ matErrorOutlineOutline }),
|
|
24157
|
-
provideNgIconsConfig({
|
|
24158
|
-
size: '1.5em',
|
|
24159
|
-
}),
|
|
24160
|
-
], viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<div class=\"h-full relative container\">\n <div\n class=\"pointer-events-auto absolute text-white flex flex-row p-2 rounded message\"\n role=\"alert\"\n [ngClass]=\"{\n 'position-bottom': position === 'bottom',\n 'position-top': position === 'top',\n expanded: this.expanded,\n 'bg-red-500': type === 'danger',\n 'bg-yellow-500': type === 'warning',\n 'bg-blue-500': type === 'info',\n }\"\n (mouseenter)=\"expand()\"\n (mouseleave)=\"expandAndClose()\"\n >\n <ng-icon class=\"mr-2 shrink-0 select-none\" [name]=\"icon\"></ng-icon>\n <div class=\"grow\" #content [ngClass]=\"{ invisible: !expanded }\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", styles: [":host{pointer-events:none}.container{filter:drop-shadow(0px 4px 3px rgba(0,0,0,.2))}.message{transition:clip-path .3s cubic-bezier(.25,.46,.45,.94)}.message.expanded{clip-path:circle(100%)}.position-top{clip-path:circle(19px at 20px 20px);align-items:start;top:0;left:0}.position-bottom{clip-path:circle(19px at 20px calc(100% - 20px));align-items:end;bottom:0;left:0}.container ::ng-deep a{text-decoration:underline;font-weight:700}.container ::ng-deep a:hover{opacity:.85}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
23556
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopupAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
23557
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: PopupAlertComponent, isStandalone: true, selector: "gn-ui-popup-alert", inputs: { icon: "icon", type: "type", position: "position" }, providers: [
|
|
23558
|
+
provideIcons({ matErrorOutlineOutline }),
|
|
23559
|
+
provideNgIconsConfig({
|
|
23560
|
+
size: '1.5em',
|
|
23561
|
+
}),
|
|
23562
|
+
], viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<div class=\"h-full relative container\">\n <div\n class=\"pointer-events-auto absolute text-white flex flex-row p-2 rounded message\"\n role=\"alert\"\n [ngClass]=\"{\n 'position-bottom': position === 'bottom',\n 'position-top': position === 'top',\n expanded: this.expanded,\n 'bg-red-500': type === 'danger',\n 'bg-yellow-500': type === 'warning',\n 'bg-blue-500': type === 'info',\n }\"\n (mouseenter)=\"expand()\"\n (mouseleave)=\"expandAndClose()\"\n >\n <ng-icon class=\"mr-2 shrink-0 select-none\" [name]=\"icon\"></ng-icon>\n <div class=\"grow\" #content [ngClass]=\"{ invisible: !expanded }\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", styles: [":host{pointer-events:none}.container{filter:drop-shadow(0px 4px 3px rgba(0,0,0,.2))}.message{transition:clip-path .3s cubic-bezier(.25,.46,.45,.94)}.message.expanded{clip-path:circle(100%)}.position-top{clip-path:circle(19px at 20px 20px);align-items:start;top:0;left:0}.position-bottom{clip-path:circle(19px at 20px calc(100% - 20px));align-items:end;bottom:0;left:0}.container ::ng-deep a{text-decoration:underline;font-weight:700}.container ::ng-deep a:hover{opacity:.85}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
24161
23563
|
}
|
|
24162
23564
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PopupAlertComponent, decorators: [{
|
|
24163
23565
|
type: Component,
|
|
@@ -24306,15 +23708,15 @@ class AutocompleteComponent {
|
|
|
24306
23708
|
getExtraClass() {
|
|
24307
23709
|
if (this.allowSubmit) {
|
|
24308
23710
|
if (this.enterButton) {
|
|
24309
|
-
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+var(--icon-padding))]
|
|
23711
|
+
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+var(--icon-padding))] top-1/2 -translate-y-1/2';
|
|
24310
23712
|
}
|
|
24311
23713
|
else {
|
|
24312
|
-
return 'border rounded-lg absolute w-8 h-8 right-[calc(var(--icon-width)+0.25*var(--icon-width))]
|
|
23714
|
+
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';
|
|
24313
23715
|
}
|
|
24314
23716
|
}
|
|
24315
23717
|
else {
|
|
24316
23718
|
if (!this.enterButton) {
|
|
24317
|
-
return 'border rounded-lg absolute w-8 h-8 right-2
|
|
23719
|
+
return 'border rounded-lg absolute w-8 h-8 right-2 top-1/2 -translate-y-1/2';
|
|
24318
23720
|
}
|
|
24319
23721
|
}
|
|
24320
23722
|
return 'border rounded-lg absolute w-8 h-8';
|
|
@@ -24459,7 +23861,7 @@ class AutocompleteComponent {
|
|
|
24459
23861
|
provideNgIconsConfig({
|
|
24460
23862
|
size: '1.75rem',
|
|
24461
23863
|
}),
|
|
24462
|
-
], 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
|
|
23864
|
+
], 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 }); }
|
|
24463
23865
|
}
|
|
24464
23866
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AutocompleteComponent, decorators: [{
|
|
24465
23867
|
type: Component,
|
|
@@ -24480,7 +23882,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
24480
23882
|
provideNgIconsConfig({
|
|
24481
23883
|
size: '1.75rem',
|
|
24482
23884
|
}),
|
|
24483
|
-
], 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
|
|
23885
|
+
], 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"] }]
|
|
24484
23886
|
}], propDecorators: { placeholder: [{
|
|
24485
23887
|
type: Input
|
|
24486
23888
|
}], enterButton: [{
|
|
@@ -25956,7 +25358,8 @@ class SearchFeatureCatalogComponent {
|
|
|
25956
25358
|
const filtered = (this.featureCatalog?.featureTypes || []).filter((featureType) => {
|
|
25957
25359
|
const fuzzyFilter = createFuzzyFilter(searchTerm);
|
|
25958
25360
|
return (fuzzyFilter(featureType.name) ||
|
|
25959
|
-
(featureType.
|
|
25361
|
+
(featureType.description &&
|
|
25362
|
+
fuzzyFilter(featureType.description)));
|
|
25960
25363
|
});
|
|
25961
25364
|
this.filteredFeatureCatalog = {
|
|
25962
25365
|
...this.featureCatalog,
|
|
@@ -26044,6 +25447,8 @@ marker('search.filters.spatialExtent.error.title');
|
|
|
26044
25447
|
marker('search.filters.spatialExtent.error.outOfBounds');
|
|
26045
25448
|
const LABEL_FROM_FILE = marker('search.filters.spatialExtent.bboxFromFile');
|
|
26046
25449
|
const LABEL_FROM_FILE_DELETE = marker('search.filters.spatialExtent.bboxFromFileDelete');
|
|
25450
|
+
const LABEL_FROM_LOCATION = marker('search.filters.spatialExtent.bboxFromLocation');
|
|
25451
|
+
const LABEL_FROM_LOCATION_DELETE = marker('search.filters.spatialExtent.bboxFromLocationDelete');
|
|
26047
25452
|
const LABEL_INITIAL = marker('search.filters.spatialExtent.bboxInitial');
|
|
26048
25453
|
const LABEL_INITIAL_DELETE = marker('search.filters.spatialExtent.bboxInitialDelete');
|
|
26049
25454
|
class SpatialExtentDropdownComponent {
|
|
@@ -26055,6 +25460,7 @@ class SpatialExtentDropdownComponent {
|
|
|
26055
25460
|
this.errorChange = new EventEmitter();
|
|
26056
25461
|
this.bbox = null;
|
|
26057
25462
|
this.fileName = '';
|
|
25463
|
+
this.locationName = '';
|
|
26058
25464
|
this.overlayPositions = [
|
|
26059
25465
|
{
|
|
26060
25466
|
originX: 'start',
|
|
@@ -26085,13 +25491,21 @@ class SpatialExtentDropdownComponent {
|
|
|
26085
25491
|
return !!this.bbox;
|
|
26086
25492
|
}
|
|
26087
25493
|
get selectionLabelKey() {
|
|
26088
|
-
|
|
25494
|
+
if (this.fileName)
|
|
25495
|
+
return LABEL_FROM_FILE;
|
|
25496
|
+
if (this.locationName)
|
|
25497
|
+
return LABEL_FROM_LOCATION;
|
|
25498
|
+
return LABEL_INITIAL;
|
|
26089
25499
|
}
|
|
26090
25500
|
get selectionDeleteLabelKey() {
|
|
26091
|
-
|
|
25501
|
+
if (this.fileName)
|
|
25502
|
+
return LABEL_FROM_FILE_DELETE;
|
|
25503
|
+
if (this.locationName)
|
|
25504
|
+
return LABEL_FROM_LOCATION_DELETE;
|
|
25505
|
+
return LABEL_INITIAL_DELETE;
|
|
26092
25506
|
}
|
|
26093
25507
|
get selectionLabelParams() {
|
|
26094
|
-
return { fileName: this.fileName };
|
|
25508
|
+
return { fileName: this.fileName, locationName: this.locationName };
|
|
26095
25509
|
}
|
|
26096
25510
|
openOverlay() {
|
|
26097
25511
|
this.overlayMinWidth =
|
|
@@ -26128,6 +25542,7 @@ class SpatialExtentDropdownComponent {
|
|
|
26128
25542
|
}
|
|
26129
25543
|
this.bbox = bbox;
|
|
26130
25544
|
this.fileName = file.name;
|
|
25545
|
+
this.locationName = '';
|
|
26131
25546
|
this.bboxChange.emit(bbox);
|
|
26132
25547
|
this.cd.markForCheck();
|
|
26133
25548
|
}
|
|
@@ -26136,6 +25551,15 @@ class SpatialExtentDropdownComponent {
|
|
|
26136
25551
|
return;
|
|
26137
25552
|
}
|
|
26138
25553
|
}
|
|
25554
|
+
setLocationBbox(bbox, name) {
|
|
25555
|
+
this.errorKey = null;
|
|
25556
|
+
this.bbox = bbox;
|
|
25557
|
+
this.locationName = name;
|
|
25558
|
+
this.fileName = '';
|
|
25559
|
+
this.fileInput?.clear();
|
|
25560
|
+
this.bboxChange.emit(bbox);
|
|
25561
|
+
this.cd.markForCheck();
|
|
25562
|
+
}
|
|
26139
25563
|
handleFileError(error) {
|
|
26140
25564
|
if (error === 'file-too-large') {
|
|
26141
25565
|
this.setError(marker('search.filters.spatialExtent.error.fileTooLarge'), {
|
|
@@ -26154,6 +25578,7 @@ class SpatialExtentDropdownComponent {
|
|
|
26154
25578
|
removeSelection(event) {
|
|
26155
25579
|
this.bbox = null;
|
|
26156
25580
|
this.fileName = '';
|
|
25581
|
+
this.locationName = '';
|
|
26157
25582
|
this.errorKey = null;
|
|
26158
25583
|
this.fileInput?.clear();
|
|
26159
25584
|
this.bboxChange.emit(null);
|
|
@@ -26170,7 +25595,7 @@ class SpatialExtentDropdownComponent {
|
|
|
26170
25595
|
matExpandLess,
|
|
26171
25596
|
matExpandMore,
|
|
26172
25597
|
}),
|
|
26173
|
-
], 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'\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 </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 }); }
|
|
25598
|
+
], 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 }); }
|
|
26174
25599
|
}
|
|
26175
25600
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SpatialExtentDropdownComponent, decorators: [{
|
|
26176
25601
|
type: Component,
|
|
@@ -26190,7 +25615,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
26190
25615
|
matExpandLess,
|
|
26191
25616
|
matExpandMore,
|
|
26192
25617
|
}),
|
|
26193
|
-
], 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'\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 </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" }]
|
|
25618
|
+
], 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" }]
|
|
26194
25619
|
}], propDecorators: { title: [{
|
|
26195
25620
|
type: Input
|
|
26196
25621
|
}], maxFileSizeMb: [{
|
|
@@ -26716,11 +26141,11 @@ class BlockListComponent {
|
|
|
26716
26141
|
this.goToPage(this.currentPage + 1);
|
|
26717
26142
|
}
|
|
26718
26143
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BlockListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
26719
|
-
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 }); }
|
|
26144
|
+
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 }); }
|
|
26720
26145
|
}
|
|
26721
26146
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BlockListComponent, decorators: [{
|
|
26722
26147
|
type: Component,
|
|
26723
|
-
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"] }]
|
|
26148
|
+
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"] }]
|
|
26724
26149
|
}], propDecorators: { containerClass: [{
|
|
26725
26150
|
type: Input
|
|
26726
26151
|
}], paginationContainerClass: [{
|
|
@@ -27459,9 +26884,7 @@ const initSearch = () => {
|
|
|
27459
26884
|
},
|
|
27460
26885
|
params: {
|
|
27461
26886
|
filters: {},
|
|
27462
|
-
pageSize:
|
|
27463
|
-
? getOptionalSearchConfig().LIMIT
|
|
27464
|
-
: DEFAULT_PAGE_SIZE,
|
|
26887
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
27465
26888
|
currentPage: 0,
|
|
27466
26889
|
favoritesOnly: false,
|
|
27467
26890
|
useSpatialFilter: true,
|
|
@@ -27910,10 +27333,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
27910
27333
|
}]
|
|
27911
27334
|
}] });
|
|
27912
27335
|
|
|
27336
|
+
const DEFAULT_GEOCODING_PROVIDER = [
|
|
27337
|
+
'geonames',
|
|
27338
|
+
{ maxRows: 5 },
|
|
27339
|
+
];
|
|
27913
27340
|
const GEOCODING_PROVIDER = new InjectionToken('geocoding-provider', {
|
|
27914
27341
|
providedIn: 'root',
|
|
27915
|
-
factory: () =>
|
|
27342
|
+
factory: () => DEFAULT_GEOCODING_PROVIDER,
|
|
27916
27343
|
});
|
|
27344
|
+
// these options are arrays in the providers, but they can be configured
|
|
27345
|
+
// with a single value for simplicity
|
|
27346
|
+
const GEOCODING_PROVIDER_ARRAY_OPTIONS = {
|
|
27347
|
+
geoadmin: ['origins', 'features'],
|
|
27348
|
+
geoplateforme: [
|
|
27349
|
+
'index',
|
|
27350
|
+
'category',
|
|
27351
|
+
'type',
|
|
27352
|
+
'postCode',
|
|
27353
|
+
'cityCode',
|
|
27354
|
+
'depCode',
|
|
27355
|
+
],
|
|
27356
|
+
};
|
|
27357
|
+
function wrapArrayOptions(options, keys) {
|
|
27358
|
+
const wrapped = { ...options };
|
|
27359
|
+
for (const key of keys) {
|
|
27360
|
+
if (typeof wrapped[key] === 'string') {
|
|
27361
|
+
wrapped[key] = [wrapped[key]];
|
|
27362
|
+
}
|
|
27363
|
+
}
|
|
27364
|
+
return wrapped;
|
|
27365
|
+
}
|
|
27917
27366
|
class GeocodingService {
|
|
27918
27367
|
constructor() {
|
|
27919
27368
|
this.provider = inject(GEOCODING_PROVIDER);
|
|
@@ -27922,13 +27371,16 @@ class GeocodingService {
|
|
|
27922
27371
|
let queryObservable;
|
|
27923
27372
|
switch (this.provider[0]) {
|
|
27924
27373
|
case 'geoadmin':
|
|
27925
|
-
queryObservable = from(queryGeoadmin(text, this.provider[1]));
|
|
27374
|
+
queryObservable = from(queryGeoadmin(text, wrapArrayOptions(this.provider[1], GEOCODING_PROVIDER_ARRAY_OPTIONS.geoadmin)));
|
|
27926
27375
|
break;
|
|
27927
27376
|
case 'geonames':
|
|
27928
27377
|
queryObservable = from(queryGeonames(text, this.provider[1]));
|
|
27929
27378
|
break;
|
|
27930
|
-
case '
|
|
27931
|
-
queryObservable = from(
|
|
27379
|
+
case 'geoplateforme':
|
|
27380
|
+
queryObservable = from(queryGeoplateforme(text, {
|
|
27381
|
+
...wrapArrayOptions(this.provider[1], GEOCODING_PROVIDER_ARRAY_OPTIONS.geoplateforme),
|
|
27382
|
+
returnTrueGeometry: true,
|
|
27383
|
+
}));
|
|
27932
27384
|
break;
|
|
27933
27385
|
default:
|
|
27934
27386
|
return throwError(() => new Error(`Unsupported geocoding provider: ${this.provider[0]}`));
|
|
@@ -27945,29 +27397,80 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
27945
27397
|
}]
|
|
27946
27398
|
}] });
|
|
27947
27399
|
|
|
27400
|
+
const GEOCODING_PROVIDER_LABELS = new InjectionToken('geocodingProviderLabels', {
|
|
27401
|
+
factory: () => ({}),
|
|
27402
|
+
});
|
|
27948
27403
|
class LocationSearchComponent {
|
|
27949
27404
|
constructor() {
|
|
27950
27405
|
this.geocodingService = inject(GeocodingService);
|
|
27406
|
+
this.labels = inject(GEOCODING_PROVIDER_LABELS);
|
|
27951
27407
|
this.placeholder = '';
|
|
27952
27408
|
this.resultSelected = new EventEmitter();
|
|
27409
|
+
this.bboxSelected = new EventEmitter();
|
|
27953
27410
|
this.displayWithFn = (item) => item.label;
|
|
27954
27411
|
this.searchAction = (text) => this.geocodingService.query(text);
|
|
27955
27412
|
}
|
|
27413
|
+
getSecondaryLabel(result) {
|
|
27414
|
+
return this.resolveLabel(result, this.labels.secondary);
|
|
27415
|
+
}
|
|
27416
|
+
getMainLabel(result) {
|
|
27417
|
+
return this.resolveLabel(result, this.labels.main) ?? result.label;
|
|
27418
|
+
}
|
|
27419
|
+
getTertiaryLabel(result) {
|
|
27420
|
+
return this.resolveLabel(result, this.labels.tertiary);
|
|
27421
|
+
}
|
|
27422
|
+
getDisplayLabel(result) {
|
|
27423
|
+
const tertiary = this.getTertiaryLabel(result);
|
|
27424
|
+
return this.getMainLabel(result) + (tertiary ? ', ' + tertiary : '');
|
|
27425
|
+
}
|
|
27426
|
+
resolveLabel(result, path) {
|
|
27427
|
+
if (!path)
|
|
27428
|
+
return undefined;
|
|
27429
|
+
let value;
|
|
27430
|
+
try {
|
|
27431
|
+
value = pointer.get(result, path);
|
|
27432
|
+
}
|
|
27433
|
+
catch {
|
|
27434
|
+
return undefined;
|
|
27435
|
+
}
|
|
27436
|
+
const values = Array.isArray(value) ? value : [value];
|
|
27437
|
+
const label = values
|
|
27438
|
+
.filter((v) => typeof v === 'string' || typeof v === 'number')
|
|
27439
|
+
.join(', ');
|
|
27440
|
+
return label || undefined;
|
|
27441
|
+
}
|
|
27442
|
+
// geoplateforme keeps a simplified geometry in geom and puts the real one,
|
|
27443
|
+
// as a JSON string, in properties.truegeometry when returnTrueGeometry is set
|
|
27444
|
+
getGeometry(result) {
|
|
27445
|
+
const trueGeometry = result.properties?.['truegeometry'];
|
|
27446
|
+
if (typeof trueGeometry === 'string') {
|
|
27447
|
+
return JSON.parse(trueGeometry);
|
|
27448
|
+
}
|
|
27449
|
+
return trueGeometry ?? result.geom;
|
|
27450
|
+
}
|
|
27956
27451
|
handleItemSelected(item) {
|
|
27957
|
-
|
|
27452
|
+
const result = item;
|
|
27453
|
+
this.resultSelected.emit(result);
|
|
27454
|
+
const geometry = this.getGeometry(result);
|
|
27455
|
+
if (geometry) {
|
|
27456
|
+
this.bboxSelected.emit({
|
|
27457
|
+
bbox: getGeometryBoundingBox(geometry),
|
|
27458
|
+
label: this.getDisplayLabel(result),
|
|
27459
|
+
});
|
|
27460
|
+
}
|
|
27958
27461
|
}
|
|
27959
27462
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LocationSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
27960
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
27463
|
+
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 }); }
|
|
27961
27464
|
}
|
|
27962
27465
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LocationSearchComponent, decorators: [{
|
|
27963
27466
|
type: Component,
|
|
27964
|
-
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]=\"
|
|
27467
|
+
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" }]
|
|
27965
27468
|
}], propDecorators: { placeholder: [{
|
|
27966
27469
|
type: Input
|
|
27967
|
-
}], displayWithTemplate: [{
|
|
27968
|
-
type: Input
|
|
27969
27470
|
}], resultSelected: [{
|
|
27970
27471
|
type: Output
|
|
27472
|
+
}], bboxSelected: [{
|
|
27473
|
+
type: Output
|
|
27971
27474
|
}] } });
|
|
27972
27475
|
|
|
27973
27476
|
// expects the replacement key ${uuid}
|
|
@@ -28128,6 +27631,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
28128
27631
|
class AbstractSearchField {
|
|
28129
27632
|
}
|
|
28130
27633
|
class SimpleSearchField {
|
|
27634
|
+
get fieldIdentifier() {
|
|
27635
|
+
return this.customIdentifier ?? this.esFieldName;
|
|
27636
|
+
}
|
|
28131
27637
|
constructor(esFieldName, injector, order = 'asc', orderType = 'key') {
|
|
28132
27638
|
this.esFieldName = esFieldName;
|
|
28133
27639
|
this.injector = injector;
|
|
@@ -28136,14 +27642,26 @@ class SimpleSearchField {
|
|
|
28136
27642
|
this.repository = this.injector.get(RecordsRepositoryInterface);
|
|
28137
27643
|
// FIXME: this is required to register runtime fields; abstract this as well
|
|
28138
27644
|
this.esService = this.injector.get(ElasticsearchService);
|
|
27645
|
+
this.includeValues = [];
|
|
27646
|
+
this.excludeValues = [];
|
|
27647
|
+
}
|
|
27648
|
+
setFieldIdentifier(fieldIdentifier) {
|
|
27649
|
+
this.customIdentifier = fieldIdentifier;
|
|
27650
|
+
this.esService.registerFieldAlias(fieldIdentifier, this.esFieldName);
|
|
28139
27651
|
}
|
|
28140
27652
|
getAggregations() {
|
|
28141
27653
|
return {
|
|
28142
|
-
[this.
|
|
27654
|
+
[this.fieldIdentifier]: {
|
|
28143
27655
|
type: 'terms',
|
|
28144
27656
|
field: this.esFieldName,
|
|
28145
27657
|
limit: 1000,
|
|
28146
27658
|
sort: [this.order, this.orderType],
|
|
27659
|
+
...(this.includeValues?.length && {
|
|
27660
|
+
includeValues: this.includeValues,
|
|
27661
|
+
}),
|
|
27662
|
+
...(this.excludeValues?.length && {
|
|
27663
|
+
excludeValues: this.excludeValues,
|
|
27664
|
+
}),
|
|
28147
27665
|
},
|
|
28148
27666
|
};
|
|
28149
27667
|
}
|
|
@@ -28151,7 +27669,7 @@ class SimpleSearchField {
|
|
|
28151
27669
|
return bucket.term.toString();
|
|
28152
27670
|
}
|
|
28153
27671
|
getAvailableValues() {
|
|
28154
|
-
return this.repository.aggregate(this.getAggregations()).pipe(map$1((response) => response[this.
|
|
27672
|
+
return this.repository.aggregate(this.getAggregations()).pipe(map$1((response) => response[this.fieldIdentifier].buckets || []), switchMap((buckets) => {
|
|
28155
27673
|
const bucketPromises = buckets.map(async (bucket) => ({
|
|
28156
27674
|
label: `${await this.getBucketLabel(bucket)} (${bucket.count})`,
|
|
28157
27675
|
value: bucket.term.toString(),
|
|
@@ -28164,7 +27682,7 @@ class SimpleSearchField {
|
|
|
28164
27682
|
// FieldValue[]
|
|
28165
27683
|
if (this.getType() === 'values') {
|
|
28166
27684
|
return of({
|
|
28167
|
-
[this.
|
|
27685
|
+
[this.fieldIdentifier]: values.reduce((acc, val) => {
|
|
28168
27686
|
const value = val.toString();
|
|
28169
27687
|
if (value !== '') {
|
|
28170
27688
|
return { ...acc, [value]: true };
|
|
@@ -28175,11 +27693,11 @@ class SimpleSearchField {
|
|
|
28175
27693
|
}
|
|
28176
27694
|
// DateRange
|
|
28177
27695
|
return of({
|
|
28178
|
-
[this.
|
|
27696
|
+
[this.fieldIdentifier]: values[0] !== '' ? values[0] : {},
|
|
28179
27697
|
});
|
|
28180
27698
|
}
|
|
28181
27699
|
getValuesForFilter(filters) {
|
|
28182
|
-
const filter = filters[this.
|
|
27700
|
+
const filter = filters[this.fieldIdentifier];
|
|
28183
27701
|
if (!filter)
|
|
28184
27702
|
return of([]);
|
|
28185
27703
|
// filter by expression
|
|
@@ -28197,6 +27715,9 @@ class SimpleSearchField {
|
|
|
28197
27715
|
getType() {
|
|
28198
27716
|
return 'values';
|
|
28199
27717
|
}
|
|
27718
|
+
clone() {
|
|
27719
|
+
return Object.create(this);
|
|
27720
|
+
}
|
|
28200
27721
|
}
|
|
28201
27722
|
class TranslatedSearchField extends SimpleSearchField {
|
|
28202
27723
|
constructor(esFieldName, injector, order = 'asc', orderType = 'key') {
|
|
@@ -28466,11 +27987,11 @@ class BoundingBoxSearchField extends SimpleSearchField {
|
|
|
28466
27987
|
}
|
|
28467
27988
|
getFiltersForValues(values) {
|
|
28468
27989
|
return of({
|
|
28469
|
-
[this.
|
|
27990
|
+
[this.fieldIdentifier]: values.map(Number),
|
|
28470
27991
|
});
|
|
28471
27992
|
}
|
|
28472
27993
|
getValuesForFilter(filters) {
|
|
28473
|
-
const filter = filters[this.
|
|
27994
|
+
const filter = filters[this.fieldIdentifier];
|
|
28474
27995
|
return of(isBoundingBox(filter) ? filter : []);
|
|
28475
27996
|
}
|
|
28476
27997
|
getType() {
|
|
@@ -28569,7 +28090,7 @@ class RecordKindField extends SimpleSearchField {
|
|
|
28569
28090
|
}
|
|
28570
28091
|
getFiltersForValues(values) {
|
|
28571
28092
|
const filters = {
|
|
28572
|
-
[this.
|
|
28093
|
+
[this.fieldIdentifier]: values.reduce((acc, value) => {
|
|
28573
28094
|
if (value === '')
|
|
28574
28095
|
return { ...acc, [value]: true };
|
|
28575
28096
|
const keysToAdd = this.TYPE_MAPPING[value] || [value];
|
|
@@ -28592,7 +28113,7 @@ class RecordKindField extends SimpleSearchField {
|
|
|
28592
28113
|
return of(filters);
|
|
28593
28114
|
}
|
|
28594
28115
|
getValuesForFilter(filters) {
|
|
28595
|
-
const filter = filters[this.
|
|
28116
|
+
const filter = filters[this.fieldIdentifier];
|
|
28596
28117
|
if (!filter)
|
|
28597
28118
|
return of([]);
|
|
28598
28119
|
const activeValues = Object.keys(filter).filter((v) => filter[v]);
|
|
@@ -28622,11 +28143,15 @@ marker('search.filters.publisherOrg');
|
|
|
28622
28143
|
marker('search.filters.user');
|
|
28623
28144
|
marker('search.filters.changeDate');
|
|
28624
28145
|
marker('search.filters.resourceCreationRevisionDate');
|
|
28146
|
+
marker('search.filters.temporalExtent');
|
|
28625
28147
|
marker('search.filters.spatialExtent');
|
|
28148
|
+
marker('search.filters.documentStandard');
|
|
28149
|
+
const CUSTOM_FIELDS = new InjectionToken('custom-fields');
|
|
28626
28150
|
class FieldsService {
|
|
28627
28151
|
constructor() {
|
|
28628
28152
|
this.injector = inject(Injector);
|
|
28629
|
-
this.
|
|
28153
|
+
this.customFields = inject(CUSTOM_FIELDS, { optional: true }) ?? [];
|
|
28154
|
+
this.baseFields = {
|
|
28630
28155
|
organization: new OrganizationSearchField(this.injector),
|
|
28631
28156
|
format: new SimpleSearchField('format', this.injector, 'asc'),
|
|
28632
28157
|
resourceType: new ResourceTypeLegacyField(this.injector), // Deprecated, use `recordKind` instead
|
|
@@ -28646,9 +28171,31 @@ class FieldsService {
|
|
|
28646
28171
|
user: new UserSearchField(this.injector),
|
|
28647
28172
|
changeDate: new DateRangeSearchField('changeDate', this.injector, 'desc'),
|
|
28648
28173
|
resourceCreationRevisionDate: new ResourceCreationRevisionDateSearchField(this.injector, 'desc'),
|
|
28174
|
+
temporalExtent: new DateRangeSearchField('resourceTemporalExtentDateRange', this.injector, 'desc'),
|
|
28649
28175
|
availableServices: new AvailableServicesField(this.injector),
|
|
28650
28176
|
spatialExtent: new BoundingBoxSearchField('spatialExtent', this.injector),
|
|
28651
28177
|
};
|
|
28178
|
+
this.fields = { ...this.baseFields };
|
|
28179
|
+
for (const customField of this.customFields) {
|
|
28180
|
+
const baseField = this.baseFields[customField.baseFilter];
|
|
28181
|
+
if (!(baseField instanceof SimpleSearchField)) {
|
|
28182
|
+
console.warn(`The custom field '${customField.name}' relies on a base field '${customField.baseFilter}' that is not supported. This field will be ignored.`);
|
|
28183
|
+
continue;
|
|
28184
|
+
}
|
|
28185
|
+
if (!customField.name.includes(':')) {
|
|
28186
|
+
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.`);
|
|
28187
|
+
continue;
|
|
28188
|
+
}
|
|
28189
|
+
const newField = baseField.clone();
|
|
28190
|
+
newField.setFieldIdentifier(customField.name);
|
|
28191
|
+
if (customField.includeValues) {
|
|
28192
|
+
newField.includeValues = customField.includeValues;
|
|
28193
|
+
}
|
|
28194
|
+
if (customField.excludeValues) {
|
|
28195
|
+
newField.excludeValues = customField.excludeValues;
|
|
28196
|
+
}
|
|
28197
|
+
this.fields[customField.name] = newField;
|
|
28198
|
+
}
|
|
28652
28199
|
}
|
|
28653
28200
|
get supportedFields() {
|
|
28654
28201
|
return Object.keys(this.fields);
|
|
@@ -28696,7 +28243,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
28696
28243
|
args: [{
|
|
28697
28244
|
providedIn: 'root',
|
|
28698
28245
|
}]
|
|
28699
|
-
}] });
|
|
28246
|
+
}], ctorParameters: () => [] });
|
|
28700
28247
|
|
|
28701
28248
|
class ApiCardComponent {
|
|
28702
28249
|
constructor() {
|
|
@@ -30722,14 +30269,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
30722
30269
|
marker('feature.catalog.attribute.type');
|
|
30723
30270
|
marker('feature.catalog.attribute.name');
|
|
30724
30271
|
marker('feature.catalog.attribute.code');
|
|
30725
|
-
marker('feature.catalog.attribute.
|
|
30272
|
+
marker('feature.catalog.attribute.description');
|
|
30726
30273
|
marker('feature.catalog.attribute.values');
|
|
30727
30274
|
class FeatureCatalogListComponent {
|
|
30728
30275
|
constructor() {
|
|
30729
30276
|
this.COLUMNS_DEFAULT = [
|
|
30730
30277
|
{ key: 'type', width: '25%' },
|
|
30731
30278
|
{ key: 'name', width: '40%' },
|
|
30732
|
-
{ key: '
|
|
30279
|
+
{ key: 'description', width: 'minmax(0px, 1fr)' },
|
|
30733
30280
|
];
|
|
30734
30281
|
this.COLUMN_VALUES = {
|
|
30735
30282
|
key: 'values',
|
|
@@ -30750,7 +30297,7 @@ class FeatureCatalogListComponent {
|
|
|
30750
30297
|
return col.key;
|
|
30751
30298
|
}
|
|
30752
30299
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureCatalogListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
30753
|
-
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.
|
|
30300
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FeatureCatalogListComponent, isStandalone: true, selector: "gn-ui-feature-catalog-list", inputs: { filteredFeatureCatalog: "filteredFeatureCatalog" }, providers: [provideIcons({ iconoirList })], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "scrollable", first: true, predicate: CdkScrollable, descendants: true, static: true }, { propertyName: "panelComponent", first: true, predicate: ["expanel"], descendants: true, read: ExpandablePanelComponent, static: true }], ngImport: i0, template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.description) {\n <div class=\"text-sm\">\n {{ featureType.description }}\n </div>\n }\n </div>\n </ng-template>\n @if (expanel && !expanel.collapsed) {\n <div\n class=\"grid gap-0\"\n [style.grid-template-columns]=\"\n getGridTemplateColumns(featureType.attributes)\n \"\n data-cy=\"feature-type-content\"\n >\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"py-1 px-2 text-sm font-bold text-left border-t break-all\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n [ngClass]=\"col.class || ''\"\n data-test=\"column-label\"\n >\n {{ 'feature.catalog.attribute.' + col.key | translate }}\n </div>\n }\n @if (expanel && !expanel.collapsed) {\n @for (row of featureType.attributes; track row) {\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"bg-white text-sm font-normal text-left border-t\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n data-test=\"cell-content\"\n >\n @if (col.key === 'values') {\n @if (row.values?.length > 0) {\n <gn-ui-cell-popin\n #popinRef\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n >\n <div\n cellContent\n data-cy=\"values-cell-popin-trigger\"\n >\n <gn-ui-button\n type=\"light\"\n extraClass=\"bg-transparent border-none\"\n (buttonClick)=\"popinRef.openOverlay()\"\n >\n <ng-icon name=\"iconoirList\" size=\"24\"></ng-icon>\n </gn-ui-button>\n </div>\n <div\n popinContent\n class=\"max-h-60 overflow-y-auto min-w-64 py-4 px-6\"\n style=\"scrollbar-width: thin\"\n >\n <ul class=\"list-disc list-inside mr-4\">\n @for (v of row.values; track v) {\n <li>\n {{ v.label || v.value }}\n </li>\n }\n </ul>\n </div>\n </gn-ui-cell-popin>\n }\n } @else {\n <gn-ui-truncated-text\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n [text]=\"row[col.key]\"\n ></gn-ui-truncated-text>\n }\n </div>\n }\n }\n }\n </div>\n }\n </gn-ui-expandable-panel>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: CellPopinComponent, selector: "gn-ui-cell-popin", inputs: ["extraClass", "cdkScrollContainer", "scrollContainer", "activePopin"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: ["title", "iconColor", "collapsed"] }, { kind: "component", type: TruncatedTextComponent, selector: "gn-ui-truncated-text", inputs: ["text", "extraClass", "scrollContainer", "cdkScrollContainer"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2$3.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
30754
30301
|
}
|
|
30755
30302
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureCatalogListComponent, decorators: [{
|
|
30756
30303
|
type: Component,
|
|
@@ -30763,7 +30310,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
30763
30310
|
TruncatedTextComponent,
|
|
30764
30311
|
NgIconComponent,
|
|
30765
30312
|
ScrollingModule,
|
|
30766
|
-
], 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.
|
|
30313
|
+
], providers: [provideIcons({ iconoirList })], template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.description) {\n <div class=\"text-sm\">\n {{ featureType.description }}\n </div>\n }\n </div>\n </ng-template>\n @if (expanel && !expanel.collapsed) {\n <div\n class=\"grid gap-0\"\n [style.grid-template-columns]=\"\n getGridTemplateColumns(featureType.attributes)\n \"\n data-cy=\"feature-type-content\"\n >\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"py-1 px-2 text-sm font-bold text-left border-t break-all\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n [ngClass]=\"col.class || ''\"\n data-test=\"column-label\"\n >\n {{ 'feature.catalog.attribute.' + col.key | translate }}\n </div>\n }\n @if (expanel && !expanel.collapsed) {\n @for (row of featureType.attributes; track row) {\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"bg-white text-sm font-normal text-left border-t\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n data-test=\"cell-content\"\n >\n @if (col.key === 'values') {\n @if (row.values?.length > 0) {\n <gn-ui-cell-popin\n #popinRef\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n >\n <div\n cellContent\n data-cy=\"values-cell-popin-trigger\"\n >\n <gn-ui-button\n type=\"light\"\n extraClass=\"bg-transparent border-none\"\n (buttonClick)=\"popinRef.openOverlay()\"\n >\n <ng-icon name=\"iconoirList\" size=\"24\"></ng-icon>\n </gn-ui-button>\n </div>\n <div\n popinContent\n class=\"max-h-60 overflow-y-auto min-w-64 py-4 px-6\"\n style=\"scrollbar-width: thin\"\n >\n <ul class=\"list-disc list-inside mr-4\">\n @for (v of row.values; track v) {\n <li>\n {{ v.label || v.value }}\n </li>\n }\n </ul>\n </div>\n </gn-ui-cell-popin>\n }\n } @else {\n <gn-ui-truncated-text\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n [text]=\"row[col.key]\"\n ></gn-ui-truncated-text>\n }\n </div>\n }\n }\n }\n </div>\n }\n </gn-ui-expandable-panel>\n </div>\n }\n </div>\n</div>\n" }]
|
|
30767
30314
|
}], propDecorators: { filteredFeatureCatalog: [{
|
|
30768
30315
|
type: Input
|
|
30769
30316
|
}], scrollContainer: [{
|
|
@@ -31901,6 +31448,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
31901
31448
|
], 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" }]
|
|
31902
31449
|
}] });
|
|
31903
31450
|
|
|
31451
|
+
marker('search.filters.spatialExtent.searchLocation');
|
|
31452
|
+
// in MB, null means no limit
|
|
31453
|
+
const SPATIAL_EXTENT_MAX_FILE_SIZE = new InjectionToken('spatialExtentMaxFileSize', { factory: () => null });
|
|
31904
31454
|
class FilterDropdownComponent {
|
|
31905
31455
|
constructor() {
|
|
31906
31456
|
this.searchFacade = inject(SearchFacade);
|
|
@@ -31908,7 +31458,7 @@ class FilterDropdownComponent {
|
|
|
31908
31458
|
this.fieldsService = inject(FieldsService);
|
|
31909
31459
|
this.notificationsService = inject(NotificationsService);
|
|
31910
31460
|
this.translateService = inject(TranslateService);
|
|
31911
|
-
this.spatialExtentMaxFileSize =
|
|
31461
|
+
this.spatialExtentMaxFileSize = inject(SPATIAL_EXTENT_MAX_FILE_SIZE);
|
|
31912
31462
|
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([])));
|
|
31913
31463
|
this.selectedDateRange$ = this.selected$.pipe(map$1((selected) => (Array.isArray(selected) ? {} : selected)));
|
|
31914
31464
|
this.selectedBoundingBox$ = this.selected$.pipe(map$1((selected) => Array.isArray(selected) && selected.length > 0
|
|
@@ -31929,6 +31479,9 @@ class FilterDropdownComponent {
|
|
|
31929
31479
|
.subscribe((filters) => this.searchService.updateFilters(filters));
|
|
31930
31480
|
this.clearSpatialExtentErrorNotification();
|
|
31931
31481
|
}
|
|
31482
|
+
onLocationSelected({ bbox, label }) {
|
|
31483
|
+
this.spatialExtentDropdown.setLocationBbox(bbox, label);
|
|
31484
|
+
}
|
|
31932
31485
|
onSpatialExtentError(error) {
|
|
31933
31486
|
this.clearSpatialExtentErrorNotification();
|
|
31934
31487
|
this.spatialExtentErrorNotificationId =
|
|
@@ -31959,7 +31512,7 @@ class FilterDropdownComponent {
|
|
|
31959
31512
|
.subscribe((filters) => this.searchService.updateFilters(filters));
|
|
31960
31513
|
}
|
|
31961
31514
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FilterDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
31962
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FilterDropdownComponent, isStandalone: true, selector: "gn-ui-filter-dropdown", inputs: { fieldName: "fieldName", title: "title" }, ngImport: i0, template: "@if (fieldType === 'dateRange') {\n <gn-ui-date-range-dropdown\n [title]=\"title\"\n [dateRange]=\"(selectedDateRange$ | async) ?? {}\"\n (dateRangeChange)=\"onDateRangeChange($event)\"\n [attr.data-cy-field]=\"fieldName\"\n ></gn-ui-date-range-dropdown>\n} @else if (fieldType === 'spatialExtent') {\n <gn-ui-spatial-extent-dropdown\n [title]=\"title\"\n [initialBbox]=\"(selectedBoundingBox$ | async) ?? null\"\n [maxFileSizeMb]=\"spatialExtentMaxFileSize\"\n (bboxChange)=\"onBboxChange($event)\"\n (errorChange)=\"onSpatialExtentError($event)\"\n [attr.data-cy-field]=\"fieldName\"\n ></gn-ui-spatial-extent-dropdown>\n} @else {\n <gn-ui-dropdown-multiselect\n class=\"w-full\"\n [title]=\"title\"\n [maxRows]=\"6\"\n [choices]=\"(choices$ | async) || []\"\n [selected]=\"selected$ | async\"\n [allowSearch]=\"true\"\n (selectValues)=\"onSelectedValues($event)\"\n [attr.data-cy-field]=\"fieldName\"\n >\n </gn-ui-dropdown-multiselect>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DateRangeDropdownComponent, selector: "gn-ui-date-range-dropdown", inputs: ["title", "dateRange"], outputs: ["dateRangeChange"] }, { kind: "component", type: DropdownMultiselectComponent, selector: "gn-ui-dropdown-multiselect", inputs: ["title", "choices", "selected", "allowSearch", "maxRows", "searchInputValue"], outputs: ["selectValues"] }, { kind: "component", type: SpatialExtentDropdownComponent, selector: "gn-ui-spatial-extent-dropdown", inputs: ["title", "maxFileSizeMb", "initialBbox"], outputs: ["bboxChange", "errorChange"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
31515
|
+
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 }); }
|
|
31963
31516
|
}
|
|
31964
31517
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FilterDropdownComponent, decorators: [{
|
|
31965
31518
|
type: Component,
|
|
@@ -31968,11 +31521,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
31968
31521
|
DateRangeDropdownComponent,
|
|
31969
31522
|
DropdownMultiselectComponent,
|
|
31970
31523
|
SpatialExtentDropdownComponent,
|
|
31971
|
-
|
|
31524
|
+
LocationSearchComponent,
|
|
31525
|
+
TranslatePipe,
|
|
31526
|
+
], 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" }]
|
|
31972
31527
|
}], propDecorators: { fieldName: [{
|
|
31973
31528
|
type: Input
|
|
31974
31529
|
}], title: [{
|
|
31975
31530
|
type: Input
|
|
31531
|
+
}], spatialExtentDropdown: [{
|
|
31532
|
+
type: ViewChild,
|
|
31533
|
+
args: [SpatialExtentDropdownComponent]
|
|
31976
31534
|
}] } });
|
|
31977
31535
|
|
|
31978
31536
|
class FuzzySearchComponent {
|
|
@@ -32589,6 +32147,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
32589
32147
|
marker('search.filters.summaryLabel.user');
|
|
32590
32148
|
marker('search.filters.summaryLabel.changeDate');
|
|
32591
32149
|
marker('search.filters.summaryLabel.resourceCreationRevisionDate');
|
|
32150
|
+
marker('search.filters.summaryLabel.temporalExtent');
|
|
32592
32151
|
const OPEN_BOUND = '…';
|
|
32593
32152
|
class SearchFiltersSummaryItemComponent {
|
|
32594
32153
|
constructor() {
|
|
@@ -34152,7 +33711,7 @@ class DataService {
|
|
|
34152
33711
|
}));
|
|
34153
33712
|
}
|
|
34154
33713
|
async getDownloadLinksFromOgcApiFeatures(ogcApiLink) {
|
|
34155
|
-
const collectionInfo = await this.getDownloadUrlsFromOgcApi(ogcApiLink.url.href);
|
|
33714
|
+
const collectionInfo = await this.getDownloadUrlsFromOgcApi(ogcApiLink.url.href, ogcApiLink.name);
|
|
34156
33715
|
return Object.keys(collectionInfo.bulkDownloadLinks).map((mimeType) => {
|
|
34157
33716
|
const urlWithoutLimit = new URL(collectionInfo.bulkDownloadLinks[mimeType]);
|
|
34158
33717
|
urlWithoutLimit.searchParams.delete('limit');
|
|
@@ -34165,27 +33724,31 @@ class DataService {
|
|
|
34165
33724
|
};
|
|
34166
33725
|
});
|
|
34167
33726
|
}
|
|
34168
|
-
async
|
|
33727
|
+
async getTargetCollectionId(endpoint, collectionId) {
|
|
33728
|
+
const collections = await endpoint.featureCollections;
|
|
33729
|
+
return collections.length === 1 && !collectionId
|
|
33730
|
+
? collections[0]
|
|
33731
|
+
: collectionId;
|
|
33732
|
+
}
|
|
33733
|
+
async getDownloadUrlsFromOgcApi(url, collectionId) {
|
|
34169
33734
|
const endpoint = new OgcApiEndpoint(url);
|
|
34170
|
-
|
|
34171
|
-
.
|
|
34172
|
-
return endpoint.getCollectionInfo(
|
|
34173
|
-
}
|
|
34174
|
-
|
|
34175
|
-
throw new Error(
|
|
34176
|
-
}
|
|
33735
|
+
try {
|
|
33736
|
+
const id = await this.getTargetCollectionId(endpoint, collectionId);
|
|
33737
|
+
return await endpoint.getCollectionInfo(id);
|
|
33738
|
+
}
|
|
33739
|
+
catch {
|
|
33740
|
+
throw new Error('ogc.unreachable.unknown');
|
|
33741
|
+
}
|
|
34177
33742
|
}
|
|
34178
|
-
async getItemsFromOgcApi(url, limit) {
|
|
33743
|
+
async getItemsFromOgcApi(url, collectionId, limit) {
|
|
34179
33744
|
const endpoint = new OgcApiEndpoint(url);
|
|
34180
|
-
|
|
34181
|
-
.
|
|
34182
|
-
return
|
|
34183
|
-
|
|
34184
|
-
|
|
34185
|
-
|
|
34186
|
-
|
|
34187
|
-
throw new Error(`ogc.unreachable.unknown`);
|
|
34188
|
-
});
|
|
33745
|
+
try {
|
|
33746
|
+
const id = await this.getTargetCollectionId(endpoint, collectionId);
|
|
33747
|
+
return await endpoint.getCollectionItems(id, limit);
|
|
33748
|
+
}
|
|
33749
|
+
catch {
|
|
33750
|
+
throw new Error('ogc.unreachable.unknown');
|
|
33751
|
+
}
|
|
34189
33752
|
}
|
|
34190
33753
|
async getItemsFromStacApi(url, options) {
|
|
34191
33754
|
return await StacEndpoint.getItemsFromUrl(url, options)
|
|
@@ -34273,7 +33836,7 @@ class DataService {
|
|
|
34273
33836
|
}
|
|
34274
33837
|
else if (link.type === 'service' &&
|
|
34275
33838
|
link.accessServiceProtocol === 'ogcFeatures') {
|
|
34276
|
-
return from(this.getDownloadUrlsFromOgcApi(link.url.href)).pipe(switchMap$1((collectionInfo) => {
|
|
33839
|
+
return from(this.getDownloadUrlsFromOgcApi(link.url.href, link.name)).pipe(switchMap$1((collectionInfo) => {
|
|
34277
33840
|
const isMimeTypeJson = (mimeType) => {
|
|
34278
33841
|
return mimeType.toLowerCase().indexOf('json') > -1;
|
|
34279
33842
|
};
|
|
@@ -35217,7 +34780,7 @@ class MdViewFacade {
|
|
|
35217
34780
|
if (this.linkClassifier.hasUsage(link, LinkUsage.GEODATA)) {
|
|
35218
34781
|
if (link.type === 'service' &&
|
|
35219
34782
|
link.accessServiceProtocol === 'ogcFeatures') {
|
|
35220
|
-
return from(this.dataService.getItemsFromOgcApi(link.url.href, 1)).pipe(map$1((collectionRecords) => {
|
|
34783
|
+
return from(this.dataService.getItemsFromOgcApi(link.url.href, link.name, 1)).pipe(map$1((collectionRecords) => {
|
|
35221
34784
|
return collectionRecords &&
|
|
35222
34785
|
collectionRecords[0] &&
|
|
35223
34786
|
collectionRecords[0].geometry
|
|
@@ -35300,7 +34863,7 @@ class MdViewEffects {
|
|
|
35300
34863
|
}
|
|
35301
34864
|
return loadFullMetadataSuccess({ full: record });
|
|
35302
34865
|
}), catchError((error) => of(loadFullMetadataFailure({ otherError: error.message })))));
|
|
35303
|
-
this.loadFeatureCatalog$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), filter$1(({ full }) => full !== undefined), switchMap$1(({ full }) => this.recordsRepository.
|
|
34866
|
+
this.loadFeatureCatalog$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), filter$1(({ full }) => full !== undefined), switchMap$1(({ full }) => this.recordsRepository.queryLinkedFeatureCatalog(full)), map$1((featureCatalog) => loadFeatureCatalogSuccess({
|
|
35304
34867
|
datasetCatalog: featureCatalog,
|
|
35305
34868
|
})), catchError((error) => of(loadFeatureCatalogFailure({
|
|
35306
34869
|
error: error.message,
|
|
@@ -40934,6 +40497,638 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
40934
40497
|
args: ['gnUiSearchRouterContainer']
|
|
40935
40498
|
}] } });
|
|
40936
40499
|
|
|
40500
|
+
const flatten = (base, obj, keepLevel = false) => Object.keys(obj).reduce((prev, curr) => {
|
|
40501
|
+
const path = base ? `${base}.${curr}` : curr;
|
|
40502
|
+
const val = obj[curr];
|
|
40503
|
+
if (keepLevel) {
|
|
40504
|
+
return { ...prev, [path]: flatten('', val) };
|
|
40505
|
+
}
|
|
40506
|
+
else if (typeof val === 'object' && !Array.isArray(val)) {
|
|
40507
|
+
return {
|
|
40508
|
+
...prev,
|
|
40509
|
+
...flatten(path, val),
|
|
40510
|
+
};
|
|
40511
|
+
}
|
|
40512
|
+
else {
|
|
40513
|
+
return { ...prev, [path]: val };
|
|
40514
|
+
}
|
|
40515
|
+
}, {});
|
|
40516
|
+
const checkKeys = (input, mandatory, optional) => {
|
|
40517
|
+
const keys = Object.keys(input);
|
|
40518
|
+
const missing = mandatory.filter((key) => keys.indexOf(key) === -1);
|
|
40519
|
+
const unrecognized = keys.filter((key) => mandatory.indexOf(key) === -1 && optional.indexOf(key) === -1);
|
|
40520
|
+
return {
|
|
40521
|
+
missing,
|
|
40522
|
+
unrecognized,
|
|
40523
|
+
};
|
|
40524
|
+
};
|
|
40525
|
+
/**
|
|
40526
|
+
* Only keeps recognized keys, flatten nested values (to allow having "." in keys),
|
|
40527
|
+
* pushes warnings and errors to the given arrays; returns null in case of error
|
|
40528
|
+
*/
|
|
40529
|
+
function parseConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
40530
|
+
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
40531
|
+
if (mandatoryKeys.length === 0)
|
|
40532
|
+
return null;
|
|
40533
|
+
outErrors.push(`The [${sectionName}] mandatory section is missing.`);
|
|
40534
|
+
return null;
|
|
40535
|
+
}
|
|
40536
|
+
const sectionConf = fullConfigObj[sectionName];
|
|
40537
|
+
const keysCheck = checkKeys(sectionConf, mandatoryKeys, optionalKeys);
|
|
40538
|
+
if (keysCheck.missing.length) {
|
|
40539
|
+
// note: this is not thrown to allow merging several Errors down the line
|
|
40540
|
+
outErrors.push(`In the [${sectionName}] section: ${keysCheck.missing.join(', ')}`);
|
|
40541
|
+
return null;
|
|
40542
|
+
}
|
|
40543
|
+
else if (keysCheck.unrecognized.length) {
|
|
40544
|
+
outWarnings.push(`In the [${sectionName}] section: ${keysCheck.unrecognized.join(', ')}`);
|
|
40545
|
+
keysCheck.unrecognized.forEach((key) => delete sectionConf[key]);
|
|
40546
|
+
}
|
|
40547
|
+
return sectionConf;
|
|
40548
|
+
}
|
|
40549
|
+
/**
|
|
40550
|
+
* Same as parseConfigSection but keeps all keys, recognized or not
|
|
40551
|
+
* Also the first level is the language code (e.g. 'en')
|
|
40552
|
+
* This is optional
|
|
40553
|
+
*/
|
|
40554
|
+
function parseTranslationsConfigSection(fullConfigObj, sectionName) {
|
|
40555
|
+
if (typeof fullConfigObj[sectionName] !== 'object') {
|
|
40556
|
+
return {};
|
|
40557
|
+
}
|
|
40558
|
+
return flatten('', fullConfigObj[sectionName], true);
|
|
40559
|
+
}
|
|
40560
|
+
/**
|
|
40561
|
+
* Same as parseConfigSection but handles an array of configs; this is
|
|
40562
|
+
* considered optional; returns null in case of error in at least one of
|
|
40563
|
+
* the sections
|
|
40564
|
+
*/
|
|
40565
|
+
function parseMultiConfigSection(fullConfigObj, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors) {
|
|
40566
|
+
const sections = fullConfigObj[sectionName];
|
|
40567
|
+
if (!sections) {
|
|
40568
|
+
return [];
|
|
40569
|
+
}
|
|
40570
|
+
if (!Array.isArray(sections)) {
|
|
40571
|
+
outErrors.push(`Expected [[${sectionName}]] to be an array of sections.`);
|
|
40572
|
+
return null;
|
|
40573
|
+
}
|
|
40574
|
+
const result = sections.map((section) => parseConfigSection({ [sectionName]: section }, sectionName, mandatoryKeys, optionalKeys, outWarnings, outErrors));
|
|
40575
|
+
if (result.some((r) => r === null)) {
|
|
40576
|
+
return null;
|
|
40577
|
+
}
|
|
40578
|
+
return result;
|
|
40579
|
+
}
|
|
40580
|
+
function checkMetadataLanguage(parsedConfigSection, outWarnings) {
|
|
40581
|
+
const lang2 = toLang2(parsedConfigSection.metadata_language.toLowerCase());
|
|
40582
|
+
if (lang2?.length !== 2) {
|
|
40583
|
+
outWarnings.push(`In the [global] section: metadata_language = "${parsedConfigSection.metadata_language}" is not a recognized ISO 639 language code`);
|
|
40584
|
+
}
|
|
40585
|
+
return parsedConfigSection;
|
|
40586
|
+
}
|
|
40587
|
+
function checkNewRecordDefaultLanguage(parsedConfigSection, outWarnings) {
|
|
40588
|
+
const lang2 = toLang2(parsedConfigSection.new_record_default_language.toLowerCase());
|
|
40589
|
+
if (!(lang2 in LANG_2_TO_3_MAPPER)) {
|
|
40590
|
+
outWarnings.push(`In the [editing] section: new_record_default_language = "${parsedConfigSection.new_record_default_language}" is not a recognized ISO 639 language code`);
|
|
40591
|
+
return {
|
|
40592
|
+
...parsedConfigSection,
|
|
40593
|
+
new_record_default_language: undefined,
|
|
40594
|
+
};
|
|
40595
|
+
}
|
|
40596
|
+
return {
|
|
40597
|
+
...parsedConfigSection,
|
|
40598
|
+
new_record_default_language: lang2,
|
|
40599
|
+
};
|
|
40600
|
+
}
|
|
40601
|
+
function checkNewRecordStandard(parsedConfigSection, outWarnings) {
|
|
40602
|
+
const standard = parsedConfigSection.new_record_standard;
|
|
40603
|
+
const normalizedStandard = typeof standard === 'string' ? standard.trim().toLowerCase() : null;
|
|
40604
|
+
if (normalizedStandard === 'iso19139' ||
|
|
40605
|
+
normalizedStandard === 'iso19115-3') {
|
|
40606
|
+
return {
|
|
40607
|
+
...parsedConfigSection,
|
|
40608
|
+
new_record_standard: normalizedStandard,
|
|
40609
|
+
};
|
|
40610
|
+
}
|
|
40611
|
+
outWarnings.push(`In the [editing] section: new_record_standard = "${standard}" is not a supported metadata standard`);
|
|
40612
|
+
return {
|
|
40613
|
+
...parsedConfigSection,
|
|
40614
|
+
new_record_standard: undefined,
|
|
40615
|
+
};
|
|
40616
|
+
}
|
|
40617
|
+
|
|
40618
|
+
/**
|
|
40619
|
+
* This loader extends the default one based on JSON files but also loads custom translations
|
|
40620
|
+
* defined in the app configuration
|
|
40621
|
+
* Implements a fallback on default lang if translated labels are empty
|
|
40622
|
+
*/
|
|
40623
|
+
class FileWithOverridesTranslateLoader extends FileTranslateLoader {
|
|
40624
|
+
getTranslation(lang) {
|
|
40625
|
+
const baseLang = lang.substring(0, 2); // removing the right part of e.g. en_EN
|
|
40626
|
+
return super.getTranslation(baseLang).pipe(map$1((translations) => ({
|
|
40627
|
+
...translations,
|
|
40628
|
+
...getCustomTranslations(baseLang),
|
|
40629
|
+
})));
|
|
40630
|
+
}
|
|
40631
|
+
}
|
|
40632
|
+
|
|
40633
|
+
const MISSING_CONFIG_ERROR = `Application configuration was not initialized correctly.
|
|
40634
|
+
This error might show up in case of an invalid/malformed configuration file.
|
|
40635
|
+
|
|
40636
|
+
Note: make sure that you have called \`loadAppConfig\` from '../../../../../libs/util/app-config/src' before starting the Angular application.`;
|
|
40637
|
+
let globalConfig = null;
|
|
40638
|
+
function getGlobalConfig() {
|
|
40639
|
+
if (globalConfig === null)
|
|
40640
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40641
|
+
return globalConfig;
|
|
40642
|
+
}
|
|
40643
|
+
let themeConfig = null;
|
|
40644
|
+
function getThemeConfig() {
|
|
40645
|
+
if (themeConfig === null)
|
|
40646
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40647
|
+
return themeConfig;
|
|
40648
|
+
}
|
|
40649
|
+
let mapConfig = null;
|
|
40650
|
+
function getOptionalMapConfig() {
|
|
40651
|
+
return mapConfig;
|
|
40652
|
+
}
|
|
40653
|
+
let searchConfig = null;
|
|
40654
|
+
function getOptionalSearchConfig() {
|
|
40655
|
+
return searchConfig;
|
|
40656
|
+
}
|
|
40657
|
+
let editorConfig = null;
|
|
40658
|
+
function getOptionalEditorConfig() {
|
|
40659
|
+
return editorConfig;
|
|
40660
|
+
}
|
|
40661
|
+
let metadataQualityConfig = null;
|
|
40662
|
+
function getMetadataQualityConfig() {
|
|
40663
|
+
return (metadataQualityConfig ||
|
|
40664
|
+
{
|
|
40665
|
+
ENABLED: false,
|
|
40666
|
+
});
|
|
40667
|
+
}
|
|
40668
|
+
let customTranslations = null;
|
|
40669
|
+
function getCustomTranslations(langCode) {
|
|
40670
|
+
if (customTranslations === null)
|
|
40671
|
+
throw new Error(MISSING_CONFIG_ERROR);
|
|
40672
|
+
return langCode in customTranslations ? customTranslations[langCode] : {};
|
|
40673
|
+
}
|
|
40674
|
+
let appConfigLoaded = false;
|
|
40675
|
+
function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
|
|
40676
|
+
console.log(`[geonetwork-ui] Loading application configuration from ${configUrl}`);
|
|
40677
|
+
return fetch(configUrl)
|
|
40678
|
+
.then((resp) => {
|
|
40679
|
+
if (!resp.ok)
|
|
40680
|
+
throw new Error('Configuration file could not be loaded');
|
|
40681
|
+
return resp.text();
|
|
40682
|
+
})
|
|
40683
|
+
.then((conf) => {
|
|
40684
|
+
let parsed;
|
|
40685
|
+
try {
|
|
40686
|
+
parsed = TOML.parse(conf, { joiner: '\n', bigint: false });
|
|
40687
|
+
}
|
|
40688
|
+
catch (e) {
|
|
40689
|
+
throw new Error(`An error occurred when parsing the configuration file: ${e.message}`);
|
|
40690
|
+
}
|
|
40691
|
+
const errors = [];
|
|
40692
|
+
const warnings = [];
|
|
40693
|
+
let parsedGlobalSection = parseConfigSection(parsed, 'global', ['geonetwork4_api_url'], [
|
|
40694
|
+
'datahub_url',
|
|
40695
|
+
'edit_url_template',
|
|
40696
|
+
'proxy_path',
|
|
40697
|
+
'metadata_language',
|
|
40698
|
+
'login_url',
|
|
40699
|
+
'logout_url',
|
|
40700
|
+
'settings_url',
|
|
40701
|
+
'web_component_embedder_url',
|
|
40702
|
+
'languages',
|
|
40703
|
+
'contact_email',
|
|
40704
|
+
'reuse_form_url',
|
|
40705
|
+
], warnings, errors);
|
|
40706
|
+
if (parsedGlobalSection?.metadata_language) {
|
|
40707
|
+
parsedGlobalSection = checkMetadataLanguage(parsedGlobalSection, warnings);
|
|
40708
|
+
}
|
|
40709
|
+
globalConfig =
|
|
40710
|
+
parsedGlobalSection === null
|
|
40711
|
+
? null
|
|
40712
|
+
: {
|
|
40713
|
+
GN4_API_URL: parsedGlobalSection.geonetwork4_api_url,
|
|
40714
|
+
DATAHUB_URL: parsedGlobalSection.datahub_url,
|
|
40715
|
+
EDIT_URL_TEMPLATE: parsedGlobalSection.edit_url_template,
|
|
40716
|
+
PROXY_PATH: parsedGlobalSection.proxy_path,
|
|
40717
|
+
METADATA_LANGUAGE: parsedGlobalSection.metadata_language
|
|
40718
|
+
? parsedGlobalSection.metadata_language.toLowerCase()
|
|
40719
|
+
: undefined,
|
|
40720
|
+
LOGIN_URL: parsedGlobalSection.login_url,
|
|
40721
|
+
LOGOUT_URL: parsedGlobalSection.logout_url,
|
|
40722
|
+
SETTINGS_URL: parsedGlobalSection.settings_url,
|
|
40723
|
+
WEB_COMPONENT_EMBEDDER_URL: parsedGlobalSection.web_component_embedder_url,
|
|
40724
|
+
LANGUAGES: parsedGlobalSection.languages,
|
|
40725
|
+
CONTACT_EMAIL: parsedGlobalSection.contact_email,
|
|
40726
|
+
REUSE_FORM_URL: parsedGlobalSection.reuse_form_url,
|
|
40727
|
+
};
|
|
40728
|
+
const parsedLayersSections = parseMultiConfigSection(parsed, 'map_layer', ['type'], ['name', 'url', 'data', 'styleUrl', 'accessToken'], warnings, errors);
|
|
40729
|
+
const parsedMapSection = parseConfigSection(parsed, 'map', [], [
|
|
40730
|
+
'max_zoom',
|
|
40731
|
+
'do_not_tile_wms',
|
|
40732
|
+
'max_extent',
|
|
40733
|
+
'max_feature_count',
|
|
40734
|
+
'baselayer',
|
|
40735
|
+
'do_not_use_default_basemap',
|
|
40736
|
+
'external_viewer_url_template',
|
|
40737
|
+
'external_viewer_open_new_tab',
|
|
40738
|
+
], warnings, errors);
|
|
40739
|
+
mapConfig =
|
|
40740
|
+
parsedMapSection === null || parsedLayersSections === null
|
|
40741
|
+
? null
|
|
40742
|
+
: {
|
|
40743
|
+
MAX_ZOOM: parsedMapSection.max_zoom,
|
|
40744
|
+
DO_NOT_TILE_WMS: parsedMapSection.do_not_tile_wms,
|
|
40745
|
+
MAX_EXTENT: parsedMapSection.max_extent,
|
|
40746
|
+
MAX_FEATURE_COUNT: parsedMapSection.max_feature_count,
|
|
40747
|
+
EXTERNAL_VIEWER_URL_TEMPLATE: parsedMapSection.external_viewer_url_template,
|
|
40748
|
+
EXTERNAL_VIEWER_OPEN_NEW_TAB: parsedMapSection.external_viewer_open_new_tab,
|
|
40749
|
+
DO_NOT_USE_DEFAULT_BASEMAP: !!parsedMapSection.do_not_use_default_basemap,
|
|
40750
|
+
MAP_LAYERS: parsedLayersSections.map((map_layer) => ({
|
|
40751
|
+
TYPE: map_layer.type,
|
|
40752
|
+
URL: map_layer.url,
|
|
40753
|
+
NAME: map_layer.name,
|
|
40754
|
+
DATA: map_layer.data,
|
|
40755
|
+
STYLE_URL: map_layer.styleUrl,
|
|
40756
|
+
ACCESS_TOKEN: map_layer.accessToken,
|
|
40757
|
+
})),
|
|
40758
|
+
};
|
|
40759
|
+
const parsedThemeSection = parseConfigSection(parsed, 'theme', ['primary_color', 'secondary_color', 'main_color', 'background_color'], [
|
|
40760
|
+
'header_foreground_color',
|
|
40761
|
+
'main_font',
|
|
40762
|
+
'title_font',
|
|
40763
|
+
'fonts_stylesheet_url',
|
|
40764
|
+
'thumbnail_placeholder',
|
|
40765
|
+
'header_background',
|
|
40766
|
+
'favicon',
|
|
40767
|
+
], warnings, errors);
|
|
40768
|
+
themeConfig =
|
|
40769
|
+
parsedThemeSection === null
|
|
40770
|
+
? null
|
|
40771
|
+
: {
|
|
40772
|
+
PRIMARY_COLOR: parsedThemeSection.primary_color,
|
|
40773
|
+
SECONDARY_COLOR: parsedThemeSection.secondary_color,
|
|
40774
|
+
MAIN_COLOR: parsedThemeSection.main_color,
|
|
40775
|
+
BACKGROUND_COLOR: parsedThemeSection.background_color,
|
|
40776
|
+
HEADER_FOREGROUND_COLOR: parsedThemeSection.header_foreground_color,
|
|
40777
|
+
THUMBNAIL_PLACEHOLDER: parsedThemeSection.thumbnail_placeholder,
|
|
40778
|
+
HEADER_BACKGROUND: parsedThemeSection.header_background,
|
|
40779
|
+
TITLE_FONT: parsedThemeSection.title_font,
|
|
40780
|
+
MAIN_FONT: parsedThemeSection.main_font,
|
|
40781
|
+
FONTS_STYLESHEET_URL: parsedThemeSection.fonts_stylesheet_url,
|
|
40782
|
+
FAVICON: parsedThemeSection.favicon,
|
|
40783
|
+
};
|
|
40784
|
+
const parsedSearchSection = parseConfigSection(parsed, 'search', [], [
|
|
40785
|
+
'record_kind_quick_filter',
|
|
40786
|
+
'filter_geometry_data',
|
|
40787
|
+
'filter_geometry_url',
|
|
40788
|
+
'do_not_use_default_search_preset',
|
|
40789
|
+
'search_preset',
|
|
40790
|
+
'advanced_filters',
|
|
40791
|
+
'limit',
|
|
40792
|
+
'spatial_extent_max_file_size',
|
|
40793
|
+
'geocoding_provider',
|
|
40794
|
+
'geocoding_provider_options',
|
|
40795
|
+
'geocoding_provider_labels',
|
|
40796
|
+
], warnings, errors);
|
|
40797
|
+
const parsedSearchParams = parseMultiConfigSection(parsed, 'search_preset', ['name'], ['sort', 'filters'], warnings, errors);
|
|
40798
|
+
const parsedCustomFilters = parseMultiConfigSection(parsed, 'custom_filter', ['name', 'base_filter'], ['exclude_values', 'include_values', 'label_key'], warnings, errors);
|
|
40799
|
+
const parsedGeocodingProviderLabels = parsedSearchSection?.geocoding_provider_labels;
|
|
40800
|
+
searchConfig =
|
|
40801
|
+
parsedSearchSection === null
|
|
40802
|
+
? null
|
|
40803
|
+
: {
|
|
40804
|
+
RECORD_KIND_QUICK_FILTER: parsedSearchSection.record_kind_quick_filter,
|
|
40805
|
+
FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
|
|
40806
|
+
FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
|
|
40807
|
+
DO_NOT_USE_DEFAULT_SEARCH_PRESET: !!parsedSearchSection.do_not_use_default_search_preset,
|
|
40808
|
+
SEARCH_PRESET: parsedSearchParams.map((param) => ({
|
|
40809
|
+
sort: param.sort,
|
|
40810
|
+
name: param.name,
|
|
40811
|
+
filters: param.filters,
|
|
40812
|
+
})),
|
|
40813
|
+
ADVANCED_FILTERS: parsedSearchSection.advanced_filters,
|
|
40814
|
+
CUSTOM_FILTERS: (parsedCustomFilters ?? []).map((customFilter) => ({
|
|
40815
|
+
name: customFilter.name,
|
|
40816
|
+
baseFilter: customFilter.base_filter,
|
|
40817
|
+
excludeValues: customFilter.exclude_values,
|
|
40818
|
+
includeValues: customFilter.include_values,
|
|
40819
|
+
labelKey: customFilter.label_key,
|
|
40820
|
+
})),
|
|
40821
|
+
LIMIT: parsedSearchSection.limit,
|
|
40822
|
+
SPATIAL_EXTENT_MAX_FILE_SIZE: parsedSearchSection.spatial_extent_max_file_size,
|
|
40823
|
+
GEOCODING_PROVIDER: parsedSearchSection.geocoding_provider,
|
|
40824
|
+
GEOCODING_PROVIDER_OPTIONS: parsedSearchSection.geocoding_provider_options,
|
|
40825
|
+
GEOCODING_PROVIDER_LABELS: parsedGeocodingProviderLabels
|
|
40826
|
+
? {
|
|
40827
|
+
MAIN: parsedGeocodingProviderLabels.main,
|
|
40828
|
+
SECONDARY: parsedGeocodingProviderLabels.secondary,
|
|
40829
|
+
TERTIARY: parsedGeocodingProviderLabels.tertiary,
|
|
40830
|
+
}
|
|
40831
|
+
: undefined,
|
|
40832
|
+
};
|
|
40833
|
+
const parsedMetadataQualitySection = parseConfigSection(parsed, 'metadata-quality', [], ['enabled'], warnings, errors);
|
|
40834
|
+
metadataQualityConfig =
|
|
40835
|
+
parsedMetadataQualitySection === null
|
|
40836
|
+
? null
|
|
40837
|
+
: {
|
|
40838
|
+
ENABLED: parsedMetadataQualitySection.enabled,
|
|
40839
|
+
SORTABLE: parsedMetadataQualitySection.sortable,
|
|
40840
|
+
};
|
|
40841
|
+
let parsedEditingSection = parseConfigSection(parsed, 'editing', [], ['new_record_default_language', 'new_record_standard'], warnings, errors);
|
|
40842
|
+
if (parsedEditingSection !== null &&
|
|
40843
|
+
parsedEditingSection.new_record_default_language !== undefined) {
|
|
40844
|
+
parsedEditingSection = checkNewRecordDefaultLanguage(parsedEditingSection, warnings);
|
|
40845
|
+
}
|
|
40846
|
+
if (parsedEditingSection !== null &&
|
|
40847
|
+
parsedEditingSection.new_record_standard !== undefined) {
|
|
40848
|
+
parsedEditingSection = checkNewRecordStandard(parsedEditingSection, warnings);
|
|
40849
|
+
}
|
|
40850
|
+
editorConfig =
|
|
40851
|
+
parsedEditingSection === null
|
|
40852
|
+
? null
|
|
40853
|
+
: {
|
|
40854
|
+
NEW_RECORD_DEFAULT_LANGUAGE: parsedEditingSection.new_record_default_language,
|
|
40855
|
+
NEW_RECORD_STANDARD: parsedEditingSection.new_record_standard,
|
|
40856
|
+
};
|
|
40857
|
+
customTranslations = parseTranslationsConfigSection(parsed, 'translations');
|
|
40858
|
+
if (errors.length) {
|
|
40859
|
+
throw new Error(`One or more mandatory settings were missing from the configuration file.
|
|
40860
|
+
${errors.join('\n')}`);
|
|
40861
|
+
}
|
|
40862
|
+
else if (warnings.length) {
|
|
40863
|
+
console.warn(`One or more unexpected settings were encountered in the configuration file.
|
|
40864
|
+
${warnings.join('\n')}`);
|
|
40865
|
+
}
|
|
40866
|
+
appConfigLoaded = true;
|
|
40867
|
+
});
|
|
40868
|
+
}
|
|
40869
|
+
function isConfigLoaded() {
|
|
40870
|
+
return appConfigLoaded;
|
|
40871
|
+
}
|
|
40872
|
+
function _reset() {
|
|
40873
|
+
globalConfig = null;
|
|
40874
|
+
themeConfig = null;
|
|
40875
|
+
editorConfig = null;
|
|
40876
|
+
customTranslations = null;
|
|
40877
|
+
}
|
|
40878
|
+
const TRANSLATE_WITH_OVERRIDES_CONFIG = {
|
|
40879
|
+
compiler: {
|
|
40880
|
+
provide: TranslateCompiler,
|
|
40881
|
+
useClass: TranslateMessageFormatCompiler,
|
|
40882
|
+
},
|
|
40883
|
+
loader: [
|
|
40884
|
+
{
|
|
40885
|
+
provide: TRANSLATE_HTTP_LOADER_CONFIG,
|
|
40886
|
+
useValue: {
|
|
40887
|
+
prefix: './assets/i18n/',
|
|
40888
|
+
suffix: '.json',
|
|
40889
|
+
},
|
|
40890
|
+
},
|
|
40891
|
+
{
|
|
40892
|
+
provide: TranslateLoader,
|
|
40893
|
+
useClass: FileWithOverridesTranslateLoader,
|
|
40894
|
+
deps: [HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
|
|
40895
|
+
},
|
|
40896
|
+
],
|
|
40897
|
+
};
|
|
40898
|
+
|
|
40899
|
+
const okAppConfigFixture = () => `
|
|
40900
|
+
[global]
|
|
40901
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
40902
|
+
proxy_path = "/proxy/?url="
|
|
40903
|
+
metadata_language = "fre"
|
|
40904
|
+
login_url = "/cas/login?service="
|
|
40905
|
+
logout_url = "/geonetwork/signout"
|
|
40906
|
+
settings_url = "/geonetwork/settings"
|
|
40907
|
+
web_component_embedder_url = "/datahub/wc-embedder.html"
|
|
40908
|
+
|
|
40909
|
+
[map]
|
|
40910
|
+
max_zoom = 10
|
|
40911
|
+
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
40912
|
+
do_not_use_default_basemap = false
|
|
40913
|
+
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
40914
|
+
external_viewer_open_new_tab = true
|
|
40915
|
+
[[map_layer]]
|
|
40916
|
+
type = "wms"
|
|
40917
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
40918
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
40919
|
+
[[map_layer]]
|
|
40920
|
+
type = "wfs"
|
|
40921
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
40922
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
40923
|
+
|
|
40924
|
+
[theme]
|
|
40925
|
+
primary_color = "#093564"
|
|
40926
|
+
secondary_color = "#c2e9dc"
|
|
40927
|
+
main_color = "#212029" # All-purpose text color
|
|
40928
|
+
background_color = "#fdfbff"
|
|
40929
|
+
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
40930
|
+
header_background = 'teal'
|
|
40931
|
+
header_foreground_color = "#872e2e"
|
|
40932
|
+
main_font = 'sans-serif'
|
|
40933
|
+
title_font = 'serif'
|
|
40934
|
+
fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
|
|
40935
|
+
|
|
40936
|
+
[search]
|
|
40937
|
+
record_kind_quick_filter = false
|
|
40938
|
+
filter_geometry_url = 'https://my.domain.org/geom.json'
|
|
40939
|
+
do_not_use_default_search_preset = false
|
|
40940
|
+
geocoding_provider = "geoplateforme"
|
|
40941
|
+
geocoding_provider_options.index = "poi"
|
|
40942
|
+
geocoding_provider_options.category = "administratif"
|
|
40943
|
+
geocoding_provider_options.limit = 5
|
|
40944
|
+
geocoding_provider_labels.main = '/properties/name/0'
|
|
40945
|
+
geocoding_provider_labels.secondary = '/properties/citycode/0'
|
|
40946
|
+
geocoding_provider_labels.tertiary = '/properties/category/1'
|
|
40947
|
+
advanced_filters = ['publicationYear', 'documentStandard', 'inspireKeyword', 'topic', 'license', 'myOrg:firstCustomFilter', 'myOrg:secondCustomFilter']
|
|
40948
|
+
|
|
40949
|
+
[[custom_filter]]
|
|
40950
|
+
name = 'myOrg:firstCustomFilter'
|
|
40951
|
+
base_filter = 'keyword'
|
|
40952
|
+
exclude_values = ['my keyword 1', 'my keyword 2']
|
|
40953
|
+
label_key = 'myOrg.firstCustomFilter'
|
|
40954
|
+
|
|
40955
|
+
[[custom_filter]]
|
|
40956
|
+
name = 'myOrg:secondCustomFilter'
|
|
40957
|
+
base_filter = 'keyword'
|
|
40958
|
+
include_values = ['my keyword 3', 'my keyword 4']
|
|
40959
|
+
label_key = 'myOrg.secondCustomFilter'
|
|
40960
|
+
|
|
40961
|
+
[[search_preset]]
|
|
40962
|
+
sort = "-createDate"
|
|
40963
|
+
name = 'filterByOrgs'
|
|
40964
|
+
filters.q = 'Carto'
|
|
40965
|
+
filters.organisation = ['Org1', 'Org2']
|
|
40966
|
+
filters.format = ['ESRI Shapefile']
|
|
40967
|
+
filters.topic = ['boundaries']
|
|
40968
|
+
filters.publicationYear = ['2023', '2022']
|
|
40969
|
+
filters.spatial = ['yes']
|
|
40970
|
+
|
|
40971
|
+
[translations.en]
|
|
40972
|
+
"my.first.key" = 'First label.'
|
|
40973
|
+
"my.second.key" = """
|
|
40974
|
+
Second label,
|
|
40975
|
+
on two lines."""
|
|
40976
|
+
|
|
40977
|
+
[translations.de]
|
|
40978
|
+
my.first.key = 'Erste Etikett.'
|
|
40979
|
+
|
|
40980
|
+
[translations.fr]
|
|
40981
|
+
my.sample.text = "Un bon exemple de texte."
|
|
40982
|
+
"my.quoted.text" = 'du texte entre guillements.'
|
|
40983
|
+
`;
|
|
40984
|
+
const appConfigWithTranslationFixture = () => okAppConfigFixture();
|
|
40985
|
+
const minimalAppConfigFixture = () => `
|
|
40986
|
+
[global]
|
|
40987
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
40988
|
+
proxy_path = "/proxy/?url="
|
|
40989
|
+
|
|
40990
|
+
[theme]
|
|
40991
|
+
primary_color = "#093564"
|
|
40992
|
+
secondary_color = "#c2e9dc"
|
|
40993
|
+
main_color = "#212029" # All-purpose text color
|
|
40994
|
+
background_color = "#fdfbff"
|
|
40995
|
+
`;
|
|
40996
|
+
const customFilterMissingMandatoryConfigFixture = () => `
|
|
40997
|
+
[global]
|
|
40998
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
40999
|
+
|
|
41000
|
+
[theme]
|
|
41001
|
+
primary_color = "#093564"
|
|
41002
|
+
secondary_color = "#c2e9dc"
|
|
41003
|
+
main_color = "#212029" # All-purpose text color
|
|
41004
|
+
background_color = "#fdfbff"
|
|
41005
|
+
|
|
41006
|
+
[search]
|
|
41007
|
+
advanced_filters = ['myOrg:firstCustomFilter']
|
|
41008
|
+
|
|
41009
|
+
[[custom_filter]]
|
|
41010
|
+
name = 'myOrg:firstCustomFilter'
|
|
41011
|
+
`;
|
|
41012
|
+
const mapConfigFixture = () => ({
|
|
41013
|
+
MAX_ZOOM: 10,
|
|
41014
|
+
MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
|
|
41015
|
+
DO_NOT_USE_DEFAULT_BASEMAP: false,
|
|
41016
|
+
DO_NOT_TILE_WMS: false,
|
|
41017
|
+
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}"}]}]',
|
|
41018
|
+
EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
|
|
41019
|
+
MAP_LAYERS: [
|
|
41020
|
+
{
|
|
41021
|
+
TYPE: 'xyz',
|
|
41022
|
+
URL: 'https://some-basemap-server',
|
|
41023
|
+
},
|
|
41024
|
+
{
|
|
41025
|
+
TYPE: 'wms',
|
|
41026
|
+
URL: 'https://some-wms-server',
|
|
41027
|
+
NAME: 'some_layername',
|
|
41028
|
+
},
|
|
41029
|
+
{
|
|
41030
|
+
TYPE: 'wfs',
|
|
41031
|
+
URL: 'https://some-wfs-server',
|
|
41032
|
+
NAME: 'some_layername',
|
|
41033
|
+
},
|
|
41034
|
+
],
|
|
41035
|
+
});
|
|
41036
|
+
const malformedConfigFixture = () => `
|
|
41037
|
+
{
|
|
41038
|
+
"I thought": "we were still doing json"
|
|
41039
|
+
}
|
|
41040
|
+
`;
|
|
41041
|
+
const missingMandatoryConfigFixture = () => `
|
|
41042
|
+
[theme]
|
|
41043
|
+
primary_color = "#093564"
|
|
41044
|
+
secondary_color = "#c2e9dc"
|
|
41045
|
+
background_color = "#fdfbff"
|
|
41046
|
+
main_font = 'sans-serif'
|
|
41047
|
+
`;
|
|
41048
|
+
const wrongLanguageCodeConfigFixture = () => `
|
|
41049
|
+
[global]
|
|
41050
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
41051
|
+
proxy_path = "/proxy/?url="
|
|
41052
|
+
metadata_language = "abc"
|
|
41053
|
+
|
|
41054
|
+
[map]
|
|
41055
|
+
|
|
41056
|
+
[theme]
|
|
41057
|
+
primary_color = "#093564"
|
|
41058
|
+
secondary_color = "#c2e9dc"
|
|
41059
|
+
main_color = "#212029" # All-purpose text color
|
|
41060
|
+
background_color = "#fdfbff"
|
|
41061
|
+
`;
|
|
41062
|
+
const unrecognizedKeysConfigFixture = () => `
|
|
41063
|
+
[global]
|
|
41064
|
+
geonetwork4_api_url = "/geonetwork/srv/api"
|
|
41065
|
+
proxy_path = "/proxy/?url="
|
|
41066
|
+
metadata_language = "fre"
|
|
41067
|
+
another_path = '/whatever'
|
|
41068
|
+
|
|
41069
|
+
[map]
|
|
41070
|
+
max_zoom = 10
|
|
41071
|
+
max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855]
|
|
41072
|
+
do_not_use_default_basemap = false
|
|
41073
|
+
external_viewer_url_template = 'https://example.com/myviewer?'
|
|
41074
|
+
external_viewer_open_new_tab = true
|
|
41075
|
+
another_zoom = 15
|
|
41076
|
+
[[map_layer]]
|
|
41077
|
+
type = "wms"
|
|
41078
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
41079
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
41080
|
+
[[map_layer]]
|
|
41081
|
+
type = "wfs"
|
|
41082
|
+
url = "https://www.geo2france.fr/geoserver/cr_hdf/ows"
|
|
41083
|
+
name = "masque_hdf_ign_carto_latin1"
|
|
41084
|
+
another_layer = "wrong layer definition"
|
|
41085
|
+
|
|
41086
|
+
[theme]
|
|
41087
|
+
primary_color = "#093564"
|
|
41088
|
+
secondary_color = "#c2e9dc"
|
|
41089
|
+
main_color = "#212029" # All-purpose text color
|
|
41090
|
+
background_color = "#fdfbff"
|
|
41091
|
+
thumbnail_placeholder = 'assets/img/placeholder.svg'
|
|
41092
|
+
header_background = 'teal'
|
|
41093
|
+
header_foreground_color = "#872e2e"
|
|
41094
|
+
main_font = 'sans-serif'
|
|
41095
|
+
title_font = 'serif'
|
|
41096
|
+
another_color = 'red'
|
|
41097
|
+
`;
|
|
41098
|
+
|
|
41099
|
+
function getMapContextLayerFromConfig(config) {
|
|
41100
|
+
switch (config.TYPE) {
|
|
41101
|
+
case 'wms':
|
|
41102
|
+
return {
|
|
41103
|
+
type: 'wms',
|
|
41104
|
+
url: config.URL,
|
|
41105
|
+
name: config.NAME,
|
|
41106
|
+
};
|
|
41107
|
+
case 'wfs':
|
|
41108
|
+
return {
|
|
41109
|
+
type: 'wfs',
|
|
41110
|
+
url: config.URL,
|
|
41111
|
+
featureType: config.NAME,
|
|
41112
|
+
};
|
|
41113
|
+
case 'xyz':
|
|
41114
|
+
return {
|
|
41115
|
+
type: config.TYPE,
|
|
41116
|
+
url: config.URL,
|
|
41117
|
+
};
|
|
41118
|
+
case 'geojson':
|
|
41119
|
+
return {
|
|
41120
|
+
type: config.TYPE,
|
|
41121
|
+
...(config.DATA ? { data: config.DATA } : { url: config.URL }),
|
|
41122
|
+
};
|
|
41123
|
+
case 'maplibre-style':
|
|
41124
|
+
return {
|
|
41125
|
+
type: config.TYPE,
|
|
41126
|
+
styleUrl: config.STYLE_URL,
|
|
41127
|
+
accessToken: config.ACCESS_TOKEN,
|
|
41128
|
+
};
|
|
41129
|
+
}
|
|
41130
|
+
}
|
|
41131
|
+
|
|
40937
41132
|
const CHART_TYPE_VALUES = [
|
|
40938
41133
|
'bar',
|
|
40939
41134
|
'bar-horizontal',
|
|
@@ -40949,5 +41144,5 @@ const CHART_TYPE_VALUES = [
|
|
|
40949
41144
|
* Generated bundle index. Do not edit.
|
|
40950
41145
|
*/
|
|
40951
41146
|
|
|
40952
|
-
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, GEOCODING_PROVIDER, 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, MapStyleService, MapUtilsService, MapViewComponent, MarkdownEditorComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataDoiComponent, MetadataInfoComponent, MetadataLinkType, MetadataMapperContext, MetadataQualityComponent, MetadataQualityItemComponent, MetadataQualityPanelComponent, ModalDialogComponent, MultilingualPanelComponent, MultilingualSearchField, MyOrgService, NAMESPACES, NOT_APPLICABLE_CONSTRAINT, NOT_KNOWN_CONSTRAINT, NotificationComponent, NotificationsContainerComponent, NotificationsService, OPEN_DATA_LICENSE, ORGANIZATIONS_STRATEGY, ORGANIZATION_PAGE_URL_TOKEN, ORGANIZATION_URL_TOKEN, OnlineResourceCardComponent, OnlineServiceResourceInputComponent, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationSearchField, OrganizationsFromGroupsService, OrganizationsFromMetadataService, OrganizationsServiceInterface, OwnerSearchField, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PaginationDotsComponent, PatchResultsAggregations, PlatformServiceInterface, PopoverComponent, PopupAlertComponent, PossibleResourceTypes, PossibleResourceTypesDefinition, PreviousNextButtonsComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_DATASET_URL_TOKEN, RECORD_REUSE_URL_TOKEN, RECORD_SERVICE_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, REUSE_LIGHT_CONFIGURATION, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_ORGANIZATION, ROUTER_ROUTE_REUSE, ROUTER_ROUTE_SEARCH, ROUTER_ROUTE_SERVICE, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordKindField, RecordMetaComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordStatusValues, RecordsMetricsComponent, RecordsRepositoryInterface, RecordsService, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResourceCreationRevisionDateSearchField, ResourceTypeLegacyField, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsHitsSearchKindComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, ResultsTableContainerComponent, ReusePresentationForms, RoleLabels, RoleValues, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SETTINGS_URL, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SPATIAL_SCOPES, SearchEffects, SearchFacade, SearchFeatureCatalogComponent, SearchFiltersSummaryComponent, SearchFiltersSummaryItemComponent, SearchInputComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, ServiceCapabilitiesComponent, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SimpleSearchField, SiteTitleComponent, SortByComponent, SortByEnum, SortableListComponent, SourceLabelComponent, SourcesService, SpatialExtentComponent, SpatialExtentDropdownComponent, SpinningLoaderComponent, StacItemsResultGridComponent, StacViewComponent, StarToggleComponent, StickyHeaderComponent, SupportedTypes, SwitchToggleComponent, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEBUG_CONFIG, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, TranslatedSearchField, TruncatedTextComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UpdateConfigAggregations, UpdateFilters, UrlInputComponent, UserFeedbackItemComponent, UserPreviewComponent, UserSearchField, VECTOR_STYLE_DEFAULT, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, XmlParseError, _reset, allChildrenElement, appConfigWithTranslationFixture, appendChildTree, appendChildren, assertValidXml, associationTypeValues, bboxToPolygon, blockModelFixture, bytesToMegabytes, canEditRecord, checkFileFormat, clearSelectedFeatures, createChild, createDocument, createElement, createFuzzyFilter, createNestedChild, createNestedElement, createSpatialExtentLayer, currentPage, defaultMapStyleFixture, defaultMapStyleHlFixture, downgradeImage, downsizeImage, draftSaveSuccess, dragPanCondition, dropEmptyTranslations, editorReducer, emptyBlockModelFixture, findChildElement, findChildOrCreate, findChildrenElement, findConverterForDocument, findNestedChildOrCreate, findNestedElement, findNestedElements, findParent, firstChildElement, formatDate, formatUserInfo, getAddressLines, getAllKeysValidator, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryBoundingBox, getGeometryFromGeoJSON, getGlobalConfig, getIndividualDisplayName, getIsMobile, getJsonDataItemsProxy, getKeywordHierarchyPath, getLayers, getLinkId, getLinkLabel, getLinkPriority, getMapContext, getMapContextLayerFromConfig, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getNamespace, getOptionalEditorConfig, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getQualityValidators, getResourceType, getReusePresentationForm, getReuseType, getRootElement, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSelectedFeatures, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, handleScrollOnNavigation, hasRecordChangedSinceDraft, hasRecordChangedSinceDraftSuccess, initSearch, initialEditorState, initialMapState, initialState, isBoundingBox, 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 };
|
|
41147
|
+
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 };
|
|
40953
41148
|
//# sourceMappingURL=geonetwork-ui.mjs.map
|