@praxisui/core 9.0.0-beta.3 → 9.0.0-beta.31
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/ai/component-registry.json +3473 -0
- package/fesm2022/praxisui-core.mjs +2389 -404
- package/package.json +6 -2
- package/types/praxisui-core.d.ts +605 -31
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, InjectionToken, Injectable, inject, Inject, Optional, makeEnvironmentProviders, signal, computed, DestroyRef, ENVIRONMENT_INITIALIZER,
|
|
2
|
+
import { Component, InjectionToken, Injectable, inject, Inject, Optional, makeEnvironmentProviders, APP_INITIALIZER, signal, computed, DestroyRef, ENVIRONMENT_INITIALIZER, ErrorHandler, EventEmitter, Output, Input, ChangeDetectionStrategy, Directive, SecurityContext, ViewContainerRef, SimpleChange, ContentChild, HostBinding, HostListener, ViewChildren, ViewChild } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common/http';
|
|
4
4
|
import { HttpHeaders, HttpClient, HttpParams, HttpResponse, HttpContextToken, HTTP_INTERCEPTORS, withInterceptors } from '@angular/common/http';
|
|
5
5
|
import { of, defer, throwError, from, EMPTY, BehaviorSubject, firstValueFrom, Subject, map as map$1, switchMap as switchMap$1 } from 'rxjs';
|
|
@@ -202,9 +202,12 @@ function collectEntityLookupIds(value) {
|
|
|
202
202
|
}
|
|
203
203
|
function buildEntityLookupEntityRef(value, entityType) {
|
|
204
204
|
const id = extractEntityLookupId(value);
|
|
205
|
-
if (id === null
|
|
206
|
-
return
|
|
207
|
-
|
|
205
|
+
if (id === null)
|
|
206
|
+
return null;
|
|
207
|
+
if (id === undefined)
|
|
208
|
+
return undefined;
|
|
209
|
+
if (id === '')
|
|
210
|
+
return '';
|
|
208
211
|
const explicitType = typeof value === 'object' &&
|
|
209
212
|
value !== null &&
|
|
210
213
|
!Array.isArray(value) &&
|
|
@@ -797,6 +800,85 @@ function resolveControlTypeAlias(value, fallback = FieldControlType.INPUT) {
|
|
|
797
800
|
return raw;
|
|
798
801
|
}
|
|
799
802
|
|
|
803
|
+
function normalizeFieldAccessMetadata(value) {
|
|
804
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
805
|
+
return undefined;
|
|
806
|
+
}
|
|
807
|
+
const source = value;
|
|
808
|
+
const visibleForAuthorities = normalizeAuthorityList(source['visibleForAuthorities']);
|
|
809
|
+
const editableForAuthorities = normalizeAuthorityList(source['editableForAuthorities']);
|
|
810
|
+
const reason = typeof source['reason'] === 'string' && source['reason'].trim()
|
|
811
|
+
? source['reason'].trim()
|
|
812
|
+
: undefined;
|
|
813
|
+
if (!visibleForAuthorities && !editableForAuthorities) {
|
|
814
|
+
return undefined;
|
|
815
|
+
}
|
|
816
|
+
return {
|
|
817
|
+
...(visibleForAuthorities ? { visibleForAuthorities } : {}),
|
|
818
|
+
...(editableForAuthorities ? { editableForAuthorities } : {}),
|
|
819
|
+
...(reason ? { reason } : {}),
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
function evaluateFieldAccess(fieldOrAccess, context = {}) {
|
|
823
|
+
const fieldAccess = normalizeFieldAccessMetadata(isFieldAccessMetadata(fieldOrAccess)
|
|
824
|
+
? fieldOrAccess
|
|
825
|
+
: fieldOrAccess?.fieldAccess);
|
|
826
|
+
if (!fieldAccess) {
|
|
827
|
+
return { evaluated: false, visible: true, editable: true };
|
|
828
|
+
}
|
|
829
|
+
const authorities = normalizeAuthoritySet(context.authorities);
|
|
830
|
+
if (!authorities) {
|
|
831
|
+
return {
|
|
832
|
+
evaluated: false,
|
|
833
|
+
visible: true,
|
|
834
|
+
editable: true,
|
|
835
|
+
...(fieldAccess.reason ? { reason: fieldAccess.reason } : {}),
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
const hasExplicitEditablePolicy = !!fieldAccess.editableForAuthorities?.length;
|
|
839
|
+
const editableAllowed = hasExplicitEditablePolicy
|
|
840
|
+
? matchesAuthority(fieldAccess.editableForAuthorities, authorities)
|
|
841
|
+
: false;
|
|
842
|
+
const visibleAllowed = matchesAuthority(fieldAccess.visibleForAuthorities, authorities) ||
|
|
843
|
+
editableAllowed;
|
|
844
|
+
return {
|
|
845
|
+
evaluated: true,
|
|
846
|
+
visible: visibleAllowed,
|
|
847
|
+
editable: editableAllowed || !hasExplicitEditablePolicy,
|
|
848
|
+
...(fieldAccess.reason ? { reason: fieldAccess.reason } : {}),
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
function isFieldAccessMetadata(value) {
|
|
852
|
+
return !!value && ('visibleForAuthorities' in value ||
|
|
853
|
+
'editableForAuthorities' in value ||
|
|
854
|
+
'reason' in value);
|
|
855
|
+
}
|
|
856
|
+
function normalizeAuthorityList(value) {
|
|
857
|
+
if (!Array.isArray(value)) {
|
|
858
|
+
return undefined;
|
|
859
|
+
}
|
|
860
|
+
const normalized = Array.from(new Set(value
|
|
861
|
+
.filter((item) => typeof item === 'string')
|
|
862
|
+
.map((item) => item.trim())
|
|
863
|
+
.filter(Boolean)));
|
|
864
|
+
return normalized.length ? normalized : undefined;
|
|
865
|
+
}
|
|
866
|
+
function normalizeAuthoritySet(authorities) {
|
|
867
|
+
if (!Array.isArray(authorities)) {
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
return new Set(authorities
|
|
871
|
+
.filter((item) => typeof item === 'string')
|
|
872
|
+
.map((item) => item.trim())
|
|
873
|
+
.filter(Boolean));
|
|
874
|
+
}
|
|
875
|
+
function matchesAuthority(required, actual) {
|
|
876
|
+
if (!required || required.length === 0) {
|
|
877
|
+
return true;
|
|
878
|
+
}
|
|
879
|
+
return required.some((authority) => actual.has(authority));
|
|
880
|
+
}
|
|
881
|
+
|
|
800
882
|
const VALUE_PRESENTATION_TYPES = new Set([
|
|
801
883
|
'string',
|
|
802
884
|
'number',
|
|
@@ -1967,6 +2049,10 @@ class SchemaNormalizerService {
|
|
|
1967
2049
|
if (ui.editable !== undefined) {
|
|
1968
2050
|
field.editable = this.parseBoolean(ui.editable);
|
|
1969
2051
|
}
|
|
2052
|
+
const fieldAccess = normalizeFieldAccessMetadata(ui.fieldAccess);
|
|
2053
|
+
if (fieldAccess) {
|
|
2054
|
+
field.fieldAccess = fieldAccess;
|
|
2055
|
+
}
|
|
1970
2056
|
if (ui.inlineEditing !== undefined) {
|
|
1971
2057
|
field.inlineEditing = this.parseBoolean(ui.inlineEditing);
|
|
1972
2058
|
}
|
|
@@ -2020,6 +2106,9 @@ class SchemaNormalizerService {
|
|
|
2020
2106
|
if (ui.helpText !== undefined) {
|
|
2021
2107
|
field.helpText = String(ui.helpText);
|
|
2022
2108
|
}
|
|
2109
|
+
if (ui.tooltip !== undefined) {
|
|
2110
|
+
field.tooltip = String(ui.tooltip);
|
|
2111
|
+
}
|
|
2023
2112
|
if (ui.hint !== undefined) {
|
|
2024
2113
|
field.hint = ui.hint;
|
|
2025
2114
|
}
|
|
@@ -3121,13 +3210,17 @@ class GenericCrudService {
|
|
|
3121
3210
|
if (!this.schemaCacheReady) {
|
|
3122
3211
|
this.schemaCacheReady = (async () => {
|
|
3123
3212
|
try {
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3213
|
+
if (typeof this.globalConfig?.ready === 'function') {
|
|
3214
|
+
await Promise.race([
|
|
3215
|
+
this.globalConfig.ready(),
|
|
3216
|
+
new Promise((resolve) => setTimeout(resolve, SCHEMA_CACHE_GLOBAL_CONFIG_READY_TIMEOUT_MS)),
|
|
3217
|
+
]);
|
|
3218
|
+
}
|
|
3128
3219
|
}
|
|
3129
3220
|
catch { }
|
|
3130
|
-
const disableCache = this.globalConfig
|
|
3221
|
+
const disableCache = typeof this.globalConfig?.get === 'function'
|
|
3222
|
+
? this.globalConfig.get('cache.disableSchemaCache')
|
|
3223
|
+
: false;
|
|
3131
3224
|
if (disableCache) {
|
|
3132
3225
|
console.debug('[CRUD:Service] Schema cache persistence is disabled by config (using MemoryCacheAdapter).');
|
|
3133
3226
|
this._schemaCache = new MemoryCacheAdapter();
|
|
@@ -5533,15 +5626,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5533
5626
|
}], ctorParameters: () => [] });
|
|
5534
5627
|
|
|
5535
5628
|
function buildBaseColumnFromDef(def) {
|
|
5629
|
+
const type = resolveColumnTypeFromFieldDefinition(def);
|
|
5630
|
+
const format = type === 'string' ? resolveTextMaskFormatFromFieldDefinition(def) : undefined;
|
|
5536
5631
|
return {
|
|
5537
5632
|
field: def.name,
|
|
5538
5633
|
header: def.label || def.name,
|
|
5539
|
-
type
|
|
5634
|
+
type,
|
|
5540
5635
|
visible: def.tableHidden === true ? false : true,
|
|
5541
5636
|
sortable: def.sortable !== false,
|
|
5542
5637
|
filterable: def.filterable === true,
|
|
5543
5638
|
resizable: true,
|
|
5544
5639
|
order: typeof def.order === 'number' ? def.order : undefined,
|
|
5640
|
+
...(format ? { format } : {}),
|
|
5545
5641
|
};
|
|
5546
5642
|
}
|
|
5547
5643
|
function applyLocalCustomizations$2(baseCol, localCol) {
|
|
@@ -5575,9 +5671,10 @@ function applyLocalCustomizations$2(baseCol, localCol) {
|
|
|
5575
5671
|
result.renderer = localCol.renderer ?? baseCol.renderer;
|
|
5576
5672
|
}
|
|
5577
5673
|
else {
|
|
5578
|
-
//
|
|
5579
|
-
|
|
5580
|
-
result.
|
|
5674
|
+
// Drop local presentation that may be incompatible with the new server type,
|
|
5675
|
+
// but keep canonical server presentation for the resolved type.
|
|
5676
|
+
result.format = baseCol.format;
|
|
5677
|
+
result.valueMapping = baseCol.valueMapping;
|
|
5581
5678
|
result.renderer = undefined;
|
|
5582
5679
|
}
|
|
5583
5680
|
return result;
|
|
@@ -5603,15 +5700,121 @@ function reconcileTableConfig(layout, serverDefs) {
|
|
|
5603
5700
|
};
|
|
5604
5701
|
return next;
|
|
5605
5702
|
}
|
|
5606
|
-
function
|
|
5607
|
-
const
|
|
5608
|
-
if (
|
|
5703
|
+
function resolveColumnTypeFromFieldDefinition(def, fallback) {
|
|
5704
|
+
const semanticType = resolveSemanticColumnTypeFromFieldDefinition(def);
|
|
5705
|
+
if (resolveTextMaskFormatFromFieldDefinition(def) &&
|
|
5706
|
+
shouldUseTextMaskForColumn(def, semanticType)) {
|
|
5707
|
+
return 'string';
|
|
5708
|
+
}
|
|
5709
|
+
if (semanticType)
|
|
5710
|
+
return semanticType;
|
|
5711
|
+
if (fallback)
|
|
5712
|
+
return fallback;
|
|
5713
|
+
return 'string';
|
|
5714
|
+
}
|
|
5715
|
+
function resolveSemanticColumnTypeFromFieldDefinition(def) {
|
|
5716
|
+
const controlType = normalizePresentationToken(def.controlType);
|
|
5717
|
+
const numericFormat = normalizePresentationToken(def.numericFormat ?? def.format);
|
|
5718
|
+
const valuePresentationType = normalizePresentationToken(def.valuePresentation?.type);
|
|
5719
|
+
const dataType = normalizePresentationToken(def.type);
|
|
5720
|
+
if (valuePresentationType === 'currency')
|
|
5721
|
+
return 'currency';
|
|
5722
|
+
if (valuePresentationType === 'percent' || valuePresentationType === 'percentage')
|
|
5723
|
+
return 'percentage';
|
|
5724
|
+
if (valuePresentationType === 'date' || valuePresentationType === 'datetime' || valuePresentationType === 'time')
|
|
5609
5725
|
return 'date';
|
|
5610
|
-
if (
|
|
5726
|
+
if (valuePresentationType === 'boolean')
|
|
5611
5727
|
return 'boolean';
|
|
5612
|
-
if (
|
|
5728
|
+
if (valuePresentationType === 'number')
|
|
5613
5729
|
return 'number';
|
|
5614
|
-
|
|
5730
|
+
if (valuePresentationType === 'string')
|
|
5731
|
+
return 'string';
|
|
5732
|
+
if (numericFormat === 'currency' || controlType === 'currency')
|
|
5733
|
+
return 'currency';
|
|
5734
|
+
if (numericFormat === 'percent' || numericFormat === 'percentage')
|
|
5735
|
+
return 'percentage';
|
|
5736
|
+
if (numericFormat === 'date' || numericFormat === 'datetime')
|
|
5737
|
+
return 'date';
|
|
5738
|
+
if (controlType === 'numerictextbox' || controlType === 'inlinenumber')
|
|
5739
|
+
return 'number';
|
|
5740
|
+
if (controlType === 'checkbox' || controlType === 'toggle' || controlType === 'inlinetoggle')
|
|
5741
|
+
return 'boolean';
|
|
5742
|
+
if (controlType.includes('date') || controlType === 'time' || controlType === 'timepicker')
|
|
5743
|
+
return 'date';
|
|
5744
|
+
if (isColumnType(dataType))
|
|
5745
|
+
return dataType;
|
|
5746
|
+
if (dataType === 'text' || dataType === 'email' || dataType === 'url' || dataType === 'password')
|
|
5747
|
+
return 'string';
|
|
5748
|
+
if (dataType.includes('date') || dataType === 'time')
|
|
5749
|
+
return 'date';
|
|
5750
|
+
if (dataType.includes('bool'))
|
|
5751
|
+
return 'boolean';
|
|
5752
|
+
if (dataType.includes('number') ||
|
|
5753
|
+
dataType.includes('int') ||
|
|
5754
|
+
dataType.includes('decimal') ||
|
|
5755
|
+
dataType.includes('double') ||
|
|
5756
|
+
dataType.includes('float')) {
|
|
5757
|
+
return 'number';
|
|
5758
|
+
}
|
|
5759
|
+
if (isTextualControlType(controlType))
|
|
5760
|
+
return 'string';
|
|
5761
|
+
return undefined;
|
|
5762
|
+
}
|
|
5763
|
+
function shouldUseTextMaskForColumn(def, semanticType) {
|
|
5764
|
+
if (!semanticType || semanticType === 'string')
|
|
5765
|
+
return true;
|
|
5766
|
+
const controlType = normalizePresentationToken(def.controlType);
|
|
5767
|
+
if (isTextualControlType(controlType))
|
|
5768
|
+
return true;
|
|
5769
|
+
if (['date', 'boolean', 'currency', 'percentage', 'custom'].includes(semanticType)) {
|
|
5770
|
+
return false;
|
|
5771
|
+
}
|
|
5772
|
+
const valuePresentationType = normalizePresentationToken(def.valuePresentation?.type);
|
|
5773
|
+
const numericFormat = normalizePresentationToken(def.numericFormat ?? def.format);
|
|
5774
|
+
return !valuePresentationType && !numericFormat;
|
|
5775
|
+
}
|
|
5776
|
+
function resolveTextMaskFormatFromFieldDefinition(def) {
|
|
5777
|
+
return resolveTextMaskFormat(def.mask ??
|
|
5778
|
+
def.displayMask ??
|
|
5779
|
+
def.inputMask ??
|
|
5780
|
+
def.extraProperties?.mask);
|
|
5781
|
+
}
|
|
5782
|
+
function resolveTextMaskFormat(value) {
|
|
5783
|
+
if (typeof value !== 'string')
|
|
5784
|
+
return undefined;
|
|
5785
|
+
const format = value.trim();
|
|
5786
|
+
if (!format)
|
|
5787
|
+
return undefined;
|
|
5788
|
+
const hasMaskTokens = /[0#9Xx]/.test(format);
|
|
5789
|
+
const hasInvalidMaskLetters = /[A-WYZa-wyz]/.test(format);
|
|
5790
|
+
return hasMaskTokens && !hasInvalidMaskLetters ? format : undefined;
|
|
5791
|
+
}
|
|
5792
|
+
function normalizePresentationToken(value) {
|
|
5793
|
+
return String(value ?? '').trim().toLowerCase().replace(/[\s_-]+/g, '');
|
|
5794
|
+
}
|
|
5795
|
+
function isColumnType(value) {
|
|
5796
|
+
return [
|
|
5797
|
+
'string',
|
|
5798
|
+
'number',
|
|
5799
|
+
'date',
|
|
5800
|
+
'boolean',
|
|
5801
|
+
'currency',
|
|
5802
|
+
'percentage',
|
|
5803
|
+
'custom',
|
|
5804
|
+
].includes(value);
|
|
5805
|
+
}
|
|
5806
|
+
function isTextualControlType(value) {
|
|
5807
|
+
return [
|
|
5808
|
+
'input',
|
|
5809
|
+
'inlineinput',
|
|
5810
|
+
'textarea',
|
|
5811
|
+
'search',
|
|
5812
|
+
'email',
|
|
5813
|
+
'url',
|
|
5814
|
+
'phone',
|
|
5815
|
+
'cpfcnpjinput',
|
|
5816
|
+
'password',
|
|
5817
|
+
].includes(value);
|
|
5615
5818
|
}
|
|
5616
5819
|
|
|
5617
5820
|
const PRAXIS_I18N_CONFIG = new InjectionToken('PRAXIS_I18N_CONFIG', {
|
|
@@ -6331,7 +6534,7 @@ const GLOBAL_SURFACE_SERVICE = new InjectionToken('GLOBAL_SURFACE_SERVICE');
|
|
|
6331
6534
|
|
|
6332
6535
|
const dialogBaseFields = [
|
|
6333
6536
|
{ key: 'message', label: 'Mensagem', type: 'textarea', rows: 2, placeholder: 'Texto principal' },
|
|
6334
|
-
{ key: 'title', label: '
|
|
6537
|
+
{ key: 'title', label: 'Título', type: 'text', placeholder: 'Título do diálogo' },
|
|
6335
6538
|
{
|
|
6336
6539
|
key: 'themeColor',
|
|
6337
6540
|
label: 'Tema',
|
|
@@ -6342,13 +6545,13 @@ const dialogBaseFields = [
|
|
|
6342
6545
|
{ value: 'dark', label: 'Dark' },
|
|
6343
6546
|
],
|
|
6344
6547
|
},
|
|
6345
|
-
{ key: 'positionTop', label: '
|
|
6346
|
-
{ key: 'positionRight', label: '
|
|
6347
|
-
{ key: 'positionBottom', label: '
|
|
6348
|
-
{ key: 'positionLeft', label: '
|
|
6548
|
+
{ key: 'positionTop', label: 'Posição topo', type: 'text', placeholder: '12px' },
|
|
6549
|
+
{ key: 'positionRight', label: 'Posição direita', type: 'text', placeholder: '12px' },
|
|
6550
|
+
{ key: 'positionBottom', label: 'Posição base', type: 'text', placeholder: '12px' },
|
|
6551
|
+
{ key: 'positionLeft', label: 'Posição esquerda', type: 'text', placeholder: '12px' },
|
|
6349
6552
|
{
|
|
6350
6553
|
key: 'actionsLayout',
|
|
6351
|
-
label: 'Layout das
|
|
6554
|
+
label: 'Layout das ações',
|
|
6352
6555
|
type: 'select',
|
|
6353
6556
|
options: [
|
|
6354
6557
|
{ value: 'start', label: 'Start' },
|
|
@@ -6359,7 +6562,7 @@ const dialogBaseFields = [
|
|
|
6359
6562
|
},
|
|
6360
6563
|
{
|
|
6361
6564
|
key: 'animationType',
|
|
6362
|
-
label: '
|
|
6565
|
+
label: 'Animação',
|
|
6363
6566
|
type: 'select',
|
|
6364
6567
|
options: [
|
|
6365
6568
|
{ value: 'translate', label: 'Translate' },
|
|
@@ -6371,7 +6574,7 @@ const dialogBaseFields = [
|
|
|
6371
6574
|
},
|
|
6372
6575
|
{
|
|
6373
6576
|
key: 'animationDirection',
|
|
6374
|
-
label: '
|
|
6577
|
+
label: 'Direção animação',
|
|
6375
6578
|
type: 'select',
|
|
6376
6579
|
options: [
|
|
6377
6580
|
{ value: 'up', label: 'Up' },
|
|
@@ -6380,13 +6583,13 @@ const dialogBaseFields = [
|
|
|
6380
6583
|
{ value: 'right', label: 'Right' },
|
|
6381
6584
|
],
|
|
6382
6585
|
},
|
|
6383
|
-
{ key: 'animationDuration', label: '
|
|
6586
|
+
{ key: 'animationDuration', label: 'Duração (ms)', type: 'number', placeholder: '300' },
|
|
6384
6587
|
{ key: 'width', label: 'Largura', type: 'text', placeholder: '480px' },
|
|
6385
6588
|
{ key: 'height', label: 'Altura', type: 'text', placeholder: 'auto' },
|
|
6386
|
-
{ key: 'minWidth', label: 'Largura
|
|
6387
|
-
{ key: 'maxWidth', label: 'Largura
|
|
6388
|
-
{ key: 'minHeight', label: 'Altura
|
|
6389
|
-
{ key: 'maxHeight', label: 'Altura
|
|
6589
|
+
{ key: 'minWidth', label: 'Largura mínima', type: 'text', placeholder: '280px' },
|
|
6590
|
+
{ key: 'maxWidth', label: 'Largura máxima', type: 'text', placeholder: '90vw' },
|
|
6591
|
+
{ key: 'minHeight', label: 'Altura mínima', type: 'text', placeholder: '120px' },
|
|
6592
|
+
{ key: 'maxHeight', label: 'Altura máxima', type: 'text', placeholder: '90vh' },
|
|
6390
6593
|
{ key: 'disableClose', label: 'Bloquear fechar', type: 'toggle' },
|
|
6391
6594
|
{ key: 'hasBackdrop', label: 'Backdrop', type: 'toggle' },
|
|
6392
6595
|
{ key: 'closeOnBackdropClick', label: 'Fechar ao clicar no backdrop', type: 'toggle' },
|
|
@@ -6414,7 +6617,7 @@ const dialogFieldsWithModeDependency = dialogFieldsWithoutMessage.map((field) =>
|
|
|
6414
6617
|
...field,
|
|
6415
6618
|
dependsOnKey: field.dependsOnKey ?? 'mode',
|
|
6416
6619
|
dependsOnValue: field.dependsOnValue ?? 'true',
|
|
6417
|
-
hint: field.hint ?? '
|
|
6620
|
+
hint: field.hint ?? 'Disponível quando "Usar diálogo" estiver ativo.',
|
|
6418
6621
|
}));
|
|
6419
6622
|
const GLOBAL_ACTION_UI_SCHEMAS = [
|
|
6420
6623
|
{
|
|
@@ -6462,7 +6665,7 @@ const GLOBAL_ACTION_UI_SCHEMAS = [
|
|
|
6462
6665
|
required: true,
|
|
6463
6666
|
placeholder: 'Texto exibido no alerta simples',
|
|
6464
6667
|
},
|
|
6465
|
-
{ key: 'mode', label: 'Usar
|
|
6668
|
+
{ key: 'mode', label: 'Usar diálogo (avançado)', type: 'toggle' },
|
|
6466
6669
|
...dialogFieldsWithModeDependency,
|
|
6467
6670
|
],
|
|
6468
6671
|
},
|
|
@@ -6481,19 +6684,19 @@ const GLOBAL_ACTION_UI_SCHEMAS = [
|
|
|
6481
6684
|
fields: [
|
|
6482
6685
|
...dialogBaseFields,
|
|
6483
6686
|
{ key: 'placeholder', label: 'Placeholder', type: 'text' },
|
|
6484
|
-
{ key: 'defaultValue', label: 'Valor
|
|
6687
|
+
{ key: 'defaultValue', label: 'Valor padrão', type: 'text' },
|
|
6485
6688
|
{ key: 'okLabel', label: 'Texto OK', type: 'text' },
|
|
6486
6689
|
{ key: 'cancelLabel', label: 'Texto cancelar', type: 'text' },
|
|
6487
6690
|
],
|
|
6488
6691
|
},
|
|
6489
6692
|
{
|
|
6490
6693
|
id: 'dialog.open',
|
|
6491
|
-
label: 'Abrir
|
|
6694
|
+
label: 'Abrir diálogo',
|
|
6492
6695
|
fields: [
|
|
6493
6696
|
...dialogBaseFields,
|
|
6494
6697
|
{
|
|
6495
6698
|
key: 'contentType',
|
|
6496
|
-
label: 'Tipo de
|
|
6699
|
+
label: 'Tipo de conteúdo',
|
|
6497
6700
|
type: 'select',
|
|
6498
6701
|
options: [
|
|
6499
6702
|
{ value: 'template', label: 'Template' },
|
|
@@ -6514,7 +6717,7 @@ const GLOBAL_ACTION_UI_SCHEMAS = [
|
|
|
6514
6717
|
{ key: 'message', label: 'Mensagem', type: 'text' },
|
|
6515
6718
|
{
|
|
6516
6719
|
key: 'level',
|
|
6517
|
-
label: '
|
|
6720
|
+
label: 'Nível',
|
|
6518
6721
|
type: 'select',
|
|
6519
6722
|
options: [
|
|
6520
6723
|
{ value: 'log', label: 'log' },
|
|
@@ -8474,6 +8677,7 @@ const DEFAULT_JSON_LOGIC_OPERATORS = [
|
|
|
8474
8677
|
const ALL_RULE_CONTEXT_ROOTS = [
|
|
8475
8678
|
'form',
|
|
8476
8679
|
'row',
|
|
8680
|
+
'rowData',
|
|
8477
8681
|
'computed',
|
|
8478
8682
|
'meta',
|
|
8479
8683
|
'source',
|
|
@@ -9332,6 +9536,7 @@ function mapFieldDefinitionToMetadata(field) {
|
|
|
9332
9536
|
'displayOrientation',
|
|
9333
9537
|
'disabled',
|
|
9334
9538
|
'readOnly',
|
|
9539
|
+
'fieldAccess',
|
|
9335
9540
|
'hidden',
|
|
9336
9541
|
'formHidden',
|
|
9337
9542
|
'tableHidden',
|
|
@@ -9496,9 +9701,25 @@ function mapFieldDefinitionToMetadata(field) {
|
|
|
9496
9701
|
metadata.maxLength = field.maxLength;
|
|
9497
9702
|
if (field.pattern !== undefined)
|
|
9498
9703
|
metadata.pattern = field.pattern;
|
|
9704
|
+
if (field.helpText !== undefined) {
|
|
9705
|
+
metadata.helpText = field.helpText;
|
|
9706
|
+
}
|
|
9499
9707
|
if (field.hint || field.helpText) {
|
|
9500
9708
|
metadata.hint = field.hint ?? field.helpText;
|
|
9501
9709
|
}
|
|
9710
|
+
if (field.tooltipOnHover !== undefined) {
|
|
9711
|
+
metadata.tooltipOnHover = field.tooltipOnHover;
|
|
9712
|
+
const tooltip = field.tooltip ??
|
|
9713
|
+
(field.tooltipOnHover === true
|
|
9714
|
+
? field.description ?? field.helpText ?? field.hint
|
|
9715
|
+
: undefined);
|
|
9716
|
+
if (tooltip !== undefined && tooltip !== null) {
|
|
9717
|
+
metadata.tooltip = String(tooltip);
|
|
9718
|
+
}
|
|
9719
|
+
}
|
|
9720
|
+
else if (field.tooltip !== undefined) {
|
|
9721
|
+
metadata.tooltip = String(field.tooltip);
|
|
9722
|
+
}
|
|
9502
9723
|
if (field.hiddenCondition !== undefined) {
|
|
9503
9724
|
metadata.hiddenCondition = field.hiddenCondition;
|
|
9504
9725
|
}
|
|
@@ -11562,7 +11783,7 @@ class ResourceDiscoveryService {
|
|
|
11562
11783
|
throw new Error('ResourceDiscoveryService cannot resolve an empty href.');
|
|
11563
11784
|
}
|
|
11564
11785
|
if (/^https?:\/\//i.test(normalizedHref)) {
|
|
11565
|
-
return normalizedHref;
|
|
11786
|
+
return this.resolveTrustedAbsoluteHref(normalizedHref, options);
|
|
11566
11787
|
}
|
|
11567
11788
|
const apiBaseUrl = this.resolveApiBaseHref(options);
|
|
11568
11789
|
if (!apiBaseUrl) {
|
|
@@ -11615,6 +11836,69 @@ class ResourceDiscoveryService {
|
|
|
11615
11836
|
const entry = this.resolveApiEntry(options);
|
|
11616
11837
|
return String(buildApiUrl(entry) || '').trim();
|
|
11617
11838
|
}
|
|
11839
|
+
resolveTrustedAbsoluteHref(href, options) {
|
|
11840
|
+
const runtimeOrigin = this.getRuntimeOrigin();
|
|
11841
|
+
const baseUrl = this.resolveApiBaseUrl(options);
|
|
11842
|
+
if (!runtimeOrigin || !baseUrl || this.isAbsoluteHttpUrl(baseUrl)) {
|
|
11843
|
+
return href;
|
|
11844
|
+
}
|
|
11845
|
+
let parsed;
|
|
11846
|
+
try {
|
|
11847
|
+
parsed = new URL(href);
|
|
11848
|
+
}
|
|
11849
|
+
catch {
|
|
11850
|
+
return href;
|
|
11851
|
+
}
|
|
11852
|
+
if (!this.isTrustedOrigin(parsed.origin, options)) {
|
|
11853
|
+
return href;
|
|
11854
|
+
}
|
|
11855
|
+
if (!this.isProxyableApiPath(parsed.pathname, baseUrl)) {
|
|
11856
|
+
return href;
|
|
11857
|
+
}
|
|
11858
|
+
return new URL(`${parsed.pathname}${parsed.search}${parsed.hash}`, `${runtimeOrigin}/`).toString();
|
|
11859
|
+
}
|
|
11860
|
+
isTrustedOrigin(origin, options) {
|
|
11861
|
+
const normalizedOrigin = this.normalizeOrigin(origin);
|
|
11862
|
+
if (!normalizedOrigin) {
|
|
11863
|
+
return false;
|
|
11864
|
+
}
|
|
11865
|
+
return this.getTrustedOrigins(options).some((trustedOrigin) => trustedOrigin === normalizedOrigin);
|
|
11866
|
+
}
|
|
11867
|
+
getTrustedOrigins(options) {
|
|
11868
|
+
const origins = this.resolveApiEntry(options).trustedOrigins || [];
|
|
11869
|
+
return origins
|
|
11870
|
+
.map((origin) => this.normalizeOrigin(origin))
|
|
11871
|
+
.filter((origin) => !!origin);
|
|
11872
|
+
}
|
|
11873
|
+
normalizeOrigin(origin) {
|
|
11874
|
+
try {
|
|
11875
|
+
return new URL(origin).origin;
|
|
11876
|
+
}
|
|
11877
|
+
catch {
|
|
11878
|
+
return null;
|
|
11879
|
+
}
|
|
11880
|
+
}
|
|
11881
|
+
isProxyableApiPath(pathname, baseUrl) {
|
|
11882
|
+
const basePath = this.normalizePathPrefix(baseUrl);
|
|
11883
|
+
if (basePath && (pathname === basePath || pathname.startsWith(`${basePath}/`))) {
|
|
11884
|
+
return true;
|
|
11885
|
+
}
|
|
11886
|
+
return pathname === '/schemas'
|
|
11887
|
+
|| pathname.startsWith('/schemas/')
|
|
11888
|
+
|| pathname === '/v3/api-docs'
|
|
11889
|
+
|| pathname.startsWith('/v3/api-docs/');
|
|
11890
|
+
}
|
|
11891
|
+
normalizePathPrefix(baseUrl) {
|
|
11892
|
+
const path = String(baseUrl || '').split(/[?#]/u)[0]?.trim() || '';
|
|
11893
|
+
if (!path.startsWith('/')) {
|
|
11894
|
+
return '';
|
|
11895
|
+
}
|
|
11896
|
+
const normalized = `/${path.replace(/^\/+|\/+$/g, '')}`;
|
|
11897
|
+
return normalized === '/' ? '' : normalized;
|
|
11898
|
+
}
|
|
11899
|
+
isAbsoluteHttpUrl(value) {
|
|
11900
|
+
return /^https?:\/\//i.test(String(value || '').trim());
|
|
11901
|
+
}
|
|
11618
11902
|
resolveApiBaseHref(options) {
|
|
11619
11903
|
const baseUrl = this.resolveApiBaseUrl(options);
|
|
11620
11904
|
if (!baseUrl) {
|
|
@@ -11922,6 +12206,209 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
11922
12206
|
args: [{ providedIn: 'any' }]
|
|
11923
12207
|
}] });
|
|
11924
12208
|
|
|
12209
|
+
const PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_OPTIONS = new InjectionToken('PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_OPTIONS');
|
|
12210
|
+
const PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_READY = new InjectionToken('PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_READY');
|
|
12211
|
+
function providePraxisEnterpriseRuntimeContext(options = {}) {
|
|
12212
|
+
const normalized = {
|
|
12213
|
+
...options,
|
|
12214
|
+
includeGlobalFetchHeaders: options.includeGlobalFetchHeaders ?? true,
|
|
12215
|
+
blocking: options.blocking ?? false,
|
|
12216
|
+
errorPolicy: options.errorPolicy ?? 'ignore',
|
|
12217
|
+
};
|
|
12218
|
+
return [
|
|
12219
|
+
{ provide: PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_OPTIONS, useValue: normalized },
|
|
12220
|
+
{
|
|
12221
|
+
provide: PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_READY,
|
|
12222
|
+
useFactory: (service) => {
|
|
12223
|
+
let promise = null;
|
|
12224
|
+
return () => {
|
|
12225
|
+
if (promise)
|
|
12226
|
+
return promise;
|
|
12227
|
+
promise = service.ready().then(() => undefined);
|
|
12228
|
+
return promise;
|
|
12229
|
+
};
|
|
12230
|
+
},
|
|
12231
|
+
deps: [EnterpriseRuntimeContextService],
|
|
12232
|
+
},
|
|
12233
|
+
{
|
|
12234
|
+
provide: APP_INITIALIZER,
|
|
12235
|
+
multi: true,
|
|
12236
|
+
useFactory: (ready) => () => normalized.blocking ? ready() : undefined,
|
|
12237
|
+
deps: [PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_READY],
|
|
12238
|
+
},
|
|
12239
|
+
];
|
|
12240
|
+
}
|
|
12241
|
+
|
|
12242
|
+
class EnterpriseRuntimeContextService {
|
|
12243
|
+
http = inject(HttpClient);
|
|
12244
|
+
apiUrl = inject(API_URL, { optional: true });
|
|
12245
|
+
options = inject(PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_OPTIONS, {
|
|
12246
|
+
optional: true,
|
|
12247
|
+
});
|
|
12248
|
+
contextSubject = new BehaviorSubject(null);
|
|
12249
|
+
loadPromise = null;
|
|
12250
|
+
contextChanges$ = this.contextSubject.asObservable();
|
|
12251
|
+
get snapshot() {
|
|
12252
|
+
return this.contextSubject.value;
|
|
12253
|
+
}
|
|
12254
|
+
ready() {
|
|
12255
|
+
if (this.contextSubject.value) {
|
|
12256
|
+
return Promise.resolve(this.contextSubject.value);
|
|
12257
|
+
}
|
|
12258
|
+
if (this.loadPromise) {
|
|
12259
|
+
return this.loadPromise;
|
|
12260
|
+
}
|
|
12261
|
+
this.loadPromise = this.load()
|
|
12262
|
+
.catch((error) => {
|
|
12263
|
+
if ((this.options?.errorPolicy ?? 'ignore') === 'fail') {
|
|
12264
|
+
throw error;
|
|
12265
|
+
}
|
|
12266
|
+
return null;
|
|
12267
|
+
})
|
|
12268
|
+
.finally(() => {
|
|
12269
|
+
this.loadPromise = null;
|
|
12270
|
+
});
|
|
12271
|
+
return this.loadPromise;
|
|
12272
|
+
}
|
|
12273
|
+
refresh() {
|
|
12274
|
+
this.loadPromise = null;
|
|
12275
|
+
return this.load().catch((error) => {
|
|
12276
|
+
if ((this.options?.errorPolicy ?? 'ignore') === 'fail') {
|
|
12277
|
+
throw error;
|
|
12278
|
+
}
|
|
12279
|
+
return null;
|
|
12280
|
+
});
|
|
12281
|
+
}
|
|
12282
|
+
tenants() {
|
|
12283
|
+
return this.getRuntimeSurface('tenants');
|
|
12284
|
+
}
|
|
12285
|
+
navigation() {
|
|
12286
|
+
return this.getRuntimeSurface('navigation');
|
|
12287
|
+
}
|
|
12288
|
+
securityEvents() {
|
|
12289
|
+
return this.getRuntimeSurface('securityEvents');
|
|
12290
|
+
}
|
|
12291
|
+
async switchContext(command) {
|
|
12292
|
+
const response = await firstValueFrom(this.http.put(this.endpoint('context'), command, {
|
|
12293
|
+
headers: this.requestHeaders({ includeSnapshot: true }),
|
|
12294
|
+
}));
|
|
12295
|
+
if (response?.effectiveContext) {
|
|
12296
|
+
this.contextSubject.next(response.effectiveContext);
|
|
12297
|
+
}
|
|
12298
|
+
return response;
|
|
12299
|
+
}
|
|
12300
|
+
headers(fallback) {
|
|
12301
|
+
return {
|
|
12302
|
+
...this.normalizeHeaders(fallback ?? {}),
|
|
12303
|
+
...this.normalizeHeaders(this.headersFromSnapshot(this.contextSubject.value)),
|
|
12304
|
+
};
|
|
12305
|
+
}
|
|
12306
|
+
async load() {
|
|
12307
|
+
const context = await firstValueFrom(this.http.get(this.endpoint('context'), {
|
|
12308
|
+
headers: this.requestHeaders(),
|
|
12309
|
+
}));
|
|
12310
|
+
this.contextSubject.next(context ?? null);
|
|
12311
|
+
return context ?? null;
|
|
12312
|
+
}
|
|
12313
|
+
async getRuntimeSurface(surface) {
|
|
12314
|
+
return firstValueFrom(this.http.get(this.endpoint(surface), {
|
|
12315
|
+
headers: this.requestHeaders({ includeSnapshot: true }),
|
|
12316
|
+
}));
|
|
12317
|
+
}
|
|
12318
|
+
endpoint(surface) {
|
|
12319
|
+
const configured = this.configuredEndpoint(surface);
|
|
12320
|
+
if (configured) {
|
|
12321
|
+
return configured;
|
|
12322
|
+
}
|
|
12323
|
+
return `${this.runtimeRoot()}/${this.surfacePath(surface)}`;
|
|
12324
|
+
}
|
|
12325
|
+
configuredEndpoint(surface) {
|
|
12326
|
+
const configured = surface === 'context'
|
|
12327
|
+
? (this.options?.endpoints?.context ?? this.options?.endpoint)
|
|
12328
|
+
: this.options?.endpoints?.[surface];
|
|
12329
|
+
const normalized = configured?.trim().replace(/\/+$/, '');
|
|
12330
|
+
return normalized || null;
|
|
12331
|
+
}
|
|
12332
|
+
runtimeRoot() {
|
|
12333
|
+
const configuredContext = this.configuredEndpoint('context');
|
|
12334
|
+
if (configuredContext?.endsWith('/context')) {
|
|
12335
|
+
return configuredContext.slice(0, -'/context'.length);
|
|
12336
|
+
}
|
|
12337
|
+
const defaultEntry = this.apiUrl?.['default'];
|
|
12338
|
+
const base = defaultEntry ? buildApiUrl(defaultEntry) : '';
|
|
12339
|
+
return base ? `${base}/praxis/runtime` : '/api/praxis/runtime';
|
|
12340
|
+
}
|
|
12341
|
+
surfacePath(surface) {
|
|
12342
|
+
switch (surface) {
|
|
12343
|
+
case 'context':
|
|
12344
|
+
return 'context';
|
|
12345
|
+
case 'tenants':
|
|
12346
|
+
return 'tenants';
|
|
12347
|
+
case 'navigation':
|
|
12348
|
+
return 'navigation';
|
|
12349
|
+
case 'securityEvents':
|
|
12350
|
+
return 'security-events';
|
|
12351
|
+
}
|
|
12352
|
+
}
|
|
12353
|
+
requestHeaders(options = {}) {
|
|
12354
|
+
const merged = this.normalizeHeaders({
|
|
12355
|
+
...(this.options?.includeGlobalFetchHeaders ?? true ? this.globalFetchHeaders() : {}),
|
|
12356
|
+
...(this.options?.headersFactory?.() ?? {}),
|
|
12357
|
+
...(options.includeSnapshot ? this.headersFromSnapshot(this.contextSubject.value) : {}),
|
|
12358
|
+
});
|
|
12359
|
+
let headers = new HttpHeaders();
|
|
12360
|
+
for (const [key, value] of Object.entries(merged)) {
|
|
12361
|
+
if (value) {
|
|
12362
|
+
headers = headers.set(key, value);
|
|
12363
|
+
}
|
|
12364
|
+
}
|
|
12365
|
+
return headers;
|
|
12366
|
+
}
|
|
12367
|
+
globalFetchHeaders() {
|
|
12368
|
+
try {
|
|
12369
|
+
const factory = globalThis.PAX_FETCH_HEADERS;
|
|
12370
|
+
return factory?.() ?? {};
|
|
12371
|
+
}
|
|
12372
|
+
catch {
|
|
12373
|
+
return {};
|
|
12374
|
+
}
|
|
12375
|
+
}
|
|
12376
|
+
headersFromSnapshot(context) {
|
|
12377
|
+
if (!context) {
|
|
12378
|
+
return {};
|
|
12379
|
+
}
|
|
12380
|
+
return {
|
|
12381
|
+
'X-Tenant-ID': context.activeTenant?.tenantId,
|
|
12382
|
+
'X-User-ID': context.user?.userId,
|
|
12383
|
+
'X-Env': context.environment ?? undefined,
|
|
12384
|
+
'Accept-Language': context.locale ?? undefined,
|
|
12385
|
+
'X-Timezone': context.timezone ?? undefined,
|
|
12386
|
+
'X-Praxis-Profile-ID': context.activeProfileId ?? undefined,
|
|
12387
|
+
'X-Praxis-Module-Key': context.activeModuleKey ?? undefined,
|
|
12388
|
+
};
|
|
12389
|
+
}
|
|
12390
|
+
normalizeHeaders(headers) {
|
|
12391
|
+
const normalized = {};
|
|
12392
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
12393
|
+
if (typeof value !== 'string') {
|
|
12394
|
+
continue;
|
|
12395
|
+
}
|
|
12396
|
+
const trimmed = value.trim();
|
|
12397
|
+
if (!trimmed) {
|
|
12398
|
+
continue;
|
|
12399
|
+
}
|
|
12400
|
+
normalized[key] = trimmed;
|
|
12401
|
+
}
|
|
12402
|
+
return normalized;
|
|
12403
|
+
}
|
|
12404
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: EnterpriseRuntimeContextService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
12405
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: EnterpriseRuntimeContextService, providedIn: 'root' });
|
|
12406
|
+
}
|
|
12407
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: EnterpriseRuntimeContextService, decorators: [{
|
|
12408
|
+
type: Injectable,
|
|
12409
|
+
args: [{ providedIn: 'root' }]
|
|
12410
|
+
}] });
|
|
12411
|
+
|
|
11925
12412
|
function clonePraxisRuntimeComponentObservation(observation) {
|
|
11926
12413
|
assertPraxisRuntimeComponentObservationSerializable(observation);
|
|
11927
12414
|
return JSON.parse(JSON.stringify(observation));
|
|
@@ -12444,9 +12931,10 @@ class SurfaceOpenMaterializerService {
|
|
|
12444
12931
|
: null;
|
|
12445
12932
|
if (collectionData) {
|
|
12446
12933
|
if (this.shouldPreserveCollectionPresentation(payload)) {
|
|
12934
|
+
const preservedPayload = this.ensureCollectionTableSelectionContract(payload);
|
|
12447
12935
|
return {
|
|
12448
|
-
...
|
|
12449
|
-
context: this.mergeMaterializationContext(
|
|
12936
|
+
...preservedPayload,
|
|
12937
|
+
context: this.mergeMaterializationContext(preservedPayload, {
|
|
12450
12938
|
readUrl,
|
|
12451
12939
|
dataShape: 'array',
|
|
12452
12940
|
recordCount: collectionData.length,
|
|
@@ -12470,18 +12958,24 @@ class SurfaceOpenMaterializerService {
|
|
|
12470
12958
|
if (data && typeof data === 'object' && !Array.isArray(data)) {
|
|
12471
12959
|
const objectData = data;
|
|
12472
12960
|
if (payload.widget.id === 'praxis-dynamic-form') {
|
|
12473
|
-
const schemaFields = await this.resolveSchemaFields(payload, discoveryOptions);
|
|
12474
12961
|
return {
|
|
12475
12962
|
...payload,
|
|
12476
12963
|
widget: {
|
|
12477
12964
|
...payload.widget,
|
|
12478
12965
|
inputs: {
|
|
12479
12966
|
...this.projectMaterializedFormInputs(payload.widget.inputs || {}),
|
|
12480
|
-
configPersistenceStrategy: 'input-first',
|
|
12481
12967
|
mode: payload.widget.inputs?.['mode'] || 'view',
|
|
12482
12968
|
initialValue: objectData,
|
|
12483
12969
|
resourceId,
|
|
12484
|
-
|
|
12970
|
+
layoutPolicy: payload.widget.inputs?.['layoutPolicy'] || {
|
|
12971
|
+
source: 'schema',
|
|
12972
|
+
intent: 'detail',
|
|
12973
|
+
preset: 'compactPresentation',
|
|
12974
|
+
lifecycle: 'live',
|
|
12975
|
+
persistence: 'transient',
|
|
12976
|
+
schemaOperation: 'detail',
|
|
12977
|
+
schemaType: 'response',
|
|
12978
|
+
},
|
|
12485
12979
|
},
|
|
12486
12980
|
},
|
|
12487
12981
|
context: this.mergeMaterializationContext(payload, {
|
|
@@ -12519,11 +13013,14 @@ class SurfaceOpenMaterializerService {
|
|
|
12519
13013
|
'resourceId',
|
|
12520
13014
|
'apiEndpointKey',
|
|
12521
13015
|
'apiUrlEntry',
|
|
13016
|
+
'schemaUrl',
|
|
13017
|
+
'readUrl',
|
|
12522
13018
|
'submitUrl',
|
|
12523
13019
|
'submitMethod',
|
|
12524
13020
|
'responseSchemaUrl',
|
|
12525
13021
|
'customEndpoints',
|
|
12526
13022
|
'configPersistenceStrategy',
|
|
13023
|
+
'layoutPolicy',
|
|
12527
13024
|
'mode',
|
|
12528
13025
|
'actions',
|
|
12529
13026
|
'enableCustomization',
|
|
@@ -12531,6 +13028,7 @@ class SurfaceOpenMaterializerService {
|
|
|
12531
13028
|
'readonlyModeGlobal',
|
|
12532
13029
|
'disabledModeGlobal',
|
|
12533
13030
|
'presentationModeGlobal',
|
|
13031
|
+
'fieldIconPolicy',
|
|
12534
13032
|
'visibleGlobal',
|
|
12535
13033
|
'layout',
|
|
12536
13034
|
'backConfig',
|
|
@@ -12544,186 +13042,6 @@ class SurfaceOpenMaterializerService {
|
|
|
12544
13042
|
]);
|
|
12545
13043
|
return Object.fromEntries(Object.entries(inputs).filter(([key]) => supported.has(key)));
|
|
12546
13044
|
}
|
|
12547
|
-
buildLocalFormConfig(data, schemaFields = []) {
|
|
12548
|
-
const fields = this.buildMaterializedFormFields(data, schemaFields);
|
|
12549
|
-
const sections = this.buildMaterializedFormSections(fields);
|
|
12550
|
-
return {
|
|
12551
|
-
sections,
|
|
12552
|
-
fieldMetadata: fields,
|
|
12553
|
-
};
|
|
12554
|
-
}
|
|
12555
|
-
buildMaterializedFormFields(data, schemaFields) {
|
|
12556
|
-
const schemaByName = new Map(schemaFields
|
|
12557
|
-
.filter((field) => !!field?.name)
|
|
12558
|
-
.map((field) => [field.name, field]));
|
|
12559
|
-
const orderedNames = schemaFields.length
|
|
12560
|
-
? [
|
|
12561
|
-
...schemaFields
|
|
12562
|
-
.filter((field) => field?.name && Object.prototype.hasOwnProperty.call(data, field.name))
|
|
12563
|
-
.sort((left, right) => (left.order ?? Number.MAX_SAFE_INTEGER) - (right.order ?? Number.MAX_SAFE_INTEGER))
|
|
12564
|
-
.map((field) => field.name),
|
|
12565
|
-
...Object.keys(data).filter((key) => !schemaByName.has(key)),
|
|
12566
|
-
]
|
|
12567
|
-
: Object.keys(data);
|
|
12568
|
-
return orderedNames
|
|
12569
|
-
.filter((key, index, keys) => keys.indexOf(key) === index)
|
|
12570
|
-
.filter((key) => this.shouldRenderMaterializedFormField(key, data[key], schemaByName.get(key), data))
|
|
12571
|
-
.map((key) => {
|
|
12572
|
-
const field = schemaByName.get(key);
|
|
12573
|
-
if (field) {
|
|
12574
|
-
return {
|
|
12575
|
-
...mapFieldDefinitionToMetadata({
|
|
12576
|
-
...field,
|
|
12577
|
-
hidden: false,
|
|
12578
|
-
formHidden: false,
|
|
12579
|
-
readOnly: true,
|
|
12580
|
-
}),
|
|
12581
|
-
readOnly: true,
|
|
12582
|
-
};
|
|
12583
|
-
}
|
|
12584
|
-
return {
|
|
12585
|
-
name: key,
|
|
12586
|
-
label: this.humanizeFieldName(key),
|
|
12587
|
-
controlType: this.inferFormControlType(data[key]),
|
|
12588
|
-
readOnly: true,
|
|
12589
|
-
};
|
|
12590
|
-
});
|
|
12591
|
-
}
|
|
12592
|
-
buildMaterializedFormSections(fields) {
|
|
12593
|
-
const groups = new Map();
|
|
12594
|
-
for (const field of fields) {
|
|
12595
|
-
const group = String(field.group || '').trim() || 'Detalhes';
|
|
12596
|
-
groups.set(group, [...(groups.get(group) || []), field]);
|
|
12597
|
-
}
|
|
12598
|
-
return Array.from(groups.entries()).map(([group, groupFields], sectionIndex) => {
|
|
12599
|
-
const fieldNames = groupFields.map((field) => field.name);
|
|
12600
|
-
const rows = this.chunk(fieldNames, 2).map((names, rowIndex) => ({
|
|
12601
|
-
id: `row-${sectionIndex + 1}-${rowIndex + 1}`,
|
|
12602
|
-
columns: names.map((name) => ({
|
|
12603
|
-
id: `col-${name}`,
|
|
12604
|
-
fields: [name],
|
|
12605
|
-
})),
|
|
12606
|
-
}));
|
|
12607
|
-
return {
|
|
12608
|
-
id: this.stableSectionId(group, sectionIndex),
|
|
12609
|
-
title: group,
|
|
12610
|
-
rows,
|
|
12611
|
-
};
|
|
12612
|
-
});
|
|
12613
|
-
}
|
|
12614
|
-
shouldRenderMaterializedFormField(key, value, field, data) {
|
|
12615
|
-
if (!key || key.startsWith('_'))
|
|
12616
|
-
return false;
|
|
12617
|
-
if (field?.hidden === true)
|
|
12618
|
-
return false;
|
|
12619
|
-
if (this.isTechnicalRelationIdField(key, field, data))
|
|
12620
|
-
return false;
|
|
12621
|
-
if (this.isDuplicateMediaUrlField(key, value, field, data))
|
|
12622
|
-
return false;
|
|
12623
|
-
if (field?.formHidden === true && !this.isResolvedDisplayCompanionField(key, data)) {
|
|
12624
|
-
return false;
|
|
12625
|
-
}
|
|
12626
|
-
if (value == null)
|
|
12627
|
-
return true;
|
|
12628
|
-
return typeof value !== 'object' || value instanceof Date;
|
|
12629
|
-
}
|
|
12630
|
-
isTechnicalRelationIdField(key, field, data) {
|
|
12631
|
-
if (key === 'id' || !/Id$/.test(key))
|
|
12632
|
-
return false;
|
|
12633
|
-
const base = key.slice(0, -2);
|
|
12634
|
-
const hasDisplayCompanion = this.hasDisplayCompanion(base, data);
|
|
12635
|
-
if (!hasDisplayCompanion)
|
|
12636
|
-
return false;
|
|
12637
|
-
const controlType = String(field?.controlType || '').toLowerCase();
|
|
12638
|
-
return Boolean(field?.endpoint
|
|
12639
|
-
|| field?.resourcePath
|
|
12640
|
-
|| field?.optionSource
|
|
12641
|
-
|| controlType.includes('select')
|
|
12642
|
-
|| field?.tableHidden === true);
|
|
12643
|
-
}
|
|
12644
|
-
isResolvedDisplayCompanionField(key, data) {
|
|
12645
|
-
const base = this.resolveDisplayCompanionBase(key);
|
|
12646
|
-
return !!base && Object.prototype.hasOwnProperty.call(data, `${base}Id`);
|
|
12647
|
-
}
|
|
12648
|
-
resolveDisplayCompanionBase(key) {
|
|
12649
|
-
const suffixes = ['Nome', 'Name', 'Label', 'Descricao', 'Description', 'Title', 'Text'];
|
|
12650
|
-
const suffix = suffixes.find((candidate) => key.endsWith(candidate));
|
|
12651
|
-
return suffix ? key.slice(0, -suffix.length) : null;
|
|
12652
|
-
}
|
|
12653
|
-
hasDisplayCompanion(base, data) {
|
|
12654
|
-
const suffixes = ['Nome', 'Name', 'Label', 'Descricao', 'Description', 'Title', 'Text'];
|
|
12655
|
-
return suffixes.some((suffix) => {
|
|
12656
|
-
const value = data[`${base}${suffix}`];
|
|
12657
|
-
return value != null && String(value).trim().length > 0;
|
|
12658
|
-
});
|
|
12659
|
-
}
|
|
12660
|
-
isDuplicateMediaUrlField(key, value, field, data) {
|
|
12661
|
-
if (typeof value !== 'string' || !this.looksLikeMediaUrlField(key, field)) {
|
|
12662
|
-
return false;
|
|
12663
|
-
}
|
|
12664
|
-
return Object.entries(data).some(([candidateKey, candidateValue]) => {
|
|
12665
|
-
if (candidateKey === key || candidateValue !== value) {
|
|
12666
|
-
return false;
|
|
12667
|
-
}
|
|
12668
|
-
return this.looksLikeAvatarFieldName(candidateKey);
|
|
12669
|
-
});
|
|
12670
|
-
}
|
|
12671
|
-
looksLikeMediaUrlField(key, field) {
|
|
12672
|
-
const type = String(field?.type || '').toLowerCase();
|
|
12673
|
-
const controlType = String(field?.controlType || '').toLowerCase();
|
|
12674
|
-
const normalized = key.toLowerCase();
|
|
12675
|
-
return Boolean(type === 'url'
|
|
12676
|
-
|| controlType.includes('url')
|
|
12677
|
-
|| normalized.includes('url')
|
|
12678
|
-
|| normalized.includes('foto')
|
|
12679
|
-
|| normalized.includes('photo')
|
|
12680
|
-
|| normalized.includes('image')
|
|
12681
|
-
|| normalized.includes('imagem'));
|
|
12682
|
-
}
|
|
12683
|
-
looksLikeAvatarFieldName(key) {
|
|
12684
|
-
const normalized = key.toLowerCase();
|
|
12685
|
-
return normalized.includes('avatar') || normalized.includes('portrait');
|
|
12686
|
-
}
|
|
12687
|
-
inferFormControlType(value) {
|
|
12688
|
-
if (typeof value === 'boolean')
|
|
12689
|
-
return 'checkbox';
|
|
12690
|
-
if (typeof value === 'number')
|
|
12691
|
-
return 'numericTextBox';
|
|
12692
|
-
if (typeof value === 'string') {
|
|
12693
|
-
if (/^\d{4}-\d{2}-\d{2}$/.test(value))
|
|
12694
|
-
return 'dateInput';
|
|
12695
|
-
if (/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value))
|
|
12696
|
-
return 'email';
|
|
12697
|
-
}
|
|
12698
|
-
return 'input';
|
|
12699
|
-
}
|
|
12700
|
-
humanizeFieldName(key) {
|
|
12701
|
-
return key
|
|
12702
|
-
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
12703
|
-
.replace(/[_-]+/g, ' ')
|
|
12704
|
-
.replace(/\s+/g, ' ')
|
|
12705
|
-
.trim()
|
|
12706
|
-
.replace(/^./, (char) => char.toUpperCase());
|
|
12707
|
-
}
|
|
12708
|
-
stableSectionId(group, index) {
|
|
12709
|
-
if (group === 'Detalhes') {
|
|
12710
|
-
return 'details';
|
|
12711
|
-
}
|
|
12712
|
-
const normalized = group
|
|
12713
|
-
.normalize('NFD')
|
|
12714
|
-
.replace(/[\u0300-\u036f]/g, '')
|
|
12715
|
-
.toLowerCase()
|
|
12716
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
12717
|
-
.replace(/^-+|-+$/g, '');
|
|
12718
|
-
return normalized || `details-${index + 1}`;
|
|
12719
|
-
}
|
|
12720
|
-
chunk(items, size) {
|
|
12721
|
-
const result = [];
|
|
12722
|
-
for (let index = 0; index < items.length; index += size) {
|
|
12723
|
-
result.push(items.slice(index, index + size));
|
|
12724
|
-
}
|
|
12725
|
-
return result;
|
|
12726
|
-
}
|
|
12727
13045
|
shouldMaterializeItemReadProjection(payload) {
|
|
12728
13046
|
const surface = payload.context?.['surface'];
|
|
12729
13047
|
const kind = String(surface?.['kind'] || '').toUpperCase();
|
|
@@ -12806,6 +13124,8 @@ class SurfaceOpenMaterializerService {
|
|
|
12806
13124
|
bindingOrder: [
|
|
12807
13125
|
'tableId',
|
|
12808
13126
|
'componentInstanceId',
|
|
13127
|
+
'configPersistenceStrategy',
|
|
13128
|
+
'resourcePath',
|
|
12809
13129
|
'title',
|
|
12810
13130
|
'subtitle',
|
|
12811
13131
|
'icon',
|
|
@@ -12813,11 +13133,17 @@ class SurfaceOpenMaterializerService {
|
|
|
12813
13133
|
'config',
|
|
12814
13134
|
'enableCustomization',
|
|
12815
13135
|
],
|
|
13136
|
+
outputs: {
|
|
13137
|
+
rowClick: 'emit',
|
|
13138
|
+
selectionChange: 'emit',
|
|
13139
|
+
widgetEvent: 'emit',
|
|
13140
|
+
},
|
|
12816
13141
|
inputs: {
|
|
12817
13142
|
...tableInputOverrides,
|
|
12818
13143
|
resourcePath: '',
|
|
12819
13144
|
tableId: String(previousInputs['tableId'] || this.stableSurfaceId(payload)),
|
|
12820
13145
|
componentInstanceId: `${this.stableSurfaceId(payload)}.${resourceId}`,
|
|
13146
|
+
configPersistenceStrategy: previousInputs['configPersistenceStrategy'] ?? 'volatile',
|
|
12821
13147
|
title: payload.title,
|
|
12822
13148
|
subtitle: payload.subtitle,
|
|
12823
13149
|
icon: payload.icon,
|
|
@@ -12833,6 +13159,52 @@ class SurfaceOpenMaterializerService {
|
|
|
12833
13159
|
}),
|
|
12834
13160
|
};
|
|
12835
13161
|
}
|
|
13162
|
+
ensureCollectionTableSelectionContract(payload) {
|
|
13163
|
+
if (payload.widget?.id !== 'praxis-table') {
|
|
13164
|
+
return payload;
|
|
13165
|
+
}
|
|
13166
|
+
const inputs = payload.widget.inputs || {};
|
|
13167
|
+
return {
|
|
13168
|
+
...payload,
|
|
13169
|
+
widget: {
|
|
13170
|
+
...payload.widget,
|
|
13171
|
+
outputs: {
|
|
13172
|
+
...(payload.widget.outputs || {}),
|
|
13173
|
+
rowClick: 'emit',
|
|
13174
|
+
selectionChange: 'emit',
|
|
13175
|
+
widgetEvent: 'emit',
|
|
13176
|
+
},
|
|
13177
|
+
inputs: {
|
|
13178
|
+
...inputs,
|
|
13179
|
+
config: this.ensureTableSelectionConfig(inputs['config']),
|
|
13180
|
+
},
|
|
13181
|
+
},
|
|
13182
|
+
};
|
|
13183
|
+
}
|
|
13184
|
+
ensureTableSelectionConfig(config) {
|
|
13185
|
+
if (!config || typeof config !== 'object' || Array.isArray(config)) {
|
|
13186
|
+
return config;
|
|
13187
|
+
}
|
|
13188
|
+
const tableConfig = config;
|
|
13189
|
+
const rawBehavior = tableConfig['behavior'];
|
|
13190
|
+
const behavior = (rawBehavior && typeof rawBehavior === 'object' && !Array.isArray(rawBehavior)
|
|
13191
|
+
? rawBehavior
|
|
13192
|
+
: {});
|
|
13193
|
+
if (behavior['selection'] && typeof behavior['selection'] === 'object') {
|
|
13194
|
+
return config;
|
|
13195
|
+
}
|
|
13196
|
+
return {
|
|
13197
|
+
...tableConfig,
|
|
13198
|
+
behavior: {
|
|
13199
|
+
...behavior,
|
|
13200
|
+
selection: {
|
|
13201
|
+
enabled: true,
|
|
13202
|
+
type: 'single',
|
|
13203
|
+
mode: 'both',
|
|
13204
|
+
},
|
|
13205
|
+
},
|
|
13206
|
+
};
|
|
13207
|
+
}
|
|
12836
13208
|
projectTableInputs(inputs) {
|
|
12837
13209
|
const supported = new Set([
|
|
12838
13210
|
'tableId',
|
|
@@ -12869,6 +13241,11 @@ class SurfaceOpenMaterializerService {
|
|
|
12869
13241
|
behavior: {
|
|
12870
13242
|
localDataMode: { enabled: true },
|
|
12871
13243
|
pagination: { enabled: true, pageSize: 10 },
|
|
13244
|
+
selection: {
|
|
13245
|
+
enabled: true,
|
|
13246
|
+
type: 'single',
|
|
13247
|
+
mode: 'both',
|
|
13248
|
+
},
|
|
12872
13249
|
},
|
|
12873
13250
|
};
|
|
12874
13251
|
}
|
|
@@ -15674,6 +16051,9 @@ const STEPPER_CONFIG_EDITOR = new InjectionToken('STEPPER_CONFIG_EDITOR');
|
|
|
15674
16051
|
const DYNAMIC_PAGE_SHELL_EDITOR = new InjectionToken('DYNAMIC_PAGE_SHELL_EDITOR');
|
|
15675
16052
|
const DYNAMIC_PAGE_CONFIG_EDITOR = new InjectionToken('DYNAMIC_PAGE_CONFIG_EDITOR');
|
|
15676
16053
|
|
|
16054
|
+
const PRAXIS_TABLE_DETAIL_INLINE_RENDERERS = new InjectionToken('PRAXIS_TABLE_DETAIL_INLINE_RENDERERS');
|
|
16055
|
+
const PRAXIS_TABLE_DETAIL_INLINE_NODE_RESOLVERS = new InjectionToken('PRAXIS_TABLE_DETAIL_INLINE_NODE_RESOLVERS');
|
|
16056
|
+
|
|
15677
16057
|
function providePraxisHttpCollectionExportProvider(options = {}) {
|
|
15678
16058
|
return [
|
|
15679
16059
|
{ provide: PRAXIS_COLLECTION_EXPORT_HTTP_OPTIONS, useValue: options },
|
|
@@ -16016,6 +16396,743 @@ const FieldDataType = {
|
|
|
16016
16396
|
* - Angular Material 3 native support
|
|
16017
16397
|
*/
|
|
16018
16398
|
|
|
16399
|
+
const VISUALIZATION_KINDS = new Set([
|
|
16400
|
+
'line',
|
|
16401
|
+
'area',
|
|
16402
|
+
'column',
|
|
16403
|
+
'comparison',
|
|
16404
|
+
'stackedBar',
|
|
16405
|
+
'radial',
|
|
16406
|
+
'harveyBall',
|
|
16407
|
+
'bullet',
|
|
16408
|
+
'delta',
|
|
16409
|
+
'processFlow',
|
|
16410
|
+
]);
|
|
16411
|
+
const VISUALIZATION_SURFACES = new Set([
|
|
16412
|
+
'table-cell',
|
|
16413
|
+
'list-item',
|
|
16414
|
+
'object-header',
|
|
16415
|
+
'card-summary',
|
|
16416
|
+
'form-presentation',
|
|
16417
|
+
]);
|
|
16418
|
+
const VISUALIZATION_SIZES = new Set([
|
|
16419
|
+
'xs',
|
|
16420
|
+
'sm',
|
|
16421
|
+
'md',
|
|
16422
|
+
'lg',
|
|
16423
|
+
'responsive',
|
|
16424
|
+
]);
|
|
16425
|
+
const VISUALIZATION_TONES = new Set([
|
|
16426
|
+
'neutral',
|
|
16427
|
+
'info',
|
|
16428
|
+
'success',
|
|
16429
|
+
'warning',
|
|
16430
|
+
'danger',
|
|
16431
|
+
'critical',
|
|
16432
|
+
]);
|
|
16433
|
+
const TABLE_SAFE_KINDS = new Set([
|
|
16434
|
+
'line',
|
|
16435
|
+
'area',
|
|
16436
|
+
'column',
|
|
16437
|
+
'comparison',
|
|
16438
|
+
'stackedBar',
|
|
16439
|
+
'radial',
|
|
16440
|
+
'harveyBall',
|
|
16441
|
+
'bullet',
|
|
16442
|
+
'delta',
|
|
16443
|
+
'processFlow',
|
|
16444
|
+
]);
|
|
16445
|
+
function normalizePraxisPresentationVisualization(value) {
|
|
16446
|
+
if (!value || typeof value !== 'object') {
|
|
16447
|
+
return undefined;
|
|
16448
|
+
}
|
|
16449
|
+
const kind = normalizeEnum$1(value.kind, VISUALIZATION_KINDS);
|
|
16450
|
+
const fallbackText = normalizeText$1(value.fallbackText);
|
|
16451
|
+
if (!kind || !fallbackText) {
|
|
16452
|
+
return undefined;
|
|
16453
|
+
}
|
|
16454
|
+
const surface = normalizeEnum$1(value.surface, VISUALIZATION_SURFACES);
|
|
16455
|
+
const size = normalizeEnum$1(value.size, VISUALIZATION_SIZES);
|
|
16456
|
+
const tone = normalizeEnum$1(value.tone, VISUALIZATION_TONES);
|
|
16457
|
+
const ariaLabel = normalizeText$1(value.ariaLabel);
|
|
16458
|
+
const valueSuffix = normalizeText$1(value.valueSuffix);
|
|
16459
|
+
return {
|
|
16460
|
+
kind,
|
|
16461
|
+
fallbackText,
|
|
16462
|
+
...(surface ? { surface } : {}),
|
|
16463
|
+
...(size ? { size } : {}),
|
|
16464
|
+
...(tone ? { tone } : {}),
|
|
16465
|
+
...(ariaLabel ? { ariaLabel } : {}),
|
|
16466
|
+
...(valueSuffix ? { valueSuffix } : {}),
|
|
16467
|
+
...(Object.prototype.hasOwnProperty.call(value, 'value') ? { value: value.value } : {}),
|
|
16468
|
+
...(normalizeExpression(value.valueExpr, 'valueExpr') ?? {}),
|
|
16469
|
+
...(normalizeExpression(value.valueSuffixExpr, 'valueSuffixExpr') ?? {}),
|
|
16470
|
+
...(normalizeNumber(value.total, 'total') ?? {}),
|
|
16471
|
+
...(normalizeExpression(value.totalExpr, 'totalExpr') ?? {}),
|
|
16472
|
+
...(normalizeNumber(value.target, 'target') ?? {}),
|
|
16473
|
+
...(normalizeExpression(value.targetExpr, 'targetExpr') ?? {}),
|
|
16474
|
+
...(normalizeNumber(value.baseline, 'baseline') ?? {}),
|
|
16475
|
+
...(normalizeExpression(value.baselineExpr, 'baselineExpr') ?? {}),
|
|
16476
|
+
...(normalizePoints(value.points) ?? {}),
|
|
16477
|
+
...(normalizeExpression(value.pointsExpr, 'pointsExpr') ?? {}),
|
|
16478
|
+
...(normalizeSegments(value.segments) ?? {}),
|
|
16479
|
+
...(normalizeExpression(value.segmentsExpr, 'segmentsExpr') ?? {}),
|
|
16480
|
+
...(normalizeThresholds(value.thresholds) ?? {}),
|
|
16481
|
+
...(normalizeExpression(value.thresholdsExpr, 'thresholdsExpr') ?? {}),
|
|
16482
|
+
...(normalizeItems(value.items) ?? {}),
|
|
16483
|
+
...(normalizeExpression(value.itemsExpr, 'itemsExpr') ?? {}),
|
|
16484
|
+
...(normalizeExpression(value.toneExpr, 'toneExpr') ?? {}),
|
|
16485
|
+
...(normalizeExpression(value.ariaLabelExpr, 'ariaLabelExpr') ?? {}),
|
|
16486
|
+
...(normalizeExpression(value.fallbackTextExpr, 'fallbackTextExpr') ?? {}),
|
|
16487
|
+
};
|
|
16488
|
+
}
|
|
16489
|
+
function isPraxisPresentationVisualizationTableSafe(value) {
|
|
16490
|
+
const normalized = normalizePraxisPresentationVisualization(value);
|
|
16491
|
+
return !!normalized && TABLE_SAFE_KINDS.has(normalized.kind);
|
|
16492
|
+
}
|
|
16493
|
+
function renderPraxisPresentationVisualizationHtml(value, options = {}) {
|
|
16494
|
+
const visualization = normalizePraxisPresentationVisualization(value);
|
|
16495
|
+
if (!visualization) {
|
|
16496
|
+
return '';
|
|
16497
|
+
}
|
|
16498
|
+
switch (visualization.kind) {
|
|
16499
|
+
case 'comparison':
|
|
16500
|
+
return renderComparisonVisualizationHtml(visualization, options);
|
|
16501
|
+
case 'stackedBar':
|
|
16502
|
+
return renderStackedBarVisualizationHtml(visualization, options);
|
|
16503
|
+
case 'bullet':
|
|
16504
|
+
return renderBulletVisualizationHtml(visualization, options);
|
|
16505
|
+
case 'delta':
|
|
16506
|
+
return renderDeltaVisualizationHtml(visualization, options);
|
|
16507
|
+
case 'radial':
|
|
16508
|
+
return renderRadialVisualizationHtml(visualization, options);
|
|
16509
|
+
case 'harveyBall':
|
|
16510
|
+
return renderHarveyBallVisualizationHtml(visualization, options);
|
|
16511
|
+
case 'line':
|
|
16512
|
+
return renderLineVisualizationHtml(visualization, options);
|
|
16513
|
+
case 'area':
|
|
16514
|
+
return renderAreaVisualizationHtml(visualization, options);
|
|
16515
|
+
case 'column':
|
|
16516
|
+
return renderColumnVisualizationHtml(visualization, options);
|
|
16517
|
+
case 'processFlow':
|
|
16518
|
+
return renderProcessFlowVisualizationHtml(visualization, options);
|
|
16519
|
+
default:
|
|
16520
|
+
return `<span class="pfx-micro-viz__fallback">${escapeHtml$1(visualization.fallbackText)}</span>`;
|
|
16521
|
+
}
|
|
16522
|
+
}
|
|
16523
|
+
function renderComparisonVisualizationHtml(visualization, options) {
|
|
16524
|
+
const points = visualization.points ?? [];
|
|
16525
|
+
const max = Math.max(1, ...points.map((point) => Math.max(0, point.value)));
|
|
16526
|
+
const rows = points
|
|
16527
|
+
.map((point) => {
|
|
16528
|
+
const width = percent(point.value, max);
|
|
16529
|
+
return `
|
|
16530
|
+
<span class="pfx-micro-viz__row" data-tone="${escapeHtml$1(point.tone ?? visualization.tone ?? 'info')}">
|
|
16531
|
+
<span class="pfx-micro-viz__label">${escapeHtml$1(point.label ?? '')}</span>
|
|
16532
|
+
<span class="pfx-micro-viz__track">
|
|
16533
|
+
<span class="pfx-micro-viz__bar" style="width:${width}%"></span>
|
|
16534
|
+
</span>
|
|
16535
|
+
<span class="pfx-micro-viz__value">${escapeHtml$1(formatMicroNumber(point.value, options.locale))}</span>
|
|
16536
|
+
</span>`;
|
|
16537
|
+
})
|
|
16538
|
+
.join('');
|
|
16539
|
+
return `<span class="pfx-micro-viz" role="img" aria-label="${escapeHtml$1(visualization.ariaLabel ?? visualization.fallbackText)}">${rows}</span>`;
|
|
16540
|
+
}
|
|
16541
|
+
function renderStackedBarVisualizationHtml(visualization, options) {
|
|
16542
|
+
const segments = visualization.segments ?? [];
|
|
16543
|
+
const total = visualization.total && visualization.total > 0
|
|
16544
|
+
? visualization.total
|
|
16545
|
+
: Math.max(1, segments.reduce((sum, segment) => sum + Math.max(0, segment.value), 0));
|
|
16546
|
+
const bars = segments
|
|
16547
|
+
.map((segment) => `
|
|
16548
|
+
<span
|
|
16549
|
+
class="pfx-micro-viz__segment"
|
|
16550
|
+
data-tone="${escapeHtml$1(segment.tone ?? visualization.tone ?? 'info')}"
|
|
16551
|
+
style="width:${percent(segment.value, total)}%"
|
|
16552
|
+
title="${escapeHtml$1(`${segment.label ?? ''} ${formatMicroNumber(segment.value, options.locale)}`.trim())}"
|
|
16553
|
+
></span>`)
|
|
16554
|
+
.join('');
|
|
16555
|
+
const meta = segments
|
|
16556
|
+
.slice(0, 3)
|
|
16557
|
+
.map((segment) => `<span>${escapeHtml$1(segment.label ?? '')}: ${escapeHtml$1(formatMicroNumber(segment.value, options.locale))}</span>`)
|
|
16558
|
+
.join('');
|
|
16559
|
+
return `
|
|
16560
|
+
<span class="pfx-micro-viz" role="img" aria-label="${escapeHtml$1(visualization.ariaLabel ?? visualization.fallbackText)}">
|
|
16561
|
+
<span class="pfx-micro-viz__segments">${bars}</span>
|
|
16562
|
+
<span class="pfx-micro-viz__meta">${meta}</span>
|
|
16563
|
+
</span>`;
|
|
16564
|
+
}
|
|
16565
|
+
function resolveBulletMax(visualization) {
|
|
16566
|
+
const thresholds = visualization.thresholds ?? [];
|
|
16567
|
+
const values = [
|
|
16568
|
+
toFiniteNumber(visualization.value) ?? 0,
|
|
16569
|
+
visualization.target ?? 0,
|
|
16570
|
+
visualization.total ?? 0,
|
|
16571
|
+
...thresholds.map(t => t.value)
|
|
16572
|
+
].filter(v => Number.isFinite(v) && v > 0);
|
|
16573
|
+
return Math.max(...values, 100);
|
|
16574
|
+
}
|
|
16575
|
+
function renderBulletVisualizationHtml(visualization, options) {
|
|
16576
|
+
const currentValue = toFiniteNumber(visualization.value) ?? 0;
|
|
16577
|
+
const max = resolveBulletMax(visualization);
|
|
16578
|
+
const target = toFiniteNumber(visualization.target);
|
|
16579
|
+
const targetLeft = target === undefined ? null : percent(target, max);
|
|
16580
|
+
const isTable = visualization.surface === 'table-cell';
|
|
16581
|
+
// thresholds
|
|
16582
|
+
const thresholds = visualization.thresholds ?? [];
|
|
16583
|
+
let previous = 0;
|
|
16584
|
+
const bands = thresholds.map(t => {
|
|
16585
|
+
const current = Math.max(t.value, previous);
|
|
16586
|
+
const left = max > 0 ? percent(previous, max) : '0';
|
|
16587
|
+
const width = max > 0 ? percent(current - previous, max) : '0';
|
|
16588
|
+
previous = current;
|
|
16589
|
+
return { left, width, tone: t.tone ?? 'info' };
|
|
16590
|
+
}).filter(b => parseFloat(b.width) > 0);
|
|
16591
|
+
const bandsHtml = bands.map(b => `<span class="pfx-micro-bullet__range" data-tone="${escapeHtml$1(b.tone)}" style="left: ${b.left}%; width: ${b.width}%;"></span>`).join('');
|
|
16592
|
+
const topHtml = isTable ? '' : `
|
|
16593
|
+
<div class="pfx-micro-bullet__top">
|
|
16594
|
+
<span class="pfx-micro-bullet__label">${escapeHtml$1(visualization.fallbackText)}</span>
|
|
16595
|
+
<span class="pfx-micro-bullet__value">
|
|
16596
|
+
${escapeHtml$1(formatMicroNumber(currentValue, options.locale))}
|
|
16597
|
+
${target === undefined ? '' : `<span class="pfx-micro-bullet__target-val">/ Target: ${escapeHtml$1(formatMicroNumber(target, options.locale))}</span>`}
|
|
16598
|
+
</span>
|
|
16599
|
+
</div>`;
|
|
16600
|
+
const bottomHtml = isTable ? '' : `
|
|
16601
|
+
<div class="pfx-micro-bullet__bottom">
|
|
16602
|
+
<span>${escapeHtml$1(formatMicroNumber(visualization.baseline ?? 0, options.locale))}</span>
|
|
16603
|
+
<span>${escapeHtml$1(formatMicroNumber(max, options.locale))}</span>
|
|
16604
|
+
</div>`;
|
|
16605
|
+
return `
|
|
16606
|
+
<span class="pfx-micro-viz pfx-micro-viz__bullet" data-tone="${escapeHtml$1(visualization.tone ?? 'info')}" role="img" aria-label="${escapeHtml$1(visualization.ariaLabel ?? visualization.fallbackText)}">
|
|
16607
|
+
${topHtml}
|
|
16608
|
+
<span class="pfx-micro-bullet__track">
|
|
16609
|
+
${bandsHtml}
|
|
16610
|
+
<span class="pfx-micro-bullet__actual" data-tone="${escapeHtml$1(visualization.tone ?? 'info')}" style="width: ${percent(currentValue, max)}%;"></span>
|
|
16611
|
+
${targetLeft === null ? '' : `<span class="pfx-micro-bullet__target" style="left: ${targetLeft}%;"></span>`}
|
|
16612
|
+
</span>
|
|
16613
|
+
${bottomHtml}
|
|
16614
|
+
</span>`;
|
|
16615
|
+
}
|
|
16616
|
+
function renderDeltaVisualizationHtml(visualization, options) {
|
|
16617
|
+
const value = toFiniteNumber(visualization.value);
|
|
16618
|
+
const direction = value === undefined ? 'neutral' : value < 0 ? 'down' : value > 0 ? 'up' : 'neutral';
|
|
16619
|
+
const symbol = direction === 'up' ? '▲' : direction === 'down' ? '▼' : '→';
|
|
16620
|
+
const tone = visualization.tone ??
|
|
16621
|
+
(value === undefined
|
|
16622
|
+
? 'neutral'
|
|
16623
|
+
: value < 0
|
|
16624
|
+
? 'danger'
|
|
16625
|
+
: value > 0
|
|
16626
|
+
? 'success'
|
|
16627
|
+
: 'neutral');
|
|
16628
|
+
const valueSuffix = visualization.valueSuffix ?? '';
|
|
16629
|
+
const text = value === undefined
|
|
16630
|
+
? visualization.fallbackText
|
|
16631
|
+
: `${formatMicroNumber(Math.abs(value), options.locale)}${valueSuffix}`;
|
|
16632
|
+
const directionLabel = direction === 'up'
|
|
16633
|
+
? 'up'
|
|
16634
|
+
: direction === 'down'
|
|
16635
|
+
? 'down'
|
|
16636
|
+
: 'stable';
|
|
16637
|
+
const aria = visualization.ariaLabel ?? `${visualization.fallbackText}: ${directionLabel} ${text}`;
|
|
16638
|
+
return `
|
|
16639
|
+
<span class="pfx-micro-viz pfx-micro-viz__delta" data-tone="${escapeHtml$1(tone)}" data-direction="${escapeHtml$1(direction)}" role="img" aria-label="${escapeHtml$1(aria)}">
|
|
16640
|
+
<span class="pfx-micro-viz__delta-symbol" aria-hidden="true">${symbol}</span>
|
|
16641
|
+
<span>${escapeHtml$1(text)}</span>
|
|
16642
|
+
</span>`;
|
|
16643
|
+
}
|
|
16644
|
+
function percent(value, total) {
|
|
16645
|
+
if (!Number.isFinite(value) || !Number.isFinite(total) || total <= 0) {
|
|
16646
|
+
return '0';
|
|
16647
|
+
}
|
|
16648
|
+
return Math.max(0, Math.min(100, (value / total) * 100)).toFixed(2);
|
|
16649
|
+
}
|
|
16650
|
+
function toFiniteNumber(value) {
|
|
16651
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
16652
|
+
}
|
|
16653
|
+
function formatMicroNumber(value, locale) {
|
|
16654
|
+
return new Intl.NumberFormat(locale || undefined, {
|
|
16655
|
+
maximumFractionDigits: Math.abs(value) < 10 ? 2 : 0,
|
|
16656
|
+
}).format(value);
|
|
16657
|
+
}
|
|
16658
|
+
function escapeHtml$1(value) {
|
|
16659
|
+
return String(value ?? '')
|
|
16660
|
+
.replace(/&/g, '&')
|
|
16661
|
+
.replace(/</g, '<')
|
|
16662
|
+
.replace(/>/g, '>')
|
|
16663
|
+
.replace(/"/g, '"')
|
|
16664
|
+
.replace(/'/g, ''');
|
|
16665
|
+
}
|
|
16666
|
+
function normalizePoints(value) {
|
|
16667
|
+
const points = normalizeNumericEntries(value);
|
|
16668
|
+
return points.length ? { points } : undefined;
|
|
16669
|
+
}
|
|
16670
|
+
function normalizeSegments(value) {
|
|
16671
|
+
const segments = normalizeNumericEntries(value);
|
|
16672
|
+
return segments.length ? { segments } : undefined;
|
|
16673
|
+
}
|
|
16674
|
+
function normalizeThresholds(value) {
|
|
16675
|
+
const thresholds = normalizeNumericEntries(value);
|
|
16676
|
+
return thresholds.length ? { thresholds } : undefined;
|
|
16677
|
+
}
|
|
16678
|
+
function normalizeItems(value) {
|
|
16679
|
+
if (!Array.isArray(value)) {
|
|
16680
|
+
return undefined;
|
|
16681
|
+
}
|
|
16682
|
+
const items = value
|
|
16683
|
+
.map((item) => normalizeVisualizationItem(item))
|
|
16684
|
+
.filter((item) => !!item);
|
|
16685
|
+
return items.length ? { items } : undefined;
|
|
16686
|
+
}
|
|
16687
|
+
function normalizeExpression(value, key) {
|
|
16688
|
+
if (typeof value === 'string') {
|
|
16689
|
+
const normalized = value.trim();
|
|
16690
|
+
return normalized ? { [key]: normalized } : undefined;
|
|
16691
|
+
}
|
|
16692
|
+
if (value && typeof value === 'object') {
|
|
16693
|
+
return { [key]: value };
|
|
16694
|
+
}
|
|
16695
|
+
return undefined;
|
|
16696
|
+
}
|
|
16697
|
+
function normalizeNumericEntries(value) {
|
|
16698
|
+
if (!Array.isArray(value)) {
|
|
16699
|
+
return [];
|
|
16700
|
+
}
|
|
16701
|
+
return value
|
|
16702
|
+
.map((item) => {
|
|
16703
|
+
if (!item || typeof item !== 'object' || !Number.isFinite(item.value)) {
|
|
16704
|
+
return null;
|
|
16705
|
+
}
|
|
16706
|
+
const label = normalizeText$1(item.label);
|
|
16707
|
+
const tone = normalizeEnum$1(item.tone, VISUALIZATION_TONES);
|
|
16708
|
+
return {
|
|
16709
|
+
value: item.value,
|
|
16710
|
+
...(label ? { label } : {}),
|
|
16711
|
+
...(tone ? { tone } : {}),
|
|
16712
|
+
};
|
|
16713
|
+
})
|
|
16714
|
+
.filter((item) => !!item);
|
|
16715
|
+
}
|
|
16716
|
+
function normalizeVisualizationItem(item) {
|
|
16717
|
+
if (!item || typeof item !== 'object') {
|
|
16718
|
+
return null;
|
|
16719
|
+
}
|
|
16720
|
+
const id = normalizeText$1(item.id);
|
|
16721
|
+
const label = normalizeText$1(item.label);
|
|
16722
|
+
const icon = normalizeText$1(item.icon);
|
|
16723
|
+
const state = normalizeText$1(item.state);
|
|
16724
|
+
const tone = normalizeEnum$1(item.tone, VISUALIZATION_TONES);
|
|
16725
|
+
const normalizedValue = Number.isFinite(item.value) ? item.value : undefined;
|
|
16726
|
+
if (!id && !label && normalizedValue === undefined && !icon && !state && !tone) {
|
|
16727
|
+
return null;
|
|
16728
|
+
}
|
|
16729
|
+
return {
|
|
16730
|
+
...(id ? { id } : {}),
|
|
16731
|
+
...(label ? { label } : {}),
|
|
16732
|
+
...(normalizedValue !== undefined ? { value: normalizedValue } : {}),
|
|
16733
|
+
...(icon ? { icon } : {}),
|
|
16734
|
+
...(state ? { state } : {}),
|
|
16735
|
+
...(tone ? { tone } : {}),
|
|
16736
|
+
};
|
|
16737
|
+
}
|
|
16738
|
+
function normalizeNumber(value, key) {
|
|
16739
|
+
return Number.isFinite(value) ? { [key]: value } : undefined;
|
|
16740
|
+
}
|
|
16741
|
+
function normalizeEnum$1(value, allowed) {
|
|
16742
|
+
if (typeof value !== 'string') {
|
|
16743
|
+
return undefined;
|
|
16744
|
+
}
|
|
16745
|
+
const normalized = value.trim();
|
|
16746
|
+
return allowed.has(normalized) ? normalized : undefined;
|
|
16747
|
+
}
|
|
16748
|
+
function normalizeText$1(value) {
|
|
16749
|
+
if (typeof value !== 'string') {
|
|
16750
|
+
return undefined;
|
|
16751
|
+
}
|
|
16752
|
+
const trimmed = value.trim();
|
|
16753
|
+
return trimmed.length ? trimmed : undefined;
|
|
16754
|
+
}
|
|
16755
|
+
function renderRadialVisualizationHtml(visualization, options) {
|
|
16756
|
+
const value = toFiniteNumber(visualization.value) ?? 0;
|
|
16757
|
+
const total = visualization.total && visualization.total > 0 ? visualization.total : 100;
|
|
16758
|
+
const pct = Math.max(0, Math.min(100, (value / total) * 100));
|
|
16759
|
+
const tone = visualization.tone ?? 'info';
|
|
16760
|
+
const dashArray = `${pct.toFixed(1)}, 100`;
|
|
16761
|
+
const pctText = `${Math.round(pct)}%`;
|
|
16762
|
+
const aria = visualization.ariaLabel ?? `${visualization.fallbackText} (${pctText})`;
|
|
16763
|
+
const isTable = visualization.surface === 'table-cell';
|
|
16764
|
+
const svgText = isTable
|
|
16765
|
+
? ''
|
|
16766
|
+
: `<text x="18" y="21" class="pfx-micro-radial-svg__text">${escapeHtml$1(pctText)}</text>`;
|
|
16767
|
+
const externalText = isTable
|
|
16768
|
+
? `<span class="pfx-micro-radial-value">${escapeHtml$1(pctText)}</span>`
|
|
16769
|
+
: '';
|
|
16770
|
+
return `
|
|
16771
|
+
<span class="pfx-micro-viz pfx-micro-viz__radial" data-tone="${escapeHtml$1(tone)}" role="img" aria-label="${escapeHtml$1(aria)}">
|
|
16772
|
+
<svg class="pfx-micro-radial-svg" viewBox="0 0 36 36">
|
|
16773
|
+
<circle class="pfx-micro-radial-svg__track" cx="18" cy="18" r="15.9155" />
|
|
16774
|
+
<circle class="pfx-micro-radial-svg__bar" cx="18" cy="18" r="15.9155" stroke-dasharray="${dashArray}" transform="rotate(-90 18 18)" />
|
|
16775
|
+
${svgText}
|
|
16776
|
+
</svg>
|
|
16777
|
+
${externalText}
|
|
16778
|
+
</span>`;
|
|
16779
|
+
}
|
|
16780
|
+
function renderHarveyBallVisualizationHtml(visualization, options) {
|
|
16781
|
+
const value = toFiniteNumber(visualization.value) ?? 0;
|
|
16782
|
+
const total = visualization.total && visualization.total > 0 ? visualization.total : 100;
|
|
16783
|
+
const pct = Math.max(0, Math.min(100, (value / total) * 100));
|
|
16784
|
+
const tone = visualization.tone ?? 'info';
|
|
16785
|
+
const strokeLength = pct * 0.50265;
|
|
16786
|
+
const dashArray = `${strokeLength.toFixed(3)} 50.265`;
|
|
16787
|
+
const aria = visualization.ariaLabel ?? `${visualization.fallbackText} (${Math.round(pct)}%)`;
|
|
16788
|
+
return `
|
|
16789
|
+
<span class="pfx-micro-viz pfx-micro-viz__harvey" data-tone="${escapeHtml$1(tone)}" role="img" aria-label="${escapeHtml$1(aria)}">
|
|
16790
|
+
<svg class="pfx-micro-harvey-svg" viewBox="0 0 36 36">
|
|
16791
|
+
<circle class="pfx-micro-harvey-svg__track" cx="18" cy="18" r="16" />
|
|
16792
|
+
<circle class="pfx-micro-harvey-svg__bar" cx="18" cy="18" r="8" stroke-dasharray="${dashArray}" transform="rotate(-90 18 18)" />
|
|
16793
|
+
</svg>
|
|
16794
|
+
<span class="pfx-micro-harvey-fraction">
|
|
16795
|
+
<strong>${escapeHtml$1(formatMicroNumber(value, options.locale))}</strong>
|
|
16796
|
+
<span class="pfx-separator">/</span>
|
|
16797
|
+
<span class="pfx-total">${escapeHtml$1(formatMicroNumber(total, options.locale))}</span>
|
|
16798
|
+
</span>
|
|
16799
|
+
</span>`;
|
|
16800
|
+
}
|
|
16801
|
+
function getPointsCoordinates(points, width, height, padding) {
|
|
16802
|
+
if (points.length < 2)
|
|
16803
|
+
return [];
|
|
16804
|
+
const values = points.map(p => p.value);
|
|
16805
|
+
const minVal = Math.min(...values);
|
|
16806
|
+
const maxVal = Math.max(...values);
|
|
16807
|
+
const valRange = maxVal - minVal === 0 ? 1 : maxVal - minVal;
|
|
16808
|
+
return points.map((p, index) => {
|
|
16809
|
+
const x = padding + (index / (points.length - 1)) * (width - 2 * padding);
|
|
16810
|
+
const y = height - padding - ((p.value - minVal) / valRange) * (height - 2 * padding);
|
|
16811
|
+
return { x, y };
|
|
16812
|
+
});
|
|
16813
|
+
}
|
|
16814
|
+
function renderLineVisualizationHtml(visualization, options) {
|
|
16815
|
+
const points = visualization.points ?? [];
|
|
16816
|
+
const tone = visualization.tone ?? 'info';
|
|
16817
|
+
if (points.length < 2) {
|
|
16818
|
+
return renderFallbackVisualizationHtml(visualization, tone);
|
|
16819
|
+
}
|
|
16820
|
+
const width = 100;
|
|
16821
|
+
const height = 30;
|
|
16822
|
+
const padding = 4;
|
|
16823
|
+
const coords = getPointsCoordinates(points, width, height, padding);
|
|
16824
|
+
const pathD = coords.map((c, i) => `${i === 0 ? 'M' : 'L'} ${c.x.toFixed(1)} ${c.y.toFixed(1)}`).join(' ');
|
|
16825
|
+
// Highlight extreme/boundary values
|
|
16826
|
+
let minIdx = 0;
|
|
16827
|
+
let maxIdx = 0;
|
|
16828
|
+
for (let i = 1; i < points.length; i++) {
|
|
16829
|
+
if (points[i].value < points[minIdx].value)
|
|
16830
|
+
minIdx = i;
|
|
16831
|
+
if (points[i].value > points[maxIdx].value)
|
|
16832
|
+
maxIdx = i;
|
|
16833
|
+
}
|
|
16834
|
+
const markers = [
|
|
16835
|
+
{ x: coords[0].x, y: coords[0].y, tone: points[0].tone ?? tone },
|
|
16836
|
+
{ x: coords[coords.length - 1].x, y: coords[coords.length - 1].y, tone: points[points.length - 1].tone ?? tone }
|
|
16837
|
+
];
|
|
16838
|
+
if (minIdx !== 0 && minIdx !== coords.length - 1) {
|
|
16839
|
+
markers.push({ x: coords[minIdx].x, y: coords[minIdx].y, tone: points[minIdx].tone ?? 'danger' });
|
|
16840
|
+
}
|
|
16841
|
+
if (maxIdx !== 0 && maxIdx !== coords.length - 1) {
|
|
16842
|
+
markers.push({ x: coords[maxIdx].x, y: coords[maxIdx].y, tone: points[maxIdx].tone ?? 'success' });
|
|
16843
|
+
}
|
|
16844
|
+
const circlesHtml = markers.map(c => `<circle cx="${c.x.toFixed(1)}" cy="${c.y.toFixed(1)}" r="2.5" class="pfx-micro-trend__marker" data-tone="${escapeHtml$1(c.tone)}" />`).join('');
|
|
16845
|
+
const isTable = visualization.surface === 'table-cell';
|
|
16846
|
+
const firstPoint = points[0];
|
|
16847
|
+
const lastPoint = points[points.length - 1];
|
|
16848
|
+
const leftHtml = isTable ? '' : `
|
|
16849
|
+
<div class="pfx-micro-trend__label-col pfx-micro-trend__label-col--start">
|
|
16850
|
+
<span class="pfx-micro-trend__value">${escapeHtml$1(formatMicroNumber(firstPoint.value, options.locale))}</span>
|
|
16851
|
+
${firstPoint.label ? `<span class="pfx-micro-trend__label">${escapeHtml$1(firstPoint.label)}</span>` : ''}
|
|
16852
|
+
</div>`;
|
|
16853
|
+
const rightHtml = isTable ? '' : `
|
|
16854
|
+
<div class="pfx-micro-trend__label-col pfx-micro-trend__label-col--end">
|
|
16855
|
+
<span class="pfx-micro-trend__value">${escapeHtml$1(formatMicroNumber(lastPoint.value, options.locale))}</span>
|
|
16856
|
+
${lastPoint.label ? `<span class="pfx-micro-trend__label">${escapeHtml$1(lastPoint.label)}</span>` : ''}
|
|
16857
|
+
</div>`;
|
|
16858
|
+
return `
|
|
16859
|
+
<span class="pfx-micro-viz-container">
|
|
16860
|
+
${leftHtml}
|
|
16861
|
+
<span class="pfx-micro-viz pfx-micro-viz__line" data-tone="${escapeHtml$1(tone)}" role="img" aria-label="${escapeHtml$1(visualization.ariaLabel ?? visualization.fallbackText)}">
|
|
16862
|
+
<svg class="pfx-micro-line__svg" viewBox="0 0 100 30">
|
|
16863
|
+
<path class="pfx-micro-line__path" d="${pathD}" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
16864
|
+
${circlesHtml}
|
|
16865
|
+
</svg>
|
|
16866
|
+
</span>
|
|
16867
|
+
${rightHtml}
|
|
16868
|
+
</span>`;
|
|
16869
|
+
}
|
|
16870
|
+
function renderAreaVisualizationHtml(visualization, options) {
|
|
16871
|
+
const points = visualization.points ?? [];
|
|
16872
|
+
const tone = visualization.tone ?? 'info';
|
|
16873
|
+
if (points.length < 2) {
|
|
16874
|
+
return renderFallbackVisualizationHtml(visualization, tone);
|
|
16875
|
+
}
|
|
16876
|
+
const width = 100;
|
|
16877
|
+
const height = 30;
|
|
16878
|
+
const padding = 4;
|
|
16879
|
+
const coords = getPointsCoordinates(points, width, height, padding);
|
|
16880
|
+
const lineD = coords.map((c, i) => `${i === 0 ? 'M' : 'L'} ${c.x.toFixed(1)} ${c.y.toFixed(1)}`).join(' ');
|
|
16881
|
+
const firstX = coords[0].x.toFixed(1);
|
|
16882
|
+
const lastX = coords[coords.length - 1].x.toFixed(1);
|
|
16883
|
+
const areaD = `${lineD} L ${lastX} ${height} L ${firstX} ${height} Z`;
|
|
16884
|
+
// Highlight extreme/boundary values
|
|
16885
|
+
let minIdx = 0;
|
|
16886
|
+
let maxIdx = 0;
|
|
16887
|
+
for (let i = 1; i < points.length; i++) {
|
|
16888
|
+
if (points[i].value < points[minIdx].value)
|
|
16889
|
+
minIdx = i;
|
|
16890
|
+
if (points[i].value > points[maxIdx].value)
|
|
16891
|
+
maxIdx = i;
|
|
16892
|
+
}
|
|
16893
|
+
const markers = [
|
|
16894
|
+
{ x: coords[0].x, y: coords[0].y, tone: points[0].tone ?? tone },
|
|
16895
|
+
{ x: coords[coords.length - 1].x, y: coords[coords.length - 1].y, tone: points[points.length - 1].tone ?? tone }
|
|
16896
|
+
];
|
|
16897
|
+
if (minIdx !== 0 && minIdx !== coords.length - 1) {
|
|
16898
|
+
markers.push({ x: coords[minIdx].x, y: coords[minIdx].y, tone: points[minIdx].tone ?? 'danger' });
|
|
16899
|
+
}
|
|
16900
|
+
if (maxIdx !== 0 && maxIdx !== coords.length - 1) {
|
|
16901
|
+
markers.push({ x: coords[maxIdx].x, y: coords[maxIdx].y, tone: points[maxIdx].tone ?? 'success' });
|
|
16902
|
+
}
|
|
16903
|
+
const circlesHtml = markers.map(c => `<circle cx="${c.x.toFixed(1)}" cy="${c.y.toFixed(1)}" r="2.5" class="pfx-micro-trend__marker" data-tone="${escapeHtml$1(c.tone)}" />`).join('');
|
|
16904
|
+
const isTable = visualization.surface === 'table-cell';
|
|
16905
|
+
const firstPoint = points[0];
|
|
16906
|
+
const lastPoint = points[points.length - 1];
|
|
16907
|
+
const leftHtml = isTable ? '' : `
|
|
16908
|
+
<div class="pfx-micro-trend__label-col pfx-micro-trend__label-col--start">
|
|
16909
|
+
<span class="pfx-micro-trend__value">${escapeHtml$1(formatMicroNumber(firstPoint.value, options.locale))}</span>
|
|
16910
|
+
${firstPoint.label ? `<span class="pfx-micro-trend__label">${escapeHtml$1(firstPoint.label)}</span>` : ''}
|
|
16911
|
+
</div>`;
|
|
16912
|
+
const rightHtml = isTable ? '' : `
|
|
16913
|
+
<div class="pfx-micro-trend__label-col pfx-micro-trend__label-col--end">
|
|
16914
|
+
<span class="pfx-micro-trend__value">${escapeHtml$1(formatMicroNumber(lastPoint.value, options.locale))}</span>
|
|
16915
|
+
${lastPoint.label ? `<span class="pfx-micro-trend__label">${escapeHtml$1(lastPoint.label)}</span>` : ''}
|
|
16916
|
+
</div>`;
|
|
16917
|
+
return `
|
|
16918
|
+
<span class="pfx-micro-viz-container">
|
|
16919
|
+
${leftHtml}
|
|
16920
|
+
<span class="pfx-micro-viz pfx-micro-viz__area" data-tone="${escapeHtml$1(tone)}" role="img" aria-label="${escapeHtml$1(visualization.ariaLabel ?? visualization.fallbackText)}">
|
|
16921
|
+
<svg class="pfx-micro-area__svg" viewBox="0 0 100 30">
|
|
16922
|
+
<path class="pfx-micro-area__fill" d="${areaD}" fill="currentColor" fill-opacity="0.15" />
|
|
16923
|
+
<path class="pfx-micro-area__path" d="${lineD}" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
16924
|
+
${circlesHtml}
|
|
16925
|
+
</svg>
|
|
16926
|
+
</span>
|
|
16927
|
+
${rightHtml}
|
|
16928
|
+
</span>`;
|
|
16929
|
+
}
|
|
16930
|
+
function renderColumnVisualizationHtml(visualization, options) {
|
|
16931
|
+
const points = visualization.points ?? [];
|
|
16932
|
+
const tone = visualization.tone ?? 'info';
|
|
16933
|
+
if (points.length === 0) {
|
|
16934
|
+
return renderFallbackVisualizationHtml(visualization, tone);
|
|
16935
|
+
}
|
|
16936
|
+
const width = 100;
|
|
16937
|
+
const height = 30;
|
|
16938
|
+
const padding = 4;
|
|
16939
|
+
const values = points.map(p => p.value);
|
|
16940
|
+
const maxVal = Math.max(...values, 0);
|
|
16941
|
+
const minVal = Math.min(...values, 0);
|
|
16942
|
+
const valRange = maxVal - minVal === 0 ? 1 : maxVal - minVal;
|
|
16943
|
+
const colWidth = Math.max(2, (width - 2 * padding) / points.length - 2);
|
|
16944
|
+
const columnsHtml = points.map((p, i) => {
|
|
16945
|
+
const x = padding + i * ((width - 2 * padding) / points.length) + 1;
|
|
16946
|
+
const rectHeight = Math.max(2, ((p.value - minVal) / valRange) * (height - 2 * padding));
|
|
16947
|
+
const rectY = height - padding - rectHeight;
|
|
16948
|
+
const itemTone = p.tone ?? tone;
|
|
16949
|
+
return `<rect class="pfx-micro-column__bar" x="${x.toFixed(1)}" y="${rectY.toFixed(1)}" width="${colWidth.toFixed(1)}" height="${rectHeight.toFixed(1)}" fill="currentColor" data-tone="${escapeHtml$1(itemTone)}" />`;
|
|
16950
|
+
}).join('');
|
|
16951
|
+
const isTable = visualization.surface === 'table-cell';
|
|
16952
|
+
const firstPoint = points[0];
|
|
16953
|
+
const lastPoint = points[points.length - 1];
|
|
16954
|
+
const leftHtml = isTable ? '' : `
|
|
16955
|
+
<div class="pfx-micro-trend__label-col pfx-micro-trend__label-col--start">
|
|
16956
|
+
<span class="pfx-micro-trend__value">${escapeHtml$1(formatMicroNumber(firstPoint.value, options.locale))}</span>
|
|
16957
|
+
${firstPoint.label ? `<span class="pfx-micro-trend__label">${escapeHtml$1(firstPoint.label)}</span>` : ''}
|
|
16958
|
+
</div>`;
|
|
16959
|
+
const rightHtml = isTable ? '' : `
|
|
16960
|
+
<div class="pfx-micro-trend__label-col pfx-micro-trend__label-col--end">
|
|
16961
|
+
<span class="pfx-micro-trend__value">${escapeHtml$1(formatMicroNumber(lastPoint.value, options.locale))}</span>
|
|
16962
|
+
${lastPoint.label ? `<span class="pfx-micro-trend__label">${escapeHtml$1(lastPoint.label)}</span>` : ''}
|
|
16963
|
+
</div>`;
|
|
16964
|
+
return `
|
|
16965
|
+
<span class="pfx-micro-viz-container">
|
|
16966
|
+
${leftHtml}
|
|
16967
|
+
<span class="pfx-micro-viz pfx-micro-viz__column" data-tone="${escapeHtml$1(tone)}" role="img" aria-label="${escapeHtml$1(visualization.ariaLabel ?? visualization.fallbackText)}">
|
|
16968
|
+
<svg class="pfx-micro-column__svg" viewBox="0 0 100 30">
|
|
16969
|
+
${columnsHtml}
|
|
16970
|
+
</svg>
|
|
16971
|
+
</span>
|
|
16972
|
+
${rightHtml}
|
|
16973
|
+
</span>`;
|
|
16974
|
+
}
|
|
16975
|
+
function renderProcessFlowVisualizationHtml(visualization, options) {
|
|
16976
|
+
const items = visualization.items ?? [];
|
|
16977
|
+
if (items.length === 0) {
|
|
16978
|
+
return renderFallbackVisualizationHtml(visualization, visualization.tone ?? 'neutral');
|
|
16979
|
+
}
|
|
16980
|
+
const isTable = visualization.surface === 'table-cell';
|
|
16981
|
+
const stepLabels = items.map((item, index) => item.label ?? item.id ?? `${index + 1}`);
|
|
16982
|
+
const aria = visualization.ariaLabel ?? `${visualization.fallbackText}: ${stepLabels.join(' > ')}`;
|
|
16983
|
+
const stepsHtml = items.map((item, index) => {
|
|
16984
|
+
const itemTone = item.tone ?? 'neutral';
|
|
16985
|
+
const itemState = item.state ?? '';
|
|
16986
|
+
const isLast = index === items.length - 1;
|
|
16987
|
+
const itemLabel = stepLabels[index];
|
|
16988
|
+
const label = !isTable && item.label ? `<span class="pfx-micro-step__label">${escapeHtml$1(item.label)}</span>` : '';
|
|
16989
|
+
const connector = !isLast ? `<span class="pfx-micro-step__connector" data-tone="${escapeHtml$1(itemTone)}"></span>` : '';
|
|
16990
|
+
const stepCircle = `
|
|
16991
|
+
<span class="pfx-micro-step__node" data-tone="${escapeHtml$1(itemTone)}" aria-hidden="true">
|
|
16992
|
+
${item.icon ? `<span class="material-icons pfx-micro-step__icon" aria-hidden="true">${escapeHtml$1(item.icon)}</span>` : `${index + 1}`}
|
|
16993
|
+
</span>`;
|
|
16994
|
+
return `
|
|
16995
|
+
<div class="pfx-micro-step" data-state="${escapeHtml$1(itemState)}" data-tone="${escapeHtml$1(itemTone)}">
|
|
16996
|
+
<div class="pfx-micro-step__node-wrapper" title="${escapeHtml$1(itemLabel)}">
|
|
16997
|
+
${stepCircle}
|
|
16998
|
+
${label}
|
|
16999
|
+
</div>
|
|
17000
|
+
${connector}
|
|
17001
|
+
</div>`;
|
|
17002
|
+
}).join('');
|
|
17003
|
+
return `
|
|
17004
|
+
<span class="pfx-micro-viz pfx-micro-viz__process" role="img" aria-label="${escapeHtml$1(aria)}">
|
|
17005
|
+
${stepsHtml}
|
|
17006
|
+
</span>`;
|
|
17007
|
+
}
|
|
17008
|
+
function renderFallbackVisualizationHtml(visualization, tone) {
|
|
17009
|
+
return `
|
|
17010
|
+
<span
|
|
17011
|
+
class="pfx-micro-viz pfx-micro-viz__fallback"
|
|
17012
|
+
data-tone="${escapeHtml$1(tone)}"
|
|
17013
|
+
role="img"
|
|
17014
|
+
aria-label="${escapeHtml$1(visualization.ariaLabel ?? visualization.fallbackText)}"
|
|
17015
|
+
>${escapeHtml$1(visualization.fallbackText)}</span>`;
|
|
17016
|
+
}
|
|
17017
|
+
|
|
17018
|
+
const TONES = new Set([
|
|
17019
|
+
'neutral',
|
|
17020
|
+
'info',
|
|
17021
|
+
'success',
|
|
17022
|
+
'warning',
|
|
17023
|
+
'danger',
|
|
17024
|
+
]);
|
|
17025
|
+
const APPEARANCES = new Set([
|
|
17026
|
+
'plain',
|
|
17027
|
+
'soft',
|
|
17028
|
+
'outlined',
|
|
17029
|
+
'filled',
|
|
17030
|
+
]);
|
|
17031
|
+
const PRESENTERS = new Set([
|
|
17032
|
+
'text',
|
|
17033
|
+
'badge',
|
|
17034
|
+
'chip',
|
|
17035
|
+
'status',
|
|
17036
|
+
'iconValue',
|
|
17037
|
+
'progress',
|
|
17038
|
+
'rating',
|
|
17039
|
+
'microVisualization',
|
|
17040
|
+
]);
|
|
17041
|
+
/**
|
|
17042
|
+
* Resolves readonly field presentation from a base semantic config plus ordered
|
|
17043
|
+
* Json Logic rules. Later matching rules override earlier presentation values.
|
|
17044
|
+
*/
|
|
17045
|
+
function resolveFieldPresentation(base, rules, context = {}, options = {}) {
|
|
17046
|
+
let resolved = normalizeFieldPresentation(base);
|
|
17047
|
+
let matchedRule = false;
|
|
17048
|
+
if (!Array.isArray(rules) || !options.jsonLogic) {
|
|
17049
|
+
return resolved;
|
|
17050
|
+
}
|
|
17051
|
+
for (const rule of rules) {
|
|
17052
|
+
if (!rule?.when || !matchesPresentationRule(rule, context, options.jsonLogic)) {
|
|
17053
|
+
continue;
|
|
17054
|
+
}
|
|
17055
|
+
const effect = normalizeFieldPresentation(rule.set ?? rule.effect);
|
|
17056
|
+
resolved = {
|
|
17057
|
+
...resolved,
|
|
17058
|
+
...effect,
|
|
17059
|
+
};
|
|
17060
|
+
matchedRule = true;
|
|
17061
|
+
}
|
|
17062
|
+
return matchedRule ? { ...resolved, matchedRule } : resolved;
|
|
17063
|
+
}
|
|
17064
|
+
function normalizeFieldPresentation(value) {
|
|
17065
|
+
if (!value || typeof value !== 'object') {
|
|
17066
|
+
return {};
|
|
17067
|
+
}
|
|
17068
|
+
const presenter = normalizePresenter(value.presenter ?? value.variant);
|
|
17069
|
+
const tone = normalizeTone(value.tone);
|
|
17070
|
+
const appearance = normalizeAppearance(value.appearance);
|
|
17071
|
+
const icon = normalizeText(value.icon);
|
|
17072
|
+
const label = normalizeText(value.label);
|
|
17073
|
+
const badge = normalizeText(value.badge);
|
|
17074
|
+
const tooltip = normalizeText(value.tooltip);
|
|
17075
|
+
const visualization = normalizePraxisPresentationVisualization(value.visualization);
|
|
17076
|
+
return {
|
|
17077
|
+
...(presenter ? { presenter } : {}),
|
|
17078
|
+
...(tone ? { tone } : {}),
|
|
17079
|
+
...(appearance ? { appearance } : {}),
|
|
17080
|
+
...(icon ? { icon } : {}),
|
|
17081
|
+
...(label ? { label } : {}),
|
|
17082
|
+
...(badge ? { badge } : {}),
|
|
17083
|
+
...(tooltip ? { tooltip } : {}),
|
|
17084
|
+
...(value.valuePresentation && typeof value.valuePresentation === 'object'
|
|
17085
|
+
? { valuePresentation: value.valuePresentation }
|
|
17086
|
+
: {}),
|
|
17087
|
+
...(visualization ? { visualization } : {}),
|
|
17088
|
+
...(value.interactions && typeof value.interactions === 'object'
|
|
17089
|
+
? { interactions: normalizeInteractions(value.interactions) }
|
|
17090
|
+
: {}),
|
|
17091
|
+
};
|
|
17092
|
+
}
|
|
17093
|
+
function matchesPresentationRule(rule, context, jsonLogic) {
|
|
17094
|
+
try {
|
|
17095
|
+
const result = jsonLogic.evaluate(rule.when, context);
|
|
17096
|
+
return typeof jsonLogic.truthy === 'function'
|
|
17097
|
+
? jsonLogic.truthy(result)
|
|
17098
|
+
: Boolean(result);
|
|
17099
|
+
}
|
|
17100
|
+
catch {
|
|
17101
|
+
return false;
|
|
17102
|
+
}
|
|
17103
|
+
}
|
|
17104
|
+
function normalizePresenter(value) {
|
|
17105
|
+
return normalizeEnum(value, PRESENTERS);
|
|
17106
|
+
}
|
|
17107
|
+
function normalizeTone(value) {
|
|
17108
|
+
return normalizeEnum(value, TONES);
|
|
17109
|
+
}
|
|
17110
|
+
function normalizeAppearance(value) {
|
|
17111
|
+
return normalizeEnum(value, APPEARANCES);
|
|
17112
|
+
}
|
|
17113
|
+
function normalizeEnum(value, allowed) {
|
|
17114
|
+
if (typeof value !== 'string') {
|
|
17115
|
+
return undefined;
|
|
17116
|
+
}
|
|
17117
|
+
const normalized = value.trim();
|
|
17118
|
+
return allowed.has(normalized) ? normalized : undefined;
|
|
17119
|
+
}
|
|
17120
|
+
function normalizeText(value) {
|
|
17121
|
+
if (typeof value !== 'string') {
|
|
17122
|
+
return undefined;
|
|
17123
|
+
}
|
|
17124
|
+
const trimmed = value.trim();
|
|
17125
|
+
return trimmed.length ? trimmed : undefined;
|
|
17126
|
+
}
|
|
17127
|
+
function normalizeInteractions(value) {
|
|
17128
|
+
return {
|
|
17129
|
+
...(value.copy === true ? { copy: true } : {}),
|
|
17130
|
+
...(value.details === true ? { details: true } : {}),
|
|
17131
|
+
...(value.expand === true ? { expand: true } : {}),
|
|
17132
|
+
...(value.link === true ? { link: true } : {}),
|
|
17133
|
+
};
|
|
17134
|
+
}
|
|
17135
|
+
|
|
16019
17136
|
/**
|
|
16020
17137
|
* @fileoverview Specialized metadata interfaces for Angular Material components
|
|
16021
17138
|
*
|
|
@@ -16392,6 +17509,43 @@ function normalizeSelectLike(meta) {
|
|
|
16392
17509
|
return m;
|
|
16393
17510
|
}
|
|
16394
17511
|
|
|
17512
|
+
const SERVER_OWNED_FIELD_SEMANTIC_KEYS = [
|
|
17513
|
+
'label',
|
|
17514
|
+
'hint',
|
|
17515
|
+
'helpText',
|
|
17516
|
+
'description',
|
|
17517
|
+
'tooltip',
|
|
17518
|
+
'tooltipOnHover',
|
|
17519
|
+
'icon',
|
|
17520
|
+
'prefixIcon',
|
|
17521
|
+
'suffixIcon',
|
|
17522
|
+
'iconPosition',
|
|
17523
|
+
'iconSize',
|
|
17524
|
+
'iconColor',
|
|
17525
|
+
'iconClass',
|
|
17526
|
+
'iconStyle',
|
|
17527
|
+
'iconFontSize',
|
|
17528
|
+
];
|
|
17529
|
+
function applyServerOwnedFieldSemantics(merged, serverField) {
|
|
17530
|
+
const next = { ...merged };
|
|
17531
|
+
const server = serverField;
|
|
17532
|
+
for (const key of SERVER_OWNED_FIELD_SEMANTIC_KEYS) {
|
|
17533
|
+
if (server[key] === undefined) {
|
|
17534
|
+
delete next[key];
|
|
17535
|
+
}
|
|
17536
|
+
else {
|
|
17537
|
+
next[key] = server[key];
|
|
17538
|
+
}
|
|
17539
|
+
}
|
|
17540
|
+
return next;
|
|
17541
|
+
}
|
|
17542
|
+
|
|
17543
|
+
function withFormConfigSections(config) {
|
|
17544
|
+
return {
|
|
17545
|
+
...config,
|
|
17546
|
+
sections: config.sections || [],
|
|
17547
|
+
};
|
|
17548
|
+
}
|
|
16395
17549
|
function createDefaultFormConfig() {
|
|
16396
17550
|
const config = {
|
|
16397
17551
|
sections: [
|
|
@@ -16435,7 +17589,21 @@ function createDefaultFormConfig() {
|
|
|
16435
17589
|
return ensureIds(config);
|
|
16436
17590
|
}
|
|
16437
17591
|
function isValidFormConfig(config) {
|
|
16438
|
-
|
|
17592
|
+
if (!config || typeof config !== 'object') {
|
|
17593
|
+
return false;
|
|
17594
|
+
}
|
|
17595
|
+
if (config.sections !== undefined) {
|
|
17596
|
+
return Array.isArray(config.sections);
|
|
17597
|
+
}
|
|
17598
|
+
return hasSchemaDrivenFormConfigGrounding(config);
|
|
17599
|
+
}
|
|
17600
|
+
function hasSchemaDrivenFormConfigGrounding(config) {
|
|
17601
|
+
const metadata = config.metadata;
|
|
17602
|
+
return (metadata?.source === 'schema' ||
|
|
17603
|
+
!!metadata?.schemaLayoutPolicy ||
|
|
17604
|
+
!!metadata?.schemaId ||
|
|
17605
|
+
!!metadata?.schemaContext ||
|
|
17606
|
+
Array.isArray(config.fieldMetadata));
|
|
16439
17607
|
}
|
|
16440
17608
|
/**
|
|
16441
17609
|
* Cria configuração vazia para inicialização
|
|
@@ -16488,7 +17656,7 @@ function mergeFieldMetadata(config, fieldMetadata) {
|
|
|
16488
17656
|
function getReferencedFieldMetadata(config, allFieldMetadata) {
|
|
16489
17657
|
// Get all field names referenced in the config
|
|
16490
17658
|
const referencedFieldNames = new Set();
|
|
16491
|
-
config.sections.forEach((section) => {
|
|
17659
|
+
withFormConfigSections(config).sections.forEach((section) => {
|
|
16492
17660
|
section.rows.forEach((row) => {
|
|
16493
17661
|
row.columns.forEach((column) => {
|
|
16494
17662
|
getFormColumnFieldNames(column).forEach((fieldName) => {
|
|
@@ -16554,7 +17722,7 @@ function syncWithServerMetadata(localConfig, serverMetadata) {
|
|
|
16554
17722
|
toggleOptions: pick('toggleOptions'),
|
|
16555
17723
|
nodes: pick('nodes'),
|
|
16556
17724
|
};
|
|
16557
|
-
mergedOverlapping.push(merged);
|
|
17725
|
+
mergedOverlapping.push(applyServerOwnedFieldSemantics(merged, serverField));
|
|
16558
17726
|
// Track simple modifications for diagnostics
|
|
16559
17727
|
['label', 'required', 'maxLength', 'minLength', 'dataType', 'controlType'].forEach((prop) => {
|
|
16560
17728
|
if (loc[prop] !== base[prop]) {
|
|
@@ -16894,7 +18062,7 @@ const EVENT_REGISTRATION_EDITORIAL_TEMPLATE = {
|
|
|
16894
18062
|
content: [
|
|
16895
18063
|
{
|
|
16896
18064
|
type: 'text',
|
|
16897
|
-
text: 'Ao enviar a
|
|
18065
|
+
text: 'Ao enviar a inscrição, o participante reconhece o tratamento dos dados para credenciamento, comunicações e operação do evento.',
|
|
16898
18066
|
},
|
|
16899
18067
|
],
|
|
16900
18068
|
}),
|
|
@@ -17035,7 +18203,7 @@ const EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE = {
|
|
|
17035
18203
|
wrap: true,
|
|
17036
18204
|
items: [
|
|
17037
18205
|
{ type: 'badge', label: 'onboarding' },
|
|
17038
|
-
{ type: 'text', text: '
|
|
18206
|
+
{ type: 'text', text: 'Admissão, conferência e preferências iniciais' },
|
|
17039
18207
|
],
|
|
17040
18208
|
},
|
|
17041
18209
|
}, {
|
|
@@ -17044,7 +18212,7 @@ const EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE = {
|
|
|
17044
18212
|
subtitle: 'Resumo do fluxo',
|
|
17045
18213
|
content: [
|
|
17046
18214
|
{ type: 'text', text: 'Dados pessoais e de contato.' },
|
|
17047
|
-
{ type: 'text', text: '
|
|
18215
|
+
{ type: 'text', text: 'Preferências operacionais iniciais.' },
|
|
17048
18216
|
{ type: 'text', text: 'Anexos e termos obrigatorios.' },
|
|
17049
18217
|
],
|
|
17050
18218
|
}),
|
|
@@ -17076,7 +18244,7 @@ const EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE = {
|
|
|
17076
18244
|
id: 'operations',
|
|
17077
18245
|
appearance: 'step',
|
|
17078
18246
|
stepLabel: '2',
|
|
17079
|
-
title: '
|
|
18247
|
+
title: 'Operação inicial',
|
|
17080
18248
|
description: 'Dados para preparacao do ambiente e comunicacao inicial.',
|
|
17081
18249
|
rows: [
|
|
17082
18250
|
{
|
|
@@ -17102,7 +18270,7 @@ const EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE = {
|
|
|
17102
18270
|
title: 'Uso interno',
|
|
17103
18271
|
subtitle: 'Antes do envio',
|
|
17104
18272
|
badge: 'info',
|
|
17105
|
-
description: 'As
|
|
18273
|
+
description: 'As informações deste fluxo são usadas exclusivamente para cadastro interno, provisionamento e comunicação de onboarding.',
|
|
17106
18274
|
}),
|
|
17107
18275
|
formBlocksBeforeActionsPlacement: 'afterSections',
|
|
17108
18276
|
actions: {
|
|
@@ -17151,7 +18319,7 @@ const EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE = {
|
|
|
17151
18319
|
required: true,
|
|
17152
18320
|
options: [
|
|
17153
18321
|
{ text: 'Presencial', value: 'ONSITE' },
|
|
17154
|
-
{ text: '
|
|
18322
|
+
{ text: 'Híbrido', value: 'HYBRID' },
|
|
17155
18323
|
{ text: 'Remoto', value: 'REMOTE' },
|
|
17156
18324
|
],
|
|
17157
18325
|
},
|
|
@@ -17162,22 +18330,22 @@ const EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE = {
|
|
|
17162
18330
|
required: true,
|
|
17163
18331
|
options: [
|
|
17164
18332
|
{ text: 'Sim', value: 'YES' },
|
|
17165
|
-
{ text: '
|
|
18333
|
+
{ text: 'Não', value: 'NO' },
|
|
17166
18334
|
],
|
|
17167
18335
|
},
|
|
17168
18336
|
{
|
|
17169
18337
|
name: 'shippingAddress',
|
|
17170
|
-
label: '
|
|
18338
|
+
label: 'Endereço para envio',
|
|
17171
18339
|
controlType: 'textarea',
|
|
17172
18340
|
},
|
|
17173
18341
|
{
|
|
17174
18342
|
name: 'accessibilityNotes',
|
|
17175
|
-
label: '
|
|
18343
|
+
label: 'Observações de acessibilidade ou preferências',
|
|
17176
18344
|
controlType: 'textarea',
|
|
17177
18345
|
},
|
|
17178
18346
|
{
|
|
17179
18347
|
name: 'privacyConsent',
|
|
17180
|
-
label: 'Confirmo
|
|
18348
|
+
label: 'Confirmo ciência sobre o tratamento dos meus dados no processo de onboarding.',
|
|
17181
18349
|
controlType: 'checkbox',
|
|
17182
18350
|
selectionMode: 'boolean',
|
|
17183
18351
|
variant: 'consent',
|
|
@@ -17250,7 +18418,7 @@ const EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE = {
|
|
|
17250
18418
|
id: 'operations',
|
|
17251
18419
|
appearance: 'step',
|
|
17252
18420
|
stepLabel: '2',
|
|
17253
|
-
title: '
|
|
18421
|
+
title: 'Operação inicial',
|
|
17254
18422
|
description: 'Configure os recursos necessarios para o primeiro dia.',
|
|
17255
18423
|
rows: [
|
|
17256
18424
|
{
|
|
@@ -17360,17 +18528,17 @@ const EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE = {
|
|
|
17360
18528
|
options: [
|
|
17361
18529
|
{ text: 'Presencial', value: 'Presencial' },
|
|
17362
18530
|
{ text: 'Remoto', value: 'Remoto' },
|
|
17363
|
-
{ text: '
|
|
18531
|
+
{ text: 'Híbrido', value: 'Híbrido' },
|
|
17364
18532
|
],
|
|
17365
18533
|
},
|
|
17366
18534
|
{
|
|
17367
18535
|
name: 'accessibilityNotes',
|
|
17368
|
-
label: '
|
|
18536
|
+
label: 'Observações adicionais',
|
|
17369
18537
|
controlType: 'textarea',
|
|
17370
18538
|
},
|
|
17371
18539
|
{
|
|
17372
18540
|
name: 'privacyConsent',
|
|
17373
|
-
label: 'Confirmo
|
|
18541
|
+
label: 'Confirmo ciência sobre o tratamento dos meus dados no processo de onboarding.',
|
|
17374
18542
|
controlType: 'checkbox',
|
|
17375
18543
|
selectionMode: 'boolean',
|
|
17376
18544
|
variant: 'consent',
|
|
@@ -17386,7 +18554,7 @@ const PRIVACY_CONSENT_EDITORIAL_TEMPLATE = {
|
|
|
17386
18554
|
version: '1.0.0',
|
|
17387
18555
|
metadata: {
|
|
17388
18556
|
title: 'Privacy Consent',
|
|
17389
|
-
description: 'Template focado em aceite
|
|
18557
|
+
description: 'Template focado em aceite explícito, base legal, preferências de comunicação e registro de consentimento.',
|
|
17390
18558
|
category: 'consent',
|
|
17391
18559
|
tags: ['privacy', 'consent', 'compliance', 'legal'],
|
|
17392
18560
|
source: 'catalog',
|
|
@@ -17408,13 +18576,13 @@ const PRIVACY_CONSENT_EDITORIAL_TEMPLATE = {
|
|
|
17408
18576
|
title: 'Consentimento e tratamento de dados',
|
|
17409
18577
|
subtitle: 'Template regulatorio',
|
|
17410
18578
|
badge: 'info',
|
|
17411
|
-
description: 'Use este template quando o objetivo principal do fluxo for registrar
|
|
18579
|
+
description: 'Use este template quando o objetivo principal do fluxo for registrar ciência, aceite e preferências relacionadas a privacidade.',
|
|
17412
18580
|
}),
|
|
17413
18581
|
sections: [
|
|
17414
18582
|
{
|
|
17415
18583
|
id: 'consent',
|
|
17416
18584
|
appearance: 'card',
|
|
17417
|
-
title: '
|
|
18585
|
+
title: 'Preferências e consentimentos',
|
|
17418
18586
|
description: 'Aceites explicitos e canais opcionais de comunicacao.',
|
|
17419
18587
|
rows: [
|
|
17420
18588
|
{
|
|
@@ -17497,7 +18665,7 @@ const PRIVACY_CONSENT_EDITORIAL_TEMPLATE = {
|
|
|
17497
18665
|
},
|
|
17498
18666
|
{
|
|
17499
18667
|
name: 'consentNotes',
|
|
17500
|
-
label: '
|
|
18668
|
+
label: 'Observações adicionais',
|
|
17501
18669
|
controlType: 'textarea',
|
|
17502
18670
|
},
|
|
17503
18671
|
],
|
|
@@ -17533,6 +18701,8 @@ const RULE_PROPERTY_SCHEMA = {
|
|
|
17533
18701
|
{ name: 'tooltip', type: 'string', label: 'Tooltip' },
|
|
17534
18702
|
{ name: 'prefixIcon', type: 'string', label: 'Ícone prefixo' },
|
|
17535
18703
|
{ name: 'suffixIcon', type: 'string', label: 'Ícone sufixo' },
|
|
18704
|
+
{ name: 'presentation', type: 'object', label: 'Apresentação', category: 'appearance' },
|
|
18705
|
+
{ name: 'presentationRules', type: 'array', label: 'Regras de apresentação', category: 'appearance' },
|
|
17536
18706
|
{ name: 'prefixText', type: 'string', label: 'Texto prefixo' },
|
|
17537
18707
|
{ name: 'suffixText', type: 'string', label: 'Texto sufixo' },
|
|
17538
18708
|
{ name: 'defaultValue', type: 'object', label: 'Valor padrão' },
|
|
@@ -18256,8 +19426,8 @@ const EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION = {
|
|
|
18256
19426
|
fields: [
|
|
18257
19427
|
{ key: 'selectedEquipment', label: 'Equipamentos', valuePath: 'formData.selectedEquipment', hideWhenEmpty: true },
|
|
18258
19428
|
{ key: 'needsEquipment', label: 'Necessita envio de equipamento', valuePath: 'formData.needsEquipment', hideWhenEmpty: true },
|
|
18259
|
-
{ key: 'shippingAddress', label: '
|
|
18260
|
-
{ key: 'accessibilityNotes', label: '
|
|
19429
|
+
{ key: 'shippingAddress', label: 'Endereço para envio', valuePath: 'formData.shippingAddress', hideWhenEmpty: true },
|
|
19430
|
+
{ key: 'accessibilityNotes', label: 'Observações adicionais', valuePath: 'formData.accessibilityNotes', hideWhenEmpty: true },
|
|
18261
19431
|
],
|
|
18262
19432
|
},
|
|
18263
19433
|
],
|
|
@@ -19566,6 +20736,388 @@ const ValidationPattern = {
|
|
|
19566
20736
|
CUSTOM: '',
|
|
19567
20737
|
};
|
|
19568
20738
|
|
|
20739
|
+
function materializeFormLayoutFromMetadata(fields, options = {}) {
|
|
20740
|
+
const policy = normalizeLayoutPolicy(options.policy);
|
|
20741
|
+
const visibleFields = normalizeFields(fields, options.includeHidden === true);
|
|
20742
|
+
const layoutFields = fieldsForLayoutPolicy(visibleFields, policy);
|
|
20743
|
+
const groupedFields = groupFields(layoutFields);
|
|
20744
|
+
const sections = groupedFields.map(([groupKey, groupFields], sectionIndex) => createSection(groupKey, groupFields, sectionIndex, policy, options));
|
|
20745
|
+
return ensureIds({
|
|
20746
|
+
sections,
|
|
20747
|
+
fieldMetadata: fieldsForPolicy(visibleFields, policy),
|
|
20748
|
+
metadata: {
|
|
20749
|
+
version: '1.0.0',
|
|
20750
|
+
lastUpdated: new Date(),
|
|
20751
|
+
source: 'schema',
|
|
20752
|
+
generatedLayoutPreset: policy.preset,
|
|
20753
|
+
schemaLayoutPolicy: policy,
|
|
20754
|
+
...(policy.preset === 'compactPresentation'
|
|
20755
|
+
? { presentationDensity: 'compact' }
|
|
20756
|
+
: {}),
|
|
20757
|
+
},
|
|
20758
|
+
});
|
|
20759
|
+
}
|
|
20760
|
+
function normalizeLayoutPolicy(policy) {
|
|
20761
|
+
const intent = policy?.intent ?? (policy?.preset === 'groupedCommand' ? 'command' : 'detail');
|
|
20762
|
+
const preset = policy?.preset ?? (intent === 'command' ? 'groupedCommand' : 'compactPresentation');
|
|
20763
|
+
return {
|
|
20764
|
+
source: policy?.source ?? 'authored',
|
|
20765
|
+
preset,
|
|
20766
|
+
intent,
|
|
20767
|
+
lifecycle: policy?.lifecycle ?? 'initial',
|
|
20768
|
+
persistence: policy?.persistence ?? 'authorable',
|
|
20769
|
+
detachBehavior: policy?.detachBehavior ?? 'none',
|
|
20770
|
+
schemaOperation: policy?.schemaOperation,
|
|
20771
|
+
schemaType: policy?.schemaType,
|
|
20772
|
+
detailSummary: policy?.detailSummary,
|
|
20773
|
+
};
|
|
20774
|
+
}
|
|
20775
|
+
function normalizeFields(fields, includeHidden) {
|
|
20776
|
+
return (fields || [])
|
|
20777
|
+
.filter((field) => !!field?.name)
|
|
20778
|
+
.filter((field) => includeHidden || !isFormHidden(field))
|
|
20779
|
+
.sort(compareFields);
|
|
20780
|
+
}
|
|
20781
|
+
function isFormHidden(field) {
|
|
20782
|
+
const anyField = field;
|
|
20783
|
+
return anyField.formHidden === true || anyField.hidden === true || anyField.visible === false;
|
|
20784
|
+
}
|
|
20785
|
+
function groupFields(fields) {
|
|
20786
|
+
const groups = new Map();
|
|
20787
|
+
for (const field of fields) {
|
|
20788
|
+
const groupKey = normalizeGroupLabel(field.group);
|
|
20789
|
+
groups.set(groupKey, [...(groups.get(groupKey) || []), field]);
|
|
20790
|
+
}
|
|
20791
|
+
return Array.from(groups.entries()).sort(([, left], [, right]) => compareGroupFields(left, right));
|
|
20792
|
+
}
|
|
20793
|
+
function createSection(groupKey, groupFields, sectionIndex, policy, options) {
|
|
20794
|
+
const title = groupKey === 'default'
|
|
20795
|
+
? options.defaultSectionTitle || 'Informacoes'
|
|
20796
|
+
: groupKey;
|
|
20797
|
+
const sectionId = stableSectionId(groupKey);
|
|
20798
|
+
const presentationRole = resolvePresentationRole(groupKey, groupFields, options.presentationRoleMap);
|
|
20799
|
+
return {
|
|
20800
|
+
id: sectionId,
|
|
20801
|
+
title,
|
|
20802
|
+
...(policy.preset === 'compactPresentation'
|
|
20803
|
+
? {
|
|
20804
|
+
icon: resolvePresentationSectionIcon(presentationRole),
|
|
20805
|
+
sectionHeader: {
|
|
20806
|
+
mode: 'icon',
|
|
20807
|
+
size: 'sm',
|
|
20808
|
+
fallbackIcon: resolvePresentationSectionIcon(presentationRole),
|
|
20809
|
+
},
|
|
20810
|
+
className: [
|
|
20811
|
+
'pdx-presentation-section',
|
|
20812
|
+
`pdx-presentation-section--${presentationRole}`,
|
|
20813
|
+
].join(' '),
|
|
20814
|
+
presentationRole,
|
|
20815
|
+
appearance: 'plain',
|
|
20816
|
+
}
|
|
20817
|
+
: {}),
|
|
20818
|
+
rows: policy.preset === 'groupedCommand'
|
|
20819
|
+
? createCommandRows(groupFields, sectionId)
|
|
20820
|
+
: createPresentationRows(groupFields, sectionId),
|
|
20821
|
+
};
|
|
20822
|
+
}
|
|
20823
|
+
function createPresentationRows(fields, sectionId) {
|
|
20824
|
+
const presentationFields = resolvePresentationFields(fields);
|
|
20825
|
+
const rows = [];
|
|
20826
|
+
let pending = [];
|
|
20827
|
+
let pendingSpan = 0;
|
|
20828
|
+
let rowIndex = 0;
|
|
20829
|
+
const flush = () => {
|
|
20830
|
+
if (!pending.length)
|
|
20831
|
+
return;
|
|
20832
|
+
rows.push({ id: `${sectionId}-row-${++rowIndex}`, columns: pending });
|
|
20833
|
+
pending = [];
|
|
20834
|
+
pendingSpan = 0;
|
|
20835
|
+
};
|
|
20836
|
+
for (const field of presentationFields) {
|
|
20837
|
+
const span = hasExplicitWidth(field)
|
|
20838
|
+
? resolveCommandSpan(field)
|
|
20839
|
+
: { xs: 12, sm: 12, md: 12, lg: 12, xl: 12 };
|
|
20840
|
+
const mdSpan = span.md ?? 12;
|
|
20841
|
+
const column = {
|
|
20842
|
+
id: `${sectionId}-col-${field.name}`,
|
|
20843
|
+
fields: [field.name],
|
|
20844
|
+
items: [{ id: `${sectionId}-item-${field.name}`, kind: 'field', fieldName: field.name }],
|
|
20845
|
+
span,
|
|
20846
|
+
};
|
|
20847
|
+
if (mdSpan >= 12) {
|
|
20848
|
+
flush();
|
|
20849
|
+
pending = [column];
|
|
20850
|
+
flush();
|
|
20851
|
+
continue;
|
|
20852
|
+
}
|
|
20853
|
+
if (pendingSpan + mdSpan > 12) {
|
|
20854
|
+
flush();
|
|
20855
|
+
}
|
|
20856
|
+
pending.push(column);
|
|
20857
|
+
pendingSpan += mdSpan;
|
|
20858
|
+
}
|
|
20859
|
+
flush();
|
|
20860
|
+
return rows;
|
|
20861
|
+
}
|
|
20862
|
+
function createCommandRows(fields, sectionId) {
|
|
20863
|
+
const rows = [];
|
|
20864
|
+
let pending = [];
|
|
20865
|
+
let pendingSpan = 0;
|
|
20866
|
+
let rowIndex = 0;
|
|
20867
|
+
const flush = () => {
|
|
20868
|
+
if (!pending.length)
|
|
20869
|
+
return;
|
|
20870
|
+
rows.push({ id: `${sectionId}-row-${++rowIndex}`, columns: pending });
|
|
20871
|
+
pending = [];
|
|
20872
|
+
pendingSpan = 0;
|
|
20873
|
+
};
|
|
20874
|
+
for (const field of fields) {
|
|
20875
|
+
const span = resolveCommandSpan(field);
|
|
20876
|
+
const mdSpan = span.md ?? 12;
|
|
20877
|
+
const column = {
|
|
20878
|
+
id: `${sectionId}-col-${field.name}`,
|
|
20879
|
+
fields: [field.name],
|
|
20880
|
+
items: [{ id: `${sectionId}-item-${field.name}`, kind: 'field', fieldName: field.name }],
|
|
20881
|
+
span,
|
|
20882
|
+
};
|
|
20883
|
+
if (mdSpan >= 12) {
|
|
20884
|
+
flush();
|
|
20885
|
+
pending = [column];
|
|
20886
|
+
flush();
|
|
20887
|
+
continue;
|
|
20888
|
+
}
|
|
20889
|
+
if (pendingSpan + mdSpan > 12) {
|
|
20890
|
+
flush();
|
|
20891
|
+
}
|
|
20892
|
+
pending.push(column);
|
|
20893
|
+
pendingSpan += mdSpan;
|
|
20894
|
+
}
|
|
20895
|
+
flush();
|
|
20896
|
+
return rows;
|
|
20897
|
+
}
|
|
20898
|
+
function resolveCommandSpan(field) {
|
|
20899
|
+
const rawWidth = field.width;
|
|
20900
|
+
const numericWidth = typeof rawWidth === 'number'
|
|
20901
|
+
? rawWidth
|
|
20902
|
+
: typeof rawWidth === 'string' && /^\d+$/.test(rawWidth.trim())
|
|
20903
|
+
? Number(rawWidth.trim())
|
|
20904
|
+
: null;
|
|
20905
|
+
if (numericWidth != null && Number.isFinite(numericWidth)) {
|
|
20906
|
+
const span = Math.max(1, Math.min(12, Math.round(numericWidth)));
|
|
20907
|
+
return {
|
|
20908
|
+
xs: 12,
|
|
20909
|
+
sm: span >= 6 ? 12 : 6,
|
|
20910
|
+
md: span,
|
|
20911
|
+
lg: span,
|
|
20912
|
+
xl: span,
|
|
20913
|
+
};
|
|
20914
|
+
}
|
|
20915
|
+
const width = String(rawWidth || '').toLowerCase();
|
|
20916
|
+
const controlType = String(field.controlType || field.type || '').toLowerCase();
|
|
20917
|
+
if (width === 'full' ||
|
|
20918
|
+
width === 'xl' ||
|
|
20919
|
+
controlType.includes('textarea') ||
|
|
20920
|
+
controlType.includes('rich') ||
|
|
20921
|
+
controlType.includes('file') ||
|
|
20922
|
+
controlType.includes('autocomplete') ||
|
|
20923
|
+
controlType.includes('lookup')) {
|
|
20924
|
+
return { xs: 12, sm: 12, md: 12, lg: 12, xl: 12 };
|
|
20925
|
+
}
|
|
20926
|
+
if (width === 'lg')
|
|
20927
|
+
return { xs: 12, sm: 12, md: 8, lg: 8, xl: 8 };
|
|
20928
|
+
if (width === 'md')
|
|
20929
|
+
return { xs: 12, sm: 12, md: 6, lg: 6, xl: 6 };
|
|
20930
|
+
if (width === 'sm')
|
|
20931
|
+
return { xs: 12, sm: 6, md: 4, lg: 4, xl: 4 };
|
|
20932
|
+
if (width === 'xs' || controlType.includes('checkbox') || controlType.includes('toggle')) {
|
|
20933
|
+
return { xs: 12, sm: 6, md: 3, lg: 3, xl: 3 };
|
|
20934
|
+
}
|
|
20935
|
+
return { xs: 12, sm: 12, md: 6, lg: 6, xl: 6 };
|
|
20936
|
+
}
|
|
20937
|
+
function hasExplicitWidth(field) {
|
|
20938
|
+
const rawWidth = field.width;
|
|
20939
|
+
return rawWidth !== undefined && rawWidth !== null && String(rawWidth).trim() !== '';
|
|
20940
|
+
}
|
|
20941
|
+
function fieldsForPolicy(fields, policy) {
|
|
20942
|
+
if (policy.preset !== 'compactPresentation') {
|
|
20943
|
+
return fields;
|
|
20944
|
+
}
|
|
20945
|
+
const presentationFieldNames = new Set(resolveDetailSummaryFields(fields, policy).map((field) => field.name));
|
|
20946
|
+
return fields.map((field) => ({
|
|
20947
|
+
...field,
|
|
20948
|
+
readOnly: true,
|
|
20949
|
+
presentationMode: field.presentationMode ?? true,
|
|
20950
|
+
...(presentationFieldNames.has(field.name)
|
|
20951
|
+
? {}
|
|
20952
|
+
: { formHidden: true, hidden: true }),
|
|
20953
|
+
valuePresentation: {
|
|
20954
|
+
...(field.valuePresentation || {}),
|
|
20955
|
+
density: (field.valuePresentation || {}).density ?? 'compact',
|
|
20956
|
+
},
|
|
20957
|
+
}));
|
|
20958
|
+
}
|
|
20959
|
+
function fieldsForLayoutPolicy(fields, policy) {
|
|
20960
|
+
if (policy.preset !== 'compactPresentation') {
|
|
20961
|
+
return fields;
|
|
20962
|
+
}
|
|
20963
|
+
return resolveDetailSummaryFields(fields, policy);
|
|
20964
|
+
}
|
|
20965
|
+
function resolvePresentationFields(fields) {
|
|
20966
|
+
return fields.filter((field) => !isFormHidden(field));
|
|
20967
|
+
}
|
|
20968
|
+
function resolveDetailSummaryFields(fields, policy) {
|
|
20969
|
+
if (policy.preset !== 'compactPresentation' || policy.intent === 'command') {
|
|
20970
|
+
return fields;
|
|
20971
|
+
}
|
|
20972
|
+
const summary = policy.detailSummary;
|
|
20973
|
+
if (!summary) {
|
|
20974
|
+
return fields;
|
|
20975
|
+
}
|
|
20976
|
+
const includeFields = normalizedSet(summary.includeFields);
|
|
20977
|
+
const excludeFields = normalizedSet(summary.excludeFields);
|
|
20978
|
+
const includeGroups = normalizedSet(summary.includeGroups);
|
|
20979
|
+
const excludeGroups = normalizedSet(summary.excludeGroups);
|
|
20980
|
+
const includeRoles = normalizedSet(summary.includeRoles);
|
|
20981
|
+
const excludeRoles = normalizedSet(summary.excludeRoles);
|
|
20982
|
+
const filtered = fields
|
|
20983
|
+
.filter((field) => {
|
|
20984
|
+
const fieldName = stableToken(field.name);
|
|
20985
|
+
const groupName = stableToken(normalizeGroupLabel(field.group));
|
|
20986
|
+
const roles = resolveFieldSummaryRoles(field);
|
|
20987
|
+
if (excludeFields.has(fieldName) || excludeGroups.has(groupName))
|
|
20988
|
+
return false;
|
|
20989
|
+
if (roles.some((role) => excludeRoles.has(role)))
|
|
20990
|
+
return false;
|
|
20991
|
+
if (includeFields.size && !includeFields.has(fieldName))
|
|
20992
|
+
return false;
|
|
20993
|
+
if (includeGroups.size && !includeGroups.has(groupName))
|
|
20994
|
+
return false;
|
|
20995
|
+
if (includeRoles.size && !roles.some((role) => includeRoles.has(role)))
|
|
20996
|
+
return false;
|
|
20997
|
+
return true;
|
|
20998
|
+
})
|
|
20999
|
+
.sort((left, right) => compareSummaryFields(left, right, summary));
|
|
21000
|
+
const maxFields = normalizePositiveInteger(summary.maxFields);
|
|
21001
|
+
return maxFields ? filtered.slice(0, maxFields) : filtered;
|
|
21002
|
+
}
|
|
21003
|
+
function compareSummaryFields(left, right, summary) {
|
|
21004
|
+
const leftPriority = resolveSummaryPriority(left, summary);
|
|
21005
|
+
const rightPriority = resolveSummaryPriority(right, summary);
|
|
21006
|
+
if (leftPriority !== rightPriority)
|
|
21007
|
+
return leftPriority - rightPriority;
|
|
21008
|
+
return compareFields(left, right);
|
|
21009
|
+
}
|
|
21010
|
+
function resolveSummaryPriority(field, summary) {
|
|
21011
|
+
const fieldName = stableToken(field.name);
|
|
21012
|
+
const groupName = stableToken(normalizeGroupLabel(field.group));
|
|
21013
|
+
const explicitFieldPriority = numberOrNull(summary.fieldPriority?.[field.name] ?? summary.fieldPriority?.[fieldName]);
|
|
21014
|
+
if (explicitFieldPriority !== null)
|
|
21015
|
+
return explicitFieldPriority;
|
|
21016
|
+
const explicitGroupPriority = numberOrNull(summary.groupPriority?.[String(field.group || '')] ?? summary.groupPriority?.[groupName]);
|
|
21017
|
+
if (explicitGroupPriority !== null)
|
|
21018
|
+
return explicitGroupPriority;
|
|
21019
|
+
const fieldPriority = numberOrNull(field.summaryPriority ??
|
|
21020
|
+
field.detailPriority ??
|
|
21021
|
+
field.presentationPriority);
|
|
21022
|
+
if (fieldPriority !== null)
|
|
21023
|
+
return fieldPriority;
|
|
21024
|
+
return typeof field.order === 'number' ? field.order : Number.MAX_SAFE_INTEGER;
|
|
21025
|
+
}
|
|
21026
|
+
function resolveFieldSummaryRoles(field) {
|
|
21027
|
+
const raw = [
|
|
21028
|
+
field.summaryRole,
|
|
21029
|
+
field.detailRole,
|
|
21030
|
+
field.presentationRole,
|
|
21031
|
+
field.presentation?.role,
|
|
21032
|
+
field.valuePresentation?.role,
|
|
21033
|
+
];
|
|
21034
|
+
const roles = [];
|
|
21035
|
+
for (const item of raw) {
|
|
21036
|
+
if (Array.isArray(item)) {
|
|
21037
|
+
roles.push(...item.map((value) => stableToken(String(value))).filter(Boolean));
|
|
21038
|
+
}
|
|
21039
|
+
else {
|
|
21040
|
+
const token = stableToken(String(item || ''));
|
|
21041
|
+
if (token)
|
|
21042
|
+
roles.push(token);
|
|
21043
|
+
}
|
|
21044
|
+
}
|
|
21045
|
+
return [...new Set(roles)];
|
|
21046
|
+
}
|
|
21047
|
+
function normalizedSet(values) {
|
|
21048
|
+
return new Set((values || []).map((value) => stableToken(value)).filter(Boolean));
|
|
21049
|
+
}
|
|
21050
|
+
function normalizePositiveInteger(value) {
|
|
21051
|
+
const numberValue = numberOrNull(value);
|
|
21052
|
+
if (numberValue === null || numberValue <= 0) {
|
|
21053
|
+
return null;
|
|
21054
|
+
}
|
|
21055
|
+
return Math.floor(numberValue);
|
|
21056
|
+
}
|
|
21057
|
+
function numberOrNull(value) {
|
|
21058
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
21059
|
+
return value;
|
|
21060
|
+
}
|
|
21061
|
+
if (typeof value === 'string' && value.trim() !== '' && Number.isFinite(Number(value))) {
|
|
21062
|
+
return Number(value);
|
|
21063
|
+
}
|
|
21064
|
+
return null;
|
|
21065
|
+
}
|
|
21066
|
+
function compareGroupFields(left, right) {
|
|
21067
|
+
return compareFields(left[0], right[0]);
|
|
21068
|
+
}
|
|
21069
|
+
function compareFields(left, right) {
|
|
21070
|
+
const leftOrder = typeof left?.order === 'number' ? left.order : Number.MAX_SAFE_INTEGER;
|
|
21071
|
+
const rightOrder = typeof right?.order === 'number' ? right.order : Number.MAX_SAFE_INTEGER;
|
|
21072
|
+
if (leftOrder !== rightOrder)
|
|
21073
|
+
return leftOrder - rightOrder;
|
|
21074
|
+
return String(left?.name || '').localeCompare(String(right?.name || ''));
|
|
21075
|
+
}
|
|
21076
|
+
function normalizeGroupLabel(group) {
|
|
21077
|
+
const value = String(group || '').trim();
|
|
21078
|
+
return value || 'default';
|
|
21079
|
+
}
|
|
21080
|
+
function resolvePresentationRole(groupName, fields, map) {
|
|
21081
|
+
const direct = map?.[groupName];
|
|
21082
|
+
if (direct)
|
|
21083
|
+
return direct;
|
|
21084
|
+
const normalized = stableToken(groupName);
|
|
21085
|
+
if (normalized.includes('ident'))
|
|
21086
|
+
return 'identity';
|
|
21087
|
+
if (normalized.includes('marc') || normalized.includes('status'))
|
|
21088
|
+
return 'markers';
|
|
21089
|
+
if (normalized.includes('regra') || normalized.includes('rule'))
|
|
21090
|
+
return 'rules';
|
|
21091
|
+
if (fields.some((field) => String(field.controlType || '').toLowerCase().includes('checkbox'))) {
|
|
21092
|
+
return 'markers';
|
|
21093
|
+
}
|
|
21094
|
+
return 'default';
|
|
21095
|
+
}
|
|
21096
|
+
function resolvePresentationSectionIcon(role) {
|
|
21097
|
+
switch (role) {
|
|
21098
|
+
case 'identity':
|
|
21099
|
+
return 'badge';
|
|
21100
|
+
case 'rules':
|
|
21101
|
+
return 'rule';
|
|
21102
|
+
case 'markers':
|
|
21103
|
+
return 'fact_check';
|
|
21104
|
+
default:
|
|
21105
|
+
return 'info';
|
|
21106
|
+
}
|
|
21107
|
+
}
|
|
21108
|
+
function stableSectionId(groupName) {
|
|
21109
|
+
const token = stableToken(groupName) || 'default';
|
|
21110
|
+
return `section-${token}`;
|
|
21111
|
+
}
|
|
21112
|
+
function stableToken(value) {
|
|
21113
|
+
return String(value || '')
|
|
21114
|
+
.normalize('NFD')
|
|
21115
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
21116
|
+
.toLowerCase()
|
|
21117
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
21118
|
+
.replace(/^-+|-+$/g, '');
|
|
21119
|
+
}
|
|
21120
|
+
|
|
19569
21121
|
function resolveSpan(span) {
|
|
19570
21122
|
const xs = clamp(span?.xs ?? 12, 'xs');
|
|
19571
21123
|
const sm = clamp(span?.sm ?? xs, 'sm');
|
|
@@ -20346,7 +21898,7 @@ class SurfaceOpenActionEditorComponent {
|
|
|
20346
21898
|
.filter(Boolean)));
|
|
20347
21899
|
}
|
|
20348
21900
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SurfaceOpenActionEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20349
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SurfaceOpenActionEditorComponent, isStandalone: true, selector: "praxis-surface-open-action-editor", inputs: { value: "value", hostKind: "hostKind" }, outputs: { valueChange: "valueChange" }, providers: [providePraxisI18nConfig(SURFACE_OPEN_I18N_CONFIG)], usesOnChanges: true, ngImport: i0, template: `
|
|
21901
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SurfaceOpenActionEditorComponent, isStandalone: true, selector: "praxis-surface-open-action-editor", inputs: { value: "value", hostKind: "hostKind" }, outputs: { valueChange: "valueChange" }, host: { attributes: { "data-praxis-surface-open-action-editor": "core" } }, providers: [providePraxisI18nConfig(SURFACE_OPEN_I18N_CONFIG)], usesOnChanges: true, ngImport: i0, template: `
|
|
20350
21902
|
<div class="surface-editor">
|
|
20351
21903
|
<div class="surface-section">
|
|
20352
21904
|
<div class="surface-section-title">{{ t('editor.presets.title', 'Presets') }}</div>
|
|
@@ -20643,17 +22195,17 @@ class SurfaceOpenActionEditorComponent {
|
|
|
20643
22195
|
{{ t('editor.bindings.empty', 'No bindings configured yet.') }}
|
|
20644
22196
|
</div>
|
|
20645
22197
|
}
|
|
20646
|
-
<div class="surface-
|
|
22198
|
+
<div class="surface-guidance">
|
|
20647
22199
|
@if (bindingSourceSuggestionsPreview) {
|
|
20648
|
-
<div>
|
|
22200
|
+
<div class="surface-guidance__item">
|
|
20649
22201
|
{{ t('editor.bindings.suggestedSources', 'Suggested sources: {{value}}', { value: bindingSourceSuggestionsPreview }) }}
|
|
20650
22202
|
</div>
|
|
20651
22203
|
}
|
|
20652
|
-
<div>
|
|
22204
|
+
<div class="surface-guidance__item surface-guidance__item--primary">
|
|
20653
22205
|
{{ t('editor.bindings.sourceSemantics', 'Use payload.* for the canonical event envelope and runtime.* for direct host state when the source component exposes it.') }}
|
|
20654
22206
|
</div>
|
|
20655
22207
|
@if (bindingTargetSuggestionsPreview) {
|
|
20656
|
-
<div>
|
|
22208
|
+
<div class="surface-guidance__item">
|
|
20657
22209
|
{{ t('editor.bindings.suggestedTargets', 'Suggested targets: {{value}}', { value: bindingTargetSuggestionsPreview }) }}
|
|
20658
22210
|
</div>
|
|
20659
22211
|
}
|
|
@@ -20689,11 +22241,11 @@ class SurfaceOpenActionEditorComponent {
|
|
|
20689
22241
|
</mat-form-field>
|
|
20690
22242
|
</div>
|
|
20691
22243
|
</div>
|
|
20692
|
-
`, isInline: true, styles: [".surface-editor{display:grid;gap:
|
|
22244
|
+
`, isInline: true, styles: [".surface-editor{display:grid;gap:14px;min-width:0}.surface-section{display:grid;gap:10px;min-width:0;padding:14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.surface-section-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:0}.surface-section-title{font-size:12px;font-weight:700;letter-spacing:0;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);margin-bottom:0}.surface-section-header .surface-section-title{margin-bottom:0}.surface-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:12px 16px;min-width:0}.surface-preset-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.surface-span-2{grid-column:span 2}.surface-span-all{width:100%;min-width:0}.surface-component-meta{display:grid;gap:4px;padding:10px 12px;border-radius:8px;background:var(--md-sys-color-surface-container)}.surface-component-title{font-weight:600;color:var(--md-sys-color-on-surface)}.surface-component-description,.surface-empty{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.45}.surface-bindings{display:grid;gap:10px;min-width:0}.surface-binding-row{display:grid;grid-template-columns:minmax(min(220px,100%),1.15fr) minmax(min(240px,100%),1.25fr) minmax(128px,.55fr) auto;gap:10px;align-items:start;min-width:0;padding:10px;border-radius:8px;background:var(--md-sys-color-surface-container)}.surface-binding-row mat-form-field:nth-child(4){grid-column:1 / -2}.surface-guidance{display:grid;gap:4px;padding:10px 12px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 18%,transparent);color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.45}.surface-guidance__item{overflow-wrap:anywhere}.surface-guidance__item--primary{color:var(--md-sys-color-on-surface)}mat-form-field{width:100%;min-width:0}@media(max-width:960px){.surface-section{padding:12px}.surface-span-2{grid-column:1 / -1}.surface-binding-row{grid-template-columns:minmax(0,1fr)}.surface-binding-row mat-form-field:nth-child(4){grid-column:auto}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
20693
22245
|
}
|
|
20694
22246
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SurfaceOpenActionEditorComponent, decorators: [{
|
|
20695
22247
|
type: Component,
|
|
20696
|
-
args: [{ selector: 'praxis-surface-open-action-editor', standalone: true, providers: [providePraxisI18nConfig(SURFACE_OPEN_I18N_CONFIG)], imports: [
|
|
22248
|
+
args: [{ selector: 'praxis-surface-open-action-editor', standalone: true, host: { 'data-praxis-surface-open-action-editor': 'core' }, providers: [providePraxisI18nConfig(SURFACE_OPEN_I18N_CONFIG)], imports: [
|
|
20697
22249
|
FormsModule,
|
|
20698
22250
|
MatButtonModule,
|
|
20699
22251
|
MatFormFieldModule,
|
|
@@ -20999,17 +22551,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
20999
22551
|
{{ t('editor.bindings.empty', 'No bindings configured yet.') }}
|
|
21000
22552
|
</div>
|
|
21001
22553
|
}
|
|
21002
|
-
<div class="surface-
|
|
22554
|
+
<div class="surface-guidance">
|
|
21003
22555
|
@if (bindingSourceSuggestionsPreview) {
|
|
21004
|
-
<div>
|
|
22556
|
+
<div class="surface-guidance__item">
|
|
21005
22557
|
{{ t('editor.bindings.suggestedSources', 'Suggested sources: {{value}}', { value: bindingSourceSuggestionsPreview }) }}
|
|
21006
22558
|
</div>
|
|
21007
22559
|
}
|
|
21008
|
-
<div>
|
|
22560
|
+
<div class="surface-guidance__item surface-guidance__item--primary">
|
|
21009
22561
|
{{ t('editor.bindings.sourceSemantics', 'Use payload.* for the canonical event envelope and runtime.* for direct host state when the source component exposes it.') }}
|
|
21010
22562
|
</div>
|
|
21011
22563
|
@if (bindingTargetSuggestionsPreview) {
|
|
21012
|
-
<div>
|
|
22564
|
+
<div class="surface-guidance__item">
|
|
21013
22565
|
{{ t('editor.bindings.suggestedTargets', 'Suggested targets: {{value}}', { value: bindingTargetSuggestionsPreview }) }}
|
|
21014
22566
|
</div>
|
|
21015
22567
|
}
|
|
@@ -21045,7 +22597,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
21045
22597
|
</mat-form-field>
|
|
21046
22598
|
</div>
|
|
21047
22599
|
</div>
|
|
21048
|
-
`, styles: [".surface-editor{display:grid;gap:
|
|
22600
|
+
`, styles: [".surface-editor{display:grid;gap:14px;min-width:0}.surface-section{display:grid;gap:10px;min-width:0;padding:14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.surface-section-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:0}.surface-section-title{font-size:12px;font-weight:700;letter-spacing:0;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant);margin-bottom:0}.surface-section-header .surface-section-title{margin-bottom:0}.surface-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:12px 16px;min-width:0}.surface-preset-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.surface-span-2{grid-column:span 2}.surface-span-all{width:100%;min-width:0}.surface-component-meta{display:grid;gap:4px;padding:10px 12px;border-radius:8px;background:var(--md-sys-color-surface-container)}.surface-component-title{font-weight:600;color:var(--md-sys-color-on-surface)}.surface-component-description,.surface-empty{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.45}.surface-bindings{display:grid;gap:10px;min-width:0}.surface-binding-row{display:grid;grid-template-columns:minmax(min(220px,100%),1.15fr) minmax(min(240px,100%),1.25fr) minmax(128px,.55fr) auto;gap:10px;align-items:start;min-width:0;padding:10px;border-radius:8px;background:var(--md-sys-color-surface-container)}.surface-binding-row mat-form-field:nth-child(4){grid-column:1 / -2}.surface-guidance{display:grid;gap:4px;padding:10px 12px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 18%,transparent);color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.45}.surface-guidance__item{overflow-wrap:anywhere}.surface-guidance__item--primary{color:var(--md-sys-color-on-surface)}mat-form-field{width:100%;min-width:0}@media(max-width:960px){.surface-section{padding:12px}.surface-span-2{grid-column:1 / -1}.surface-binding-row{grid-template-columns:minmax(0,1fr)}.surface-binding-row mat-form-field:nth-child(4){grid-column:auto}}\n"] }]
|
|
21049
22601
|
}], propDecorators: { value: [{
|
|
21050
22602
|
type: Input
|
|
21051
22603
|
}], hostKind: [{
|
|
@@ -21072,6 +22624,12 @@ const ENUMS$1 = {
|
|
|
21072
22624
|
textTransformApply: ['displayOnly', 'saveOnly', 'both'],
|
|
21073
22625
|
fieldSource: ['schema', 'local'],
|
|
21074
22626
|
fieldSubmitPolicy: ['include', 'omit', 'includeWhenDirty'],
|
|
22627
|
+
fieldPresentationTone: ['neutral', 'info', 'success', 'warning', 'danger'],
|
|
22628
|
+
fieldPresentationAppearance: ['plain', 'soft', 'outlined', 'filled'],
|
|
22629
|
+
fieldPresenterKind: ['text', 'badge', 'chip', 'status', 'iconValue', 'progress', 'rating', 'microVisualization'],
|
|
22630
|
+
presentationVisualizationKind: ['line', 'area', 'column', 'comparison', 'stackedBar', 'radial', 'harveyBall', 'bullet', 'delta', 'processFlow'],
|
|
22631
|
+
presentationVisualizationSurface: ['table-cell', 'list-item', 'object-header', 'card-summary', 'form-presentation'],
|
|
22632
|
+
presentationVisualizationSize: ['xs', 'sm', 'md', 'lg', 'responsive'],
|
|
21075
22633
|
visibleIn: ['form', 'filter', 'table', 'dialog'],
|
|
21076
22634
|
appearance: ['fill', 'outline'],
|
|
21077
22635
|
color: ['primary', 'accent', 'warn'],
|
|
@@ -21082,7 +22640,7 @@ const ENUMS$1 = {
|
|
|
21082
22640
|
sectionDescriptionStyle: ['bodyLarge', 'bodyMedium', 'bodySmall'],
|
|
21083
22641
|
};
|
|
21084
22642
|
const FIELD_METADATA_CAPABILITIES = {
|
|
21085
|
-
version: 'v1.
|
|
22643
|
+
version: 'v1.5',
|
|
21086
22644
|
enums: ENUMS$1,
|
|
21087
22645
|
notes: [
|
|
21088
22646
|
'Condições booleanas declarativas devem usar Json Logic canônico. Funções permanecem restritas a escapes host-level como transforms e validators customizados.',
|
|
@@ -21091,8 +22649,11 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21091
22649
|
'Detalhes específicos de cada controle (ex: opções de datepicker, máscaras específicas) devem ser consultados nos catálogos de microcomponentes.',
|
|
21092
22650
|
'POLICY: Arrays e objetos (ex: options, validators) devem sofrer merge/append, nunca substituição completa sem confirmação.',
|
|
21093
22651
|
'Não gere função para conditionalDisplay/conditionalRequired. Use Json Logic serializável; funções ficam restritas a transforms e validators customizados.',
|
|
21094
|
-
'POLICY: Campos auxiliares do host devem usar source=local ou transient=true em FieldMetadata;
|
|
22652
|
+
'POLICY: Campos auxiliares do host devem usar source=local ou transient=true em FieldMetadata; não invente campos no DTO/backend quando eles não devem participar do payload persistido.',
|
|
21095
22653
|
'POLICY: formSubmit.formData e o payload filtrado para backend; formSubmit.rawFormData preserva os valores completos da UI, incluindo campos locais/transient.',
|
|
22654
|
+
'POLICY: fieldAccess e metadata-driven UX; nao trate como seguranca frontend. Use somente authorities explicitas, nunca capabilities como sinonimo implicito.',
|
|
22655
|
+
'POLICY: presentation/presentationRules descrevem somente estado visual semantico em modo leitura. Nao gere CSS, HTML, comandos ou mutacoes por Json Logic.',
|
|
22656
|
+
'POLICY: presentation.visualization e renderer-neutral. Nao gere EChartsOption, SVG, HTML ou CSS; use kind/surface/size/fallbackText e dados semanticos.',
|
|
21096
22657
|
],
|
|
21097
22658
|
capabilities: [
|
|
21098
22659
|
// =============================================================================
|
|
@@ -21194,6 +22755,13 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21194
22755
|
description: 'Texto de ajuda exibido abaixo do campo.',
|
|
21195
22756
|
intentExamples: ['colocar dica', 'ajuda no rodapé do campo'],
|
|
21196
22757
|
},
|
|
22758
|
+
{
|
|
22759
|
+
path: 'helpText',
|
|
22760
|
+
category: 'identity',
|
|
22761
|
+
valueKind: 'string',
|
|
22762
|
+
description: 'Texto semântico de ajuda publicado pelo schema/DTO.',
|
|
22763
|
+
intentExamples: ['explicar regra de negócio do campo', 'ajuda vinda do backend'],
|
|
22764
|
+
},
|
|
21197
22765
|
{
|
|
21198
22766
|
path: 'tooltip',
|
|
21199
22767
|
category: 'identity',
|
|
@@ -21201,6 +22769,13 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21201
22769
|
description: 'Texto exibido ao passar o mouse.',
|
|
21202
22770
|
intentExamples: ['adicionar tooltip'],
|
|
21203
22771
|
},
|
|
22772
|
+
{
|
|
22773
|
+
path: 'tooltipOnHover',
|
|
22774
|
+
category: 'identity',
|
|
22775
|
+
valueKind: 'boolean',
|
|
22776
|
+
description: 'Habilita apresentação do tooltip no hover quando suportado pelo renderer.',
|
|
22777
|
+
intentExamples: ['mostrar tooltip ao passar o mouse', 'ativar dica no hover'],
|
|
22778
|
+
},
|
|
21204
22779
|
{
|
|
21205
22780
|
path: 'description',
|
|
21206
22781
|
category: 'identity',
|
|
@@ -21292,24 +22867,24 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21292
22867
|
category: 'data',
|
|
21293
22868
|
valueKind: 'enum',
|
|
21294
22869
|
allowedValues: ENUMS$1.fieldSource,
|
|
21295
|
-
description: 'Origem
|
|
21296
|
-
intentExamples: ['campo local', 'campo auxiliar do host', 'campo que
|
|
21297
|
-
safetyNotes: '
|
|
22870
|
+
description: 'Origem semântica do campo. Use local para campos do host que não vêm do schema backend.',
|
|
22871
|
+
intentExamples: ['campo local', 'campo auxiliar do host', 'campo que não vem do schema'],
|
|
22872
|
+
safetyNotes: 'Não marque como local um campo que exista no schema backend; remova a semântica local quando houver colisão com campo server-backed.',
|
|
21298
22873
|
},
|
|
21299
22874
|
{
|
|
21300
22875
|
path: 'transient',
|
|
21301
22876
|
category: 'data',
|
|
21302
22877
|
valueKind: 'boolean',
|
|
21303
|
-
description: 'Marca o campo como
|
|
21304
|
-
intentExamples: ['campo
|
|
21305
|
-
safetyNotes: 'Campos transient continuam participando de UI,
|
|
22878
|
+
description: 'Marca o campo como temporário/local para preenchimento. O dynamic-form omite do submit por padrão.',
|
|
22879
|
+
intentExamples: ['campo temporário', 'campo transient', 'não enviar no payload', 'usar apenas na UI'],
|
|
22880
|
+
safetyNotes: 'Campos transient continuam participando de UI, validação, regras, visibilidade e valueChange; eles apenas saem do payload persistido por padrão.',
|
|
21306
22881
|
},
|
|
21307
22882
|
{
|
|
21308
22883
|
path: 'submitPolicy',
|
|
21309
22884
|
category: 'behavior',
|
|
21310
22885
|
valueKind: 'enum',
|
|
21311
22886
|
allowedValues: ENUMS$1.fieldSubmitPolicy,
|
|
21312
|
-
description: '
|
|
22887
|
+
description: 'Política de submit para sobrescrever o padrão de campos locais/transient.',
|
|
21313
22888
|
intentExamples: ['omitir do submit', 'enviar mesmo sendo local', 'enviar apenas se alterado'],
|
|
21314
22889
|
safetyNotes: 'Use omit para nunca persistir, include para enviar sempre e includeWhenDirty apenas quando o controle estiver dirty.',
|
|
21315
22890
|
},
|
|
@@ -21412,6 +22987,166 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21412
22987
|
description: 'Tamanho do ícone.',
|
|
21413
22988
|
intentExamples: ['ícone pequeno', 'aumentar tamanho do ícone', 'ícone grande'],
|
|
21414
22989
|
},
|
|
22990
|
+
{
|
|
22991
|
+
path: 'iconColor',
|
|
22992
|
+
category: 'appearance',
|
|
22993
|
+
valueKind: 'string',
|
|
22994
|
+
description: 'Cor semântica ou token de cor aplicado ao ícone principal.',
|
|
22995
|
+
intentExamples: ['ícone em cor primária', 'usar token do tema no ícone'],
|
|
22996
|
+
},
|
|
22997
|
+
{
|
|
22998
|
+
path: 'iconClass',
|
|
22999
|
+
category: 'appearance',
|
|
23000
|
+
valueKind: 'string',
|
|
23001
|
+
description: 'Classe CSS controlada pelo host para o ícone principal.',
|
|
23002
|
+
intentExamples: ['usar classe de ícone outlined', 'aplicar classe corporativa'],
|
|
23003
|
+
},
|
|
23004
|
+
{
|
|
23005
|
+
path: 'iconStyle',
|
|
23006
|
+
category: 'appearance',
|
|
23007
|
+
valueKind: 'string',
|
|
23008
|
+
description: 'Estilo visual semântico do ícone quando o renderer suportar variações.',
|
|
23009
|
+
intentExamples: ['usar ícone arredondado', 'aplicar estilo filled'],
|
|
23010
|
+
},
|
|
23011
|
+
{
|
|
23012
|
+
path: 'iconFontSize',
|
|
23013
|
+
category: 'appearance',
|
|
23014
|
+
valueKind: 'string',
|
|
23015
|
+
description: 'Tamanho tipográfico do ícone principal.',
|
|
23016
|
+
intentExamples: ['ícone com 18px', 'ajustar tamanho do ícone'],
|
|
23017
|
+
},
|
|
23018
|
+
// =============================================================================
|
|
23019
|
+
// PRESENTATION MODE
|
|
23020
|
+
// =============================================================================
|
|
23021
|
+
{
|
|
23022
|
+
path: 'valuePresentation',
|
|
23023
|
+
category: 'appearance',
|
|
23024
|
+
valueKind: 'object',
|
|
23025
|
+
description: 'Formato canonico de exibicao em superficies readonly/display, como moeda, numero, percentual, data, datetime, time e boolean.',
|
|
23026
|
+
safetyNotes: 'Preferir este contrato a formatadores legados quando a intencao for apresentacao de valor.',
|
|
23027
|
+
intentExamples: ['mostrar como moeda', 'formatar como data longa', 'exibir percentual'],
|
|
23028
|
+
},
|
|
23029
|
+
{
|
|
23030
|
+
path: 'presentation',
|
|
23031
|
+
category: 'appearance',
|
|
23032
|
+
valueKind: 'object',
|
|
23033
|
+
description: 'Estado visual semantico base para presentationMode, incluindo presenter, tone, icon, label, badge, tooltip, appearance e formatter opcional.',
|
|
23034
|
+
safetyNotes: 'Use apenas semantica declarativa; nao incluir CSS arbitrario, HTML, comandos ou efeitos mutaveis.',
|
|
23035
|
+
intentExamples: ['status com icone', 'badge de pendente', 'campo em tom warning'],
|
|
23036
|
+
},
|
|
23037
|
+
{
|
|
23038
|
+
path: 'presentation.presenter',
|
|
23039
|
+
category: 'appearance',
|
|
23040
|
+
valueKind: 'enum',
|
|
23041
|
+
allowedValues: ENUMS$1.fieldPresenterKind,
|
|
23042
|
+
description: 'Tipo semantico de renderizacao em modo apresentacao.',
|
|
23043
|
+
intentExamples: ['renderizar como status', 'usar chip', 'mostrar icone com valor'],
|
|
23044
|
+
},
|
|
23045
|
+
{
|
|
23046
|
+
path: 'presentation.tone',
|
|
23047
|
+
category: 'appearance',
|
|
23048
|
+
valueKind: 'enum',
|
|
23049
|
+
allowedValues: ENUMS$1.fieldPresentationTone,
|
|
23050
|
+
description: 'Tom semantico mapeado pelo consumidor para tokens de tema.',
|
|
23051
|
+
intentExamples: ['tom de sucesso', 'tom de alerta', 'tom de erro'],
|
|
23052
|
+
},
|
|
23053
|
+
{
|
|
23054
|
+
path: 'presentation.appearance',
|
|
23055
|
+
category: 'appearance',
|
|
23056
|
+
valueKind: 'enum',
|
|
23057
|
+
allowedValues: ENUMS$1.fieldPresentationAppearance,
|
|
23058
|
+
description: 'Nivel de enfase visual do apresentador.',
|
|
23059
|
+
intentExamples: ['status preenchido', 'badge contornado', 'chip suave'],
|
|
23060
|
+
},
|
|
23061
|
+
{
|
|
23062
|
+
path: 'presentation.icon',
|
|
23063
|
+
category: 'appearance',
|
|
23064
|
+
valueKind: 'string',
|
|
23065
|
+
description: 'Nome de icone Material Symbols usado pelo apresentador semantico.',
|
|
23066
|
+
intentExamples: ['icone lock', 'icone payments', 'icone schedule'],
|
|
23067
|
+
},
|
|
23068
|
+
{
|
|
23069
|
+
path: 'presentation.label',
|
|
23070
|
+
category: 'identity',
|
|
23071
|
+
valueKind: 'string',
|
|
23072
|
+
description: 'Rotulo semantico exibido por apresentadores como status, badge ou chip.',
|
|
23073
|
+
intentExamples: ['rotulo Bloqueado', 'texto Aprovado', 'status Aguardando aprovacao'],
|
|
23074
|
+
},
|
|
23075
|
+
{
|
|
23076
|
+
path: 'presentation.badge',
|
|
23077
|
+
category: 'appearance',
|
|
23078
|
+
valueKind: 'string',
|
|
23079
|
+
description: 'Marcador secundario opcional exibido junto ao valor em superficies de apresentacao.',
|
|
23080
|
+
intentExamples: ['badge alto valor', 'marcador D+35', 'sinalizar revisao executiva'],
|
|
23081
|
+
},
|
|
23082
|
+
{
|
|
23083
|
+
path: 'presentation.valuePresentation',
|
|
23084
|
+
category: 'appearance',
|
|
23085
|
+
valueKind: 'object',
|
|
23086
|
+
description: 'Override de formatacao aplicado apenas pela superficie de apresentacao.',
|
|
23087
|
+
safetyNotes: 'Nao altera o valor real do FormControl nem o payload de submit.',
|
|
23088
|
+
},
|
|
23089
|
+
{
|
|
23090
|
+
path: 'presentation.visualization',
|
|
23091
|
+
category: 'appearance',
|
|
23092
|
+
valueKind: 'object',
|
|
23093
|
+
description: 'Micro visualizacao renderer-neutral para superficies compactas como tabela, lista, header, card e form read-only.',
|
|
23094
|
+
safetyNotes: 'Exige fallback textual e nao pode conter opcoes de ECharts, HTML, SVG bruto, CSS ou comandos.',
|
|
23095
|
+
intentExamples: ['micro chart de SLA', 'barra empilhada em celula', 'bullet chart de orcamento', 'fluxo compacto de aprovacao'],
|
|
23096
|
+
},
|
|
23097
|
+
{
|
|
23098
|
+
path: 'presentation.visualization.kind',
|
|
23099
|
+
category: 'appearance',
|
|
23100
|
+
valueKind: 'enum',
|
|
23101
|
+
allowedValues: ENUMS$1.presentationVisualizationKind,
|
|
23102
|
+
description: 'Tipo semantico da micro visualizacao de apresentacao.',
|
|
23103
|
+
intentExamples: ['comparison', 'stackedBar', 'bullet', 'processFlow'],
|
|
23104
|
+
},
|
|
23105
|
+
{
|
|
23106
|
+
path: 'presentation.visualization.surface',
|
|
23107
|
+
category: 'layout',
|
|
23108
|
+
valueKind: 'enum',
|
|
23109
|
+
allowedValues: ENUMS$1.presentationVisualizationSurface,
|
|
23110
|
+
description: 'Superficie alvo usada para aplicar regras de densidade e fallback.',
|
|
23111
|
+
intentExamples: ['table-cell', 'list-item', 'form-presentation'],
|
|
23112
|
+
},
|
|
23113
|
+
{
|
|
23114
|
+
path: 'presentation.visualization.size',
|
|
23115
|
+
category: 'layout',
|
|
23116
|
+
valueKind: 'enum',
|
|
23117
|
+
allowedValues: ENUMS$1.presentationVisualizationSize,
|
|
23118
|
+
description: 'Tamanho semantico da micro visualizacao.',
|
|
23119
|
+
intentExamples: ['xs em tabela', 'md em header', 'responsive em card'],
|
|
23120
|
+
},
|
|
23121
|
+
{
|
|
23122
|
+
path: 'presentation.visualization.fallbackText',
|
|
23123
|
+
category: 'accessibility',
|
|
23124
|
+
valueKind: 'string',
|
|
23125
|
+
description: 'Texto equivalente obrigatorio para fallback, exportacao e leitores de tela.',
|
|
23126
|
+
safetyNotes: 'Deve explicar valor, unidade, meta, tendencia ou estado quando aplicavel.',
|
|
23127
|
+
},
|
|
23128
|
+
{
|
|
23129
|
+
path: 'presentationRules',
|
|
23130
|
+
category: 'appearance',
|
|
23131
|
+
valueKind: 'array',
|
|
23132
|
+
description: 'Regras Json Logic ordenadas que sobrescrevem presentation em modo readonly/display; regras posteriores que casam vencem.',
|
|
23133
|
+
safetyNotes: 'As regras devem produzir apenas set/effect semantico. Nao use para alterar valor, executar acao, navegar ou injetar HTML/CSS.',
|
|
23134
|
+
intentExamples: ['se status for BLOQUEADO, usar tone danger', 'se valor maior que limite, mostrar badge de revisao'],
|
|
23135
|
+
},
|
|
23136
|
+
{
|
|
23137
|
+
path: 'presentationRules[].when',
|
|
23138
|
+
category: 'behavior',
|
|
23139
|
+
valueKind: 'object',
|
|
23140
|
+
description: 'Guarda Json Logic avaliada contra o contexto de apresentacao do campo.',
|
|
23141
|
+
safetyNotes: 'Use Json Logic serializavel; funcoes nao sao aceitas.',
|
|
23142
|
+
},
|
|
23143
|
+
{
|
|
23144
|
+
path: 'presentationRules[].set',
|
|
23145
|
+
category: 'appearance',
|
|
23146
|
+
valueKind: 'object',
|
|
23147
|
+
description: 'Patch semantico aplicado sobre presentation quando a guarda for verdadeira.',
|
|
23148
|
+
safetyNotes: 'Somente presenter, tone, icon, label, badge, tooltip, appearance, valuePresentation e interactions seguras.',
|
|
23149
|
+
},
|
|
21415
23150
|
// =============================================================================
|
|
21416
23151
|
// MASK / FORMAT
|
|
21417
23152
|
// =============================================================================
|
|
@@ -21451,8 +23186,8 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21451
23186
|
path: 'required',
|
|
21452
23187
|
category: 'validation',
|
|
21453
23188
|
valueKind: 'boolean',
|
|
21454
|
-
description: 'Campo
|
|
21455
|
-
intentExamples: ['campo
|
|
23189
|
+
description: 'Campo obrigatório (alias rápido do validators.required).',
|
|
23190
|
+
intentExamples: ['campo obrigatório', 'exigir preenchimento'],
|
|
21456
23191
|
},
|
|
21457
23192
|
{
|
|
21458
23193
|
path: 'validators.requiredMessage',
|
|
@@ -21471,7 +23206,7 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21471
23206
|
path: 'validators.emailMessage',
|
|
21472
23207
|
category: 'validation',
|
|
21473
23208
|
valueKind: 'string',
|
|
21474
|
-
description: 'Mensagem customizada para
|
|
23209
|
+
description: 'Mensagem customizada para validação de email.',
|
|
21475
23210
|
},
|
|
21476
23211
|
{
|
|
21477
23212
|
path: 'validators.minLength',
|
|
@@ -21611,15 +23346,15 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21611
23346
|
path: 'validators.customValidator',
|
|
21612
23347
|
category: 'validation',
|
|
21613
23348
|
valueKind: 'expression',
|
|
21614
|
-
description: 'Validador customizado (
|
|
21615
|
-
safetyNotes: '
|
|
23349
|
+
description: 'Validador customizado (função).',
|
|
23350
|
+
safetyNotes: 'Funções não são serializáveis; exige wiring manual.',
|
|
21616
23351
|
},
|
|
21617
23352
|
{
|
|
21618
23353
|
path: 'validators.asyncValidator',
|
|
21619
23354
|
category: 'validation',
|
|
21620
23355
|
valueKind: 'expression',
|
|
21621
|
-
description: 'Validador async customizado (
|
|
21622
|
-
safetyNotes: '
|
|
23356
|
+
description: 'Validador async customizado (função).',
|
|
23357
|
+
safetyNotes: 'Funções não são serializáveis; exige wiring manual.',
|
|
21623
23358
|
},
|
|
21624
23359
|
{
|
|
21625
23360
|
path: 'validators.matchField',
|
|
@@ -21637,8 +23372,8 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21637
23372
|
path: 'validators.uniqueValidator',
|
|
21638
23373
|
category: 'validation',
|
|
21639
23374
|
valueKind: 'expression',
|
|
21640
|
-
description: 'Validador de unicidade via API (
|
|
21641
|
-
safetyNotes: '
|
|
23375
|
+
description: 'Validador de unicidade via API (função).',
|
|
23376
|
+
safetyNotes: 'Funções não são serializáveis; exige wiring manual.',
|
|
21642
23377
|
},
|
|
21643
23378
|
{
|
|
21644
23379
|
path: 'validators.uniqueMessage',
|
|
@@ -21650,8 +23385,8 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21650
23385
|
path: 'validators.conditionalValidation',
|
|
21651
23386
|
category: 'validation',
|
|
21652
23387
|
valueKind: 'array',
|
|
21653
|
-
description: 'Regras de
|
|
21654
|
-
safetyNotes: 'Use regras declarativas com Json Logic
|
|
23388
|
+
description: 'Regras de validação condicional.',
|
|
23389
|
+
safetyNotes: 'Use regras declarativas com Json Logic serializável; não gere funções aqui.',
|
|
21655
23390
|
},
|
|
21656
23391
|
{
|
|
21657
23392
|
path: 'validators.conditionalValidation[].condition',
|
|
@@ -21671,13 +23406,13 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21671
23406
|
category: 'validation',
|
|
21672
23407
|
valueKind: 'enum',
|
|
21673
23408
|
allowedValues: ENUMS$1.validatorTrigger,
|
|
21674
|
-
description: 'Gatilho de
|
|
23409
|
+
description: 'Gatilho de validação no validator.',
|
|
21675
23410
|
},
|
|
21676
23411
|
{
|
|
21677
23412
|
path: 'validators.validationDebounce',
|
|
21678
23413
|
category: 'validation',
|
|
21679
23414
|
valueKind: 'number',
|
|
21680
|
-
description: 'Debounce de
|
|
23415
|
+
description: 'Debounce de validação no validator (ms).',
|
|
21681
23416
|
},
|
|
21682
23417
|
{
|
|
21683
23418
|
path: 'validators.showInlineErrors',
|
|
@@ -21800,6 +23535,35 @@ const FIELD_METADATA_CAPABILITIES = {
|
|
|
21800
23535
|
description: 'Oculta apenas no filtro.',
|
|
21801
23536
|
intentExamples: ['esconder na busca', 'remover do filtro'],
|
|
21802
23537
|
},
|
|
23538
|
+
{
|
|
23539
|
+
path: 'fieldAccess',
|
|
23540
|
+
category: 'behavior',
|
|
23541
|
+
valueKind: 'object',
|
|
23542
|
+
description: 'Politica canonica de UX para visibilidade/edicao por authorities publicadas pelo backend.',
|
|
23543
|
+
safetyNotes: 'Nao e barreira de seguranca. O backend continua responsavel por filtrar dados sensiveis e validar payloads.',
|
|
23544
|
+
intentExamples: ['campo visivel somente para RH', 'bloquear edicao por perfil corporativo'],
|
|
23545
|
+
},
|
|
23546
|
+
{
|
|
23547
|
+
path: 'fieldAccess.visibleForAuthorities',
|
|
23548
|
+
category: 'behavior',
|
|
23549
|
+
valueKind: 'array',
|
|
23550
|
+
description: 'Authorities que podem ver o campo no runtime quando a UX tiver claims explicitas.',
|
|
23551
|
+
safetyNotes: 'Nao inferir a partir de capabilities sem mapeamento canonico publicado.',
|
|
23552
|
+
},
|
|
23553
|
+
{
|
|
23554
|
+
path: 'fieldAccess.editableForAuthorities',
|
|
23555
|
+
category: 'behavior',
|
|
23556
|
+
valueKind: 'array',
|
|
23557
|
+
description: 'Authorities que podem editar o campo no runtime quando a UX tiver claims explicitas.',
|
|
23558
|
+
safetyNotes: 'Edicao concedida implica materializacao visivel no runtime; a validacao final permanece no backend.',
|
|
23559
|
+
},
|
|
23560
|
+
{
|
|
23561
|
+
path: 'fieldAccess.reason',
|
|
23562
|
+
category: 'misc',
|
|
23563
|
+
valueKind: 'string',
|
|
23564
|
+
description: 'Justificativa explicativa/auditavel da politica de acesso do campo.',
|
|
23565
|
+
safetyNotes: 'Reason sozinho nao deve decidir acesso nem revelar detalhes sensiveis para usuarios sem permissao.',
|
|
23566
|
+
},
|
|
21803
23567
|
// =============================================================================
|
|
21804
23568
|
// DEPENDENCIES
|
|
21805
23569
|
// =============================================================================
|
|
@@ -22004,12 +23768,12 @@ const ENUMS = {
|
|
|
22004
23768
|
actionPlacement: ['header', 'window'],
|
|
22005
23769
|
};
|
|
22006
23770
|
const CAPS = [
|
|
22007
|
-
{ path: 'page', category: 'page', valueKind: 'object', description: '
|
|
23771
|
+
{ path: 'page', category: 'page', valueKind: 'object', description: 'Definição da página dinâmica.' },
|
|
22008
23772
|
{ path: 'page.context', category: 'context', valueKind: 'object', description: 'Contexto compartilhado entre widgets.' },
|
|
22009
|
-
{ path: 'page.layoutPreset', category: 'layout', valueKind: 'string', description: 'ID
|
|
22010
|
-
{ path: 'page.layoutPresetOptions', category: 'layout', valueKind: 'object', description: '
|
|
22011
|
-
{ path: 'page.themePreset', category: 'appearance', valueKind: 'string', description: 'ID opcional do preset de tema para shell,
|
|
22012
|
-
{ path: 'page.layout', category: 'layout', valueKind: 'object', description: 'Layout base da
|
|
23773
|
+
{ path: 'page.layoutPreset', category: 'layout', valueKind: 'string', description: 'ID canônico opcional do preset estrutural da página.' },
|
|
23774
|
+
{ path: 'page.layoutPresetOptions', category: 'layout', valueKind: 'object', description: 'Opções específicas do preset estrutural consumidas por builders e runtimes futuros.' },
|
|
23775
|
+
{ path: 'page.themePreset', category: 'appearance', valueKind: 'string', description: 'ID opcional do preset de tema para shell, gráficos, densidade e defaults visuais.' },
|
|
23776
|
+
{ path: 'page.layout', category: 'layout', valueKind: 'object', description: 'Layout base da página.' },
|
|
22013
23777
|
{ path: 'page.layout.orientation', category: 'layout', valueKind: 'enum', allowedValues: ENUMS.layoutOrientation, description: 'Orientacao do grid (vertical/columns).' },
|
|
22014
23778
|
{ path: 'page.layout.columns', category: 'layout', valueKind: 'number', description: 'Numero de colunas (quando orientation=columns).' },
|
|
22015
23779
|
{ path: 'page.layout.gap', category: 'layout', valueKind: 'string', description: 'Gap entre widgets (ex: 16px).' },
|
|
@@ -22018,7 +23782,7 @@ const CAPS = [
|
|
|
22018
23782
|
{ path: 'page.layout.breakpoints.md', category: 'layout', valueKind: 'number', description: 'Colunas para breakpoint md.' },
|
|
22019
23783
|
{ path: 'page.layout.breakpoints.lg', category: 'layout', valueKind: 'number', description: 'Colunas para breakpoint lg.' },
|
|
22020
23784
|
{ path: 'page.layout.breakpoints.xl', category: 'layout', valueKind: 'number', description: 'Colunas para breakpoint xl.' },
|
|
22021
|
-
{ path: 'page.canvas', category: 'layout', valueKind: 'object', description: 'Canvas espacial
|
|
23785
|
+
{ path: 'page.canvas', category: 'layout', valueKind: 'object', description: 'Canvas espacial canônico da página quando houver geometria explícita.' },
|
|
22022
23786
|
{ path: 'page.canvas.mode', category: 'layout', valueKind: 'enum', allowedValues: ENUMS.canvasMode, description: 'Modo canonico do canvas. Valor atual: grid.' },
|
|
22023
23787
|
{ path: 'page.canvas.columns', category: 'layout', valueKind: 'number', description: 'Numero de colunas do canvas espacial.' },
|
|
22024
23788
|
{ path: 'page.canvas.rowUnit', category: 'layout', valueKind: 'string', description: 'Altura base das linhas do canvas, como 80px.' },
|
|
@@ -22032,10 +23796,10 @@ const CAPS = [
|
|
|
22032
23796
|
{ path: 'page.canvas.items.<widgetKey>.rowSpan', category: 'layout', valueKind: 'number', description: 'Quantidade de linhas ocupadas pelo widget.' },
|
|
22033
23797
|
{ path: 'page.canvas.items.<widgetKey>.zIndex', category: 'layout', valueKind: 'number', description: 'Camada opcional do item no canvas.' },
|
|
22034
23798
|
{ path: 'page.canvas.items.<widgetKey>.constraints', category: 'layout', valueKind: 'object', description: 'Restricoes opcionais de posicao e tamanho do item no canvas.' },
|
|
22035
|
-
{ path: 'page.canvas.items.<widgetKey>.constraints.minColSpan', category: 'layout', valueKind: 'number', description: 'Span
|
|
22036
|
-
{ path: 'page.canvas.items.<widgetKey>.constraints.minRowSpan', category: 'layout', valueKind: 'number', description: 'Span
|
|
22037
|
-
{ path: 'page.canvas.items.<widgetKey>.constraints.maxColSpan', category: 'layout', valueKind: 'number', description: 'Span
|
|
22038
|
-
{ path: 'page.canvas.items.<widgetKey>.constraints.maxRowSpan', category: 'layout', valueKind: 'number', description: 'Span
|
|
23799
|
+
{ path: 'page.canvas.items.<widgetKey>.constraints.minColSpan', category: 'layout', valueKind: 'number', description: 'Span mínimo de colunas permitido.' },
|
|
23800
|
+
{ path: 'page.canvas.items.<widgetKey>.constraints.minRowSpan', category: 'layout', valueKind: 'number', description: 'Span mínimo de linhas permitido.' },
|
|
23801
|
+
{ path: 'page.canvas.items.<widgetKey>.constraints.maxColSpan', category: 'layout', valueKind: 'number', description: 'Span máximo de colunas permitido.' },
|
|
23802
|
+
{ path: 'page.canvas.items.<widgetKey>.constraints.maxRowSpan', category: 'layout', valueKind: 'number', description: 'Span máximo de linhas permitido.' },
|
|
22039
23803
|
{ path: 'page.canvas.items.<widgetKey>.constraints.lockPosition', category: 'layout', valueKind: 'boolean', description: 'Bloqueia alteracao de posicao do item no canvas.' },
|
|
22040
23804
|
{ path: 'page.canvas.items.<widgetKey>.constraints.lockSize', category: 'layout', valueKind: 'boolean', description: 'Bloqueia alteracao de tamanho do item no canvas.' },
|
|
22041
23805
|
{ path: 'page.widgets', category: 'widgets', valueKind: 'array', description: 'Lista de widgets renderizados.' },
|
|
@@ -22043,32 +23807,32 @@ const CAPS = [
|
|
|
22043
23807
|
{ path: 'page.widgets[].className', category: 'widgets', valueKind: 'string', description: 'Classe CSS opcional do widget.' },
|
|
22044
23808
|
{ path: 'page.widgets[].definition.id', category: 'widgets', valueKind: 'string', description: 'ID do componente do widget (ex: praxis-table).' },
|
|
22045
23809
|
{ path: 'page.widgets[].definition.inputs', category: 'widgets', valueKind: 'object', description: 'Inputs iniciais do widget.' },
|
|
22046
|
-
{ path: 'page.widgets[].definition.inputs.hostCapabilities', category: 'widgets', valueKind: 'object', description: 'Capacidades runtime mediadas pelo host quando definition.id = praxis-rich-content.
|
|
22047
|
-
{ path: 'page.widgets[].definition.inputs.hostCapabilities.dispatchAction', category: 'widgets', valueKind: 'object', description: 'Dispatcher runtime para actionButton e actions declarativas de rich content hospedado na
|
|
22048
|
-
{ path: 'page.widgets[].definition.inputs.hostCapabilities.isActionAvailable', category: 'widgets', valueKind: 'object', description: 'Resolver runtime de disponibilidade de actionId para rich content hospedado na
|
|
22049
|
-
{ path: 'page.widgets[].definition.inputs.hostCapabilities.hasCapability', category: 'widgets', valueKind: 'object', description: 'Resolver runtime de capabilities como page.customization.enabled e page.widget.selected para rich content hospedado na
|
|
23810
|
+
{ path: 'page.widgets[].definition.inputs.hostCapabilities', category: 'widgets', valueKind: 'object', description: 'Capacidades runtime mediadas pelo host quando definition.id = praxis-rich-content. Não pertence ao JSON persistido.' },
|
|
23811
|
+
{ path: 'page.widgets[].definition.inputs.hostCapabilities.dispatchAction', category: 'widgets', valueKind: 'object', description: 'Dispatcher runtime para actionButton e actions declarativas de rich content hospedado na página.' },
|
|
23812
|
+
{ path: 'page.widgets[].definition.inputs.hostCapabilities.isActionAvailable', category: 'widgets', valueKind: 'object', description: 'Resolver runtime de disponibilidade de actionId para rich content hospedado na página.' },
|
|
23813
|
+
{ path: 'page.widgets[].definition.inputs.hostCapabilities.hasCapability', category: 'widgets', valueKind: 'object', description: 'Resolver runtime de capabilities como page.customization.enabled e page.widget.selected para rich content hospedado na página.' },
|
|
22050
23814
|
{ path: 'page.widgets[].definition.bindingOrder', category: 'widgets', valueKind: 'array', description: 'Ordem de binding de inputs.' },
|
|
22051
|
-
{ path: 'page.widgets[].shell', category: 'shell', valueKind: 'object', description: '
|
|
23815
|
+
{ path: 'page.widgets[].shell', category: 'shell', valueKind: 'object', description: 'Configuração do shell do widget.' },
|
|
22052
23816
|
{ path: 'page.widgets[].shell.kind', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.shellKind, description: 'Tipo de shell.' },
|
|
22053
|
-
{ path: 'page.widgets[].shell.title', category: 'shell', valueKind: 'string', description: '
|
|
22054
|
-
{ path: 'page.widgets[].shell.subtitle', category: 'shell', valueKind: 'string', description: '
|
|
22055
|
-
{ path: 'page.widgets[].shell.icon', category: 'shell', valueKind: 'string', description: '
|
|
23817
|
+
{ path: 'page.widgets[].shell.title', category: 'shell', valueKind: 'string', description: 'Título do shell.' },
|
|
23818
|
+
{ path: 'page.widgets[].shell.subtitle', category: 'shell', valueKind: 'string', description: 'Subtítulo do shell.' },
|
|
23819
|
+
{ path: 'page.widgets[].shell.icon', category: 'shell', valueKind: 'string', description: 'Ícone do shell.' },
|
|
22056
23820
|
{ path: 'page.widgets[].shell.showHeader', category: 'shell', valueKind: 'boolean', description: 'Exibe o header do shell.' },
|
|
22057
|
-
{ path: 'page.widgets[].shell.actions', category: 'shell', valueKind: 'array', description: '
|
|
22058
|
-
{ path: 'page.widgets[].shell.actions[].id', category: 'shell', valueKind: 'string', description: 'ID da
|
|
22059
|
-
{ path: 'page.widgets[].shell.actions[].label', category: 'shell', valueKind: 'string', description: 'Label da
|
|
22060
|
-
{ path: 'page.widgets[].shell.actions[].icon', category: 'shell', valueKind: 'string', description: '
|
|
22061
|
-
{ path: 'page.widgets[].shell.actions[].variant', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.actionVariant, description: 'Estilo visual da
|
|
22062
|
-
{ path: 'page.widgets[].shell.actions[].placement', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.actionPlacement, description: 'Posicionamento da
|
|
22063
|
-
{ path: 'page.widgets[].shell.actions[].emit', category: 'shell', valueKind: 'string', description: 'Evento emitido ao acionar a
|
|
23821
|
+
{ path: 'page.widgets[].shell.actions', category: 'shell', valueKind: 'array', description: 'Ações do shell.' },
|
|
23822
|
+
{ path: 'page.widgets[].shell.actions[].id', category: 'shell', valueKind: 'string', description: 'ID da ação.' },
|
|
23823
|
+
{ path: 'page.widgets[].shell.actions[].label', category: 'shell', valueKind: 'string', description: 'Label da ação.' },
|
|
23824
|
+
{ path: 'page.widgets[].shell.actions[].icon', category: 'shell', valueKind: 'string', description: 'Ícone da ação.' },
|
|
23825
|
+
{ path: 'page.widgets[].shell.actions[].variant', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.actionVariant, description: 'Estilo visual da ação.' },
|
|
23826
|
+
{ path: 'page.widgets[].shell.actions[].placement', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.actionPlacement, description: 'Posicionamento da ação.' },
|
|
23827
|
+
{ path: 'page.widgets[].shell.actions[].emit', category: 'shell', valueKind: 'string', description: 'Evento emitido ao acionar a ação.' },
|
|
22064
23828
|
{ path: 'page.state', category: 'state', valueKind: 'object', description: 'Estado declarativo opcional compartilhado por widgets e composicao.' },
|
|
22065
23829
|
{ path: 'page.state.values', category: 'state', valueKind: 'object', description: 'Valores primarios mutaveis escritos por widgets, defaults ou host.' },
|
|
22066
23830
|
{ path: 'page.state.schema', category: 'state', valueKind: 'object', description: 'Descritores dos paths primarios de estado.' },
|
|
22067
23831
|
{ path: 'page.state.schema.<token>.type', category: 'state', valueKind: 'string', description: 'Tipo semantico opcional do path de estado.' },
|
|
22068
23832
|
{ path: 'page.state.schema.<token>.initial', category: 'state', valueKind: 'object', description: 'Valor inicial usado quando page.state.values omite o path.' },
|
|
22069
|
-
{ path: 'page.state.schema.<token>.persist', category: 'state', valueKind: 'boolean', description: 'Indica se o path
|
|
23833
|
+
{ path: 'page.state.schema.<token>.persist', category: 'state', valueKind: 'boolean', description: 'Indica se o path primário deve ser persistido com a página.' },
|
|
22070
23834
|
{ path: 'page.state.schema.<token>.mergeStrategy', category: 'state', valueKind: 'enum', allowedValues: ENUMS.stateMergeStrategy, description: 'Como escritas de widget/estado combinam com o valor atual.' },
|
|
22071
|
-
{ path: 'page.state.schema.<token>.description', category: 'state', valueKind: 'string', description: '
|
|
23835
|
+
{ path: 'page.state.schema.<token>.description', category: 'state', valueKind: 'string', description: 'Descrição opcional do path para builders e catálogos AI.' },
|
|
22072
23836
|
{ path: 'page.state.schema.<token>.tags', category: 'state', valueKind: 'array', description: 'Tags opcionais para busca e governanca do estado.' },
|
|
22073
23837
|
{ path: 'page.state.derived', category: 'state', valueKind: 'object', description: 'Descritores de estado derivado recomputado pelo runtime.' },
|
|
22074
23838
|
{ path: 'page.state.derived.<token>.dependsOn', category: 'state', valueKind: 'array', description: 'Paths de estado que alimentam o valor derivado.' },
|
|
@@ -22077,9 +23841,9 @@ const CAPS = [
|
|
|
22077
23841
|
{ path: 'page.state.derived.<token>.compute.expression', category: 'state', valueKind: 'expression', description: 'Expressao Json Logic para compute.kind=json-logic.' },
|
|
22078
23842
|
{ path: 'page.state.derived.<token>.compute.value', category: 'state', valueKind: 'object', description: 'Valor template para compute.kind=template.' },
|
|
22079
23843
|
{ path: 'page.state.derived.<token>.compute.operator', category: 'state', valueKind: 'string', description: 'Operador para compute.kind=operator.' },
|
|
22080
|
-
{ path: 'page.state.derived.<token>.compute.options', category: 'state', valueKind: 'object', description: '
|
|
23844
|
+
{ path: 'page.state.derived.<token>.compute.options', category: 'state', valueKind: 'object', description: 'Opções do operador ou transformer.' },
|
|
22081
23845
|
{ path: 'page.state.derived.<token>.compute.transformerId', category: 'state', valueKind: 'string', description: 'Identificador do transformer para compute.kind=transformer.' },
|
|
22082
|
-
{ path: 'page.state.derived.<token>.description', category: 'state', valueKind: 'string', description: '
|
|
23846
|
+
{ path: 'page.state.derived.<token>.description', category: 'state', valueKind: 'string', description: 'Descrição opcional do estado derivado.' },
|
|
22083
23847
|
{ path: 'page.state.derived.<token>.cache', category: 'state', valueKind: 'boolean', description: 'Permite cache futuro do valor derivado.' },
|
|
22084
23848
|
{ path: 'page.composition', category: 'connections', valueKind: 'object', description: 'Envelope canonico da composicao persistida.' },
|
|
22085
23849
|
{ path: 'page.composition.version', category: 'connections', valueKind: 'string', description: 'Versao do envelope de composicao.' },
|
|
@@ -22095,7 +23859,7 @@ const CAPS = [
|
|
|
22095
23859
|
{ path: 'page.composition.links[].from.ref.nestedPath[].kind', category: 'connections', valueKind: 'string', description: 'Tipo do segmento nested de origem.' },
|
|
22096
23860
|
{ path: 'page.composition.links[].from.ref.nestedPath[].id', category: 'connections', valueKind: 'string', description: 'Identificador estrutural do segmento nested de origem.' },
|
|
22097
23861
|
{ path: 'page.composition.links[].from.ref.nestedPath[].key', category: 'connections', valueKind: 'string', description: 'Chave estavel do widget filho no segmento terminal de origem.', critical: true },
|
|
22098
|
-
{ path: 'page.composition.links[].from.ref.nestedPath[].index', category: 'connections', valueKind: 'number', description: '
|
|
23862
|
+
{ path: 'page.composition.links[].from.ref.nestedPath[].index', category: 'connections', valueKind: 'number', description: 'Índice auxiliar para diagnóstico visual; não use como identidade primária.' },
|
|
22099
23863
|
{ path: 'page.composition.links[].from.ref.nestedPath[].componentType', category: 'connections', valueKind: 'string', description: 'Tipo do componente real do widget filho de origem.' },
|
|
22100
23864
|
{ path: 'page.composition.links[].to', category: 'connections', valueKind: 'object', description: 'Endpoint de destino do link.' },
|
|
22101
23865
|
{ path: 'page.composition.links[].to.kind', category: 'connections', valueKind: 'string', description: 'Tipo do endpoint de destino, como component-port, state ou global-action.' },
|
|
@@ -22110,11 +23874,11 @@ const CAPS = [
|
|
|
22110
23874
|
{ path: 'page.composition.links[].to.ref.nestedPath[].kind', category: 'connections', valueKind: 'string', description: 'Tipo do segmento nested de destino.' },
|
|
22111
23875
|
{ path: 'page.composition.links[].to.ref.nestedPath[].id', category: 'connections', valueKind: 'string', description: 'Identificador estrutural do segmento nested de destino.' },
|
|
22112
23876
|
{ path: 'page.composition.links[].to.ref.nestedPath[].key', category: 'connections', valueKind: 'string', description: 'Chave estavel do widget filho no segmento terminal de destino.', critical: true },
|
|
22113
|
-
{ path: 'page.composition.links[].to.ref.nestedPath[].index', category: 'connections', valueKind: 'number', description: '
|
|
23877
|
+
{ path: 'page.composition.links[].to.ref.nestedPath[].index', category: 'connections', valueKind: 'number', description: 'Índice auxiliar para diagnóstico visual; não use como identidade primária.' },
|
|
22114
23878
|
{ path: 'page.composition.links[].to.ref.nestedPath[].componentType', category: 'connections', valueKind: 'string', description: 'Tipo do componente real do widget filho de destino.' },
|
|
22115
|
-
{ path: 'page.composition.links[].intent', category: 'connections', valueKind: 'string', description: '
|
|
23879
|
+
{ path: 'page.composition.links[].intent', category: 'connections', valueKind: 'string', description: 'Intenção semântica do link.' },
|
|
22116
23880
|
{ path: 'page.composition.links[].transform', category: 'connections', valueKind: 'object', description: 'Pipeline de transformacao do link.' },
|
|
22117
|
-
{ path: 'page.composition.links[].condition', category: 'connections', valueKind: 'expression', description: 'Guarda
|
|
23881
|
+
{ path: 'page.composition.links[].condition', category: 'connections', valueKind: 'expression', description: 'Guarda semântica opcional do link, expressa como um único AST Json Logic canônico.' },
|
|
22118
23882
|
{ path: 'page.composition.links[].policy', category: 'connections', valueKind: 'object', description: 'Politicas operacionais opcionais do link, como debounce, distinct e missing-value.' },
|
|
22119
23883
|
{ path: 'page.composition.links[].metadata', category: 'connections', valueKind: 'object', description: 'Metadados opcionais do link.' },
|
|
22120
23884
|
{ path: 'page.grouping', category: 'layout', valueKind: 'array', description: 'Modelo semantico opcional de secoes, abas, areas hero e rails.' },
|
|
@@ -22155,15 +23919,15 @@ const DYNAMIC_PAGE_AI_CAPABILITIES = {
|
|
|
22155
23919
|
enums: ENUMS,
|
|
22156
23920
|
targets: ['praxis-dynamic-page'],
|
|
22157
23921
|
notes: [
|
|
22158
|
-
'Este
|
|
23922
|
+
'Este catálogo é específico para o runtime praxis-dynamic-page; operações de authoring/mutação pertencem ao manifesto do praxis-page-builder.',
|
|
22159
23923
|
'WidgetPageDefinition e o contrato canonico persistido: widgets, composition.links, state, context, layout, canvas, presets, grouping, slotAssignments, deviceLayouts e themePreset.',
|
|
22160
23924
|
'Widgets e page.composition.links sao arrays; ferramentas de patch legadas fazem merge por key estavel e id estavel.',
|
|
22161
|
-
'page.canvas.items
|
|
22162
|
-
'Taxonomia editorial: condition usa Json Logic
|
|
23925
|
+
'page.canvas.items é um mapa por widget key; não modele canvas.items como array.',
|
|
23926
|
+
'Taxonomia editorial: condition usa Json Logic canônico; transform usa pipeline declarativo; não trate ambos como a mesma "expression".',
|
|
22163
23927
|
'Para remocao/replace, use flags {_remove:true} ou {_replace:true} no item.',
|
|
22164
23928
|
'Para renomear um link, inclua {_beforeKey:"link-id-anterior"} no item.',
|
|
22165
|
-
'Inputs de widgets dependem do componente (ex: praxis-table, praxis-dynamic-form). Evite inventar campos; prefira pedir
|
|
22166
|
-
'Quando page.widgets[].definition.id for praxis-rich-content, o host praxis-dynamic-page injeta hostCapabilities em runtime para actions e capability gating;
|
|
23929
|
+
'Inputs de widgets dependem do componente (ex: praxis-table, praxis-dynamic-form). Evite inventar campos; prefira pedir confirmação.',
|
|
23930
|
+
'Quando page.widgets[].definition.id for praxis-rich-content, o host praxis-dynamic-page injeta hostCapabilities em runtime para actions e capability gating; não serialize funções nem tente persistir page.widgets[].definition.inputs.hostCapabilities.',
|
|
22167
23931
|
'Use ids estaveis para links e keys estaveis para widgets.',
|
|
22168
23932
|
'Nested component ports usam endpoint component-port com nestedPath; o owner em ref.widget continua sendo o widget top-level.',
|
|
22169
23933
|
'Objetivo: compor widgets e relacionamentos canonicos (ex.: master-detail).',
|
|
@@ -22192,7 +23956,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22192
23956
|
mode: 'enum',
|
|
22193
23957
|
options: [
|
|
22194
23958
|
{ value: 'fixed', label: 'Linhas fixas' },
|
|
22195
|
-
{ value: 'content', label: '
|
|
23959
|
+
{ value: 'content', label: 'Conteúdo' },
|
|
22196
23960
|
],
|
|
22197
23961
|
},
|
|
22198
23962
|
'page.canvas.collisionPolicy': {
|
|
@@ -22261,7 +24025,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22261
24025
|
'page.widgets[].shell.actions[].variant': {
|
|
22262
24026
|
mode: 'enum',
|
|
22263
24027
|
options: [
|
|
22264
|
-
{ value: 'icon', label: '
|
|
24028
|
+
{ value: 'icon', label: 'Ícone' },
|
|
22265
24029
|
{ value: 'text', label: 'Texto' },
|
|
22266
24030
|
{ value: 'outlined', label: 'Outlined' },
|
|
22267
24031
|
],
|
|
@@ -22291,7 +24055,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22291
24055
|
mode: 'suggested',
|
|
22292
24056
|
options: [
|
|
22293
24057
|
{ value: 'rowClick', label: 'Clique na linha (praxis-table)', example: 'Usar table.rowClick -> form.resourceId via transform pick-path payload.row.id' },
|
|
22294
|
-
{ value: 'rowAction', label: '
|
|
24058
|
+
{ value: 'rowAction', label: 'Ação da linha (praxis-table)' },
|
|
22295
24059
|
{ value: 'formSubmit', label: 'Submit do formulario (praxis-dynamic-form)' },
|
|
22296
24060
|
],
|
|
22297
24061
|
},
|
|
@@ -22305,7 +24069,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22305
24069
|
'page.composition.links[].transform.steps[].config.path': {
|
|
22306
24070
|
mode: 'suggested',
|
|
22307
24071
|
options: [
|
|
22308
|
-
{ value: 'payload.row.id', label: 'ID
|
|
24072
|
+
{ value: 'payload.row.id', label: 'ID padrão do registro', example: 'rowClick -> resourceId' },
|
|
22309
24073
|
],
|
|
22310
24074
|
},
|
|
22311
24075
|
},
|
|
@@ -22617,7 +24381,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22617
24381
|
{ name: 'toInput', type: 'STRING' },
|
|
22618
24382
|
{ name: 'map', type: 'STRING' },
|
|
22619
24383
|
],
|
|
22620
|
-
safetyNotes: 'Use transform pick-path payload.row.id para master-detail
|
|
24384
|
+
safetyNotes: 'Use transform pick-path payload.row.id para master-detail padrão.',
|
|
22621
24385
|
patchTemplate: {
|
|
22622
24386
|
page: {
|
|
22623
24387
|
composition: {
|
|
@@ -22668,7 +24432,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22668
24432
|
{ name: 'fromWidget', type: 'STRING' },
|
|
22669
24433
|
{ name: 'toWidget', type: 'STRING' },
|
|
22670
24434
|
],
|
|
22671
|
-
safetyNotes: '
|
|
24435
|
+
safetyNotes: 'Padrão master-detail: rowClick -> resourceId com transform pick-path payload.row.id.',
|
|
22672
24436
|
patchTemplate: {
|
|
22673
24437
|
page: {
|
|
22674
24438
|
composition: {
|
|
@@ -22711,7 +24475,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22711
24475
|
},
|
|
22712
24476
|
{
|
|
22713
24477
|
id: 'page.template.applyMasterDetail',
|
|
22714
|
-
intentExamples: ['criar
|
|
24478
|
+
intentExamples: ['criar página master detail', 'setup master detail', 'tabela e formulário', 'master-detail'],
|
|
22715
24479
|
operation: 'create',
|
|
22716
24480
|
scope: 'GLOBAL',
|
|
22717
24481
|
valueType: 'OBJECT',
|
|
@@ -22720,7 +24484,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22720
24484
|
{ name: 'formId', type: 'STRING' },
|
|
22721
24485
|
{ name: 'resourcePath', type: 'STRING' },
|
|
22722
24486
|
],
|
|
22723
|
-
safetyNotes: '
|
|
24487
|
+
safetyNotes: 'Padrão master-detail: tabela (rowClick) -> formulario (resourceId) com transform pick-path payload.row.id.',
|
|
22724
24488
|
patchTemplate: {
|
|
22725
24489
|
page: {
|
|
22726
24490
|
widgets: [
|
|
@@ -22796,30 +24560,30 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
22796
24560
|
},
|
|
22797
24561
|
hints: [
|
|
22798
24562
|
'praxis-dynamic-page e runtime de composicao: consome WidgetPageDefinition, renderiza widgets e mantem relacoes em page.composition.links.',
|
|
22799
|
-
'
|
|
24563
|
+
'Mutações agentic de página pertencem ao manifesto do praxis-page-builder; use este context pack como descoberta/runtime guidance.',
|
|
22800
24564
|
'WidgetPageDefinition inclui widgets, composition.links, state, context, layout, canvas, layoutPreset, layoutPresetOptions, grouping, slotAssignments, deviceLayouts e themePreset.',
|
|
22801
|
-
'page.canvas.items
|
|
24565
|
+
'page.canvas.items é um mapa por widget key, não um array; cada entrada guarda col, row, colSpan, rowSpan, zIndex e constraints opcionais.',
|
|
22802
24566
|
'Widgets e composition.links sao arrays; o patching deve fazer merge por key (widgets) e por id (links).',
|
|
22803
|
-
'Preferir
|
|
24567
|
+
'Preferir mudanças incrementais: alterar/estender em vez de substituir toda a página.',
|
|
22804
24568
|
'Para remover um item, envie {_remove: true} junto ao widget/link.',
|
|
22805
24569
|
'Para substituir um item inteiro, envie {_replace: true}.',
|
|
22806
24570
|
'Para alterar origem/destino de link, use {_beforeKey} com o id antigo.',
|
|
22807
24571
|
'Use keys estaveis para widgets e ids estaveis para links ao criar composicoes.',
|
|
22808
24572
|
'resourcePath sempre e o path base do recurso (sem /filter, /all).',
|
|
22809
|
-
'Praxis Table gera colunas dinamicamente a partir do resourcePath quando columns
|
|
22810
|
-
'Praxis Dynamic Form gera campos dinamicamente a partir do resourcePath quando config
|
|
22811
|
-
'Quando um widget praxis-rich-content estiver hospedado na
|
|
24573
|
+
'Praxis Table gera colunas dinamicamente a partir do resourcePath quando columns não forem definidas.',
|
|
24574
|
+
'Praxis Dynamic Form gera campos dinamicamente a partir do resourcePath quando config não for definida.',
|
|
24575
|
+
'Quando um widget praxis-rich-content estiver hospedado na página, definition.inputs.document continua sendo o contrato persistido; hostCapabilities é injetado somente em runtime pelo praxis-dynamic-page para actions e capability gating.',
|
|
22812
24576
|
'Praxis List pode filtrar via config.dataSource.query (enviado para /filter).',
|
|
22813
24577
|
'Quando houver recursos secundarios (ex.: enderecos), use contextHints.addressResourcePath.',
|
|
22814
24578
|
'Exemplo master-detail: tabela emite rowClick -> form.resourceId via transform pick-path payload.row.id.',
|
|
22815
24579
|
'Pattern Master-Detail: { "id":"master.rowClick->detail.resourceId", "from":{"kind":"component-port","ref":{"port":"rowClick","direction":"output"}}, "to":{"kind":"component-port","ref":{"port":"resourceId","direction":"input"}}, "transform":{"steps":[{"kind":"pick-path","config":{"path":"payload.row.id"}}]}}',
|
|
22816
24580
|
'Ao criar widgets, use inputs minimos e complemente depois (evite inventar campos).',
|
|
22817
24581
|
'Quando widgets ja existem, interpretar ports de origem/destino antes de conectar.',
|
|
22818
|
-
'
|
|
22819
|
-
'
|
|
24582
|
+
'Intenção comum: criar página master-detail = criar tabela + criar formulário + conectar seleção via composition.links.',
|
|
24583
|
+
'Intenção comum: ajustar página existente = modificar apenas widgets/inputs necessários.',
|
|
22820
24584
|
'Exemplo de link canonico (master-detail): { id:"masterTable.rowClick->detailForm.resourceId", from:{kind:"component-port",ref:{widget:"masterTable",port:"rowClick",direction:"output"}}, to:{kind:"component-port",ref:{widget:"detailForm",port:"resourceId",direction:"input"}}, intent:"event-propagation", transform:{version:"2.0",phase:"link-propagation",mode:"single-value",steps:[{kind:"pick-path",phase:"link-propagation",input:{source:"event"},config:{path:"payload.row.id"}}]}}',
|
|
22821
|
-
'Exemplo de widget tabela (
|
|
22822
|
-
'Exemplo de widget
|
|
24585
|
+
'Exemplo de widget tabela (mínimo): { key:"masterTable", definition:{ id:"praxis-table", inputs:{ resourcePath:"/api/x" }}}',
|
|
24586
|
+
'Exemplo de widget formulário (mínimo): { key:"detailForm", definition:{ id:"praxis-dynamic-form", inputs:{ resourcePath:"/api/x", mode:"view" }}}',
|
|
22823
24587
|
'Se houver idField conhecido, use transform pick-path payload.row.{idField} em links canonicos.',
|
|
22824
24588
|
],
|
|
22825
24589
|
};
|
|
@@ -24945,9 +26709,21 @@ class DynamicWidgetLoaderDirective {
|
|
|
24945
26709
|
const defaultOrderMap = {
|
|
24946
26710
|
'praxis-table': ['tableId', 'componentInstanceId', 'configPersistenceStrategy', 'resourcePath', 'data', 'config'],
|
|
24947
26711
|
'praxis-crud': ['crudId', 'componentInstanceId', 'metadata'],
|
|
24948
|
-
'praxis-dynamic-form': [
|
|
26712
|
+
'praxis-dynamic-form': [
|
|
26713
|
+
'formId',
|
|
26714
|
+
'componentInstanceId',
|
|
26715
|
+
'resourcePath',
|
|
26716
|
+
'schemaUrl',
|
|
26717
|
+
'submitUrl',
|
|
26718
|
+
'submitMethod',
|
|
26719
|
+
'apiEndpointKey',
|
|
26720
|
+
'apiUrlEntry',
|
|
26721
|
+
'initialValue',
|
|
26722
|
+
'mode',
|
|
26723
|
+
'layoutPolicy',
|
|
26724
|
+
],
|
|
24949
26725
|
'praxis-tabs': ['tabsId', 'componentInstanceId', 'configPersistenceStrategy', 'config'],
|
|
24950
|
-
'praxis-list': ['listId', 'componentInstanceId', 'config'],
|
|
26726
|
+
'praxis-list': ['listId', 'componentInstanceId', 'enableCustomization', 'config'],
|
|
24951
26727
|
'praxis-expansion': ['expansionId', 'componentInstanceId', 'config'],
|
|
24952
26728
|
'praxis-stepper': ['stepperId', 'componentInstanceId', 'config'],
|
|
24953
26729
|
'praxis-files-upload': ['filesUploadId', 'componentInstanceId', 'config'],
|
|
@@ -25307,28 +27083,160 @@ const BUILTIN_SHELL_PRESETS = {
|
|
|
25307
27083
|
},
|
|
25308
27084
|
'light-neutral': {
|
|
25309
27085
|
card: {
|
|
25310
|
-
background: '
|
|
25311
|
-
borderColor: '
|
|
27086
|
+
background: 'var(--md-sys-color-surface)',
|
|
27087
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-outline-variant) 82%, transparent)',
|
|
25312
27088
|
borderRadius: '12px',
|
|
25313
|
-
shadow: '0 4px
|
|
27089
|
+
shadow: '0 4px 14px color-mix(in srgb, var(--md-sys-color-shadow, #000) 7%, transparent)',
|
|
25314
27090
|
},
|
|
25315
27091
|
header: {
|
|
25316
|
-
|
|
25317
|
-
|
|
25318
|
-
|
|
27092
|
+
background: 'color-mix(in srgb, var(--md-sys-color-surface-container-low) 72%, transparent)',
|
|
27093
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-outline-variant) 70%, transparent)',
|
|
27094
|
+
titleColor: 'var(--md-sys-color-on-surface)',
|
|
27095
|
+
subtitleColor: 'var(--md-sys-color-on-surface-variant)',
|
|
27096
|
+
iconColor: 'var(--md-sys-color-primary)',
|
|
27097
|
+
},
|
|
27098
|
+
body: {
|
|
27099
|
+
background: 'var(--md-sys-color-surface)',
|
|
27100
|
+
textColor: 'var(--md-sys-color-on-surface)',
|
|
25319
27101
|
},
|
|
25320
27102
|
},
|
|
25321
27103
|
graphite: {
|
|
25322
27104
|
card: {
|
|
25323
|
-
background: '
|
|
25324
|
-
borderColor: '
|
|
25325
|
-
borderRadius: '
|
|
25326
|
-
shadow: '0
|
|
27105
|
+
background: 'color-mix(in srgb, var(--md-sys-color-surface) 94%, var(--md-sys-color-surface-container-high) 6%)',
|
|
27106
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-outline-variant) 74%, transparent)',
|
|
27107
|
+
borderRadius: '12px',
|
|
27108
|
+
shadow: '0 8px 22px color-mix(in srgb, var(--md-sys-color-shadow, #000) 11%, transparent)',
|
|
27109
|
+
},
|
|
27110
|
+
header: {
|
|
27111
|
+
background: 'color-mix(in srgb, var(--md-sys-color-surface-container-low) 76%, transparent)',
|
|
27112
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-outline-variant) 62%, transparent)',
|
|
27113
|
+
titleColor: 'var(--md-sys-color-on-surface)',
|
|
27114
|
+
subtitleColor: 'var(--md-sys-color-on-surface-variant)',
|
|
27115
|
+
iconColor: 'var(--md-sys-color-primary)',
|
|
27116
|
+
},
|
|
27117
|
+
body: {
|
|
27118
|
+
background: 'var(--md-sys-color-surface)',
|
|
27119
|
+
textColor: 'var(--md-sys-color-on-surface)',
|
|
27120
|
+
},
|
|
27121
|
+
},
|
|
27122
|
+
frameless: {
|
|
27123
|
+
card: {
|
|
27124
|
+
background: 'transparent',
|
|
27125
|
+
borderColor: 'transparent',
|
|
27126
|
+
borderRadius: '0',
|
|
27127
|
+
shadow: 'none',
|
|
25327
27128
|
},
|
|
25328
27129
|
header: {
|
|
25329
|
-
|
|
25330
|
-
|
|
25331
|
-
|
|
27130
|
+
background: 'transparent',
|
|
27131
|
+
borderColor: 'transparent',
|
|
27132
|
+
titleColor: 'var(--md-sys-color-on-surface)',
|
|
27133
|
+
subtitleColor: 'var(--md-sys-color-on-surface-variant)',
|
|
27134
|
+
iconColor: 'var(--md-sys-color-primary)',
|
|
27135
|
+
},
|
|
27136
|
+
body: {
|
|
27137
|
+
background: 'transparent',
|
|
27138
|
+
textColor: 'var(--md-sys-color-on-surface)',
|
|
27139
|
+
padding: '0',
|
|
27140
|
+
},
|
|
27141
|
+
},
|
|
27142
|
+
'data-panel': {
|
|
27143
|
+
card: {
|
|
27144
|
+
background: 'var(--md-sys-color-surface)',
|
|
27145
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-outline-variant) 76%, transparent)',
|
|
27146
|
+
borderRadius: '10px',
|
|
27147
|
+
shadow: '0 5px 16px color-mix(in srgb, var(--md-sys-color-shadow, #000) 7%, transparent)',
|
|
27148
|
+
},
|
|
27149
|
+
header: {
|
|
27150
|
+
background: 'color-mix(in srgb, var(--md-sys-color-surface-container-low) 64%, transparent)',
|
|
27151
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-outline-variant) 58%, transparent)',
|
|
27152
|
+
titleColor: 'var(--md-sys-color-on-surface)',
|
|
27153
|
+
subtitleColor: 'var(--md-sys-color-on-surface-variant)',
|
|
27154
|
+
iconColor: 'var(--md-sys-color-primary)',
|
|
27155
|
+
},
|
|
27156
|
+
body: {
|
|
27157
|
+
background: 'var(--md-sys-color-surface)',
|
|
27158
|
+
textColor: 'var(--md-sys-color-on-surface)',
|
|
27159
|
+
padding: '12px',
|
|
27160
|
+
},
|
|
27161
|
+
},
|
|
27162
|
+
'chart-panel': {
|
|
27163
|
+
card: {
|
|
27164
|
+
background: 'color-mix(in srgb, var(--md-sys-color-surface) 92%, var(--md-sys-color-primary-container) 8%)',
|
|
27165
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-primary) 22%, var(--md-sys-color-outline-variant) 62%)',
|
|
27166
|
+
borderRadius: '12px',
|
|
27167
|
+
shadow: '0 10px 24px color-mix(in srgb, var(--md-sys-color-shadow, #000) 9%, transparent)',
|
|
27168
|
+
},
|
|
27169
|
+
header: {
|
|
27170
|
+
background: 'color-mix(in srgb, var(--md-sys-color-primary-container) 22%, transparent)',
|
|
27171
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent)',
|
|
27172
|
+
titleColor: 'var(--md-sys-color-on-surface)',
|
|
27173
|
+
subtitleColor: 'var(--md-sys-color-on-surface-variant)',
|
|
27174
|
+
iconColor: 'var(--md-sys-color-primary)',
|
|
27175
|
+
},
|
|
27176
|
+
body: {
|
|
27177
|
+
background: 'transparent',
|
|
27178
|
+
textColor: 'var(--md-sys-color-on-surface)',
|
|
27179
|
+
padding: '12px',
|
|
27180
|
+
},
|
|
27181
|
+
},
|
|
27182
|
+
'metric-panel': {
|
|
27183
|
+
card: {
|
|
27184
|
+
background: 'color-mix(in srgb, var(--md-sys-color-surface-container-low) 78%, var(--md-sys-color-primary-container) 22%)',
|
|
27185
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-primary) 24%, transparent)',
|
|
27186
|
+
borderRadius: '10px',
|
|
27187
|
+
shadow: '0 8px 18px color-mix(in srgb, var(--md-sys-color-shadow, #000) 8%, transparent)',
|
|
27188
|
+
},
|
|
27189
|
+
header: {
|
|
27190
|
+
background: 'transparent',
|
|
27191
|
+
borderColor: 'transparent',
|
|
27192
|
+
titleColor: 'var(--md-sys-color-on-surface)',
|
|
27193
|
+
subtitleColor: 'var(--md-sys-color-on-surface-variant)',
|
|
27194
|
+
iconColor: 'var(--md-sys-color-primary)',
|
|
27195
|
+
},
|
|
27196
|
+
body: {
|
|
27197
|
+
background: 'transparent',
|
|
27198
|
+
textColor: 'var(--md-sys-color-on-surface)',
|
|
27199
|
+
padding: '10px 12px',
|
|
27200
|
+
},
|
|
27201
|
+
},
|
|
27202
|
+
'executive-card': {
|
|
27203
|
+
card: {
|
|
27204
|
+
background: 'color-mix(in srgb, var(--md-sys-color-surface) 88%, var(--md-sys-color-surface-container-high) 12%)',
|
|
27205
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-primary) 28%, var(--md-sys-color-outline-variant) 50%)',
|
|
27206
|
+
borderRadius: '10px',
|
|
27207
|
+
shadow: '0 12px 28px color-mix(in srgb, var(--md-sys-color-shadow, #000) 13%, transparent)',
|
|
27208
|
+
},
|
|
27209
|
+
header: {
|
|
27210
|
+
background: 'color-mix(in srgb, var(--md-sys-color-primary-container) 18%, transparent)',
|
|
27211
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-primary) 22%, transparent)',
|
|
27212
|
+
titleColor: 'var(--md-sys-color-on-surface)',
|
|
27213
|
+
subtitleColor: 'var(--md-sys-color-on-surface-variant)',
|
|
27214
|
+
iconColor: 'var(--md-sys-color-primary)',
|
|
27215
|
+
},
|
|
27216
|
+
body: {
|
|
27217
|
+
background: 'transparent',
|
|
27218
|
+
textColor: 'var(--md-sys-color-on-surface)',
|
|
27219
|
+
padding: '14px',
|
|
27220
|
+
},
|
|
27221
|
+
},
|
|
27222
|
+
'filter-bar': {
|
|
27223
|
+
card: {
|
|
27224
|
+
background: 'color-mix(in srgb, var(--md-sys-color-surface-container-low) 74%, var(--md-sys-color-secondary-container) 26%)',
|
|
27225
|
+
borderColor: 'color-mix(in srgb, var(--md-sys-color-secondary) 24%, transparent)',
|
|
27226
|
+
borderRadius: '999px',
|
|
27227
|
+
shadow: '0 6px 18px color-mix(in srgb, var(--md-sys-color-shadow, #000) 7%, transparent)',
|
|
27228
|
+
},
|
|
27229
|
+
header: {
|
|
27230
|
+
background: 'transparent',
|
|
27231
|
+
borderColor: 'transparent',
|
|
27232
|
+
titleColor: 'var(--md-sys-color-on-surface)',
|
|
27233
|
+
subtitleColor: 'var(--md-sys-color-on-surface-variant)',
|
|
27234
|
+
iconColor: 'var(--md-sys-color-secondary)',
|
|
27235
|
+
},
|
|
27236
|
+
body: {
|
|
27237
|
+
background: 'transparent',
|
|
27238
|
+
textColor: 'var(--md-sys-color-on-surface)',
|
|
27239
|
+
padding: '10px 14px',
|
|
25332
27240
|
},
|
|
25333
27241
|
},
|
|
25334
27242
|
};
|
|
@@ -25404,6 +27312,11 @@ class WidgetShellComponent {
|
|
|
25404
27312
|
const builtins = this.buildWindowActions(custom);
|
|
25405
27313
|
return [...builtins, ...custom];
|
|
25406
27314
|
}
|
|
27315
|
+
displayActionIcon(action) {
|
|
27316
|
+
return action.pressed === true && action.pressedIcon
|
|
27317
|
+
? action.pressedIcon
|
|
27318
|
+
: action.icon;
|
|
27319
|
+
}
|
|
25407
27320
|
onAction(action, ev) {
|
|
25408
27321
|
ev.stopPropagation();
|
|
25409
27322
|
const handled = this.handleWindowAction(action);
|
|
@@ -25413,6 +27326,7 @@ class WidgetShellComponent {
|
|
|
25413
27326
|
command: action.command,
|
|
25414
27327
|
emit: action.emit,
|
|
25415
27328
|
payload,
|
|
27329
|
+
pressed: action.pressed,
|
|
25416
27330
|
action,
|
|
25417
27331
|
};
|
|
25418
27332
|
this.loader?.dispatchAction(event);
|
|
@@ -25603,14 +27517,16 @@ class WidgetShellComponent {
|
|
|
25603
27517
|
<button
|
|
25604
27518
|
[disabled]="action.disabled"
|
|
25605
27519
|
[matTooltip]="action.tooltip || ''"
|
|
25606
|
-
matTooltipPosition="
|
|
27520
|
+
matTooltipPosition="above"
|
|
25607
27521
|
[ngClass]="action.variant === 'outlined' ? 'pdx-action-outlined' : 'pdx-action-text'"
|
|
27522
|
+
[class.pdx-shell-action--pressed]="action.pressed === true"
|
|
25608
27523
|
mat-button
|
|
25609
27524
|
type="button"
|
|
27525
|
+
[attr.aria-pressed]="action.pressed == null ? null : action.pressed"
|
|
25610
27526
|
(click)="onAction(action, $event)"
|
|
25611
27527
|
>
|
|
25612
|
-
@if (action
|
|
25613
|
-
<mat-icon [praxisIcon]="
|
|
27528
|
+
@if (displayActionIcon(action); as actionIcon) {
|
|
27529
|
+
<mat-icon [praxisIcon]="actionIcon"></mat-icon>
|
|
25614
27530
|
}
|
|
25615
27531
|
<span class="pdx-action-label">{{ action.label }}</span>
|
|
25616
27532
|
</button>
|
|
@@ -25620,13 +27536,15 @@ class WidgetShellComponent {
|
|
|
25620
27536
|
mat-icon-button
|
|
25621
27537
|
[disabled]="action.disabled"
|
|
25622
27538
|
[matTooltip]="action.tooltip || action.label || ''"
|
|
25623
|
-
matTooltipPosition="
|
|
27539
|
+
matTooltipPosition="above"
|
|
25624
27540
|
[attr.aria-label]="action.label || action.tooltip || action.id"
|
|
27541
|
+
[attr.aria-pressed]="action.pressed == null ? null : action.pressed"
|
|
27542
|
+
[class.pdx-shell-action--pressed]="action.pressed === true"
|
|
25625
27543
|
type="button"
|
|
25626
27544
|
(click)="onAction(action, $event)"
|
|
25627
27545
|
>
|
|
25628
|
-
@if (action
|
|
25629
|
-
<mat-icon [praxisIcon]="
|
|
27546
|
+
@if (displayActionIcon(action); as actionIcon) {
|
|
27547
|
+
<mat-icon [praxisIcon]="actionIcon"></mat-icon>
|
|
25630
27548
|
}
|
|
25631
27549
|
</button>
|
|
25632
27550
|
}
|
|
@@ -25637,7 +27555,7 @@ class WidgetShellComponent {
|
|
|
25637
27555
|
mat-icon-button
|
|
25638
27556
|
type="button"
|
|
25639
27557
|
[matTooltip]="moreActionsLabel()"
|
|
25640
|
-
matTooltipPosition="
|
|
27558
|
+
matTooltipPosition="above"
|
|
25641
27559
|
[attr.aria-label]="moreActionsLabel()"
|
|
25642
27560
|
[matMenuTriggerFor]="overflowMenu"
|
|
25643
27561
|
(click)="$event.stopPropagation()"
|
|
@@ -25653,13 +27571,15 @@ class WidgetShellComponent {
|
|
|
25653
27571
|
mat-icon-button
|
|
25654
27572
|
[disabled]="action.disabled"
|
|
25655
27573
|
[matTooltip]="action.tooltip || action.label || ''"
|
|
25656
|
-
matTooltipPosition="
|
|
27574
|
+
matTooltipPosition="above"
|
|
25657
27575
|
[attr.aria-label]="action.label || action.tooltip || action.id"
|
|
27576
|
+
[attr.aria-pressed]="action.pressed == null ? null : action.pressed"
|
|
27577
|
+
[class.pdx-shell-action--pressed]="action.pressed === true"
|
|
25658
27578
|
type="button"
|
|
25659
27579
|
(click)="onAction(action, $event)"
|
|
25660
27580
|
>
|
|
25661
|
-
@if (action
|
|
25662
|
-
<mat-icon [praxisIcon]="
|
|
27581
|
+
@if (displayActionIcon(action); as actionIcon) {
|
|
27582
|
+
<mat-icon [praxisIcon]="actionIcon"></mat-icon>
|
|
25663
27583
|
}
|
|
25664
27584
|
</button>
|
|
25665
27585
|
}
|
|
@@ -25670,10 +27590,11 @@ class WidgetShellComponent {
|
|
|
25670
27590
|
@for (action of overflowHeaderActions; track action.id) {
|
|
25671
27591
|
<button
|
|
25672
27592
|
mat-menu-item
|
|
27593
|
+
[attr.aria-pressed]="action.pressed == null ? null : action.pressed"
|
|
25673
27594
|
(click)="onAction(action, $event)"
|
|
25674
27595
|
>
|
|
25675
|
-
@if (action
|
|
25676
|
-
<mat-icon [praxisIcon]="
|
|
27596
|
+
@if (displayActionIcon(action); as actionIcon) {
|
|
27597
|
+
<mat-icon [praxisIcon]="actionIcon"></mat-icon>
|
|
25677
27598
|
}
|
|
25678
27599
|
<span>{{ action.label || action.id }}</span>
|
|
25679
27600
|
</button>
|
|
@@ -25688,7 +27609,7 @@ class WidgetShellComponent {
|
|
|
25688
27609
|
@if (expanded || fullscreen) {
|
|
25689
27610
|
<div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
|
|
25690
27611
|
}
|
|
25691
|
-
`, isInline: true, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
27612
|
+
`, isInline: true, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
25692
27613
|
}
|
|
25693
27614
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: WidgetShellComponent, decorators: [{
|
|
25694
27615
|
type: Component,
|
|
@@ -25747,14 +27668,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
25747
27668
|
<button
|
|
25748
27669
|
[disabled]="action.disabled"
|
|
25749
27670
|
[matTooltip]="action.tooltip || ''"
|
|
25750
|
-
matTooltipPosition="
|
|
27671
|
+
matTooltipPosition="above"
|
|
25751
27672
|
[ngClass]="action.variant === 'outlined' ? 'pdx-action-outlined' : 'pdx-action-text'"
|
|
27673
|
+
[class.pdx-shell-action--pressed]="action.pressed === true"
|
|
25752
27674
|
mat-button
|
|
25753
27675
|
type="button"
|
|
27676
|
+
[attr.aria-pressed]="action.pressed == null ? null : action.pressed"
|
|
25754
27677
|
(click)="onAction(action, $event)"
|
|
25755
27678
|
>
|
|
25756
|
-
@if (action
|
|
25757
|
-
<mat-icon [praxisIcon]="
|
|
27679
|
+
@if (displayActionIcon(action); as actionIcon) {
|
|
27680
|
+
<mat-icon [praxisIcon]="actionIcon"></mat-icon>
|
|
25758
27681
|
}
|
|
25759
27682
|
<span class="pdx-action-label">{{ action.label }}</span>
|
|
25760
27683
|
</button>
|
|
@@ -25764,13 +27687,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
25764
27687
|
mat-icon-button
|
|
25765
27688
|
[disabled]="action.disabled"
|
|
25766
27689
|
[matTooltip]="action.tooltip || action.label || ''"
|
|
25767
|
-
matTooltipPosition="
|
|
27690
|
+
matTooltipPosition="above"
|
|
25768
27691
|
[attr.aria-label]="action.label || action.tooltip || action.id"
|
|
27692
|
+
[attr.aria-pressed]="action.pressed == null ? null : action.pressed"
|
|
27693
|
+
[class.pdx-shell-action--pressed]="action.pressed === true"
|
|
25769
27694
|
type="button"
|
|
25770
27695
|
(click)="onAction(action, $event)"
|
|
25771
27696
|
>
|
|
25772
|
-
@if (action
|
|
25773
|
-
<mat-icon [praxisIcon]="
|
|
27697
|
+
@if (displayActionIcon(action); as actionIcon) {
|
|
27698
|
+
<mat-icon [praxisIcon]="actionIcon"></mat-icon>
|
|
25774
27699
|
}
|
|
25775
27700
|
</button>
|
|
25776
27701
|
}
|
|
@@ -25781,7 +27706,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
25781
27706
|
mat-icon-button
|
|
25782
27707
|
type="button"
|
|
25783
27708
|
[matTooltip]="moreActionsLabel()"
|
|
25784
|
-
matTooltipPosition="
|
|
27709
|
+
matTooltipPosition="above"
|
|
25785
27710
|
[attr.aria-label]="moreActionsLabel()"
|
|
25786
27711
|
[matMenuTriggerFor]="overflowMenu"
|
|
25787
27712
|
(click)="$event.stopPropagation()"
|
|
@@ -25797,13 +27722,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
25797
27722
|
mat-icon-button
|
|
25798
27723
|
[disabled]="action.disabled"
|
|
25799
27724
|
[matTooltip]="action.tooltip || action.label || ''"
|
|
25800
|
-
matTooltipPosition="
|
|
27725
|
+
matTooltipPosition="above"
|
|
25801
27726
|
[attr.aria-label]="action.label || action.tooltip || action.id"
|
|
27727
|
+
[attr.aria-pressed]="action.pressed == null ? null : action.pressed"
|
|
27728
|
+
[class.pdx-shell-action--pressed]="action.pressed === true"
|
|
25802
27729
|
type="button"
|
|
25803
27730
|
(click)="onAction(action, $event)"
|
|
25804
27731
|
>
|
|
25805
|
-
@if (action
|
|
25806
|
-
<mat-icon [praxisIcon]="
|
|
27732
|
+
@if (displayActionIcon(action); as actionIcon) {
|
|
27733
|
+
<mat-icon [praxisIcon]="actionIcon"></mat-icon>
|
|
25807
27734
|
}
|
|
25808
27735
|
</button>
|
|
25809
27736
|
}
|
|
@@ -25814,10 +27741,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
25814
27741
|
@for (action of overflowHeaderActions; track action.id) {
|
|
25815
27742
|
<button
|
|
25816
27743
|
mat-menu-item
|
|
27744
|
+
[attr.aria-pressed]="action.pressed == null ? null : action.pressed"
|
|
25817
27745
|
(click)="onAction(action, $event)"
|
|
25818
27746
|
>
|
|
25819
|
-
@if (action
|
|
25820
|
-
<mat-icon [praxisIcon]="
|
|
27747
|
+
@if (displayActionIcon(action); as actionIcon) {
|
|
27748
|
+
<mat-icon [praxisIcon]="actionIcon"></mat-icon>
|
|
25821
27749
|
}
|
|
25822
27750
|
<span>{{ action.label || action.id }}</span>
|
|
25823
27751
|
</button>
|
|
@@ -25832,7 +27760,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
25832
27760
|
@if (expanded || fullscreen) {
|
|
25833
27761
|
<div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
|
|
25834
27762
|
}
|
|
25835
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"] }]
|
|
27763
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"] }]
|
|
25836
27764
|
}], propDecorators: { hostCollapsed: [{
|
|
25837
27765
|
type: HostBinding,
|
|
25838
27766
|
args: ['class.pdx-widget-shell-collapsed']
|
|
@@ -26010,7 +27938,7 @@ const BUILTIN_PAGE_THEME_PRESETS = {
|
|
|
26010
27938
|
id: 'analytics-calm',
|
|
26011
27939
|
label: 'Analytics Calm',
|
|
26012
27940
|
description: 'Superfícies leves, ênfase clara em dados e motion sutil.',
|
|
26013
|
-
shellPreset: '
|
|
27941
|
+
shellPreset: 'chart-panel',
|
|
26014
27942
|
chartThemePreset: 'executive',
|
|
26015
27943
|
density: 'comfortable',
|
|
26016
27944
|
motion: 'subtle',
|
|
@@ -26027,7 +27955,7 @@ const BUILTIN_PAGE_THEME_PRESETS = {
|
|
|
26027
27955
|
id: 'workspace-balanced',
|
|
26028
27956
|
label: 'Workspace Balanced',
|
|
26029
27957
|
description: 'Equilíbrio entre densidade operacional e clareza visual.',
|
|
26030
|
-
shellPreset: '
|
|
27958
|
+
shellPreset: 'data-panel',
|
|
26031
27959
|
chartThemePreset: 'default',
|
|
26032
27960
|
density: 'comfortable',
|
|
26033
27961
|
motion: 'subtle',
|
|
@@ -26044,7 +27972,7 @@ const BUILTIN_PAGE_THEME_PRESETS = {
|
|
|
26044
27972
|
id: 'ops-monitoring',
|
|
26045
27973
|
label: 'Ops Monitoring',
|
|
26046
27974
|
description: 'Contraste um pouco maior para leitura rápida de status, filas e alertas.',
|
|
26047
|
-
shellPreset: '
|
|
27975
|
+
shellPreset: 'data-panel',
|
|
26048
27976
|
chartThemePreset: 'compact',
|
|
26049
27977
|
density: 'compact',
|
|
26050
27978
|
motion: 'subtle',
|
|
@@ -26061,7 +27989,7 @@ const BUILTIN_PAGE_THEME_PRESETS = {
|
|
|
26061
27989
|
id: 'executive-command-center',
|
|
26062
27990
|
label: 'Executive Command Center',
|
|
26063
27991
|
description: 'Superfície premium para dashboards corporativos com hierarquia executiva, dados densos e ações de decisão.',
|
|
26064
|
-
shellPreset: '
|
|
27992
|
+
shellPreset: 'executive-card',
|
|
26065
27993
|
chartThemePreset: 'executive',
|
|
26066
27994
|
density: 'compact',
|
|
26067
27995
|
motion: 'subtle',
|
|
@@ -31033,9 +32961,18 @@ class DynamicWidgetPageComponent {
|
|
|
31033
32961
|
if (!widget.shell) {
|
|
31034
32962
|
return runtimeEnrichedWidget;
|
|
31035
32963
|
}
|
|
32964
|
+
const widgetTemplateContext = {
|
|
32965
|
+
...templateContext,
|
|
32966
|
+
widget: {
|
|
32967
|
+
key: widget.key,
|
|
32968
|
+
definition: this.cloneStateValues(widget.definition),
|
|
32969
|
+
inputs: this.cloneStateValues(widget.definition?.inputs || {}),
|
|
32970
|
+
shell: this.cloneStateValues(widget.shell || {}),
|
|
32971
|
+
},
|
|
32972
|
+
};
|
|
31036
32973
|
return {
|
|
31037
32974
|
...runtimeEnrichedWidget,
|
|
31038
|
-
shell: this.resolveTemplate(widget.shell,
|
|
32975
|
+
shell: this.resolveTemplate(widget.shell, widgetTemplateContext),
|
|
31039
32976
|
};
|
|
31040
32977
|
});
|
|
31041
32978
|
}
|
|
@@ -31088,9 +33025,16 @@ class DynamicWidgetPageComponent {
|
|
|
31088
33025
|
origin: 'dynamic-page.rich-content',
|
|
31089
33026
|
componentId: 'praxis-dynamic-page',
|
|
31090
33027
|
},
|
|
33028
|
+
}).then((result) => {
|
|
33029
|
+
if (!result?.success) {
|
|
33030
|
+
this.emitRichContentCustomAction(widgetKey, actionId, payload);
|
|
33031
|
+
}
|
|
31091
33032
|
});
|
|
31092
33033
|
return;
|
|
31093
33034
|
}
|
|
33035
|
+
this.emitRichContentCustomAction(widgetKey, actionId, payload);
|
|
33036
|
+
}
|
|
33037
|
+
emitRichContentCustomAction(widgetKey, actionId, payload) {
|
|
31094
33038
|
this.onWidgetEvent(widgetKey, {
|
|
31095
33039
|
ownerWidgetKey: widgetKey,
|
|
31096
33040
|
sourceComponentId: 'praxis-rich-content',
|
|
@@ -31412,6 +33356,8 @@ class DynamicWidgetPageComponent {
|
|
|
31412
33356
|
void this.confirmAndRemoveWidget(fromKey);
|
|
31413
33357
|
return;
|
|
31414
33358
|
}
|
|
33359
|
+
if (this.handleToggleInputCommand(fromKey, evt))
|
|
33360
|
+
return;
|
|
31415
33361
|
if (this.handleSetInputCommand(fromKey, evt))
|
|
31416
33362
|
return;
|
|
31417
33363
|
const output = evt?.emit || (evt?.id ? `shell:${evt.id}` : undefined);
|
|
@@ -31436,6 +33382,32 @@ class DynamicWidgetPageComponent {
|
|
|
31436
33382
|
this.widgets.set(widgets);
|
|
31437
33383
|
return true;
|
|
31438
33384
|
}
|
|
33385
|
+
handleToggleInputCommand(fromKey, evt) {
|
|
33386
|
+
if (evt?.command !== 'pdx:toggle-input')
|
|
33387
|
+
return false;
|
|
33388
|
+
const payload = evt?.payload;
|
|
33389
|
+
const input = typeof payload?.input === 'string' ? payload.input.trim() : '';
|
|
33390
|
+
if (!input)
|
|
33391
|
+
return true;
|
|
33392
|
+
const page = this.ensurePageDefinition();
|
|
33393
|
+
const widget = (page.widgets || []).find((candidate) => candidate.key === fromKey);
|
|
33394
|
+
const currentValue = this.lookup(widget?.definition?.inputs || {}, input);
|
|
33395
|
+
const nextValue = !Boolean(currentValue);
|
|
33396
|
+
const result = this.applyWidgetInputPatchToPage(page, fromKey, {
|
|
33397
|
+
ownerWidgetKey: fromKey,
|
|
33398
|
+
sourceComponentId: 'widget-shell',
|
|
33399
|
+
output: evt.emit || `shell:${evt.id}`,
|
|
33400
|
+
payload: {
|
|
33401
|
+
inputPatch: {
|
|
33402
|
+
[input]: nextValue,
|
|
33403
|
+
},
|
|
33404
|
+
},
|
|
33405
|
+
});
|
|
33406
|
+
if (result.changed) {
|
|
33407
|
+
this.applyPageUpdate(result.page, true, undefined, false, true);
|
|
33408
|
+
}
|
|
33409
|
+
return true;
|
|
33410
|
+
}
|
|
31439
33411
|
mergeOrder(keys) {
|
|
31440
33412
|
const seen = new Set();
|
|
31441
33413
|
const out = [];
|
|
@@ -33974,24 +35946,24 @@ const PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA = {
|
|
|
33974
35946
|
selector: 'praxis-dynamic-page',
|
|
33975
35947
|
component: DynamicWidgetPageComponent,
|
|
33976
35948
|
friendlyName: 'Dynamic Page',
|
|
33977
|
-
description: '
|
|
35949
|
+
description: 'Página dinâmica com widgets e composition.links em layout responsivo, incluindo mediação runtime para rich-content hospedado.',
|
|
33978
35950
|
icon: 'dashboard',
|
|
33979
35951
|
inputs: [
|
|
33980
|
-
{ name: 'page', type: 'WidgetPageDefinition', description: '
|
|
35952
|
+
{ name: 'page', type: 'WidgetPageDefinition', description: 'Definição da página (widgets, layout e composition.links).' },
|
|
33981
35953
|
{ name: 'context', type: 'Record<string, any>', description: 'Contexto adicional compartilhado entre widgets.' },
|
|
33982
|
-
{ name: 'strictValidation', type: 'boolean', description: 'Habilita
|
|
33983
|
-
{ name: 'enableCustomization', type: 'boolean', description: 'Habilita affordances de
|
|
33984
|
-
{ name: 'showPageSettingsButton', type: 'boolean', description: 'Exibe
|
|
35954
|
+
{ name: 'strictValidation', type: 'boolean', description: 'Habilita validação estrita de inputs.' },
|
|
35955
|
+
{ name: 'enableCustomization', type: 'boolean', description: 'Habilita affordances de edição na página.' },
|
|
35956
|
+
{ name: 'showPageSettingsButton', type: 'boolean', description: 'Exibe botão de configuração da página.' },
|
|
33985
35957
|
{ name: 'shellEditorComponent', type: 'Type<any>', description: 'Override do editor de shell dos widgets.' },
|
|
33986
|
-
{ name: 'pageEditorComponent', type: 'Type<any>', description: 'Override do editor de
|
|
33987
|
-
{ name: 'autoPersist', type: 'boolean', description: 'Ativa
|
|
33988
|
-
{ name: 'pageIdentity', type: 'PageIdentity', description: 'Identidade de
|
|
33989
|
-
{ name: 'componentInstanceId', type: 'string', description: 'Identificador opcional para
|
|
35958
|
+
{ name: 'pageEditorComponent', type: 'Type<any>', description: 'Override do editor de configuração da página.' },
|
|
35959
|
+
{ name: 'autoPersist', type: 'boolean', description: 'Ativa persistência automática (load/save) da página.' },
|
|
35960
|
+
{ name: 'pageIdentity', type: 'PageIdentity', description: 'Identidade de persistência (tenant/usuário/rota/locale).' },
|
|
35961
|
+
{ name: 'componentInstanceId', type: 'string', description: 'Identificador opcional para múltiplas instâncias na mesma rota.' },
|
|
33990
35962
|
],
|
|
33991
35963
|
outputs: [
|
|
33992
|
-
{ name: 'pageChange', type: 'WidgetPageDefinition', description: 'Emitido ao alterar a
|
|
33993
|
-
{ name: 'widgetEvent', type: 'WidgetEventEnvelope', description: 'Reemite eventos dos widgets filhos com ownerWidgetKey para
|
|
33994
|
-
{ name: 'widgetDiagnosticsChange', type: 'Record<string, WidgetResolutionDiagnostic>', description: 'Emitido quando o runtime detecta widgets resolvidos ou falhos durante o carregamento
|
|
35964
|
+
{ name: 'pageChange', type: 'WidgetPageDefinition', description: 'Emitido ao alterar a definição da página.' },
|
|
35965
|
+
{ name: 'widgetEvent', type: 'WidgetEventEnvelope', description: 'Reemite eventos dos widgets filhos com ownerWidgetKey para integrações do host.' },
|
|
35966
|
+
{ name: 'widgetDiagnosticsChange', type: 'Record<string, WidgetResolutionDiagnostic>', description: 'Emitido quando o runtime detecta widgets resolvidos ou falhos durante o carregamento dinâmico.' },
|
|
33995
35967
|
],
|
|
33996
35968
|
tags: ['widget', 'page', 'dynamic', 'layout'],
|
|
33997
35969
|
lib: '@praxisui/core',
|
|
@@ -34026,6 +35998,8 @@ class PraxisSurfaceHostComponent {
|
|
|
34026
35998
|
*/
|
|
34027
35999
|
renderTitleInsideBody = false;
|
|
34028
36000
|
widgetEvent = new EventEmitter();
|
|
36001
|
+
rowClick = new EventEmitter();
|
|
36002
|
+
selectionChange = new EventEmitter();
|
|
34029
36003
|
beforeWidgetLoader;
|
|
34030
36004
|
mainWidgetLoader;
|
|
34031
36005
|
afterWidgetLoader;
|
|
@@ -34139,13 +36113,19 @@ class PraxisSurfaceHostComponent {
|
|
|
34139
36113
|
}
|
|
34140
36114
|
}
|
|
34141
36115
|
onSlotWidgetEvent(ownerWidgetKey, event) {
|
|
36116
|
+
if (event.output === 'rowClick') {
|
|
36117
|
+
this.rowClick.emit(event.payload);
|
|
36118
|
+
}
|
|
36119
|
+
if (event.output === 'selectionChange') {
|
|
36120
|
+
this.selectionChange.emit(event.payload);
|
|
36121
|
+
}
|
|
34142
36122
|
this.widgetEvent.emit({
|
|
34143
36123
|
...event,
|
|
34144
36124
|
ownerWidgetKey: event.ownerWidgetKey || ownerWidgetKey,
|
|
34145
36125
|
});
|
|
34146
36126
|
}
|
|
34147
36127
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisSurfaceHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
34148
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisSurfaceHostComponent, isStandalone: true, selector: "praxis-surface-host", inputs: { title: "title", subtitle: "subtitle", icon: "icon", beforeWidget: "beforeWidget", widget: "widget", afterWidget: "afterWidget", context: "context", strictValidation: "strictValidation", renderTitleInsideBody: "renderTitleInsideBody" }, outputs: { widgetEvent: "widgetEvent" }, viewQueries: [{ propertyName: "beforeWidgetLoader", first: true, predicate: ["beforeWidgetLoader"], descendants: true, read: DynamicWidgetLoaderDirective }, { propertyName: "mainWidgetLoader", first: true, predicate: ["mainWidgetLoader"], descendants: true, read: DynamicWidgetLoaderDirective }, { propertyName: "afterWidgetLoader", first: true, predicate: ["afterWidgetLoader"], descendants: true, read: DynamicWidgetLoaderDirective }], usesOnChanges: true, ngImport: i0, template: `
|
|
36128
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisSurfaceHostComponent, isStandalone: true, selector: "praxis-surface-host", inputs: { title: "title", subtitle: "subtitle", icon: "icon", beforeWidget: "beforeWidget", widget: "widget", afterWidget: "afterWidget", context: "context", strictValidation: "strictValidation", renderTitleInsideBody: "renderTitleInsideBody" }, outputs: { widgetEvent: "widgetEvent", rowClick: "rowClick", selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "beforeWidgetLoader", first: true, predicate: ["beforeWidgetLoader"], descendants: true, read: DynamicWidgetLoaderDirective }, { propertyName: "mainWidgetLoader", first: true, predicate: ["mainWidgetLoader"], descendants: true, read: DynamicWidgetLoaderDirective }, { propertyName: "afterWidgetLoader", first: true, predicate: ["afterWidgetLoader"], descendants: true, read: DynamicWidgetLoaderDirective }], usesOnChanges: true, ngImport: i0, template: `
|
|
34149
36129
|
<div class="pdx-surface-host">
|
|
34150
36130
|
@if (subtitle || (title && renderTitleInsideBody)) {
|
|
34151
36131
|
<header class="pdx-surface-host__header">
|
|
@@ -34172,6 +36152,7 @@ class PraxisSurfaceHostComponent {
|
|
|
34172
36152
|
[ownerWidgetKey]="beforeWidgetKey"
|
|
34173
36153
|
[context]="context"
|
|
34174
36154
|
[strictValidation]="strictValidation"
|
|
36155
|
+
[autoWireOutputs]="true"
|
|
34175
36156
|
(widgetEvent)="onSlotWidgetEvent(beforeWidgetKey, $event)"
|
|
34176
36157
|
></ng-container>
|
|
34177
36158
|
</div>
|
|
@@ -34184,6 +36165,7 @@ class PraxisSurfaceHostComponent {
|
|
|
34184
36165
|
[ownerWidgetKey]="mainWidgetKey"
|
|
34185
36166
|
[context]="context"
|
|
34186
36167
|
[strictValidation]="strictValidation"
|
|
36168
|
+
[autoWireOutputs]="true"
|
|
34187
36169
|
(widgetEvent)="onSlotWidgetEvent(mainWidgetKey, $event)"
|
|
34188
36170
|
></ng-container>
|
|
34189
36171
|
}
|
|
@@ -34196,6 +36178,7 @@ class PraxisSurfaceHostComponent {
|
|
|
34196
36178
|
[ownerWidgetKey]="afterWidgetKey"
|
|
34197
36179
|
[context]="context"
|
|
34198
36180
|
[strictValidation]="strictValidation"
|
|
36181
|
+
[autoWireOutputs]="true"
|
|
34199
36182
|
(widgetEvent)="onSlotWidgetEvent(afterWidgetKey, $event)"
|
|
34200
36183
|
></ng-container>
|
|
34201
36184
|
</div>
|
|
@@ -34233,6 +36216,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
34233
36216
|
[ownerWidgetKey]="beforeWidgetKey"
|
|
34234
36217
|
[context]="context"
|
|
34235
36218
|
[strictValidation]="strictValidation"
|
|
36219
|
+
[autoWireOutputs]="true"
|
|
34236
36220
|
(widgetEvent)="onSlotWidgetEvent(beforeWidgetKey, $event)"
|
|
34237
36221
|
></ng-container>
|
|
34238
36222
|
</div>
|
|
@@ -34245,6 +36229,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
34245
36229
|
[ownerWidgetKey]="mainWidgetKey"
|
|
34246
36230
|
[context]="context"
|
|
34247
36231
|
[strictValidation]="strictValidation"
|
|
36232
|
+
[autoWireOutputs]="true"
|
|
34248
36233
|
(widgetEvent)="onSlotWidgetEvent(mainWidgetKey, $event)"
|
|
34249
36234
|
></ng-container>
|
|
34250
36235
|
}
|
|
@@ -34257,6 +36242,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
34257
36242
|
[ownerWidgetKey]="afterWidgetKey"
|
|
34258
36243
|
[context]="context"
|
|
34259
36244
|
[strictValidation]="strictValidation"
|
|
36245
|
+
[autoWireOutputs]="true"
|
|
34260
36246
|
(widgetEvent)="onSlotWidgetEvent(afterWidgetKey, $event)"
|
|
34261
36247
|
></ng-container>
|
|
34262
36248
|
</div>
|
|
@@ -34284,6 +36270,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
34284
36270
|
type: Input
|
|
34285
36271
|
}], widgetEvent: [{
|
|
34286
36272
|
type: Output
|
|
36273
|
+
}], rowClick: [{
|
|
36274
|
+
type: Output
|
|
36275
|
+
}], selectionChange: [{
|
|
36276
|
+
type: Output
|
|
34287
36277
|
}], beforeWidgetLoader: [{
|
|
34288
36278
|
type: ViewChild,
|
|
34289
36279
|
args: ['beforeWidgetLoader', { read: DynamicWidgetLoaderDirective }]
|
|
@@ -35244,15 +37234,9 @@ function applyLocalCustomizations$1(base, local) {
|
|
|
35244
37234
|
// Server authority on identity/core props
|
|
35245
37235
|
const authoritative = {
|
|
35246
37236
|
name: base.name,
|
|
35247
|
-
label: base.label,
|
|
35248
37237
|
type: base.type,
|
|
35249
37238
|
controlType: base.controlType,
|
|
35250
37239
|
required: base.required,
|
|
35251
|
-
hint: base.hint,
|
|
35252
|
-
helpText: base.helpText,
|
|
35253
|
-
description: base.description,
|
|
35254
|
-
icon: base.icon,
|
|
35255
|
-
iconPosition: base.iconPosition,
|
|
35256
37240
|
endpoint: base.endpoint,
|
|
35257
37241
|
resourcePath: base.resourcePath,
|
|
35258
37242
|
optionSource: base.optionSource,
|
|
@@ -35288,12 +37272,13 @@ function applyLocalCustomizations$1(base, local) {
|
|
|
35288
37272
|
? serverBackedLocal.queryParams
|
|
35289
37273
|
: base.queryParams,
|
|
35290
37274
|
};
|
|
35291
|
-
|
|
37275
|
+
const merged = {
|
|
35292
37276
|
...base,
|
|
35293
37277
|
...serverBackedLocal,
|
|
35294
37278
|
...authoritative,
|
|
35295
37279
|
...preserved,
|
|
35296
37280
|
};
|
|
37281
|
+
return applyServerOwnedFieldSemantics(merged, base);
|
|
35297
37282
|
}
|
|
35298
37283
|
function mergeServerVisibilityFlag(serverValue) {
|
|
35299
37284
|
return serverValue === true ? true : undefined;
|
|
@@ -35758,4 +37743,4 @@ function provideHookWhitelist(allowed) {
|
|
|
35758
37743
|
* Generated bundle index. Do not edit.
|
|
35759
37744
|
*/
|
|
35760
37745
|
|
|
35761
|
-
export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, AnalyticsPresentationResolver, AnalyticsSchemaContractService, AnalyticsStatsRequestBuilderService, ApiConfigStorage, ApiEndpoint, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, BUILTIN_SHELL_PRESETS, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentKeyService, ComponentMetadataRegistry, CompositionRuntimeFacade, ConsoleLoggerSink, CrudOperationResolutionService, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, DEFAULT_JSON_LOGIC_OPERATORS, DEFAULT_TABLE_CONFIG, DOMAIN_CATALOG_COMPONENT_CONTEXT_PACK, DOMAIN_CATALOG_CONTEXT_HINT_SCHEMA_VERSION, DYNAMIC_PAGE_AI_CAPABILITIES, DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK, DYNAMIC_PAGE_CONFIG_EDITOR, DYNAMIC_PAGE_SHELL_EDITOR, DefaultLoadingRenderer, DeferredAsyncConfigStorage, DomainCatalogService, DomainKnowledgeService, DomainRuleService, DynamicFormService, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EDITORIAL_ALLOWED_CONTENT_FORMATS, EDITORIAL_COMPLIANCE_PRESETS, EDITORIAL_EXTERNAL_LINK_REL, EDITORIAL_FORM_TEMPLATE_CATALOG, EDITORIAL_HTML_ENABLED, EDITORIAL_MARKDOWN_IMAGES_ENABLED, EDITORIAL_SOLUTION_CATALOG, EDITORIAL_SOLUTION_PRESETS, EDITORIAL_THEME_PRESETS, EDITORIAL_WIDGET_CONVENTION_INPUTS, EDITORIAL_WIDGET_TAG, EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE, EVENT_REGISTRATION_EDITORIAL_SOLUTION, EVENT_REGISTRATION_EDITORIAL_TEMPLATE, EmptyStateCardComponent, ErrorMessageService, FIELD_METADATA_CAPABILITIES, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, FIELD_SELECTOR_REGISTRY_OVERRIDES, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FieldSelectorRegistry, FormHooksRegistry, GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_HANDLERS, GLOBAL_ACTION_UI_SCHEMAS, GLOBAL_ANALYTICS_SERVICE, GLOBAL_API_CLIENT, GLOBAL_CONFIG, GLOBAL_DIALOG_SERVICE, GLOBAL_ROUTE_GUARD_RESOLVER, GLOBAL_SURFACE_SERVICE, GLOBAL_TOAST_SERVICE, GenericCrudService, GlobalActionService, GlobalConfigService, INLINE_FILTER_ALIAS_TOKENS, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_SET, INLINE_FILTER_CONTROL_TYPE_VALUES, INLINE_FILTER_TOKEN_TO_BASE_CONTROL_TYPE, INLINE_FILTER_TOKEN_TO_CONTROL_TYPE, IconPickerService, IconPosition, IconSize, LOGGER_LEVEL_BY_ENV, LOGGER_LEVEL_PRIORITY, LoadingOrchestrator, LocalConnectionStorage, LocalStorageAsyncAdapter, LocalStorageCacheAdapter, LocalStorageConfigService, LoggerService, LoggerThrottleTracker, LoggerWarnOnceTracker, MemoryCacheAdapter, NestedPortCatalogService, NestedWidgetConfigAccessor, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, ObservabilityDashboardService, OverlayDeciderService, PRAXIS_COLLECTION_EXPORT_HTTP_OPTIONS, PRAXIS_COLLECTION_EXPORT_PROVIDER, PRAXIS_CORPORATE_SENSITIVE_KEYS, PRAXIS_DEFAULT_EXPORT_SECURITY_POLICY, PRAXIS_DEFAULT_OBSERVABILITY_ALERT_RULES, PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA, PRAXIS_EXPORT_FORMULA_PREFIXES, PRAXIS_EXPORT_SECURITY_POLICY, PRAXIS_FOOTER_LINKS_METADATA, PRAXIS_GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_OPTIONS, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_READY, PRAXIS_GLOBAL_CONFIG_TENANT_RESOLVER, PRAXIS_HERO_BANNER_METADATA, PRAXIS_I18N_CONFIG, PRAXIS_I18N_TRANSLATOR, PRAXIS_JSON_LOGIC_OPERATORS, PRAXIS_LAYER_SCALE_DEFAULTS, PRAXIS_LAYER_SCALE_VARS, PRAXIS_LEGAL_NOTICE_METADATA, PRAXIS_LOADING_CTX, PRAXIS_LOADING_RENDERER, PRAXIS_LOGGER_CONFIG, PRAXIS_LOGGER_SINKS, PRAXIS_OBSERVABILITY_DASHBOARD_OPTIONS, PRAXIS_QUERY_FILTER_EXPRESSION_SCHEMA_VERSION, PRAXIS_RICH_TEXT_BLOCK_METADATA, PRAXIS_TELEMETRY_TRANSPORT, PRAXIS_USER_CONTEXT_SUMMARY_METADATA, PRIVACY_CONSENT_EDITORIAL_SOLUTION, PRIVACY_CONSENT_EDITORIAL_TEMPLATE, PraxisCollectionExportService, PraxisCore, PraxisFooterLinksComponent, PraxisGlobalErrorHandler, PraxisHeroBannerComponent, PraxisHttpCollectionExportProvider, PraxisI18nService, PraxisIconDirective, PraxisIconPickerComponent, PraxisJsonLogicError, PraxisJsonLogicService, PraxisLayerScaleStyleService, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRichTextBlockComponent, PraxisRuntimeComponentObservationRegistryService, PraxisSurfaceHostComponent, PraxisUserContextSummaryComponent, RESOURCE_DISCOVERY_I18N_CONFIG, RESOURCE_DISCOVERY_I18N_NAMESPACE, RULE_PROPERTY_SCHEMA, RemoteConfigStorage, ResourceActionOpenAdapterService, ResourceDiscoveryService, ResourceQuickConnectComponent, ResourceSurfaceOpenAdapterService, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SURFACE_DRAWER_BRIDGE, SURFACE_OPEN_I18N_CONFIG, SURFACE_OPEN_I18N_NAMESPACE, SURFACE_OPEN_PRESETS, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, SurfaceBindingRuntimeService, SurfaceOpenActionEditorComponent, SurfaceOpenMaterializerService, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryLoggerSink, TelemetryService, ValidationPattern, WidgetPageStateRuntimeService, WidgetShellComponent, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, assertPraxisCollectionExportArtifact, assertPraxisRuntimeComponentObservationSerializable, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildFormConfigFromEditorialTemplate, buildHeaders, buildPageKey, buildPraxisEffectDistinctKey, buildPraxisLayerScaleCss, buildSchemaId, buildSchemaIdStorageKeySegment, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, clampRange, classifyEntityLookupResult, clonePraxisRuntimeComponentObservation, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCorporateLoggerConfig, createCorporateObservabilityOptions, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createEmptyRichContentDocument, createFieldLayoutItem, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, domainKnowledgeTimelineToRichContentDocument, domainRuleTimelineToRichContentDocument, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, escapePraxisExportCell, extractNormalizedError, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEditorialCompliancePresetById, getEditorialFormTemplateById, getEditorialFormTemplateCatalog, getEditorialSolutionById, getEditorialSolutionCatalog, getEditorialSolutionPresetById, getEditorialThemePresetById, getEssentialConfig, getFieldMetadataCapabilities, getFormColumnFieldNames, getFormLayoutFieldNames, getGlobalActionCatalog, getGlobalActionPayloadActualType, getGlobalActionPayloadTypeIssue, getGlobalActionUiSchema, getMissingGlobalActionPayloadKeys, getReferencedFieldMetadata, getRequiredGlobalActionPayloadKeys, getTextTransformer, hasMeaningfulGlobalActionPayloadValue, hasPraxisCollectionExportArtifact, interpolatePraxisTranslation, isAllowedEditorialContentFormat, isAllowedEditorialHref, isCssTextTransform, isEditorialComponentMeta, isEntityLookupMultiplePayloadMode, isEntityLookupPayloadMode, isEntityLookupPayloadModeCompatible, isEntityLookupResultSelectable, isEntityLookupSinglePayloadMode, isFormLayoutItem, isGlobalActionRef, isInlineFilterControlType, isLookupDialogSize, isLookupFilterFieldType, isLookupFilterOperator, isPraxisRuntimeGlobalActionEffect, isRangeValidForFilter, isRequiredGlobalActionParamPayloadMissing, isRequiredGlobalActionPayloadMissing, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, maxFileSizeValidator, mergeFieldMetadata, mergePraxisI18nConfigs, mergeTableConfigs, migrateFormLayoutRule, migrateLegacyCompositionLink, migrateLegacyCompositionLinks, minWordsValidator, normalizeControlTypeKey, normalizeControlTypeToken, normalizeEditorialLink, normalizeEnd, normalizeFieldConstraints, normalizeFormConfig, normalizeFormLayoutItems, normalizeFormMetadata, normalizeGlobalActionRef$1 as normalizeGlobalActionRef, normalizeLookupFilterRequest, normalizePath, normalizePraxisDataQueryContext, normalizePraxisEffectPolicy, normalizePraxisQueryFilterExpression, normalizePraxisQueryFilterNode, normalizeResourceAvailabilityReasonCode, normalizeStart, normalizeUnknownError, normalizeWidgetEventPath, notifySuccessHook, parseJsonResponseOrEmpty, praxisLoadingInterceptorFn, prefillFromContextHook, provideDefaultFormHooks, provideFieldSelectorRegistryBase, provideFieldSelectorRegistryOverride, provideFieldSelectorRegistryRuntime, provideFormHookPresets, provideFormHooks, provideGlobalActionCatalog, provideGlobalActionHandler, provideGlobalConfig, provideGlobalConfigReady, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, providePraxisAnalyticsGlobalActions, providePraxisCollectionExportProvider, providePraxisDynamicPageMetadata, providePraxisFooterLinksMetadata, providePraxisGlobalActionCatalog, providePraxisGlobalActions, providePraxisGlobalConfigBootstrap, providePraxisHeroBannerMetadata, providePraxisHttpCollectionExportProvider, providePraxisHttpLoading, providePraxisI18n, providePraxisI18nConfig, providePraxisI18nTranslator, providePraxisIconDefaults, providePraxisJsonLogicOperator, providePraxisJsonLogicOperatorOverride, providePraxisLegalNoticeMetadata, providePraxisLoadingDefaults, providePraxisLogging, providePraxisRichTextBlockMetadata, providePraxisToastGlobalActions, providePraxisUserContextSummaryMetadata, provideRemoteGlobalConfig, readPraxisExportValue, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, registerPraxisRuntimeComponentObservation, removeDiacritics, reportTelemetryHookFactory, requiredCheckedValidator, requiredPresenceValidator, resolveBuiltinPresets, resolveControlTypeAlias, resolveDefaultValuePresentationFormat, resolveEntityLookupPayloadMode, resolveHidden, resolveInlineFilterControlType, resolveInlineFilterControlTypeToBaseControlType, resolveLoggerConfig, resolveObservabilityOptions, resolveOffset, resolveOrder, resolvePraxisCollectionExportItems, resolvePraxisExportFields, resolvePraxisExportScope, resolvePraxisFilterCriteria, resolveResourceAvailabilityReasonKey, resolveSpan, resolveValuePresentation, resolveValuePresentationLocale, serializeEntityLookupValueForPayload, serializeOptionSourceFilterRequest, serializePraxisCollectionToCsv, serializePraxisCollectionToJson, slugify, stripMasksHook, supportsImplicitValuePresentation, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, translateResourceAvailabilityReason, translateResourceDiscoveryText, translateUnavailableWorkflowMessage, trim, uniqueAsyncValidator, urlValidator, validateGlobalActionRef, validateGlobalActionRefs, withMessage, withPraxisHttpLoading };
|
|
37746
|
+
export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, AnalyticsPresentationResolver, AnalyticsSchemaContractService, AnalyticsStatsRequestBuilderService, ApiConfigStorage, ApiEndpoint, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, BUILTIN_SHELL_PRESETS, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentKeyService, ComponentMetadataRegistry, CompositionRuntimeFacade, ConsoleLoggerSink, CrudOperationResolutionService, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, DEFAULT_JSON_LOGIC_OPERATORS, DEFAULT_TABLE_CONFIG, DOMAIN_CATALOG_COMPONENT_CONTEXT_PACK, DOMAIN_CATALOG_CONTEXT_HINT_SCHEMA_VERSION, DYNAMIC_PAGE_AI_CAPABILITIES, DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK, DYNAMIC_PAGE_CONFIG_EDITOR, DYNAMIC_PAGE_SHELL_EDITOR, DefaultLoadingRenderer, DeferredAsyncConfigStorage, DomainCatalogService, DomainKnowledgeService, DomainRuleService, DynamicFormService, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EDITORIAL_ALLOWED_CONTENT_FORMATS, EDITORIAL_COMPLIANCE_PRESETS, EDITORIAL_EXTERNAL_LINK_REL, EDITORIAL_FORM_TEMPLATE_CATALOG, EDITORIAL_HTML_ENABLED, EDITORIAL_MARKDOWN_IMAGES_ENABLED, EDITORIAL_SOLUTION_CATALOG, EDITORIAL_SOLUTION_PRESETS, EDITORIAL_THEME_PRESETS, EDITORIAL_WIDGET_CONVENTION_INPUTS, EDITORIAL_WIDGET_TAG, EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE, EVENT_REGISTRATION_EDITORIAL_SOLUTION, EVENT_REGISTRATION_EDITORIAL_TEMPLATE, EmptyStateCardComponent, EnterpriseRuntimeContextService, ErrorMessageService, FIELD_METADATA_CAPABILITIES, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, FIELD_SELECTOR_REGISTRY_OVERRIDES, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FieldSelectorRegistry, FormHooksRegistry, GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_HANDLERS, GLOBAL_ACTION_UI_SCHEMAS, GLOBAL_ANALYTICS_SERVICE, GLOBAL_API_CLIENT, GLOBAL_CONFIG, GLOBAL_DIALOG_SERVICE, GLOBAL_ROUTE_GUARD_RESOLVER, GLOBAL_SURFACE_SERVICE, GLOBAL_TOAST_SERVICE, GenericCrudService, GlobalActionService, GlobalConfigService, INLINE_FILTER_ALIAS_TOKENS, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_SET, INLINE_FILTER_CONTROL_TYPE_VALUES, INLINE_FILTER_TOKEN_TO_BASE_CONTROL_TYPE, INLINE_FILTER_TOKEN_TO_CONTROL_TYPE, IconPickerService, IconPosition, IconSize, LOGGER_LEVEL_BY_ENV, LOGGER_LEVEL_PRIORITY, LoadingOrchestrator, LocalConnectionStorage, LocalStorageAsyncAdapter, LocalStorageCacheAdapter, LocalStorageConfigService, LoggerService, LoggerThrottleTracker, LoggerWarnOnceTracker, MemoryCacheAdapter, NestedPortCatalogService, NestedWidgetConfigAccessor, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, ObservabilityDashboardService, OverlayDeciderService, PRAXIS_COLLECTION_EXPORT_HTTP_OPTIONS, PRAXIS_COLLECTION_EXPORT_PROVIDER, PRAXIS_CORPORATE_SENSITIVE_KEYS, PRAXIS_DEFAULT_EXPORT_SECURITY_POLICY, PRAXIS_DEFAULT_OBSERVABILITY_ALERT_RULES, PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA, PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_OPTIONS, PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_READY, PRAXIS_EXPORT_FORMULA_PREFIXES, PRAXIS_EXPORT_SECURITY_POLICY, PRAXIS_FOOTER_LINKS_METADATA, PRAXIS_GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_OPTIONS, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_READY, PRAXIS_GLOBAL_CONFIG_TENANT_RESOLVER, PRAXIS_HERO_BANNER_METADATA, PRAXIS_I18N_CONFIG, PRAXIS_I18N_TRANSLATOR, PRAXIS_JSON_LOGIC_OPERATORS, PRAXIS_LAYER_SCALE_DEFAULTS, PRAXIS_LAYER_SCALE_VARS, PRAXIS_LEGAL_NOTICE_METADATA, PRAXIS_LOADING_CTX, PRAXIS_LOADING_RENDERER, PRAXIS_LOGGER_CONFIG, PRAXIS_LOGGER_SINKS, PRAXIS_OBSERVABILITY_DASHBOARD_OPTIONS, PRAXIS_QUERY_FILTER_EXPRESSION_SCHEMA_VERSION, PRAXIS_RICH_TEXT_BLOCK_METADATA, PRAXIS_TABLE_DETAIL_INLINE_NODE_RESOLVERS, PRAXIS_TABLE_DETAIL_INLINE_RENDERERS, PRAXIS_TELEMETRY_TRANSPORT, PRAXIS_USER_CONTEXT_SUMMARY_METADATA, PRIVACY_CONSENT_EDITORIAL_SOLUTION, PRIVACY_CONSENT_EDITORIAL_TEMPLATE, PraxisCollectionExportService, PraxisCore, PraxisFooterLinksComponent, PraxisGlobalErrorHandler, PraxisHeroBannerComponent, PraxisHttpCollectionExportProvider, PraxisI18nService, PraxisIconDirective, PraxisIconPickerComponent, PraxisJsonLogicError, PraxisJsonLogicService, PraxisLayerScaleStyleService, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRichTextBlockComponent, PraxisRuntimeComponentObservationRegistryService, PraxisSurfaceHostComponent, PraxisUserContextSummaryComponent, RESOURCE_DISCOVERY_I18N_CONFIG, RESOURCE_DISCOVERY_I18N_NAMESPACE, RULE_PROPERTY_SCHEMA, RemoteConfigStorage, ResourceActionOpenAdapterService, ResourceDiscoveryService, ResourceQuickConnectComponent, ResourceSurfaceOpenAdapterService, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SURFACE_DRAWER_BRIDGE, SURFACE_OPEN_I18N_CONFIG, SURFACE_OPEN_I18N_NAMESPACE, SURFACE_OPEN_PRESETS, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, SurfaceBindingRuntimeService, SurfaceOpenActionEditorComponent, SurfaceOpenMaterializerService, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryLoggerSink, TelemetryService, ValidationPattern, WidgetPageStateRuntimeService, WidgetShellComponent, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, assertPraxisCollectionExportArtifact, assertPraxisRuntimeComponentObservationSerializable, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildFormConfigFromEditorialTemplate, buildHeaders, buildPageKey, buildPraxisEffectDistinctKey, buildPraxisLayerScaleCss, buildSchemaId, buildSchemaIdStorageKeySegment, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, clampRange, classifyEntityLookupResult, clonePraxisRuntimeComponentObservation, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCorporateLoggerConfig, createCorporateObservabilityOptions, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createEmptyRichContentDocument, createFieldLayoutItem, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, domainKnowledgeTimelineToRichContentDocument, domainRuleTimelineToRichContentDocument, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, escapePraxisExportCell, evaluateFieldAccess, extractNormalizedError, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEditorialCompliancePresetById, getEditorialFormTemplateById, getEditorialFormTemplateCatalog, getEditorialSolutionById, getEditorialSolutionCatalog, getEditorialSolutionPresetById, getEditorialThemePresetById, getEssentialConfig, getFieldMetadataCapabilities, getFormColumnFieldNames, getFormLayoutFieldNames, getGlobalActionCatalog, getGlobalActionPayloadActualType, getGlobalActionPayloadTypeIssue, getGlobalActionUiSchema, getMissingGlobalActionPayloadKeys, getReferencedFieldMetadata, getRequiredGlobalActionPayloadKeys, getTextTransformer, hasMeaningfulGlobalActionPayloadValue, hasPraxisCollectionExportArtifact, interpolatePraxisTranslation, isAllowedEditorialContentFormat, isAllowedEditorialHref, isCssTextTransform, isEditorialComponentMeta, isEntityLookupMultiplePayloadMode, isEntityLookupPayloadMode, isEntityLookupPayloadModeCompatible, isEntityLookupResultSelectable, isEntityLookupSinglePayloadMode, isFormLayoutItem, isGlobalActionRef, isInlineFilterControlType, isLookupDialogSize, isLookupFilterFieldType, isLookupFilterOperator, isPraxisPresentationVisualizationTableSafe, isPraxisRuntimeGlobalActionEffect, isRangeValidForFilter, isRequiredGlobalActionParamPayloadMissing, isRequiredGlobalActionPayloadMissing, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, materializeFormLayoutFromMetadata, maxFileSizeValidator, mergeFieldMetadata, mergePraxisI18nConfigs, mergeTableConfigs, migrateFormLayoutRule, migrateLegacyCompositionLink, migrateLegacyCompositionLinks, minWordsValidator, normalizeControlTypeKey, normalizeControlTypeToken, normalizeEditorialLink, normalizeEnd, normalizeFieldAccessMetadata, normalizeFieldConstraints, normalizeFieldPresentation, normalizeFormConfig, normalizeFormLayoutItems, normalizeFormMetadata, normalizeGlobalActionRef$1 as normalizeGlobalActionRef, normalizeLayoutPolicy, normalizeLookupFilterRequest, normalizePath, normalizePraxisDataQueryContext, normalizePraxisEffectPolicy, normalizePraxisPresentationVisualization, normalizePraxisQueryFilterExpression, normalizePraxisQueryFilterNode, normalizeResourceAvailabilityReasonCode, normalizeStart, normalizeUnknownError, normalizeWidgetEventPath, notifySuccessHook, parseJsonResponseOrEmpty, praxisLoadingInterceptorFn, prefillFromContextHook, provideDefaultFormHooks, provideFieldSelectorRegistryBase, provideFieldSelectorRegistryOverride, provideFieldSelectorRegistryRuntime, provideFormHookPresets, provideFormHooks, provideGlobalActionCatalog, provideGlobalActionHandler, provideGlobalConfig, provideGlobalConfigReady, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, providePraxisAnalyticsGlobalActions, providePraxisCollectionExportProvider, providePraxisDynamicPageMetadata, providePraxisEnterpriseRuntimeContext, providePraxisFooterLinksMetadata, providePraxisGlobalActionCatalog, providePraxisGlobalActions, providePraxisGlobalConfigBootstrap, providePraxisHeroBannerMetadata, providePraxisHttpCollectionExportProvider, providePraxisHttpLoading, providePraxisI18n, providePraxisI18nConfig, providePraxisI18nTranslator, providePraxisIconDefaults, providePraxisJsonLogicOperator, providePraxisJsonLogicOperatorOverride, providePraxisLegalNoticeMetadata, providePraxisLoadingDefaults, providePraxisLogging, providePraxisRichTextBlockMetadata, providePraxisToastGlobalActions, providePraxisUserContextSummaryMetadata, provideRemoteGlobalConfig, readPraxisExportValue, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, registerPraxisRuntimeComponentObservation, removeDiacritics, renderPraxisPresentationVisualizationHtml, reportTelemetryHookFactory, requiredCheckedValidator, requiredPresenceValidator, resolveBuiltinPresets, resolveColumnTypeFromFieldDefinition, resolveControlTypeAlias, resolveDefaultValuePresentationFormat, resolveEntityLookupPayloadMode, resolveFieldPresentation, resolveHidden, resolveInlineFilterControlType, resolveInlineFilterControlTypeToBaseControlType, resolveLoggerConfig, resolveObservabilityOptions, resolveOffset, resolveOrder, resolvePraxisCollectionExportItems, resolvePraxisExportFields, resolvePraxisExportScope, resolvePraxisFilterCriteria, resolveResourceAvailabilityReasonKey, resolveSpan, resolveTextMaskFormat, resolveTextMaskFormatFromFieldDefinition, resolveValuePresentation, resolveValuePresentationLocale, serializeEntityLookupValueForPayload, serializeOptionSourceFilterRequest, serializePraxisCollectionToCsv, serializePraxisCollectionToJson, slugify, stripMasksHook, supportsImplicitValuePresentation, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, translateResourceAvailabilityReason, translateResourceDiscoveryText, translateUnavailableWorkflowMessage, trim, uniqueAsyncValidator, urlValidator, validateGlobalActionRef, validateGlobalActionRefs, withFormConfigSections, withMessage, withPraxisHttpLoading };
|