geonetwork-ui 2.11.0-dev.7f3cfba04 → 2.11.0-dev.840dcc932

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/fesm2022/geonetwork-ui.mjs +233 -18
  2. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  3. package/index.d.ts +43 -16
  4. package/index.d.ts.map +1 -1
  5. package/package.json +1 -1
  6. package/src/libs/api/metadata-converter/src/lib/fixtures/mel.records.dataset+featurecatalog.ts +83 -5
  7. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +3 -3
  8. package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +15 -6
  9. package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +20 -8
  10. package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +131 -0
  11. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +2 -0
  12. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +78 -1
  13. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +11 -0
  14. package/src/libs/common/domain/src/lib/model/record/flags.model.ts +1 -0
  15. package/src/libs/common/domain/src/lib/model/record/index.ts +1 -0
  16. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +11 -8
  17. package/src/libs/common/domain/src/lib/platform.service.interface.ts +1 -0
  18. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +19 -0
  19. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +3 -3
  20. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-constraints/form-field-constraints.component.ts +3 -5
  21. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.ts +2 -2
  22. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-record-flags/form-field-record-flag-component.css +0 -0
  23. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-record-flags/form-field-record-flag-component.html +18 -0
  24. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-record-flags/form-field-record-flag-component.ts +86 -0
  25. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +100 -88
  26. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +11 -4
  27. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +18 -4
  28. package/src/libs/feature/editor/src/lib/expressions.ts +67 -0
  29. package/src/libs/feature/editor/src/lib/fields.config.ts +13 -0
  30. package/src/libs/feature/editor/src/lib/models/editor-config.model.ts +10 -4
  31. package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.html +1 -1
  32. package/translations/de.json +4 -0
  33. package/translations/en.json +4 -0
  34. package/translations/es.json +4 -0
  35. package/translations/fr.json +4 -0
  36. package/translations/it.json +4 -0
  37. package/translations/nl.json +4 -0
  38. package/translations/pt.json +4 -0
  39. package/translations/sk.json +4 -0
@@ -14,7 +14,7 @@ import * as i4 from '@ngx-translate/core';
14
14
  import { TranslateLoader, TranslateCompiler, TranslateDefaultParser, TranslateParser, TranslateService, provideTranslateService, TranslateDirective, TranslatePipe, TranslateModule } from '@ngx-translate/core';
15
15
  import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
16
16
  import { TranslateHttpLoader, TRANSLATE_HTTP_LOADER_CONFIG } from '@ngx-translate/http-loader';
17
- import { map as map$1, shareReplay as shareReplay$1, catchError, tap as tap$1, filter as filter$1, startWith as startWith$1, withLatestFrom, switchMap as switchMap$1, take, mergeMap, delay, debounceTime, distinctUntilChanged, finalize, throttleTime, first as first$1, pairwise as pairwise$1, share, defaultIfEmpty, toArray } from 'rxjs/operators';
17
+ import { map as map$1, shareReplay as shareReplay$1, catchError, tap as tap$1, withLatestFrom, filter as filter$1, startWith as startWith$1, switchMap as switchMap$1, take, mergeMap, delay, debounceTime, distinctUntilChanged, finalize, throttleTime, first as first$1, pairwise as pairwise$1, share, defaultIfEmpty, toArray } from 'rxjs/operators';
18
18
  import { lt, valid, coerce, satisfies, ltr } from 'semver';
19
19
  import chroma from 'chroma-js';
20
20
  import * as i1$1 from '@angular/common';
@@ -52,7 +52,7 @@ import { matClose, matContentCopy, matExpandMore, matExpandLess, matSearch, matS
52
52
  import * as i1$4 from '@angular/material/checkbox';
53
53
  import { MatCheckboxModule } from '@angular/material/checkbox';
54
54
  import * as i1$5 from '@angular/material/tooltip';
55
- import { MatTooltipModule } from '@angular/material/tooltip';
55
+ import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
56
56
  import { MAT_DATE_LOCALE, MAT_DATE_FORMATS, DateAdapter } from '@angular/material/core';
57
57
  import { MAT_DATE_FNS_FORMATS, DateFnsAdapter } from '@angular/material-date-fns-adapter';
58
58
  import { enUS } from 'date-fns/locale/en-US';
@@ -2469,6 +2469,8 @@ class Iso19139Converter extends BaseConverter {
2469
2469
  this.writers['resourceIdentifiers'](record, rootEl);
2470
2470
  if (record.kind === 'dataset') {
2471
2471
  fieldChanged('status') && this.writers['status'](record, rootEl);
2472
+ fieldChanged('featureTypeDescriptions') &&
2473
+ this.writers['featureTypeDescriptions'](record, rootEl);
2472
2474
  }
2473
2475
  if (record.kind === 'dataset' || record.kind === 'reuse') {
2474
2476
  fieldChanged('updateFrequency') &&
@@ -2640,14 +2642,16 @@ function extractCharacterStringOrText() {
2640
2642
  return fallback(extractCharacterString(), readText());
2641
2643
  }
2642
2644
  function extractListedValue() {
2643
- return pipe(combine(pipe(findChildElement('gfc:code', false), extractCharacterString()), pipe(findChildElement('gfc:label', false), extractCharacterString())), map(([code, label]) => ({
2644
- ...(code && { code }),
2645
+ 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 ?? '',
2645
2647
  ...(label && { label }),
2648
+ ...(description && { description }),
2646
2649
  })));
2647
2650
  }
2648
2651
  function extractFeatureAttribute() {
2649
- return pipe(combine(pipe(findChildElement('gfc:memberName', false), extractCharacterStringOrText()), pipe(findChildElement('gfc:definition', false), extractCharacterString()), pipe(findChildElement('gfc:code', false), extractCharacterString()), pipe(findNestedElement('gfc:valueType', 'gco:TypeName', 'gco:aName'), extractCharacterString()), pipe(findNestedElements('gfc:listedValue', 'gfc:FC_ListedValue'), mapArray(extractListedValue()), filterArray((value) => !!(value.code || value.label)))), map(([name, description, code, type, values]) => ({
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]) => ({
2650
2653
  name: name ?? '',
2654
+ ...(label && { label }),
2651
2655
  ...(description && { description }),
2652
2656
  ...(code && { code }),
2653
2657
  ...(type && { type }),
@@ -2655,8 +2659,9 @@ function extractFeatureAttribute() {
2655
2659
  })));
2656
2660
  }
2657
2661
  function readFeatureTypeDescriptions(rootEl) {
2658
- return pipe(findNestedElements('mdb:contentInfo', 'mrc:MD_FeatureCatalogue', 'mrc:featureCatalogue', 'gfc:FC_FeatureCatalogue', 'gfc:featureType', 'gfc:FC_FeatureType'), mapArray(pipe(combine(pipe(findChildElement('gfc:typeName', false), extractCharacterStringOrText()), pipe(findChildElement('gfc:definition', false), extractCharacterString()), pipe(findNestedElements('gfc:carrierOfCharacteristics', 'gfc:FC_FeatureAttribute'), mapArray(extractFeatureAttribute()))), map(([name, description, attributes]) => ({
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]) => ({
2659
2663
  name: name ?? '',
2664
+ ...(label && { label }),
2660
2665
  ...(description && { description }),
2661
2666
  attributes,
2662
2667
  })))))(rootEl);
@@ -2815,6 +2820,52 @@ function writeAssociatedRecords(record, rootEl) {
2815
2820
  .filter((assoc) => assoc.uniqueIdentifier && assoc.associationType)
2816
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);
2817
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
+ }
2818
2869
 
2819
2870
  class Iso191153Converter extends Iso19139Converter {
2820
2871
  constructor() {
@@ -2852,6 +2903,7 @@ class Iso191153Converter extends Iso19139Converter {
2852
2903
  this.writers['lineage'] = writeLineage;
2853
2904
  this.writers['sourceRecords'] = writeSourceRecords;
2854
2905
  this.writers['associatedRecords'] = writeAssociatedRecords;
2906
+ this.writers['featureTypeDescriptions'] = writeFeatureTypeDescriptions;
2855
2907
  this.writers['onlineResources'] = writeOnlineResources;
2856
2908
  this.writers['status'] = writeStatus;
2857
2909
  this.writers['spatialRepresentation'] = writeSpatialRepresentation;
@@ -2941,10 +2993,12 @@ class Iso191153Converter extends Iso19139Converter {
2941
2993
  });
2942
2994
  }
2943
2995
  async writeRecord(record, reference) {
2944
- let result = await super.writeRecord(record, reference);
2945
- // fix gco namespace definition (changes between iso19139 and iso19115-3
2946
- result = result.replace('"http://www.isotc211.org/2005/gco"', '"http://standards.iso.org/iso/19115/-3/gco/1.0"');
2947
- 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"'));
2948
3002
  }
2949
3003
  }
2950
3004
 
@@ -19088,7 +19142,7 @@ class Gn4FieldMapper {
19088
19142
  const values = (attr.values ?? [])
19089
19143
  .filter((value) => value.code || value.label)
19090
19144
  .map((value) => ({
19091
- ...(value.code && { code: value.code }),
19145
+ value: value.code || '',
19092
19146
  ...(value.label && { label: value.label }),
19093
19147
  }));
19094
19148
  return {
@@ -20510,7 +20564,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
20510
20564
  }] } });
20511
20565
 
20512
20566
  var name = "geonetwork-ui";
20513
- var version = "2.11.0-dev.7f3cfba04";
20567
+ var version = "2.11.0-dev.840dcc932";
20514
20568
  var engines = {
20515
20569
  node: ">=24"
20516
20570
  };
@@ -21423,10 +21477,21 @@ class Gn4Repository {
21423
21477
  this.platformService = inject(PlatformServiceInterface);
21424
21478
  this.gn4LanguagesApi = inject(LanguagesApiService);
21425
21479
  this.settingsService = inject(Gn4SettingsService);
21480
+ this.gn4TagsApi = inject(TagsApiService);
21426
21481
  this.disableDraft = inject(DISABLE_DRAFT, { optional: true }) ?? false;
21427
21482
  this.defaultConverter = inject(DEFAULT_RECORD_CONVERTER);
21428
21483
  this._draftsChanged = new Subject();
21429
21484
  this.draftsChanged$ = this._draftsChanged.asObservable();
21485
+ /*
21486
+ * FLAGS
21487
+ * Note: in GN4 API, categories are named "tags"
21488
+ */
21489
+ this.categoriesIdentifierForFlags = this.gn4TagsApi.getTags().pipe(map$1((categories) => categories.reduce((acc, category) => {
21490
+ if (category.name.startsWith('geonetwork-ui-flag:')) {
21491
+ acc[category.name.replace(/^geonetwork-ui-flag:/, '')] = category.id;
21492
+ }
21493
+ return acc;
21494
+ }, {})), shareReplay$1(1));
21430
21495
  }
21431
21496
  search({ filters, fields, offset, limit, sort, filterIds, filterGeometry, }) {
21432
21497
  return this.gn4SearchApi
@@ -21728,6 +21793,32 @@ class Gn4Repository {
21728
21793
  removeRecordFromLocalStorage(recordId) {
21729
21794
  window.localStorage.removeItem(this.getLocalStorageKeyForRecord(recordId));
21730
21795
  }
21796
+ getCategoryIdForFlag(flagName) {
21797
+ return this.categoriesIdentifierForFlags.pipe(map$1((categories) => {
21798
+ const categoryId = categories[flagName];
21799
+ if (categoryId === undefined) {
21800
+ console.warn(`The record flag ${flagName} is not created on GeoNetwork backend; please create a category with the name geonetwork-ui-flag:${flagName} for this to work.`);
21801
+ return null;
21802
+ }
21803
+ return categoryId;
21804
+ }));
21805
+ }
21806
+ setRecordFlag(uniqueIdentifier, flagName, value) {
21807
+ return this.getCategoryIdForFlag(flagName).pipe(switchMap((categoryId) => {
21808
+ if (categoryId === null)
21809
+ return of();
21810
+ return value
21811
+ ? this.gn4RecordsApi.tagRecord(uniqueIdentifier, [categoryId], false)
21812
+ : this.gn4RecordsApi.deleteTags(uniqueIdentifier, [categoryId]);
21813
+ }));
21814
+ }
21815
+ getRecordFlag(uniqueIdentifier, flagName) {
21816
+ return this.gn4RecordsApi.getRecordTags(uniqueIdentifier).pipe(withLatestFrom(this.getCategoryIdForFlag(flagName)), map$1(([tags, categoryId]) => {
21817
+ if (categoryId === null)
21818
+ return false;
21819
+ return Array.from(tags).some((tag) => tag.id === categoryId);
21820
+ }));
21821
+ }
21731
21822
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: Gn4Repository, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
21732
21823
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: Gn4Repository }); }
21733
21824
  }
@@ -22343,6 +22434,9 @@ class Gn4PlatformService {
22343
22434
  this.me$ = this.disableAuth
22344
22435
  ? of(null)
22345
22436
  : of(true).pipe(switchMap(() => this.meApi.getMe()), switchMap((apiUser) => this.mapper.userFromMeApi(apiUser)), shareReplay$1({ bufferSize: 1, refCount: true }));
22437
+ this.isAdmin$ = this.disableAuth
22438
+ ? of(false)
22439
+ : of(true).pipe(switchMap(() => this.meApi.getMe()), map$1((apiUser) => !!apiUser?.admin), shareReplay$1({ bufferSize: 1, refCount: true }));
22346
22440
  /**
22347
22441
  * A map of already loaded thesauri (groups of keywords); the key is a URI
22348
22442
  * @private
@@ -22378,6 +22472,9 @@ class Gn4PlatformService {
22378
22472
  isAnonymous() {
22379
22473
  return this.isUserAnonymous$;
22380
22474
  }
22475
+ isAdministrator() {
22476
+ return this.isAdmin$;
22477
+ }
22381
22478
  getOrganizations() {
22382
22479
  return undefined;
22383
22480
  }
@@ -30243,7 +30340,7 @@ class FeatureCatalogListComponent {
30243
30340
  return col.key;
30244
30341
  }
30245
30342
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureCatalogListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
30246
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FeatureCatalogListComponent, isStandalone: true, selector: "gn-ui-feature-catalog-list", inputs: { filteredFeatureCatalog: "filteredFeatureCatalog" }, providers: [provideIcons({ iconoirList })], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "scrollable", first: true, predicate: CdkScrollable, descendants: true, static: true }, { propertyName: "panelComponent", first: true, predicate: ["expanel"], descendants: true, read: ExpandablePanelComponent, static: true }], ngImport: i0, template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.description) {\n <div class=\"text-sm\">\n {{ featureType.description }}\n </div>\n }\n </div>\n </ng-template>\n @if (expanel && !expanel.collapsed) {\n <div\n class=\"grid gap-0\"\n [style.grid-template-columns]=\"\n getGridTemplateColumns(featureType.attributes)\n \"\n data-cy=\"feature-type-content\"\n >\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"py-1 px-2 text-sm font-bold text-left border-t break-all\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n [ngClass]=\"col.class || ''\"\n data-test=\"column-label\"\n >\n {{ 'feature.catalog.attribute.' + col.key | translate }}\n </div>\n }\n @if (expanel && !expanel.collapsed) {\n @for (row of featureType.attributes; track row) {\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"bg-white text-sm font-normal text-left border-t\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n data-test=\"cell-content\"\n >\n @if (col.key === 'values') {\n @if (row.values?.length > 0) {\n <gn-ui-cell-popin\n #popinRef\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n >\n <div\n cellContent\n data-cy=\"values-cell-popin-trigger\"\n >\n <gn-ui-button\n type=\"light\"\n extraClass=\"bg-transparent border-none\"\n (buttonClick)=\"popinRef.openOverlay()\"\n >\n <ng-icon name=\"iconoirList\" size=\"24\"></ng-icon>\n </gn-ui-button>\n </div>\n <div\n popinContent\n class=\"max-h-60 overflow-y-auto min-w-64 py-4 px-6\"\n style=\"scrollbar-width: thin\"\n >\n <ul class=\"list-disc list-inside mr-4\">\n @for (v of row.values; track v) {\n <li>\n {{ v.label || v.code }}\n </li>\n }\n </ul>\n </div>\n </gn-ui-cell-popin>\n }\n } @else {\n <gn-ui-truncated-text\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n [text]=\"row[col.key]\"\n ></gn-ui-truncated-text>\n }\n </div>\n }\n }\n }\n </div>\n }\n </gn-ui-expandable-panel>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: CellPopinComponent, selector: "gn-ui-cell-popin", inputs: ["extraClass", "cdkScrollContainer", "scrollContainer", "activePopin"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: ["title", "iconColor", "collapsed"] }, { kind: "component", type: TruncatedTextComponent, selector: "gn-ui-truncated-text", inputs: ["text", "extraClass", "scrollContainer", "cdkScrollContainer"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2$3.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
30343
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FeatureCatalogListComponent, isStandalone: true, selector: "gn-ui-feature-catalog-list", inputs: { filteredFeatureCatalog: "filteredFeatureCatalog" }, providers: [provideIcons({ iconoirList })], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "scrollable", first: true, predicate: CdkScrollable, descendants: true, static: true }, { propertyName: "panelComponent", first: true, predicate: ["expanel"], descendants: true, read: ExpandablePanelComponent, static: true }], ngImport: i0, template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.description) {\n <div class=\"text-sm\">\n {{ featureType.description }}\n </div>\n }\n </div>\n </ng-template>\n @if (expanel && !expanel.collapsed) {\n <div\n class=\"grid gap-0\"\n [style.grid-template-columns]=\"\n getGridTemplateColumns(featureType.attributes)\n \"\n data-cy=\"feature-type-content\"\n >\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"py-1 px-2 text-sm font-bold text-left border-t break-all\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n [ngClass]=\"col.class || ''\"\n data-test=\"column-label\"\n >\n {{ 'feature.catalog.attribute.' + col.key | translate }}\n </div>\n }\n @if (expanel && !expanel.collapsed) {\n @for (row of featureType.attributes; track row) {\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"bg-white text-sm font-normal text-left border-t\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n data-test=\"cell-content\"\n >\n @if (col.key === 'values') {\n @if (row.values?.length > 0) {\n <gn-ui-cell-popin\n #popinRef\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n >\n <div\n cellContent\n data-cy=\"values-cell-popin-trigger\"\n >\n <gn-ui-button\n type=\"light\"\n extraClass=\"bg-transparent border-none\"\n (buttonClick)=\"popinRef.openOverlay()\"\n >\n <ng-icon name=\"iconoirList\" size=\"24\"></ng-icon>\n </gn-ui-button>\n </div>\n <div\n popinContent\n class=\"max-h-60 overflow-y-auto min-w-64 py-4 px-6\"\n style=\"scrollbar-width: thin\"\n >\n <ul class=\"list-disc list-inside mr-4\">\n @for (v of row.values; track v) {\n <li>\n {{ v.label || v.value }}\n </li>\n }\n </ul>\n </div>\n </gn-ui-cell-popin>\n }\n } @else {\n <gn-ui-truncated-text\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n [text]=\"row[col.key]\"\n ></gn-ui-truncated-text>\n }\n </div>\n }\n }\n }\n </div>\n }\n </gn-ui-expandable-panel>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: CellPopinComponent, selector: "gn-ui-cell-popin", inputs: ["extraClass", "cdkScrollContainer", "scrollContainer", "activePopin"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: ["title", "iconColor", "collapsed"] }, { kind: "component", type: TruncatedTextComponent, selector: "gn-ui-truncated-text", inputs: ["text", "extraClass", "scrollContainer", "cdkScrollContainer"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2$3.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
30247
30344
  }
30248
30345
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FeatureCatalogListComponent, decorators: [{
30249
30346
  type: Component,
@@ -30256,7 +30353,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
30256
30353
  TruncatedTextComponent,
30257
30354
  NgIconComponent,
30258
30355
  ScrollingModule,
30259
- ], providers: [provideIcons({ iconoirList })], template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.description) {\n <div class=\"text-sm\">\n {{ featureType.description }}\n </div>\n }\n </div>\n </ng-template>\n @if (expanel && !expanel.collapsed) {\n <div\n class=\"grid gap-0\"\n [style.grid-template-columns]=\"\n getGridTemplateColumns(featureType.attributes)\n \"\n data-cy=\"feature-type-content\"\n >\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"py-1 px-2 text-sm font-bold text-left border-t break-all\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n [ngClass]=\"col.class || ''\"\n data-test=\"column-label\"\n >\n {{ 'feature.catalog.attribute.' + col.key | translate }}\n </div>\n }\n @if (expanel && !expanel.collapsed) {\n @for (row of featureType.attributes; track row) {\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"bg-white text-sm font-normal text-left border-t\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n data-test=\"cell-content\"\n >\n @if (col.key === 'values') {\n @if (row.values?.length > 0) {\n <gn-ui-cell-popin\n #popinRef\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n >\n <div\n cellContent\n data-cy=\"values-cell-popin-trigger\"\n >\n <gn-ui-button\n type=\"light\"\n extraClass=\"bg-transparent border-none\"\n (buttonClick)=\"popinRef.openOverlay()\"\n >\n <ng-icon name=\"iconoirList\" size=\"24\"></ng-icon>\n </gn-ui-button>\n </div>\n <div\n popinContent\n class=\"max-h-60 overflow-y-auto min-w-64 py-4 px-6\"\n style=\"scrollbar-width: thin\"\n >\n <ul class=\"list-disc list-inside mr-4\">\n @for (v of row.values; track v) {\n <li>\n {{ v.label || v.code }}\n </li>\n }\n </ul>\n </div>\n </gn-ui-cell-popin>\n }\n } @else {\n <gn-ui-truncated-text\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n [text]=\"row[col.key]\"\n ></gn-ui-truncated-text>\n }\n </div>\n }\n }\n }\n </div>\n }\n </gn-ui-expandable-panel>\n </div>\n }\n </div>\n</div>\n" }]
30356
+ ], providers: [provideIcons({ iconoirList })], template: "<div\n cdkScrollable\n class=\"h-[562px] relative overflow-y-auto overflow-hidden\"\n data-cy=\"feat-catalog-scrollable\"\n>\n <div #scrollContainer class=\"flex flex-col gap-2 py-5 px-5\">\n @for (\n featureType of filteredFeatureCatalog?.featureTypes;\n track featureType\n ) {\n <div class=\"rounded shadow bg-white\">\n <gn-ui-expandable-panel\n #expanel\n [collapsed]=\"filteredFeatureCatalog?.featureTypes?.length !== 1\"\n iconColor=\"black\"\n >\n <ng-template #titleTemplate>\n <div class=\"px-2\">\n <div class=\"text-lg font-bold\">{{ featureType.name }}</div>\n @if (featureType.description) {\n <div class=\"text-sm\">\n {{ featureType.description }}\n </div>\n }\n </div>\n </ng-template>\n @if (expanel && !expanel.collapsed) {\n <div\n class=\"grid gap-0\"\n [style.grid-template-columns]=\"\n getGridTemplateColumns(featureType.attributes)\n \"\n data-cy=\"feature-type-content\"\n >\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"py-1 px-2 text-sm font-bold text-left border-t break-all\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n [ngClass]=\"col.class || ''\"\n data-test=\"column-label\"\n >\n {{ 'feature.catalog.attribute.' + col.key | translate }}\n </div>\n }\n @if (expanel && !expanel.collapsed) {\n @for (row of featureType.attributes; track row) {\n @for (\n col of getColumnsDefinition(featureType.attributes);\n track trackByColumn(i, col);\n let i = $index\n ) {\n <div\n class=\"bg-white text-sm font-normal text-left border-t\"\n [class.border-l]=\"i > 0\"\n [class.border-gray-300]=\"i > 0\"\n data-test=\"cell-content\"\n >\n @if (col.key === 'values') {\n @if (row.values?.length > 0) {\n <gn-ui-cell-popin\n #popinRef\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n >\n <div\n cellContent\n data-cy=\"values-cell-popin-trigger\"\n >\n <gn-ui-button\n type=\"light\"\n extraClass=\"bg-transparent border-none\"\n (buttonClick)=\"popinRef.openOverlay()\"\n >\n <ng-icon name=\"iconoirList\" size=\"24\"></ng-icon>\n </gn-ui-button>\n </div>\n <div\n popinContent\n class=\"max-h-60 overflow-y-auto min-w-64 py-4 px-6\"\n style=\"scrollbar-width: thin\"\n >\n <ul class=\"list-disc list-inside mr-4\">\n @for (v of row.values; track v) {\n <li>\n {{ v.label || v.value }}\n </li>\n }\n </ul>\n </div>\n </gn-ui-cell-popin>\n }\n } @else {\n <gn-ui-truncated-text\n [scrollContainer]=\"scrollContainer\"\n [cdkScrollContainer]=\"scrollable\"\n [text]=\"row[col.key]\"\n ></gn-ui-truncated-text>\n }\n </div>\n }\n }\n }\n </div>\n }\n </gn-ui-expandable-panel>\n </div>\n }\n </div>\n</div>\n" }]
30260
30357
  }], propDecorators: { filteredFeatureCatalog: [{
30261
30358
  type: Input
30262
30359
  }], scrollContainer: [{
@@ -36468,6 +36565,15 @@ const DEFAULT_CONFIGURATION = {
36468
36565
  labelKey: marker('editor.record.form.field.title'),
36469
36566
  },
36470
36567
  },
36568
+ {
36569
+ model: 'flags',
36570
+ modelSpecifier: 'flags:IS_REFERENCE_DATASET',
36571
+ formFieldConfig: {
36572
+ labelKey: marker('editor.record.form.field.flags.IS_REFERENCE_DATASET'),
36573
+ hintKey: marker('editor.record.form.field.hint.flags.IS_REFERENCE_DATASET'),
36574
+ },
36575
+ hidden: '${record.kind != "dataset" || !user.isAdmin}',
36576
+ },
36471
36577
  {
36472
36578
  model: 'abstract',
36473
36579
  formFieldConfig: {
@@ -39352,6 +39458,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
39352
39458
  type: Output
39353
39459
  }] } });
39354
39460
 
39461
+ class FormFieldRecordFlagComponent {
39462
+ constructor() {
39463
+ this.flagName = input(...(ngDevMode ? [undefined, { debugName: "flagName" }] : []));
39464
+ this.labelKey = input(...(ngDevMode ? [undefined, { debugName: "labelKey" }] : []));
39465
+ this.hintKey = input(...(ngDevMode ? [undefined, { debugName: "hintKey" }] : []));
39466
+ this.editorFacade = inject(EditorFacade);
39467
+ this.repository = inject(RecordsRepositoryInterface);
39468
+ this.notificationsService = inject(NotificationsService);
39469
+ this.translateService = inject(TranslateService);
39470
+ this.record = toSignal(this.editorFacade.record$);
39471
+ this.recordKind = toSignal(this.editorFacade.record$.pipe(map$1((record) => record.kind)));
39472
+ this.initialValue$ = this.editorFacade.record$.pipe(filter((record) => !!record), switchMap$1((record) => this.repository.getRecordFlag(record.uniqueIdentifier, this.flagName())));
39473
+ }
39474
+ onToggle(enabled) {
39475
+ if (this.record() === null) {
39476
+ return;
39477
+ }
39478
+ this.repository
39479
+ .setRecordFlag(this.record().uniqueIdentifier, this.flagName(), enabled)
39480
+ .subscribe({
39481
+ next: () => {
39482
+ // do nothing
39483
+ },
39484
+ error: (error) => {
39485
+ this.notificationsService.showNotification({
39486
+ type: 'error',
39487
+ title: this.translateService.instant('editor.record.flag.saveError.title'),
39488
+ text: `${this.translateService.instant('editor.record.flag.saveError.body', {
39489
+ recordKind: this.recordKind(),
39490
+ })} ${error.message}`,
39491
+ }, undefined, error);
39492
+ },
39493
+ });
39494
+ }
39495
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldRecordFlagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
39496
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FormFieldRecordFlagComponent, isStandalone: true, selector: "gn-ui-form-field-record-flag", inputs: { flagName: { classPropertyName: "flagName", publicName: "flagName", isSignal: true, isRequired: false, transformFunction: null }, labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, hintKey: { classPropertyName: "hintKey", publicName: "hintKey", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex-1 flex justify-between items-center\">\n <gn-ui-check-toggle\n [label]=\"labelKey() | translate\"\n [value]=\"initialValue$ | async\"\n (toggled)=\"onToggle($event)\"\n [attr.data-cy]=\"'record-flag-toggle-' + flagName()\"\n ></gn-ui-check-toggle>\n\n @if (hintKey()) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"hintKey() | translate\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: CheckToggleComponent, selector: "gn-ui-check-toggle", inputs: ["title", "label", "value", "color"], outputs: ["toggled"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
39497
+ provideIcons({
39498
+ matHelpOutline,
39499
+ }),
39500
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
39501
+ }
39502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldRecordFlagComponent, decorators: [{
39503
+ type: Component,
39504
+ args: [{ selector: 'gn-ui-form-field-record-flag', standalone: true, imports: [AsyncPipe, CheckToggleComponent, TranslatePipe, NgIcon, MatTooltip], viewProviders: [
39505
+ provideIcons({
39506
+ matHelpOutline,
39507
+ }),
39508
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex-1 flex justify-between items-center\">\n <gn-ui-check-toggle\n [label]=\"labelKey() | translate\"\n [value]=\"initialValue$ | async\"\n (toggled)=\"onToggle($event)\"\n [attr.data-cy]=\"'record-flag-toggle-' + flagName()\"\n ></gn-ui-check-toggle>\n\n @if (hintKey()) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"hintKey() | translate\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n</div>\n" }]
39509
+ }], propDecorators: { flagName: [{ type: i0.Input, args: [{ isSignal: true, alias: "flagName", required: false }] }], labelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelKey", required: false }] }], hintKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "hintKey", required: false }] }] } });
39510
+
39355
39511
  class FormFieldComponent {
39356
39512
  constructor() {
39357
39513
  this.valueChange = new EventEmitter();
@@ -39370,6 +39526,7 @@ class FormFieldComponent {
39370
39526
  this.model === 'legalConstraints' ||
39371
39527
  this.model === 'securityConstraints' ||
39372
39528
  this.model === 'otherConstraints' ||
39529
+ this.model === 'flags' ||
39373
39530
  this.componentName === 'form-field-constraints-shortcuts');
39374
39531
  }
39375
39532
  get valueAsString() {
@@ -39409,6 +39566,9 @@ class FormFieldComponent {
39409
39566
  const identifiers = this.value;
39410
39567
  return identifiers?.[0]?.code || '';
39411
39568
  }
39569
+ get recordFlag() {
39570
+ return this.modelSpecifier?.replace(/^flags:/, '');
39571
+ }
39412
39572
  handleResourceIdentifierChange(code) {
39413
39573
  const identifiers = this.value;
39414
39574
  if (!code) {
@@ -39426,7 +39586,7 @@ class FormFieldComponent {
39426
39586
  }
39427
39587
  }
39428
39588
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
39429
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: FormFieldComponent, isStandalone: true, selector: "gn-ui-form-field", inputs: { uniqueIdentifier: "uniqueIdentifier", recordKind: "recordKind", model: "model", modelSpecifier: "modelSpecifier", componentName: "componentName", config: "config", value: "value" }, outputs: { valueChange: "valueChange" }, providers: [provideIcons({ matEditOutline, matHelpOutline })], viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }], hostDirectives: [{ directive: FieldFocusDirective }], ngImport: i0, template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container [ngSwitch]=\"model\">\n <ng-container *ngSwitchCase=\"'title'\">\n <div class=\"flex flex-row flex-start items-center gap-3 mb-[12px]\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder'\n | translate: { recordKind }\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <ng-icon\n name=\"matEditOutline\"\n size=\"16\"\n class=\"m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n ></ng-icon>\n <ng-icon\n *ngIf=\"config.hintKey\"\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"config.hintKey! | translate: { recordKind }\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'abstract'\">\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngSwitchCase=\"'overviews'\">\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [recordKind]=\"recordKind\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceIdentifiers'\">\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceCreated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceUpdated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'updateFrequency'\">\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n [recordKind]=\"recordKind\"\n ></gn-ui-form-field-update-frequency>\n </ng-container>\n <ng-container *ngSwitchCase=\"'associatedRecords'\">\n <gn-ui-form-field-associated-records\n [value]=\"valueAsAssociatedRecords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-associated-records>\n </ng-container>\n <ng-container *ngSwitchCase=\"'temporalExtents'\">\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spatialExtents'\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngSwitchCase=\"'keywords'\">\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n </ng-container>\n <ng-container *ngSwitchCase=\"'topics'\">\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n </ng-container>\n <ng-container *ngSwitchCase=\"'licenses'\">\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'legalConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'securityConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'otherConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container\n ></ng-container>\n <ng-template #formFieldConstraints>\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints\n ></ng-template>\n\n <ng-container *ngSwitchCase=\"'contactsForResource'\">\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'contacts'\">\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n [modelSpecifier]=\"modelSpecifier\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:!link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-link-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-single-link-resource\n *ngIf=\"modelSpecifier === 'onlineResourceType:singleLink'\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-single-link-resource>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!model\">\n <ng-container [ngSwitch]=\"componentName\">\n <ng-container *ngSwitchCase=\"'form-field-constraints-shortcuts'\">\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'form-field-spatial-toggle'\">\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n </ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n", styles: [":host{scroll-margin-top:90px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FormFieldWrapperComponent, selector: "gn-ui-form-field-wrapper", inputs: ["label", "hint"] }, { kind: "component", type: FormFieldLicenseComponent, selector: "gn-ui-form-field-license", inputs: ["label", "recordLicences"], outputs: ["recordLicencesChange"] }, { kind: "component", type: FormFieldDateComponent, selector: "gn-ui-form-field-date", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldUpdateFrequencyComponent, selector: "gn-ui-form-field-update-frequency", inputs: ["value", "recordKind"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldAssociatedRecordsComponent, selector: "gn-ui-form-field-associated-records", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldTemporalExtentsComponent, selector: "gn-ui-form-field-temporal-extents", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: ["type", "readonly", "invalid", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: ["label", "hint", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent" }, { kind: "component", type: FormFieldKeywordsComponent, selector: "gn-ui-form-field-keywords", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOverviewsComponent, selector: "gn-ui-form-field-overviews", inputs: ["metadataUuid", "recordKind", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsForResourceComponent, selector: "gn-ui-form-field-contacts-for-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineResourcesComponent, selector: "gn-ui-form-field-online-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineLinkResourcesComponent, selector: "gn-ui-form-field-online-link-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineSingleLinkResourceComponent, selector: "gn-ui-form-field-online-single-link-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsComponent, selector: "gn-ui-form-field-contacts", inputs: ["value", "modelSpecifier"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsComponent, selector: "gn-ui-form-field-constraints", inputs: ["label", "value", "constraintType"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsShortcutsComponent, selector: "gn-ui-form-field-constraints-shortcuts" }, { kind: "component", type: FormFieldSpatialToggleComponent, selector: "gn-ui-form-field-spatial-toggle" }, { kind: "component", type: FormFieldTopicsComponent, selector: "gn-ui-form-field-topics", inputs: ["value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "directive", type: i4$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
39589
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FormFieldComponent, isStandalone: true, selector: "gn-ui-form-field", inputs: { uniqueIdentifier: "uniqueIdentifier", recordKind: "recordKind", model: "model", modelSpecifier: "modelSpecifier", componentName: "componentName", config: "config", value: "value" }, outputs: { valueChange: "valueChange" }, providers: [provideIcons({ matEditOutline, matHelpOutline })], viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }], hostDirectives: [{ directive: FieldFocusDirective }], ngImport: i0, template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n @if (withoutWrapper) {\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n } @else {\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n }\n</div>\n\n<ng-template #fieldContent>\n @switch (model) {\n @case ('title') {\n <div class=\"flex flex-row flex-start items-center gap-3\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder'\n | translate: { recordKind }\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <ng-icon\n name=\"matEditOutline\"\n size=\"16\"\n class=\"m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n ></ng-icon>\n @if (config.hintKey) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"config.hintKey! | translate: { recordKind }\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n </div>\n </div>\n }\n @case ('abstract') {\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n }\n @case ('overviews') {\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [recordKind]=\"recordKind\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n }\n @case ('resourceIdentifiers') {\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n }\n @case ('resourceCreated') {\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n }\n @case ('resourceUpdated') {\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n }\n @case ('updateFrequency') {\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n [recordKind]=\"recordKind\"\n ></gn-ui-form-field-update-frequency>\n }\n @case ('associatedRecords') {\n <gn-ui-form-field-associated-records\n [value]=\"valueAsAssociatedRecords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-associated-records>\n }\n @case ('temporalExtents') {\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n }\n @case ('spatialExtents') {\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n }\n @case ('keywords') {\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n }\n @case ('topics') {\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n }\n @case ('licenses') {\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n }\n\n <!-- TODO: merge these cases together when migrated to angular 21 -->\n @case ('legalConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n @case ('securityConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n @case ('otherConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n\n @case ('contactsForResource') {\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n }\n @case ('contacts') {\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n [modelSpecifier]=\"modelSpecifier\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n }\n @case ('onlineResources') {\n @if (modelSpecifier === 'onlineResourceType:!link') {\n <gn-ui-form-field-online-resources\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n } @else if (modelSpecifier === 'onlineResourceType:link') {\n <gn-ui-form-field-online-link-resources\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n } @else if (modelSpecifier === 'onlineResourceType:singleLink') {\n <gn-ui-form-field-online-single-link-resource\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-single-link-resource>\n }\n }\n @case ('flags') {\n <gn-ui-form-field-record-flag\n [flagName]=\"recordFlag\"\n [labelKey]=\"config.labelKey\"\n [hintKey]=\"config.hintKey\"\n ></gn-ui-form-field-record-flag>\n }\n }\n\n @if (!model) {\n @switch (componentName) {\n @case ('form-field-constraints-shortcuts') {\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n }\n @case ('form-field-spatial-toggle') {\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n }\n }\n }\n</ng-template>\n", styles: [":host{scroll-margin-top:90px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FormFieldWrapperComponent, selector: "gn-ui-form-field-wrapper", inputs: ["label", "hint"] }, { kind: "component", type: FormFieldLicenseComponent, selector: "gn-ui-form-field-license", inputs: ["label", "recordLicences"], outputs: ["recordLicencesChange"] }, { kind: "component", type: FormFieldDateComponent, selector: "gn-ui-form-field-date", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldUpdateFrequencyComponent, selector: "gn-ui-form-field-update-frequency", inputs: ["value", "recordKind"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldAssociatedRecordsComponent, selector: "gn-ui-form-field-associated-records", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldTemporalExtentsComponent, selector: "gn-ui-form-field-temporal-extents", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: ["type", "readonly", "invalid", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: ["label", "hint", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent" }, { kind: "component", type: FormFieldKeywordsComponent, selector: "gn-ui-form-field-keywords", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOverviewsComponent, selector: "gn-ui-form-field-overviews", inputs: ["metadataUuid", "recordKind", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsForResourceComponent, selector: "gn-ui-form-field-contacts-for-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineResourcesComponent, selector: "gn-ui-form-field-online-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineLinkResourcesComponent, selector: "gn-ui-form-field-online-link-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineSingleLinkResourceComponent, selector: "gn-ui-form-field-online-single-link-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsComponent, selector: "gn-ui-form-field-contacts", inputs: ["value", "modelSpecifier"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsComponent, selector: "gn-ui-form-field-constraints", inputs: ["label", "value", "constraintType"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsShortcutsComponent, selector: "gn-ui-form-field-constraints-shortcuts" }, { kind: "component", type: FormFieldSpatialToggleComponent, selector: "gn-ui-form-field-spatial-toggle" }, { kind: "component", type: FormFieldTopicsComponent, selector: "gn-ui-form-field-topics", inputs: ["value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "directive", type: i4$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: FormFieldRecordFlagComponent, selector: "gn-ui-form-field-record-flag", inputs: ["flagName", "labelKey", "hintKey"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
39430
39590
  }
39431
39591
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FormFieldComponent, decorators: [{
39432
39592
  type: Component,
@@ -39456,7 +39616,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
39456
39616
  FormFieldTopicsComponent,
39457
39617
  TextFieldModule,
39458
39618
  NgIconComponent,
39459
- ], providers: [provideIcons({ matEditOutline, matHelpOutline })], hostDirectives: [FieldFocusDirective], template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container [ngSwitch]=\"model\">\n <ng-container *ngSwitchCase=\"'title'\">\n <div class=\"flex flex-row flex-start items-center gap-3 mb-[12px]\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder'\n | translate: { recordKind }\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <ng-icon\n name=\"matEditOutline\"\n size=\"16\"\n class=\"m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n ></ng-icon>\n <ng-icon\n *ngIf=\"config.hintKey\"\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"config.hintKey! | translate: { recordKind }\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'abstract'\">\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngSwitchCase=\"'overviews'\">\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [recordKind]=\"recordKind\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceIdentifiers'\">\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceCreated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceUpdated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'updateFrequency'\">\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n [recordKind]=\"recordKind\"\n ></gn-ui-form-field-update-frequency>\n </ng-container>\n <ng-container *ngSwitchCase=\"'associatedRecords'\">\n <gn-ui-form-field-associated-records\n [value]=\"valueAsAssociatedRecords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-associated-records>\n </ng-container>\n <ng-container *ngSwitchCase=\"'temporalExtents'\">\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spatialExtents'\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngSwitchCase=\"'keywords'\">\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n </ng-container>\n <ng-container *ngSwitchCase=\"'topics'\">\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n </ng-container>\n <ng-container *ngSwitchCase=\"'licenses'\">\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'legalConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'securityConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'otherConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container\n ></ng-container>\n <ng-template #formFieldConstraints>\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints\n ></ng-template>\n\n <ng-container *ngSwitchCase=\"'contactsForResource'\">\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'contacts'\">\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n [modelSpecifier]=\"modelSpecifier\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:!link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-link-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-single-link-resource\n *ngIf=\"modelSpecifier === 'onlineResourceType:singleLink'\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-single-link-resource>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!model\">\n <ng-container [ngSwitch]=\"componentName\">\n <ng-container *ngSwitchCase=\"'form-field-constraints-shortcuts'\">\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'form-field-spatial-toggle'\">\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n </ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n", styles: [":host{scroll-margin-top:90px}\n"] }]
39619
+ FormFieldRecordFlagComponent,
39620
+ ], providers: [provideIcons({ matEditOutline, matHelpOutline })], hostDirectives: [FieldFocusDirective], template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n @if (withoutWrapper) {\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n } @else {\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n }\n</div>\n\n<ng-template #fieldContent>\n @switch (model) {\n @case ('title') {\n <div class=\"flex flex-row flex-start items-center gap-3\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder'\n | translate: { recordKind }\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <ng-icon\n name=\"matEditOutline\"\n size=\"16\"\n class=\"m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n ></ng-icon>\n @if (config.hintKey) {\n <ng-icon\n name=\"matHelpOutline\"\n size=\"16\"\n class=\"m-2\"\n [matTooltip]=\"config.hintKey! | translate: { recordKind }\"\n matTooltipPosition=\"above\"\n ></ng-icon>\n }\n </div>\n </div>\n }\n @case ('abstract') {\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [hint]=\"config.hintKey! | translate: { recordKind }\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n }\n @case ('overviews') {\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [recordKind]=\"recordKind\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n }\n @case ('resourceIdentifiers') {\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n }\n @case ('resourceCreated') {\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n }\n @case ('resourceUpdated') {\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n }\n @case ('updateFrequency') {\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n [recordKind]=\"recordKind\"\n ></gn-ui-form-field-update-frequency>\n }\n @case ('associatedRecords') {\n <gn-ui-form-field-associated-records\n [value]=\"valueAsAssociatedRecords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-associated-records>\n }\n @case ('temporalExtents') {\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n }\n @case ('spatialExtents') {\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n }\n @case ('keywords') {\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n }\n @case ('topics') {\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n }\n @case ('licenses') {\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate: { recordKind }\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n }\n\n <!-- TODO: merge these cases together when migrated to angular 21 -->\n @case ('legalConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n @case ('securityConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n @case ('otherConstraints') {\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints>\n }\n\n @case ('contactsForResource') {\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n }\n @case ('contacts') {\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n [modelSpecifier]=\"modelSpecifier\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n }\n @case ('onlineResources') {\n @if (modelSpecifier === 'onlineResourceType:!link') {\n <gn-ui-form-field-online-resources\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n } @else if (modelSpecifier === 'onlineResourceType:link') {\n <gn-ui-form-field-online-link-resources\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n } @else if (modelSpecifier === 'onlineResourceType:singleLink') {\n <gn-ui-form-field-online-single-link-resource\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-single-link-resource>\n }\n }\n @case ('flags') {\n <gn-ui-form-field-record-flag\n [flagName]=\"recordFlag\"\n [labelKey]=\"config.labelKey\"\n [hintKey]=\"config.hintKey\"\n ></gn-ui-form-field-record-flag>\n }\n }\n\n @if (!model) {\n @switch (componentName) {\n @case ('form-field-constraints-shortcuts') {\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n }\n @case ('form-field-spatial-toggle') {\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n }\n }\n }\n</ng-template>\n", styles: [":host{scroll-margin-top:90px}\n"] }]
39460
39621
  }], propDecorators: { uniqueIdentifier: [{
39461
39622
  type: Input
39462
39623
  }], recordKind: [{
@@ -39487,9 +39648,13 @@ const TOKEN_OPERATOR_LOGICAL = ['==', '!='];
39487
39648
  const TOKEN_STRING_LITERAL = ["'", '"'];
39488
39649
  const TOKEN_GROUP_START = '(';
39489
39650
  const TOKEN_GROUP_END = ')';
39651
+ const TOKEN_OPERATOR_BOOLEAN = ['&&', '||'];
39652
+ const TOKEN_OPERATOR_NOT = '!';
39490
39653
  // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence
39491
39654
  const OPERATORS_BY_PRECEDENCE = [
39492
39655
  [TOKEN_OPERATOR_TERNARY_FIRST, TOKEN_OPERATOR_TERNARY_SECOND],
39656
+ TOKEN_OPERATOR_BOOLEAN,
39657
+ [TOKEN_OPERATOR_NOT],
39493
39658
  TOKEN_OPERATOR_LOGICAL,
39494
39659
  ];
39495
39660
  const ALL_OPERATORS = OPERATORS_BY_PRECEDENCE.flat();
@@ -39599,6 +39764,16 @@ function evaluateInternal(expression, currentContext) {
39599
39764
  pos++;
39600
39765
  continue;
39601
39766
  }
39767
+ // BOOLEAN LITERAL
39768
+ const isBooleanLiteral = readNext(expression, pos, 4) === 'true' ||
39769
+ readNext(expression, pos, 5) === 'false';
39770
+ if (isBooleanLiteral) {
39771
+ const literal = readNext(expression, pos, 4) === 'true' ? 'true' : 'false';
39772
+ pos += literal.length;
39773
+ const booleanLiteral = literal === 'true';
39774
+ currentEvaluator = () => booleanLiteral;
39775
+ continue;
39776
+ }
39602
39777
  // SYMBOL (NAME)
39603
39778
  const isSymbol = /[a-zA-Z]/.test(readNext(expression, pos));
39604
39779
  if (isSymbol) {
@@ -39689,6 +39864,35 @@ function evaluateInternal(expression, currentContext) {
39689
39864
  };
39690
39865
  continue;
39691
39866
  }
39867
+ // BOOLEAN OPERATORS
39868
+ const isBooleanOperator = TOKEN_OPERATOR_BOOLEAN.some((token) => readNext(expression, pos, token.length) === token);
39869
+ if (isBooleanOperator) {
39870
+ const matchingOperator = TOKEN_OPERATOR_BOOLEAN.find((token) => readNext(expression, pos, token.length) === token);
39871
+ const isAnd = matchingOperator === '&&';
39872
+ pos += matchingOperator.length;
39873
+ const leftEvaluator = currentEvaluator;
39874
+ const rightExpression = readUntilNextOperator(expression, pos, matchingOperator);
39875
+ pos += rightExpression.length;
39876
+ const rightEvaluator = evaluateInternal(rightExpression, currentContext).evaluator;
39877
+ currentEvaluator = (context) => {
39878
+ return isAnd
39879
+ ? Boolean(leftEvaluator(context) && rightEvaluator(context))
39880
+ : Boolean(leftEvaluator(context) || rightEvaluator(context));
39881
+ };
39882
+ continue;
39883
+ }
39884
+ // PREFIX OPERATORS
39885
+ const isNotOperator = readNext(expression, pos) === TOKEN_OPERATOR_NOT;
39886
+ if (isNotOperator) {
39887
+ pos++;
39888
+ const operandExpression = readUntilNextOperator(expression, pos, TOKEN_OPERATOR_NOT);
39889
+ pos += operandExpression.length;
39890
+ const operandEvaluator = evaluateInternal(operandExpression, currentContext).evaluator;
39891
+ currentEvaluator = (context) => {
39892
+ return !operandEvaluator(context);
39893
+ };
39894
+ continue;
39895
+ }
39692
39896
  // TERNARY OPERATOR
39693
39897
  const isTernary = readNext(expression, pos) === TOKEN_OPERATOR_TERNARY_FIRST;
39694
39898
  if (isTernary) {
@@ -39759,6 +39963,7 @@ class RecordFormComponent {
39759
39963
  constructor() {
39760
39964
  this.facade = inject(EditorFacade);
39761
39965
  this.notifications = inject(NotificationsService);
39966
+ this.platform = inject(PlatformServiceInterface);
39762
39967
  this.subscription = new Subscription();
39763
39968
  this.recordUniqueIdentifier$ = this.facade.record$.pipe(map$2((record) => record.uniqueIdentifier));
39764
39969
  this.recordKind$ = this.facade.record$.pipe(map$2((record) => record.kind));
@@ -39769,6 +39974,8 @@ class RecordFormComponent {
39769
39974
  this.formFields = viewChildren(FormFieldComponent, ...(ngDevMode ? [{ debugName: "formFields" }] : []));
39770
39975
  this.sectionFocusDirectives = viewChildren('sectionFocus', ...(ngDevMode ? [{ debugName: "sectionFocusDirectives" }] : []));
39771
39976
  this.recordSignal = toSignal(this.facade.record$, { requireSync: true });
39977
+ this.userSignal = toSignal(this.platform.getMe());
39978
+ this.isAdminSignal = toSignal(this.platform.isAdministrator());
39772
39979
  this.expressionCache = new Map();
39773
39980
  }
39774
39981
  focusField(model, sectionIndex) {
@@ -39793,7 +40000,7 @@ class RecordFormComponent {
39793
40000
  this.subscription.unsubscribe();
39794
40001
  }
39795
40002
  handleFieldValueChange(model, newValue) {
39796
- if (!model) {
40003
+ if (!model || model === 'flags') {
39797
40004
  return;
39798
40005
  }
39799
40006
  this.facade.updateRecordField(model, newValue);
@@ -39836,7 +40043,15 @@ ${errors.map((err) => `> ${err}`).join('\n')}`);
39836
40043
  text: 'An error happened while evaluating an expression inside the editor configuration; open the developer console for more information',
39837
40044
  });
39838
40045
  }
39839
- this.expressionCache.set(expression, computed(() => evaluator({ globals: { record: this.recordSignal() } })));
40046
+ this.expressionCache.set(expression, computed(() => evaluator({
40047
+ globals: {
40048
+ record: this.recordSignal(),
40049
+ user: {
40050
+ ...this.userSignal(),
40051
+ isAdmin: this.isAdminSignal(),
40052
+ },
40053
+ },
40054
+ })));
39840
40055
  return this.expressionCache.get(expression);
39841
40056
  }
39842
40057
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RecordFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }