@praxisui/dynamic-form 3.0.0-beta.5 → 3.0.0-beta.7
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/README.md +21 -3
- package/fesm2022/praxisui-dynamic-form.mjs +1435 -179
- package/fesm2022/praxisui-dynamic-form.mjs.map +1 -1
- package/index.d.ts +27 -3
- package/package.json +7 -7
|
@@ -22,7 +22,7 @@ import { MatBadgeModule } from '@angular/material/badge';
|
|
|
22
22
|
import { firstValueFrom, BehaviorSubject, Subject, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs';
|
|
23
23
|
import { take, takeUntil, debounceTime, finalize, map } from 'rxjs/operators';
|
|
24
24
|
import * as i1$2 from '@praxisui/core';
|
|
25
|
-
import { PraxisIconDirective, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, ASYNC_CONFIG_STORAGE, migrateFormLayoutRule, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceQuickConnectComponent, mapFieldDefinitionsToMetadata, syncWithServerMetadata, PRAXIS_LOADING_CTX, normalizeControlTypeKey, resolveSpan, resolveOffset, resolveOrder, resolveHidden, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, CONNECTION_STORAGE, PRAXIS_LOADING_RENDERER, FORM_HOOKS_PRESETS, DynamicWidgetLoaderDirective, EmptyStateCardComponent, isValidFormConfig, ComponentMetadataRegistry, FieldControlType, GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_SPEC_CATALOG, getGlobalActionCatalog, PRAXIS_GLOBAL_ACTION_CATALOG, getGlobalActionUiSchema } from '@praxisui/core';
|
|
25
|
+
import { PraxisIconDirective, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, ASYNC_CONFIG_STORAGE, migrateFormLayoutRule, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceQuickConnectComponent, mapFieldDefinitionsToMetadata, syncWithServerMetadata, PRAXIS_LOADING_CTX, normalizeControlTypeKey, resolveSpan, resolveOffset, resolveOrder, resolveHidden, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, CONNECTION_STORAGE, PRAXIS_LOADING_RENDERER, FORM_HOOKS_PRESETS, DynamicWidgetLoaderDirective, EmptyStateCardComponent, isValidFormConfig, ComponentMetadataRegistry, FieldControlType, GLOBAL_ACTION_CATALOG, PraxisI18nService, GLOBAL_ACTION_SPEC_CATALOG, getGlobalActionCatalog, PRAXIS_GLOBAL_ACTION_CATALOG, SURFACE_OPEN_I18N_NAMESPACE, getGlobalActionUiSchema, SurfaceOpenActionEditorComponent, providePraxisI18nConfig, SURFACE_OPEN_I18N_CONFIG } from '@praxisui/core';
|
|
26
26
|
import * as i1 from '@praxisui/dynamic-fields';
|
|
27
27
|
import { getControlTypeCatalog, ConfirmDialogComponent, DynamicFieldLoaderDirective } from '@praxisui/dynamic-fields';
|
|
28
28
|
import { BaseAiAdapter, PraxisAiAssistantComponent } from '@praxisui/ai';
|
|
@@ -846,7 +846,7 @@ function generateRulePropertyWhenFalseCapabilities(targetType, properties) {
|
|
|
846
846
|
return result;
|
|
847
847
|
}
|
|
848
848
|
const FORM_AI_CAPABILITIES = {
|
|
849
|
-
version: 'v1.
|
|
849
|
+
version: 'v1.9', // Adds section header actions and richer section authoring affordances.
|
|
850
850
|
enums: ENUMS$1,
|
|
851
851
|
targets: [
|
|
852
852
|
'praxis-dynamic-form',
|
|
@@ -1298,6 +1298,62 @@ const FORM_AI_CAPABILITIES = {
|
|
|
1298
1298
|
valueKind: 'string',
|
|
1299
1299
|
description: 'Texto de tooltip para o cabeçalho da seção.',
|
|
1300
1300
|
},
|
|
1301
|
+
{
|
|
1302
|
+
path: 'sections[].headerActions',
|
|
1303
|
+
category: 'layout',
|
|
1304
|
+
valueKind: 'array',
|
|
1305
|
+
description: 'Lista de ações iconográficas renderizadas no canto direito do cabeçalho da seção.',
|
|
1306
|
+
safetyNotes: 'Prefira IDs estáveis porque essas ações podem ser alvo de regras e integrações do host.',
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
path: 'sections[].headerActions[].id',
|
|
1310
|
+
category: 'layout',
|
|
1311
|
+
valueKind: 'string',
|
|
1312
|
+
description: 'ID estável da ação de cabeçalho da seção.',
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
path: 'sections[].headerActions[].label',
|
|
1316
|
+
category: 'layout',
|
|
1317
|
+
valueKind: 'string',
|
|
1318
|
+
description: 'Label acessível usada em tooltip e aria-label da ação.',
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
path: 'sections[].headerActions[].icon',
|
|
1322
|
+
category: 'layout',
|
|
1323
|
+
valueKind: 'string',
|
|
1324
|
+
description: 'Ícone renderizado na ação do cabeçalho da seção.',
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
path: 'sections[].headerActions[].action',
|
|
1328
|
+
category: 'layout',
|
|
1329
|
+
valueKind: 'string',
|
|
1330
|
+
description: 'Nome opcional da ação emitida no customAction; se ausente, o runtime usa o ID.',
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
path: 'sections[].headerActions[].tooltip',
|
|
1334
|
+
category: 'layout',
|
|
1335
|
+
valueKind: 'string',
|
|
1336
|
+
description: 'Tooltip opcional da ação; se ausente, o runtime usa a label.',
|
|
1337
|
+
},
|
|
1338
|
+
{
|
|
1339
|
+
path: 'sections[].headerActions[].color',
|
|
1340
|
+
category: 'appearance',
|
|
1341
|
+
valueKind: 'enum',
|
|
1342
|
+
allowedValues: ['primary', 'accent', 'warn', 'basic'],
|
|
1343
|
+
description: 'Tom visual da ação do cabeçalho da seção.',
|
|
1344
|
+
},
|
|
1345
|
+
{
|
|
1346
|
+
path: 'sections[].headerActions[].visible',
|
|
1347
|
+
category: 'layout',
|
|
1348
|
+
valueKind: 'boolean',
|
|
1349
|
+
description: 'Controla a visibilidade da ação do cabeçalho da seção.',
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
path: 'sections[].headerActions[].disabled',
|
|
1353
|
+
category: 'layout',
|
|
1354
|
+
valueKind: 'boolean',
|
|
1355
|
+
description: 'Controla o estado desabilitado da ação do cabeçalho da seção.',
|
|
1356
|
+
},
|
|
1301
1357
|
{
|
|
1302
1358
|
path: 'sections[].className',
|
|
1303
1359
|
category: 'appearance',
|
|
@@ -2645,6 +2701,15 @@ const TASK_PRESETS = {
|
|
|
2645
2701
|
'sections[].descriptionColor',
|
|
2646
2702
|
'sections[].headerAlign',
|
|
2647
2703
|
'sections[].headerTooltip',
|
|
2704
|
+
'sections[].headerActions',
|
|
2705
|
+
'sections[].headerActions[].id',
|
|
2706
|
+
'sections[].headerActions[].label',
|
|
2707
|
+
'sections[].headerActions[].icon',
|
|
2708
|
+
'sections[].headerActions[].action',
|
|
2709
|
+
'sections[].headerActions[].tooltip',
|
|
2710
|
+
'sections[].headerActions[].color',
|
|
2711
|
+
'sections[].headerActions[].visible',
|
|
2712
|
+
'sections[].headerActions[].disabled',
|
|
2648
2713
|
'sections[].rows[].gap',
|
|
2649
2714
|
'sections[].rows[].rowGap',
|
|
2650
2715
|
'sections[].rows[].columns[].fields[]',
|
|
@@ -3648,11 +3713,13 @@ function sanitizeRuleEffect(rule) {
|
|
|
3648
3713
|
}
|
|
3649
3714
|
function normalizeTargets$1(rule) {
|
|
3650
3715
|
const rawTargets = (rule.targets && rule.targets.length ? rule.targets : rule.targetFields) || [];
|
|
3651
|
-
const detectedType = rawTargets.some((t) => t
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3716
|
+
const detectedType = rawTargets.some((t) => isScopedSectionHeaderActionTarget$1(t) || isUnscopedSectionHeaderActionTarget$1(t))
|
|
3717
|
+
? 'action'
|
|
3718
|
+
: rawTargets.some((t) => t?.startsWith('section:')) ? 'section'
|
|
3719
|
+
: rawTargets.some((t) => t?.startsWith('action:')) ? 'action'
|
|
3720
|
+
: rawTargets.some((t) => t?.startsWith('row:')) ? 'row'
|
|
3721
|
+
: rawTargets.some((t) => t?.startsWith('column:')) ? 'column'
|
|
3722
|
+
: rule.targetType || 'field';
|
|
3656
3723
|
const targets = rawTargets.map((t) => stripPrefix(t));
|
|
3657
3724
|
const allowed = ['field', 'section', 'action', 'row', 'column'];
|
|
3658
3725
|
const explicit = allowed.includes(rule.targetType)
|
|
@@ -3664,6 +3731,9 @@ function normalizeTargets$1(rule) {
|
|
|
3664
3731
|
};
|
|
3665
3732
|
}
|
|
3666
3733
|
function stripPrefix(value) {
|
|
3734
|
+
if (isScopedSectionHeaderActionTarget$1(value) || isUnscopedSectionHeaderActionTarget$1(value)) {
|
|
3735
|
+
return value;
|
|
3736
|
+
}
|
|
3667
3737
|
if (value?.startsWith('section:'))
|
|
3668
3738
|
return value.substring('section:'.length);
|
|
3669
3739
|
if (value?.startsWith('action:'))
|
|
@@ -3674,6 +3744,12 @@ function stripPrefix(value) {
|
|
|
3674
3744
|
return value.substring('column:'.length);
|
|
3675
3745
|
return value;
|
|
3676
3746
|
}
|
|
3747
|
+
function isScopedSectionHeaderActionTarget$1(value) {
|
|
3748
|
+
return !!value && value.startsWith('section:') && value.includes(':header-action:');
|
|
3749
|
+
}
|
|
3750
|
+
function isUnscopedSectionHeaderActionTarget$1(value) {
|
|
3751
|
+
return !!value && value.startsWith('header-action:');
|
|
3752
|
+
}
|
|
3677
3753
|
function coerceValue(def, value) {
|
|
3678
3754
|
// null is treated as an explicit "remove override"
|
|
3679
3755
|
if (value === null) {
|
|
@@ -6435,6 +6511,16 @@ class PraxisDynamicForm {
|
|
|
6435
6511
|
const props = this.getSectionRuleProps(section);
|
|
6436
6512
|
return props.headerTooltip ?? section.headerTooltip;
|
|
6437
6513
|
}
|
|
6514
|
+
getSectionHeaderActions(section) {
|
|
6515
|
+
const props = this.getSectionRuleProps(section);
|
|
6516
|
+
const source = props.headerActions ?? section.headerActions;
|
|
6517
|
+
if (!Array.isArray(source))
|
|
6518
|
+
return [];
|
|
6519
|
+
return source
|
|
6520
|
+
.filter((action) => !!action && typeof action.id === 'string' && !!action.id.trim())
|
|
6521
|
+
.map((action) => this.applySectionHeaderActionOverrides(section, action))
|
|
6522
|
+
.filter((action) => action.visible !== false);
|
|
6523
|
+
}
|
|
6438
6524
|
getSectionHeaderAlign(section) {
|
|
6439
6525
|
const props = this.getSectionRuleProps(section);
|
|
6440
6526
|
return props.headerAlign ?? section.headerAlign;
|
|
@@ -6454,6 +6540,100 @@ class PraxisDynamicForm {
|
|
|
6454
6540
|
const gap = props.descriptionGapBottom ?? section.descriptionGapBottom;
|
|
6455
6541
|
return gap ?? null;
|
|
6456
6542
|
}
|
|
6543
|
+
getSectionHeaderActionColor(action) {
|
|
6544
|
+
const c = String(action.color || '').toLowerCase();
|
|
6545
|
+
switch (c) {
|
|
6546
|
+
case 'primary':
|
|
6547
|
+
return 'primary';
|
|
6548
|
+
case 'accent':
|
|
6549
|
+
case 'secondary':
|
|
6550
|
+
return 'accent';
|
|
6551
|
+
case 'warn':
|
|
6552
|
+
case 'danger':
|
|
6553
|
+
case 'error':
|
|
6554
|
+
return 'warn';
|
|
6555
|
+
default:
|
|
6556
|
+
return undefined;
|
|
6557
|
+
}
|
|
6558
|
+
}
|
|
6559
|
+
getSectionHeaderActionTooltip(action) {
|
|
6560
|
+
return action.tooltip || action.label;
|
|
6561
|
+
}
|
|
6562
|
+
isSectionHeaderActionDisabled(action) {
|
|
6563
|
+
return this.submitting || !!action.disabled || !!action.loading;
|
|
6564
|
+
}
|
|
6565
|
+
getSectionHeaderActionNgClass(action) {
|
|
6566
|
+
const className = action.className;
|
|
6567
|
+
const tone = String(action.color || 'basic').toLowerCase();
|
|
6568
|
+
return {
|
|
6569
|
+
...(className ? { [className]: true } : {}),
|
|
6570
|
+
[`tone-${tone}`]: true,
|
|
6571
|
+
loading: !!action.loading,
|
|
6572
|
+
};
|
|
6573
|
+
}
|
|
6574
|
+
getSectionHeaderActionStyles(action) {
|
|
6575
|
+
return action.style && Object.keys(action.style).length ? action.style : null;
|
|
6576
|
+
}
|
|
6577
|
+
getSectionHeaderActionLoadingLabel(action) {
|
|
6578
|
+
return action.tooltip || action.label;
|
|
6579
|
+
}
|
|
6580
|
+
onSectionHeaderActionClick(section, action, event) {
|
|
6581
|
+
event.preventDefault();
|
|
6582
|
+
event.stopPropagation();
|
|
6583
|
+
if (this.isSectionHeaderActionDisabled(action))
|
|
6584
|
+
return;
|
|
6585
|
+
const actionId = this.getSectionHeaderActionEventId(action);
|
|
6586
|
+
if (!actionId)
|
|
6587
|
+
return;
|
|
6588
|
+
const confirmationMessage = this._getConfirmationMessageForAliases(...this.getSectionHeaderActionRuleKeys(section, action), actionId, action.id);
|
|
6589
|
+
const emitAction = () => {
|
|
6590
|
+
this.customAction.emit({
|
|
6591
|
+
actionId,
|
|
6592
|
+
formData: this.form.value,
|
|
6593
|
+
isValid: this.form.valid,
|
|
6594
|
+
source: 'section-header',
|
|
6595
|
+
...(section.id ? { sectionId: section.id } : {}),
|
|
6596
|
+
});
|
|
6597
|
+
};
|
|
6598
|
+
if (confirmationMessage) {
|
|
6599
|
+
this._showConfirmationDialog(actionId, confirmationMessage, emitAction);
|
|
6600
|
+
}
|
|
6601
|
+
else {
|
|
6602
|
+
emitAction();
|
|
6603
|
+
}
|
|
6604
|
+
}
|
|
6605
|
+
applySectionHeaderActionOverrides(section, action) {
|
|
6606
|
+
const override = this.getSectionHeaderActionRuleKeys(section, action)
|
|
6607
|
+
.map((key) => (key ? this.actionRuleProps?.[key] : undefined))
|
|
6608
|
+
.find((candidate) => !!candidate);
|
|
6609
|
+
if (!override)
|
|
6610
|
+
return action;
|
|
6611
|
+
return {
|
|
6612
|
+
...action,
|
|
6613
|
+
...(override.label !== undefined ? { label: override.label } : {}),
|
|
6614
|
+
...(override.icon !== undefined ? { icon: override.icon } : {}),
|
|
6615
|
+
...(override.visible !== undefined ? { visible: override.visible } : {}),
|
|
6616
|
+
...(override.disabled !== undefined ? { disabled: override.disabled } : {}),
|
|
6617
|
+
...(override.loading !== undefined ? { loading: override.loading } : {}),
|
|
6618
|
+
...(override.tooltip !== undefined ? { tooltip: override.tooltip } : {}),
|
|
6619
|
+
...(override.color !== undefined ? { color: override.color } : {}),
|
|
6620
|
+
...(override.className !== undefined ? { className: override.className } : {}),
|
|
6621
|
+
...(override.style !== undefined ? { style: override.style } : {}),
|
|
6622
|
+
};
|
|
6623
|
+
}
|
|
6624
|
+
getSectionHeaderActionEventId(action) {
|
|
6625
|
+
return action.action?.trim() || action.id.trim();
|
|
6626
|
+
}
|
|
6627
|
+
getSectionHeaderActionRuleKeys(section, action) {
|
|
6628
|
+
const logicalId = this.getSectionHeaderActionEventId(action);
|
|
6629
|
+
const scopedKey = section.id && logicalId
|
|
6630
|
+
? `section:${section.id}:header-action:${logicalId}`
|
|
6631
|
+
: undefined;
|
|
6632
|
+
const unscopedHeaderActionKey = logicalId
|
|
6633
|
+
? `header-action:${logicalId}`
|
|
6634
|
+
: undefined;
|
|
6635
|
+
return [scopedKey, unscopedHeaderActionKey, logicalId, action.id?.trim()].filter((value) => !!value);
|
|
6636
|
+
}
|
|
6457
6637
|
getRowRuleProps(row) {
|
|
6458
6638
|
if (!row || !row.id)
|
|
6459
6639
|
return {};
|
|
@@ -6931,14 +7111,23 @@ class PraxisDynamicForm {
|
|
|
6931
7111
|
return Object.keys(styles).length ? styles : null;
|
|
6932
7112
|
}
|
|
6933
7113
|
_getConfirmationMessage(actionId) {
|
|
7114
|
+
return this._getConfirmationMessageForAliases(actionId);
|
|
7115
|
+
}
|
|
7116
|
+
_getConfirmationMessageForAliases(...actionIds) {
|
|
6934
7117
|
const messages = this.config.messages;
|
|
6935
7118
|
if (!messages)
|
|
6936
7119
|
return undefined;
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
7120
|
+
for (const actionId of actionIds) {
|
|
7121
|
+
if (!actionId)
|
|
7122
|
+
continue;
|
|
7123
|
+
const customMessage = messages.customActions?.[actionId]?.confirmation;
|
|
7124
|
+
if (customMessage)
|
|
7125
|
+
return customMessage;
|
|
7126
|
+
const confirmation = messages.confirmations?.[actionId];
|
|
7127
|
+
if (confirmation)
|
|
7128
|
+
return confirmation;
|
|
7129
|
+
}
|
|
7130
|
+
return undefined;
|
|
6942
7131
|
}
|
|
6943
7132
|
_showConfirmationDialog(actionId, message, onConfirm) {
|
|
6944
7133
|
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
|
|
@@ -11054,7 +11243,7 @@ class PraxisDynamicForm {
|
|
|
11054
11243
|
}
|
|
11055
11244
|
}
|
|
11056
11245
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisDynamicForm, deps: [{ token: i1$2.GenericCrudService }, { token: i1$3.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: FormLayoutService }, { token: FormContextService }, { token: FormRulesService }, { token: i6$1.SettingsPanelService }, { token: i2.MatDialog }, { token: ASYNC_CONFIG_STORAGE }, { token: CONNECTION_STORAGE }, { token: i1$2.DynamicFormService }, { token: i8.MatSnackBar }, { token: CanvasStateService }, { token: DynamicFormLayoutService }, { token: i1$2.ErrorMessageService }, { token: i1$2.SchemaNormalizerService }, { token: i1$2.ComponentMetadataRegistry }, { token: i1$2.GlobalConfigService }, { token: i1$2.ComponentKeyService }, { token: i1$2.LoadingOrchestrator }, { token: PRAXIS_LOADING_RENDERER, optional: true }, { token: i11.Router, optional: true }, { token: i11.ActivatedRoute, optional: true }, { token: i1$2.FormHooksRegistry, optional: true }, { token: FORM_HOOKS_PRESETS, optional: true }, { token: i1$2.LoggerService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
11057
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisDynamicForm, isStandalone: true, selector: "praxis-dynamic-form", inputs: { resourcePath: "resourcePath", resourceId: "resourceId", editorialContext: "editorialContext", mode: "mode", config: "config", schemaSource: "schemaSource", enableCustomization: "enableCustomization", formId: "formId", componentInstanceId: "componentInstanceId", layout: "layout", backConfig: "backConfig", hooks: "hooks", removeEmptyContainersOnSave: "removeEmptyContainersOnSave", reactiveValidation: "reactiveValidation", reactiveValidationDebounceMs: "reactiveValidationDebounceMs", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", readonlyModeGlobal: "readonlyModeGlobal", disabledModeGlobal: "disabledModeGlobal", presentationModeGlobal: "presentationModeGlobal", visibleGlobal: "visibleGlobal", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", formReady: "formReady", valueChange: "valueChange", syncCompleted: "syncCompleted", initializationError: "initializationError", loadingStateChange: "loadingStateChange", enableCustomizationChange: "enableCustomizationChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange", fieldRenderError: "fieldRenderError", widgetEvent: "widgetEvent" }, viewQueries: [{ propertyName: "formHost", first: true, predicate: ["formHost"], descendants: true }, { propertyName: "fieldLoaders", predicate: DynamicFieldLoaderDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (isLoading) {\n<!-- Loading State -->\n<div class=\"form-loading\">\n <mat-progress-spinner diameter=\"40\"></mat-progress-spinner>\n <p>Carregando formul\u00E1rio...</p>\n</div>\n} @else if (initializationStatus === 'error') {\n<!-- Error State -->\n<div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n</div>\n} @else if (initializationStatus === 'success') {\n<!-- Inline banner for schema change (only when customization is enabled) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n</div>\n}\n\n<!-- Configuration Controls -->\n@if (shouldShowConfigControls && enableCustomization) {\n<div class=\"form-config-controls\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n <button type=\"button\" mat-icon-button (click)=\"openConfigEditor()\" [disabled]=\"isLoading\" class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\" [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\">\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\">\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n}\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\n<praxis-empty-state-card icon=\"link\" [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"></praxis-empty-state-card>\n}\n<form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\" [class.readonly-mode]=\"effectiveReadonly\"\n [class.editorial-visual-context]=\"hasEditorialVisualContext()\"\n [class.pfx-mounting]=\"isMounting\" [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\" [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n [style.--pdx-form-mount-duration]=\"getMountDurationVar()\"\n [style.--pdx-form-mount-offset]=\"getMountOffsetVar()\"\n [style.--pdx-form-mount-stagger]=\"getMountStaggerVar()\"\n class=\"praxis-dynamic-form\">\n <praxis-canvas-toolbar (editMetadata)=\"openSelectedElementEditor()\" (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\" (moveDown)=\"onToolbarMove('down')\" (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\" (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\" (requestClose)=\"onToolbarRequestClose()\"\n *ngIf=\"enableCustomization && selectedElement\" [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\n\n @if (formBlocksBefore.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n @for (block of formBlocksBefore; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('before', $event)\">\n </ng-container>\n }\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"config.actions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @for (section of config.sections; track (section.id ?? $index); let sectionIndex = $index;\n let last = $last) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n @if (isSectionVisible(section)) {\n <div #sectionEl class=\"form-section canvas-element\" data-canvas-type=\"section\" [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\" (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [attr.data-section-appearance]=\"getSectionAppearance(section) || null\"\n [style.marginBottom.px]=\"!last ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(section)\">\n <div\n class=\"section-heading\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [class.step-appearance]=\"getSectionAppearance(section) === 'step'\"\n >\n <div class=\"section-heading-text\" [matTooltip]=\"getSectionHeaderTooltip(section) || null\"\n [matTooltipDisabled]=\"!getSectionHeaderTooltip(section)\">\n @if (getSectionStepLabel(section)) {\n <div class=\"section-step-label\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionStepLabel(section) }}\n </div>\n }\n @if (getSectionTitle(section)) {\n <h3 class=\"section-title\" [class.title-large]=\"getSectionTitleStyle(section) === 'titleLarge'\"\n [class.title-medium]=\"getSectionTitleStyle(section) === 'titleMedium'\"\n [class.title-small]=\"getSectionTitleStyle(section) === 'titleSmall'\"\n [class.headline-small]=\"getSectionTitleStyle(section) === 'headlineSmall'\"\n [style.marginBottom.px]=\"getSectionTitleGapBottom(section) ?? 20\" [style.color]=\"getSectionTitleColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [attr.id]=\"sectionPanelId(section, sectionIndex) + '-title'\">\n @let sectionHeaderVisual = getSectionHeaderVisual(section);\n @let sectionHeaderAvatarSize = getSectionHeaderAvatarSize(section);\n @if (sectionHeaderVisual.kind === 'icon') {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.kind === 'image') {\n <img class=\"section-title-avatar section-title-avatar-image\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\"\n [src]=\"sectionHeaderVisual.src\" [alt]=\"sectionHeaderVisual.alt\" />\n }\n @if (sectionHeaderVisual.kind === 'initials') {\n <span class=\"section-title-avatar section-title-avatar-text\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n {{ sectionHeaderVisual.text }}\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n @if (sectionHeaderVisual.kind === 'placeholder') {\n <span class=\"section-title-avatar section-title-avatar-placeholder\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n @if (sectionHeaderVisual.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.text) {\n <span>{{ sectionHeaderVisual.text }}</span>\n }\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n {{ getSectionTitle(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" mat-icon-button (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n </h3>\n }\n @if (getSectionDescription(section)) {\n <p class=\"section-description\" [class.body-large]=\"getSectionDescriptionStyle(section) === 'bodyLarge'\"\n [class.body-medium]=\"getSectionDescriptionStyle(section) === 'bodyMedium'\"\n [class.body-small]=\"getSectionDescriptionStyle(section) === 'bodySmall'\"\n [style.marginBottom.px]=\"getSectionDescriptionGapBottom(section) ?? 8\" [style.color]=\"getSectionDescriptionColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionDescription(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" mat-icon-button\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n </p>\n }\n </div>\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" mat-icon-button\n (click)=\"toggleSectionCollapse($event, section)\" [attr.aria-expanded]=\"!isSectionCollapsed(section)\"\n [attr.aria-controls]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-label]=\"isSectionCollapsed(section) ? 'Expandir se\u00E7\u00E3o' : 'Recolher se\u00E7\u00E3o'\">\n <mat-icon [praxisIcon]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\"></mat-icon>\n </button>\n }\n </div>\n\n <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-labelledby]=\"getSectionTitle(section) ? sectionPanelId(section, sectionIndex) + '-title' : null\">\n @if (!isSectionCollapsed(section)) {\n @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n @if (isRowVisible(row)) {\n <div class=\"row-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n <div #rowEl class=\"form-row grid-12 canvas-element\" data-canvas-type=\"row\" [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\" [style.--pfx-grid-gap.px]=\"getRowGap(row)\"\n [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [style.--pfx-mount-index]=\"rowIndex\"\n [style.marginBottom.px]=\"rowIndex < section.rows.length - 1 ? (getRowRowGap(row) ?? null) : null\"\n [ngClass]=\"getRowClasses(row)\" [ngStyle]=\"getRowStyles(row)\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\" (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\" [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\">\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div class=\"column-drop-wrapper\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\">\n <div #colEl class=\"form-column canvas-element\" [ngClass]=\"getColumnClasses(column)\"\n [style.padding.px]=\"getColumnPadding(column)\" [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [ngStyle]=\"getColumnStyles(column)\" [attr.data-testid]=\"column.testId || null\"\n [attr.data-row-gap]=\"getRowRowGap(row)\" data-canvas-type=\"column\" [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\" (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\">\n <ng-container dynamicFieldLoader [fields]=\"getColumnFields(column)\" [formGroup]=\"form\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"disabledModeGlobal === null ? null : disabledModeGlobal\"\n [presentationMode]=\"presentationForLoader\" [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"enableCustomization\" (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\" (canvasClick)=\"onFieldClick($event)\"\n (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n </div>\n </div>\n } }\n </div>\n </div>\n }\n }\n } @else {\n <div class=\"section-collapsed-placeholder\">\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'unfold_more'\"></mat-icon>\n <span>{{ getSectionCollapsedSummary(section) }}</span>\n </div>\n }\n @if (last && beforeActionsPlacement === 'insideLastSection' && formBlocksBeforeActions.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n @for (block of formBlocksBeforeActions; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('beforeActions', $event)\">\n </ng-container>\n }\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"config.actions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n </div>\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner diameter=\"40\" color=\"primary\"></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n\n @if (enableCustomization && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button mat-fab color=\"primary\" aria-label=\"Adicionar nova se\u00E7\u00E3o\" (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n }\n }\n </div>\n }\n\n @if (beforeActionsPlacement !== 'insideLastSection' && formBlocksBeforeActions.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n @for (block of formBlocksBeforeActions; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('beforeActions', $event)\">\n </ng-container>\n }\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"config.actions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n @for (block of formBlocksAfter; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('after', $event)\">\n </ng-container>\n }\n </section>\n }\n</form>\n@if (!enableCustomization && mode === 'view') {\n<div class=\"ai-floating-assistant\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n</div>\n}\n}\n", styles: ["@charset \"UTF-8\";.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@media(min-width:600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@media(min-width:900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@media(min-width:1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@media(min-width:1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: var(--md-sys-color-secondary)}.canvas-mode-enabled .canvas-element[data-canvas-type=column],.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: var(--md-sys-color-tertiary)}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:solid;box-shadow:0 0 0 2px var(--outline-color, var(--md-sys-color-primary))}.canvas-mode-enabled .canvas-element.hovered{z-index:1000}.canvas-mode-enabled .canvas-element.selected{z-index:2000}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:500}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}:host{display:block;position:relative}.form-config-controls{position:sticky;top:10px;margin-left:auto;margin-bottom:10px;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--md-sys-color-surface) 92%,transparent);padding:6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);border-radius:999px;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 10px 22px #0f172a14;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.88;transition:opacity .16s ease,box-shadow .16s ease,border-color .16s ease,transform .16s ease}.form-config-controls>*{pointer-events:auto}.praxis-dynamic-form:hover .form-config-controls,.praxis-dynamic-form:focus-within .form-config-controls{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%);box-shadow:0 14px 28px #0f172a1f;transform:translateY(-1px)}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 34px;width:34px;height:34px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);border:1px solid transparent}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent)}.ai-floating-assistant{position:sticky;right:0;bottom:12px;margin-top:14px;margin-left:auto;width:fit-content;z-index:70;pointer-events:none}.ai-floating-assistant praxis-ai-assistant{pointer-events:auto;display:inline-flex}.ai-floating-assistant .ai-trigger-btn{box-shadow:0 12px 28px #0f172a24}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-on-surface);gap:1rem}.form-loading p{margin:0;font-size:.875rem;opacity:.7}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem;box-shadow:0 12px 30px #7f1d1d1f}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.pfx-form-info-banner{margin-bottom:14px;padding:12px 14px;border-radius:16px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant) 82%);background:color-mix(in srgb,var(--md-sys-color-primary-container) 24%,var(--md-sys-color-surface) 76%);color:var(--md-sys-color-on-surface);display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.pfx-form-info-banner .text{font-size:.92rem;line-height:1.5;font-weight:600}.pfx-form-info-banner .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.praxis-dynamic-form{display:flex;flex-direction:column;transition:all .3s ease;position:relative;font-family:inherit;font-size:inherit;color:inherit;--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--md-sys-color-surface-container) );--pfx-editorial-form-surface-muted: var(--md-sys-color-surface-container-low);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--md-sys-color-outline-variant) );--pfx-editorial-form-text: var(--md-sys-color-on-surface);--pfx-editorial-form-text-muted: var(--md-sys-color-on-surface-variant);--pfx-editorial-form-field-surface: color-mix( in srgb, var(--pfx-editorial-form-surface-muted) 76%, var(--pfx-editorial-form-surface) 24% );--pfx-editorial-form-field-outline: color-mix( in srgb, var(--pfx-editorial-form-border) 88%, transparent );--pfx-editorial-form-accent: var(--md-sys-color-primary);--pfx-editorial-form-accent-text: var(--md-sys-color-on-primary);--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-field-radius: var(--pfx-form-field-radius, 4px);--pfx-editorial-form-border-width: 1px;--pfx-editorial-form-field-border-width: 1px;--pfx-editorial-form-shadow: none;--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-surface-flat: color-mix( in srgb, var(--pfx-editorial-form-surface) 78%, var(--pfx-editorial-form-surface-muted) 22% );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-label-strong: color-mix( in srgb, var(--pfx-editorial-form-text) 96%, white 4% );--pfx-form-label-muted: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 92%, var(--pfx-editorial-form-text) 8% );--pfx-form-field-surface-rest: color-mix( in srgb, var(--pfx-editorial-form-field-surface) 82%, var(--pfx-editorial-form-surface) 18% );--pfx-form-field-surface-focus: color-mix( in srgb, var(--pfx-editorial-form-accent) 4%, var(--pfx-form-field-surface-rest) 96% );--pfx-form-field-min-height: 48px;--pfx-form-section-padding: clamp(1.1rem, 1.8vw, 1.5rem);--pfx-form-section-gap: 22px;--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent )}.praxis-dynamic-form.editorial-visual-context{font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--editorial-text-primary, var(--md-sys-color-on-surface));--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--md-sys-color-primary)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--md-sys-color-on-primary)) );--pfx-editorial-form-radius: var(--editorial-card-radius, 18px);--pfx-editorial-form-field-radius: var( --editorial-field-radius, var(--editorial-card-radius, 14px) );--pfx-editorial-form-border-width: var(--editorial-card-border-width, 1px);--pfx-editorial-form-field-border-width: var(--editorial-field-border-width, 1px);--pfx-editorial-form-shadow: var(--editorial-card-shadow, none);--md-sys-color-surface: var( --pfx-editorial-form-surface, var(--md-sys-color-surface) );--md-sys-color-surface-container: var( --pfx-editorial-form-surface, var(--md-sys-color-surface-container) );--md-sys-color-surface-container-low: var( --pfx-editorial-form-surface-muted, var(--md-sys-color-surface-container-low) );--md-sys-color-surface-variant: var( --pfx-editorial-form-field-surface, var(--md-sys-color-surface-variant) );--md-sys-color-outline: var( --pfx-editorial-form-field-outline, var(--md-sys-color-outline) );--md-sys-color-outline-variant: var( --pfx-editorial-form-border, var(--md-sys-color-outline-variant) );--md-sys-color-on-surface: var( --pfx-editorial-form-text, var(--md-sys-color-on-surface) );--md-sys-color-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant) );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--md-sys-color-on-primary: var( --pfx-editorial-form-accent-text, var(--md-sys-color-on-primary) );--md-sys-color-on-surface-rgb: var( --editorial-text-primary-rgb, var(--md-sys-color-on-surface-rgb) );--mat-sys-on-surface: var( --pfx-editorial-form-text, var(--mat-sys-on-surface) );--mat-sys-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--mat-sys-on-surface-variant) );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, var(--mat-sys-on-surface-rgb, var(--md-sys-color-on-surface-rgb)) );color:var(--pfx-editorial-form-text);color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);box-shadow:none;transition:all .2s ease;position:relative}.praxis-dynamic-form.editorial-visual-context .form-section{border:var(--pfx-editorial-form-border-width) solid var(--pfx-editorial-form-border)!important;background:var(--pfx-editorial-form-surface)!important;box-shadow:var(--editorial-card-shadow, none)}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{background-color:var(--pfx-editorial-form-surface)!important;background-image:linear-gradient(180deg,color-mix(in srgb,var(--editorial-accent, var(--md-sys-color-primary)) 6%,transparent) 0%,transparent 132px)!important;background-repeat:no-repeat!important}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}.section-title{margin:0 0 var(--pfx-section-title-mb, 12px) 0;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-size:var(--editorial-step-title-size, 1.12rem);font-weight:700;color:var(--pfx-form-label-strong)}.section-heading{display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--pfx-form-section-divider)}.section-heading.align-center{flex-direction:column;align-items:center;text-align:center}.section-heading.align-center .section-heading-text{display:grid;justify-items:center}.section-step-label{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;margin:0 0 8px;border-radius:999px;background:color-mix(in srgb,var(--pfx-editorial-form-accent) 10%,transparent);color:color-mix(in srgb,var(--pfx-editorial-form-accent) 84%,var(--pfx-form-label-strong) 16%);font-size:.72rem;font-weight:800;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));letter-spacing:.08em;text-transform:uppercase}.section-heading-text{flex:1 1 auto;min-width:0}.section-collapse-btn{margin-left:4px;color:var(--pfx-form-label-muted)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-title.title-large,.section-title.title-medium,.section-title.title-small,.section-title.headline-small{font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-weight:var(--editorial-title-weight, 600)}.section-description{margin:0;font-family:var(--editorial-body-font-family, inherit);font-size:.93rem;color:var(--pfx-form-label-muted);line-height:1.6}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.section-description.body-large,.section-description.body-medium,.section-description.body-small{font-family:var(--editorial-body-font-family, inherit);font-weight:var(--editorial-body-weight, 400)}.section-title.align-center,.section-description.align-center,.section-step-label.align-center{text-align:center}.form-section.section-appearance-plain{border-color:transparent;border-radius:0;padding:0;background:transparent}.form-section.section-appearance-plain .section-heading{margin-bottom:14px}.form-section.section-appearance-step{border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);border-color:var(--pfx-form-section-divider);box-shadow:none}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{border-radius:var(--editorial-card-radius, 20px);box-shadow:none}.form-section.section-appearance-step .section-heading{margin-bottom:22px;padding-bottom:16px;border-bottom:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .section-title{font:var(--mdc-typography-title-large, 700 22px/28px system-ui);color:var(--pfx-form-label-strong);margin-bottom:8px}.form-section.section-appearance-step .section-description{color:var(--pfx-form-label-muted);max-width:60ch}.form-section.section-appearance-step .section-step-label{min-height:24px;padding:0 10px;margin-bottom:10px;box-shadow:none}.form-section.section-appearance-step .section-heading.align-center .section-description{max-width:52ch}.form-section.section-appearance-step .section-body{display:grid;gap:8px;padding-top:0}.form-section.section-appearance-step .form-row{margin-bottom:var(--pfx-field-gap, 1rem)}.form-section.section-appearance-step .form-column{gap:var(--pfx-field-gap, 12px)}.form-section .form-editorial-blocks{display:grid;gap:16px}.form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{margin-top:24px;padding-top:18px;border-top:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]{gap:18px}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]>*+*{margin-top:2px}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:18px;padding-top:0}.praxis-dynamic-form>.form-editorial-blocks[data-editorial-placement=after]{margin-top:6px}:host-context(.mdc-theme-dark) .form-section.section-appearance-step,:host-context(.theme-dark) .form-section.section-appearance-step{border-color:color-mix(in srgb,var(--pfx-editorial-form-border) 82%,transparent);box-shadow:none}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-title,:host-context(.theme-dark) .form-section.section-appearance-step .section-title{color:color-mix(in srgb,var(--pfx-editorial-form-text) 96%,white)}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-description,:host-context(.theme-dark) .form-section.section-appearance-step .section-description{color:color-mix(in srgb,var(--pfx-editorial-form-text-muted) 86%,var(--pfx-editorial-form-text) 14%)}:host-context(.mdc-theme-dark) .section-step-label,:host-context(.theme-dark) .section-step-label{background:color-mix(in srgb,var(--md-sys-color-primary-container) 54%,transparent);color:color-mix(in srgb,var(--md-sys-color-primary) 88%,white)}:host-context(.mdc-theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions],:host-context(.theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{border-top-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 90%,transparent)}.inline-edit-btn{margin-left:6px;vertical-align:middle;--mdc-icon-button-size: 28px;--mdc-icon-button-icon-size: 16px}.inline-edit-btn mat-icon{font-size:16px;width:16px;height:16px}.section-body.collapsed{border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);border-radius:6px;padding:8px 10px}.section-collapsed-placeholder{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:.95rem}.section-collapsed-placeholder mat-icon{font-size:20px;width:20px;height:20px}.form-row{display:flex;gap:1.1rem;margin-bottom:var(--pfx-field-gap, 1.1rem);transition:all .2s ease;border-radius:6px;position:relative}.praxis-dynamic-form.pfx-mounting .form-row{opacity:0;transform:translateY(var(--pdx-form-mount-offset, 6px));animation:pdxFormMount var(--pdx-form-mount-duration, .16s) ease-out both;animation-delay:calc(var(--pfx-mount-index, 0) * var(--pdx-form-mount-stagger, 20ms))}@media(prefers-reduced-motion:reduce){.praxis-dynamic-form.pfx-mounting .form-row{animation:none;opacity:1;transform:none}}@keyframes pdxFormMount{to{opacity:1;transform:translateY(0)}}.praxis-dynamic-form .mat-mdc-form-field{width:100%;margin-bottom:var(--pfx-field-gap, 10px);font-family:inherit;--mdc-filled-text-field-container-color: var(--pfx-form-field-surface-rest);--mdc-filled-text-field-focus-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-active-indicator-color: var(--pfx-editorial-form-field-outline);--mdc-filled-text-field-hover-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-filled-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-caret-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-input-text-placeholder-color: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 82%, transparent );--mdc-outlined-text-field-outline-color: var(--pfx-editorial-form-field-outline);--mdc-outlined-text-field-hover-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-outlined-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-outlined-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-filled-text-field-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-filled-text-field-focus-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-outline-width: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-focus-outline-width: var(--pfx-editorial-form-field-border-width);--mat-select-enabled-trigger-text-color: var(--pfx-editorial-form-text);--mat-select-enabled-arrow-color: var(--pfx-form-label-muted);--mat-form-field-enabled-select-arrow-color: var(--pfx-form-label-muted);--mat-form-field-focus-select-arrow-color: var(--pfx-editorial-form-accent);--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field{font-family:var(--editorial-body-font-family, inherit)}.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{background:var(--pfx-form-field-surface-rest);border-radius:var(--pfx-editorial-form-field-radius);min-height:var(--pfx-form-field-min-height);transition:background-color .16s ease,box-shadow .16s ease,border-color .16s ease}.praxis-dynamic-form.editorial-visual-context .mat-mdc-text-field-wrapper,.praxis-dynamic-form.editorial-visual-context .mdc-text-field,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--filled,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--outlined{background-color:var(--pfx-form-field-surface-rest)!important;background:var(--pfx-form-field-surface-rest)!important}.praxis-dynamic-form .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-form-label-muted)}.praxis-dynamic-form .mat-mdc-input-element,.praxis-dynamic-form .mat-mdc-select-value-text,.praxis-dynamic-form .mat-mdc-form-field-infix,.praxis-dynamic-form .mat-mdc-select-min-line{color:var(--pfx-editorial-form-text)}.praxis-dynamic-form .mat-mdc-form-field:hover .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field:hover .mdc-text-field,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mdc-text-field{background:var(--pfx-form-field-surface-focus)}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-value-text,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field-infix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-min-line,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input{color:var(--pfx-editorial-form-text)!important;-webkit-text-fill-color:var(--pfx-editorial-form-text)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-editorial-form-text-muted)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 68%,transparent)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element::placeholder,.praxis-dynamic-form.editorial-visual-context textarea.mat-mdc-input-element::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 58%,transparent)!important}.praxis-dynamic-form .mat-mdc-radio-button,.praxis-dynamic-form .mat-mdc-checkbox,.praxis-dynamic-form .mat-mdc-slide-toggle{--mdc-radio-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-checkmark-color: var(--pfx-editorial-form-accent-text);--mdc-checkbox-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-focus-state-layer-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-handle-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-track-color: color-mix(in srgb, var(--pfx-editorial-form-accent) 45%, #fff)}.praxis-dynamic-form [data-field-type=input],.praxis-dynamic-form [data-field-type=textarea],.praxis-dynamic-form [data-field-type=email],.praxis-dynamic-form [data-field-type=password],.praxis-dynamic-form [data-field-type=url],.praxis-dynamic-form [data-field-type=search],.praxis-dynamic-form [data-field-type=phone],.praxis-dynamic-form [data-field-type=numericTextBox],.praxis-dynamic-form [data-field-type=currency],.praxis-dynamic-form [data-field-type=cpfCnpj],.praxis-dynamic-form [data-field-type=date],.praxis-dynamic-form [data-field-type=dateInput],.praxis-dynamic-form [data-field-type=dateRange],.praxis-dynamic-form [data-field-type=dateTimeLocal],.praxis-dynamic-form [data-field-type=time],.praxis-dynamic-form [data-field-type=timePicker],.praxis-dynamic-form [data-field-type=timeRange],.praxis-dynamic-form [data-field-type=month],.praxis-dynamic-form [data-field-type=week],.praxis-dynamic-form [data-field-type=yearInput],.praxis-dynamic-form [data-field-type=select],.praxis-dynamic-form [data-field-type=multi-select],.praxis-dynamic-form [data-field-type=searchable-select],.praxis-dynamic-form [data-field-type=async-select],.praxis-dynamic-form [data-field-type=autocomplete],.praxis-dynamic-form [data-field-type=tree-select],.praxis-dynamic-form [data-field-type=multi-select-tree],.praxis-dynamic-form [data-field-type=priceRange],.praxis-dynamic-form [data-field-type=file-upload]{display:block;width:100%;min-width:0}.praxis-dynamic-form .mat-mdc-form-field-subscript-wrapper{min-height:var(--pfx-subscript-min-h, 22px)}.form-row:last-child{margin-bottom:0}.form-column{display:grid;align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media(max-width:768px){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:14px}}.section-title{display:flex;align-items:center;gap:8px}.section-title .section-title-icon{font-size:1.25em;line-height:1}.section-title-avatar{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-form-section-avatar-size);height:var(--_pfx-form-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-form-section-avatar-size);overflow:hidden}.section-title-avatar.size-sm{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-title-avatar.size-md{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-title-avatar.size-lg{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-title-avatar-image{object-fit:cover;border:1px solid color-mix(in srgb,var(--pfx-form-section-divider) 72%,transparent);background:var(--pfx-form-section-surface-flat)}.section-title-avatar-text,.section-title-avatar-placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent) 14%,var(--pfx-form-section-surface-flat));color:color-mix(in srgb,var(--pfx-editorial-form-accent) 82%,var(--pfx-form-label-strong) 18%);font-size:calc(var(--_pfx-form-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-title-avatar-placeholder mat-icon{font-size:calc(var(--_pfx-form-section-avatar-size) * .5625);width:calc(var(--_pfx-form-section-avatar-size) * .5625);height:calc(var(--_pfx-form-section-avatar-size) * .5625);line-height:calc(var(--_pfx-form-section-avatar-size) * .5625)}.section-title-avatar-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent"], exportAs: ["dynamicWidgetLoader"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i15.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i17.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: CanvasToolbarComponent, selector: "praxis-canvas-toolbar", inputs: ["selectedElement"], outputs: ["editMetadata", "delete", "moveUp", "moveDown", "selectPath", "requestClose", "toggleReadonly", "toggleRequired", "toggleHidden", "toggleDisabled"] }, { kind: "component", type: PraxisFormActionsComponent, selector: "praxis-form-actions", inputs: ["actions", "editorialVisualContext", "isSubmitting", "formIsValid", "submitError", "formId", "actionOverrides"], outputs: ["action"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone"] }, { kind: "component", type: PraxisAiAssistantComponent, selector: "praxis-ai-assistant", inputs: ["adapter", "riskPolicy", "allowManualPatchEdit"] }] });
|
|
11246
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisDynamicForm, isStandalone: true, selector: "praxis-dynamic-form", inputs: { resourcePath: "resourcePath", resourceId: "resourceId", editorialContext: "editorialContext", mode: "mode", config: "config", schemaSource: "schemaSource", enableCustomization: "enableCustomization", formId: "formId", componentInstanceId: "componentInstanceId", layout: "layout", backConfig: "backConfig", hooks: "hooks", removeEmptyContainersOnSave: "removeEmptyContainersOnSave", reactiveValidation: "reactiveValidation", reactiveValidationDebounceMs: "reactiveValidationDebounceMs", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", readonlyModeGlobal: "readonlyModeGlobal", disabledModeGlobal: "disabledModeGlobal", presentationModeGlobal: "presentationModeGlobal", visibleGlobal: "visibleGlobal", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", formReady: "formReady", valueChange: "valueChange", syncCompleted: "syncCompleted", initializationError: "initializationError", loadingStateChange: "loadingStateChange", enableCustomizationChange: "enableCustomizationChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange", fieldRenderError: "fieldRenderError", widgetEvent: "widgetEvent" }, viewQueries: [{ propertyName: "formHost", first: true, predicate: ["formHost"], descendants: true }, { propertyName: "fieldLoaders", predicate: DynamicFieldLoaderDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (isLoading) {\n<!-- Loading State -->\n<div class=\"form-loading\">\n <mat-progress-spinner diameter=\"40\"></mat-progress-spinner>\n <p>Carregando formul\u00E1rio...</p>\n</div>\n} @else if (initializationStatus === 'error') {\n<!-- Error State -->\n<div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n</div>\n} @else if (initializationStatus === 'success') {\n<!-- Inline banner for schema change (only when customization is enabled) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n</div>\n}\n\n<!-- Configuration Controls -->\n@if (shouldShowConfigControls && enableCustomization) {\n<div class=\"form-config-controls\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n <button type=\"button\" mat-icon-button (click)=\"openConfigEditor()\" [disabled]=\"isLoading\" class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\" [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\">\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\">\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n}\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\n<praxis-empty-state-card icon=\"link\" [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"></praxis-empty-state-card>\n}\n<form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\" [class.readonly-mode]=\"effectiveReadonly\"\n [class.editorial-visual-context]=\"hasEditorialVisualContext()\"\n [class.pfx-mounting]=\"isMounting\" [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\" [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n [style.--pdx-form-mount-duration]=\"getMountDurationVar()\"\n [style.--pdx-form-mount-offset]=\"getMountOffsetVar()\"\n [style.--pdx-form-mount-stagger]=\"getMountStaggerVar()\"\n class=\"praxis-dynamic-form\">\n <praxis-canvas-toolbar (editMetadata)=\"openSelectedElementEditor()\" (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\" (moveDown)=\"onToolbarMove('down')\" (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\" (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\" (requestClose)=\"onToolbarRequestClose()\"\n *ngIf=\"enableCustomization && selectedElement\" [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\n\n @if (formBlocksBefore.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n @for (block of formBlocksBefore; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('before', $event)\">\n </ng-container>\n }\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"config.actions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @for (section of config.sections; track (section.id ?? $index); let sectionIndex = $index;\n let last = $last) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n @if (isSectionVisible(section)) {\n <div #sectionEl class=\"form-section canvas-element\" data-canvas-type=\"section\" [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\" (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [attr.data-section-appearance]=\"getSectionAppearance(section) || null\"\n [style.marginBottom.px]=\"!last ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(section)\">\n <div\n class=\"section-heading\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [class.step-appearance]=\"getSectionAppearance(section) === 'step'\"\n >\n <div class=\"section-heading-text\" [matTooltip]=\"getSectionHeaderTooltip(section) || null\"\n [matTooltipDisabled]=\"!getSectionHeaderTooltip(section)\">\n @if (getSectionStepLabel(section)) {\n <div class=\"section-step-label\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionStepLabel(section) }}\n </div>\n }\n @if (getSectionTitle(section)) {\n <h3 class=\"section-title\" [class.title-large]=\"getSectionTitleStyle(section) === 'titleLarge'\"\n [class.title-medium]=\"getSectionTitleStyle(section) === 'titleMedium'\"\n [class.title-small]=\"getSectionTitleStyle(section) === 'titleSmall'\"\n [class.headline-small]=\"getSectionTitleStyle(section) === 'headlineSmall'\"\n [style.marginBottom.px]=\"getSectionTitleGapBottom(section) ?? 20\" [style.color]=\"getSectionTitleColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [attr.id]=\"sectionPanelId(section, sectionIndex) + '-title'\">\n @let sectionHeaderVisual = getSectionHeaderVisual(section);\n @let sectionHeaderAvatarSize = getSectionHeaderAvatarSize(section);\n @if (sectionHeaderVisual.kind === 'icon') {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.kind === 'image') {\n <img class=\"section-title-avatar section-title-avatar-image\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\"\n [src]=\"sectionHeaderVisual.src\" [alt]=\"sectionHeaderVisual.alt\" />\n }\n @if (sectionHeaderVisual.kind === 'initials') {\n <span class=\"section-title-avatar section-title-avatar-text\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n {{ sectionHeaderVisual.text }}\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n @if (sectionHeaderVisual.kind === 'placeholder') {\n <span class=\"section-title-avatar section-title-avatar-placeholder\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n @if (sectionHeaderVisual.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.text) {\n <span>{{ sectionHeaderVisual.text }}</span>\n }\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n {{ getSectionTitle(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" mat-icon-button (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n </h3>\n }\n @if (getSectionDescription(section)) {\n <p class=\"section-description\" [class.body-large]=\"getSectionDescriptionStyle(section) === 'bodyLarge'\"\n [class.body-medium]=\"getSectionDescriptionStyle(section) === 'bodyMedium'\"\n [class.body-small]=\"getSectionDescriptionStyle(section) === 'bodySmall'\"\n [style.marginBottom.px]=\"getSectionDescriptionGapBottom(section) ?? 8\" [style.color]=\"getSectionDescriptionColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionDescription(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" mat-icon-button\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n </p>\n }\n </div>\n @if (getSectionHeaderActions(section).length) {\n <div class=\"section-heading-actions\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n @for (action of getSectionHeaderActions(section); track action.id) {\n <button\n type=\"button\"\n class=\"section-heading-action-btn\"\n mat-icon-button\n [color]=\"getSectionHeaderActionColor(action)\"\n [disabled]=\"isSectionHeaderActionDisabled(action)\"\n [matTooltip]=\"getSectionHeaderActionTooltip(action)\"\n [attr.aria-label]=\"action.label\"\n [attr.aria-busy]=\"action.loading ? 'true' : null\"\n [ngClass]=\"getSectionHeaderActionNgClass(action)\"\n [ngStyle]=\"getSectionHeaderActionStyles(action)\"\n (click)=\"onSectionHeaderActionClick(section, action, $event)\"\n >\n @if (action.loading) {\n <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\"></mat-progress-spinner>\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\"></mat-icon>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" mat-icon-button\n (click)=\"toggleSectionCollapse($event, section)\" [attr.aria-expanded]=\"!isSectionCollapsed(section)\"\n [attr.aria-controls]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-label]=\"isSectionCollapsed(section) ? 'Expandir se\u00E7\u00E3o' : 'Recolher se\u00E7\u00E3o'\">\n <mat-icon [praxisIcon]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\"></mat-icon>\n </button>\n }\n </div>\n\n <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-labelledby]=\"getSectionTitle(section) ? sectionPanelId(section, sectionIndex) + '-title' : null\">\n @if (!isSectionCollapsed(section)) {\n @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n @if (isRowVisible(row)) {\n <div class=\"row-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n <div #rowEl class=\"form-row grid-12 canvas-element\" data-canvas-type=\"row\" [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\" [style.--pfx-grid-gap.px]=\"getRowGap(row)\"\n [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [style.--pfx-mount-index]=\"rowIndex\"\n [style.marginBottom.px]=\"rowIndex < section.rows.length - 1 ? (getRowRowGap(row) ?? null) : null\"\n [ngClass]=\"getRowClasses(row)\" [ngStyle]=\"getRowStyles(row)\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\" (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\" [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\">\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div class=\"column-drop-wrapper\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\">\n <div #colEl class=\"form-column canvas-element\" [ngClass]=\"getColumnClasses(column)\"\n [style.padding.px]=\"getColumnPadding(column)\" [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [ngStyle]=\"getColumnStyles(column)\" [attr.data-testid]=\"column.testId || null\"\n [attr.data-row-gap]=\"getRowRowGap(row)\" data-canvas-type=\"column\" [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\" (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\">\n <ng-container dynamicFieldLoader [fields]=\"getColumnFields(column)\" [formGroup]=\"form\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"disabledModeGlobal === null ? null : disabledModeGlobal\"\n [presentationMode]=\"presentationForLoader\" [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"enableCustomization\" (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\" (canvasClick)=\"onFieldClick($event)\"\n (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n </div>\n </div>\n } }\n </div>\n </div>\n }\n }\n } @else {\n <div class=\"section-collapsed-placeholder\">\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'unfold_more'\"></mat-icon>\n <span>{{ getSectionCollapsedSummary(section) }}</span>\n </div>\n }\n @if (last && beforeActionsPlacement === 'insideLastSection' && formBlocksBeforeActions.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n @for (block of formBlocksBeforeActions; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('beforeActions', $event)\">\n </ng-container>\n }\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"config.actions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n </div>\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner diameter=\"40\" color=\"primary\"></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n\n @if (enableCustomization && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button mat-fab color=\"primary\" aria-label=\"Adicionar nova se\u00E7\u00E3o\" (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n }\n }\n </div>\n }\n\n @if (beforeActionsPlacement !== 'insideLastSection' && formBlocksBeforeActions.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n @for (block of formBlocksBeforeActions; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('beforeActions', $event)\">\n </ng-container>\n }\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"config.actions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n @for (block of formBlocksAfter; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('after', $event)\">\n </ng-container>\n }\n </section>\n }\n</form>\n@if (!enableCustomization && mode === 'view') {\n<div class=\"ai-floating-assistant\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n</div>\n}\n}\n", styles: ["@charset \"UTF-8\";.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@media(min-width:600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@media(min-width:900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@media(min-width:1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@media(min-width:1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: var(--md-sys-color-secondary)}.canvas-mode-enabled .canvas-element[data-canvas-type=column],.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: var(--md-sys-color-tertiary)}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:solid;box-shadow:0 0 0 2px var(--outline-color, var(--md-sys-color-primary))}.canvas-mode-enabled .canvas-element.hovered{z-index:1000}.canvas-mode-enabled .canvas-element.selected{z-index:2000}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:500}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}:host{display:block;position:relative}.form-config-controls{position:sticky;top:10px;margin-left:auto;margin-bottom:10px;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--md-sys-color-surface) 92%,transparent);padding:6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);border-radius:999px;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 10px 22px #0f172a14;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.88;transition:opacity .16s ease,box-shadow .16s ease,border-color .16s ease,transform .16s ease}.form-config-controls>*{pointer-events:auto}.praxis-dynamic-form:hover .form-config-controls,.praxis-dynamic-form:focus-within .form-config-controls{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%);box-shadow:0 14px 28px #0f172a1f;transform:translateY(-1px)}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 34px;width:34px;height:34px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);border:1px solid transparent}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent)}.ai-floating-assistant{position:sticky;right:0;bottom:12px;margin-top:14px;margin-left:auto;width:fit-content;z-index:70;pointer-events:none}.ai-floating-assistant praxis-ai-assistant{pointer-events:auto;display:inline-flex}.ai-floating-assistant .ai-trigger-btn{box-shadow:0 12px 28px #0f172a24}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-on-surface);gap:1rem}.form-loading p{margin:0;font-size:.875rem;opacity:.7}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem;box-shadow:0 12px 30px #7f1d1d1f}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.pfx-form-info-banner{margin-bottom:14px;padding:12px 14px;border-radius:16px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant) 82%);background:color-mix(in srgb,var(--md-sys-color-primary-container) 24%,var(--md-sys-color-surface) 76%);color:var(--md-sys-color-on-surface);display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.pfx-form-info-banner .text{font-size:.92rem;line-height:1.5;font-weight:600}.pfx-form-info-banner .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.praxis-dynamic-form{display:flex;flex-direction:column;transition:all .3s ease;position:relative;font-family:inherit;font-size:inherit;color:inherit;--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--md-sys-color-surface-container) );--pfx-editorial-form-surface-muted: var(--md-sys-color-surface-container-low);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--md-sys-color-outline-variant) );--pfx-editorial-form-text: var(--md-sys-color-on-surface);--pfx-editorial-form-text-muted: var(--md-sys-color-on-surface-variant);--pfx-editorial-form-field-surface: color-mix( in srgb, var(--pfx-editorial-form-surface-muted) 76%, var(--pfx-editorial-form-surface) 24% );--pfx-editorial-form-field-outline: color-mix( in srgb, var(--pfx-editorial-form-border) 88%, transparent );--pfx-editorial-form-accent: var(--md-sys-color-primary);--pfx-editorial-form-accent-text: var(--md-sys-color-on-primary);--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-field-radius: var(--pfx-form-field-radius, 4px);--pfx-editorial-form-border-width: 1px;--pfx-editorial-form-field-border-width: 1px;--pfx-editorial-form-shadow: none;--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-surface-flat: color-mix( in srgb, var(--pfx-editorial-form-surface) 78%, var(--pfx-editorial-form-surface-muted) 22% );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-label-strong: color-mix( in srgb, var(--pfx-editorial-form-text) 96%, white 4% );--pfx-form-label-muted: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 92%, var(--pfx-editorial-form-text) 8% );--pfx-form-field-surface-rest: color-mix( in srgb, var(--pfx-editorial-form-field-surface) 82%, var(--pfx-editorial-form-surface) 18% );--pfx-form-field-surface-focus: color-mix( in srgb, var(--pfx-editorial-form-accent) 4%, var(--pfx-form-field-surface-rest) 96% );--pfx-form-field-min-height: 48px;--pfx-form-section-padding: clamp(1.1rem, 1.8vw, 1.5rem);--pfx-form-section-gap: 22px;--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent )}.praxis-dynamic-form.editorial-visual-context{font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--editorial-text-primary, var(--md-sys-color-on-surface));--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--md-sys-color-primary)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--md-sys-color-on-primary)) );--pfx-editorial-form-radius: var(--editorial-card-radius, 18px);--pfx-editorial-form-field-radius: var( --editorial-field-radius, var(--editorial-card-radius, 14px) );--pfx-editorial-form-border-width: var(--editorial-card-border-width, 1px);--pfx-editorial-form-field-border-width: var(--editorial-field-border-width, 1px);--pfx-editorial-form-shadow: var(--editorial-card-shadow, none);--md-sys-color-surface: var( --pfx-editorial-form-surface, var(--md-sys-color-surface) );--md-sys-color-surface-container: var( --pfx-editorial-form-surface, var(--md-sys-color-surface-container) );--md-sys-color-surface-container-low: var( --pfx-editorial-form-surface-muted, var(--md-sys-color-surface-container-low) );--md-sys-color-surface-variant: var( --pfx-editorial-form-field-surface, var(--md-sys-color-surface-variant) );--md-sys-color-outline: var( --pfx-editorial-form-field-outline, var(--md-sys-color-outline) );--md-sys-color-outline-variant: var( --pfx-editorial-form-border, var(--md-sys-color-outline-variant) );--md-sys-color-on-surface: var( --pfx-editorial-form-text, var(--md-sys-color-on-surface) );--md-sys-color-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant) );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--md-sys-color-on-primary: var( --pfx-editorial-form-accent-text, var(--md-sys-color-on-primary) );--md-sys-color-on-surface-rgb: var( --editorial-text-primary-rgb, var(--md-sys-color-on-surface-rgb) );--mat-sys-on-surface: var( --pfx-editorial-form-text, var(--mat-sys-on-surface) );--mat-sys-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--mat-sys-on-surface-variant) );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, var(--mat-sys-on-surface-rgb, var(--md-sys-color-on-surface-rgb)) );color:var(--pfx-editorial-form-text);color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);box-shadow:none;transition:all .2s ease;position:relative}.praxis-dynamic-form.editorial-visual-context .form-section{border:var(--pfx-editorial-form-border-width) solid var(--pfx-editorial-form-border)!important;background:var(--pfx-editorial-form-surface)!important;box-shadow:var(--editorial-card-shadow, none)}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{background-color:var(--pfx-editorial-form-surface)!important;background-image:linear-gradient(180deg,color-mix(in srgb,var(--editorial-accent, var(--md-sys-color-primary)) 6%,transparent) 0%,transparent 132px)!important;background-repeat:no-repeat!important}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}.section-title{margin:0 0 var(--pfx-section-title-mb, 12px) 0;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-size:var(--editorial-step-title-size, 1.12rem);font-weight:700;color:var(--pfx-form-label-strong)}.section-heading{display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--pfx-form-section-divider)}.section-heading.align-center{flex-direction:column;align-items:center;text-align:center}.section-heading.align-center .section-heading-text{display:grid;justify-items:center}.section-step-label{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;margin:0 0 8px;border-radius:999px;background:color-mix(in srgb,var(--pfx-editorial-form-accent) 10%,transparent);color:color-mix(in srgb,var(--pfx-editorial-form-accent) 84%,var(--pfx-form-label-strong) 16%);font-size:.72rem;font-weight:800;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));letter-spacing:.08em;text-transform:uppercase}.section-heading-text{flex:1 1 auto;min-width:0}.section-heading-actions{display:inline-flex;align-items:center;align-self:flex-start;flex-wrap:wrap;gap:4px;margin-left:auto}.section-heading-actions.align-center{align-self:center;margin-left:0}.section-heading-action-btn{color:var(--pfx-form-label-muted)}.section-heading-action-btn .mat-mdc-progress-spinner,.section-heading-action-btn mat-progress-spinner{--mdc-circular-progress-active-indicator-color: currentColor}.section-heading-action-btn.loading{opacity:.72;pointer-events:none}.section-heading-action-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.section-collapse-btn{margin-left:4px;color:var(--pfx-form-label-muted)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-title.title-large,.section-title.title-medium,.section-title.title-small,.section-title.headline-small{font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-weight:var(--editorial-title-weight, 600)}.section-description{margin:0;font-family:var(--editorial-body-font-family, inherit);font-size:.93rem;color:var(--pfx-form-label-muted);line-height:1.6}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.section-description.body-large,.section-description.body-medium,.section-description.body-small{font-family:var(--editorial-body-font-family, inherit);font-weight:var(--editorial-body-weight, 400)}.section-title.align-center,.section-description.align-center,.section-step-label.align-center{text-align:center}.form-section.section-appearance-plain{border-color:transparent;border-radius:0;padding:0;background:transparent}.form-section.section-appearance-plain .section-heading{margin-bottom:14px}.form-section.section-appearance-step{border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);border-color:var(--pfx-form-section-divider);box-shadow:none}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{border-radius:var(--editorial-card-radius, 20px);box-shadow:none}.form-section.section-appearance-step .section-heading{margin-bottom:22px;padding-bottom:16px;border-bottom:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .section-title{font:var(--mdc-typography-title-large, 700 22px/28px system-ui);color:var(--pfx-form-label-strong);margin-bottom:8px}.form-section.section-appearance-step .section-description{color:var(--pfx-form-label-muted);max-width:60ch}.form-section.section-appearance-step .section-step-label{min-height:24px;padding:0 10px;margin-bottom:10px;box-shadow:none}.form-section.section-appearance-step .section-heading.align-center .section-description{max-width:52ch}.form-section.section-appearance-step .section-body{display:grid;gap:8px;padding-top:0}.form-section.section-appearance-step .form-row{margin-bottom:var(--pfx-field-gap, 1rem)}.form-section.section-appearance-step .form-column{gap:var(--pfx-field-gap, 12px)}.form-section .form-editorial-blocks{display:grid;gap:16px}.form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{margin-top:24px;padding-top:18px;border-top:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]{gap:18px}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]>*+*{margin-top:2px}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:18px;padding-top:0}.praxis-dynamic-form>.form-editorial-blocks[data-editorial-placement=after]{margin-top:6px}:host-context(.mdc-theme-dark) .form-section.section-appearance-step,:host-context(.theme-dark) .form-section.section-appearance-step{border-color:color-mix(in srgb,var(--pfx-editorial-form-border) 82%,transparent);box-shadow:none}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-title,:host-context(.theme-dark) .form-section.section-appearance-step .section-title{color:color-mix(in srgb,var(--pfx-editorial-form-text) 96%,white)}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-description,:host-context(.theme-dark) .form-section.section-appearance-step .section-description{color:color-mix(in srgb,var(--pfx-editorial-form-text-muted) 86%,var(--pfx-editorial-form-text) 14%)}:host-context(.mdc-theme-dark) .section-step-label,:host-context(.theme-dark) .section-step-label{background:color-mix(in srgb,var(--md-sys-color-primary-container) 54%,transparent);color:color-mix(in srgb,var(--md-sys-color-primary) 88%,white)}:host-context(.mdc-theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions],:host-context(.theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{border-top-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 90%,transparent)}.inline-edit-btn{margin-left:6px;vertical-align:middle;--mdc-icon-button-size: 28px;--mdc-icon-button-icon-size: 16px}.inline-edit-btn mat-icon{font-size:16px;width:16px;height:16px}.section-body.collapsed{border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);border-radius:6px;padding:8px 10px}.section-collapsed-placeholder{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:.95rem}.section-collapsed-placeholder mat-icon{font-size:20px;width:20px;height:20px}.form-row{display:flex;gap:1.1rem;margin-bottom:var(--pfx-field-gap, 1.1rem);transition:all .2s ease;border-radius:6px;position:relative}.praxis-dynamic-form.pfx-mounting .form-row{opacity:0;transform:translateY(var(--pdx-form-mount-offset, 6px));animation:pdxFormMount var(--pdx-form-mount-duration, .16s) ease-out both;animation-delay:calc(var(--pfx-mount-index, 0) * var(--pdx-form-mount-stagger, 20ms))}@media(prefers-reduced-motion:reduce){.praxis-dynamic-form.pfx-mounting .form-row{animation:none;opacity:1;transform:none}}@keyframes pdxFormMount{to{opacity:1;transform:translateY(0)}}.praxis-dynamic-form .mat-mdc-form-field{width:100%;margin-bottom:var(--pfx-field-gap, 10px);font-family:inherit;--mdc-filled-text-field-container-color: var(--pfx-form-field-surface-rest);--mdc-filled-text-field-focus-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-active-indicator-color: var(--pfx-editorial-form-field-outline);--mdc-filled-text-field-hover-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-filled-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-caret-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-input-text-placeholder-color: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 82%, transparent );--mdc-outlined-text-field-outline-color: var(--pfx-editorial-form-field-outline);--mdc-outlined-text-field-hover-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-outlined-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-outlined-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-filled-text-field-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-filled-text-field-focus-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-outline-width: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-focus-outline-width: var(--pfx-editorial-form-field-border-width);--mat-select-enabled-trigger-text-color: var(--pfx-editorial-form-text);--mat-select-enabled-arrow-color: var(--pfx-form-label-muted);--mat-form-field-enabled-select-arrow-color: var(--pfx-form-label-muted);--mat-form-field-focus-select-arrow-color: var(--pfx-editorial-form-accent);--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field{font-family:var(--editorial-body-font-family, inherit)}.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{background:var(--pfx-form-field-surface-rest);border-radius:var(--pfx-editorial-form-field-radius);min-height:var(--pfx-form-field-min-height);transition:background-color .16s ease,box-shadow .16s ease,border-color .16s ease}.praxis-dynamic-form.editorial-visual-context .mat-mdc-text-field-wrapper,.praxis-dynamic-form.editorial-visual-context .mdc-text-field,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--filled,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--outlined{background-color:var(--pfx-form-field-surface-rest)!important;background:var(--pfx-form-field-surface-rest)!important}.praxis-dynamic-form .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-form-label-muted)}.praxis-dynamic-form .mat-mdc-input-element,.praxis-dynamic-form .mat-mdc-select-value-text,.praxis-dynamic-form .mat-mdc-form-field-infix,.praxis-dynamic-form .mat-mdc-select-min-line{color:var(--pfx-editorial-form-text)}.praxis-dynamic-form .mat-mdc-form-field:hover .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field:hover .mdc-text-field,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mdc-text-field{background:var(--pfx-form-field-surface-focus)}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-value-text,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field-infix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-min-line,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input{color:var(--pfx-editorial-form-text)!important;-webkit-text-fill-color:var(--pfx-editorial-form-text)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-editorial-form-text-muted)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 68%,transparent)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element::placeholder,.praxis-dynamic-form.editorial-visual-context textarea.mat-mdc-input-element::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 58%,transparent)!important}.praxis-dynamic-form .mat-mdc-radio-button,.praxis-dynamic-form .mat-mdc-checkbox,.praxis-dynamic-form .mat-mdc-slide-toggle{--mdc-radio-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-checkmark-color: var(--pfx-editorial-form-accent-text);--mdc-checkbox-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-focus-state-layer-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-handle-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-track-color: color-mix(in srgb, var(--pfx-editorial-form-accent) 45%, #fff)}.praxis-dynamic-form [data-field-type=input],.praxis-dynamic-form [data-field-type=textarea],.praxis-dynamic-form [data-field-type=email],.praxis-dynamic-form [data-field-type=password],.praxis-dynamic-form [data-field-type=url],.praxis-dynamic-form [data-field-type=search],.praxis-dynamic-form [data-field-type=phone],.praxis-dynamic-form [data-field-type=numericTextBox],.praxis-dynamic-form [data-field-type=currency],.praxis-dynamic-form [data-field-type=cpfCnpj],.praxis-dynamic-form [data-field-type=date],.praxis-dynamic-form [data-field-type=dateInput],.praxis-dynamic-form [data-field-type=dateRange],.praxis-dynamic-form [data-field-type=dateTimeLocal],.praxis-dynamic-form [data-field-type=time],.praxis-dynamic-form [data-field-type=timePicker],.praxis-dynamic-form [data-field-type=timeRange],.praxis-dynamic-form [data-field-type=month],.praxis-dynamic-form [data-field-type=week],.praxis-dynamic-form [data-field-type=yearInput],.praxis-dynamic-form [data-field-type=select],.praxis-dynamic-form [data-field-type=multi-select],.praxis-dynamic-form [data-field-type=searchable-select],.praxis-dynamic-form [data-field-type=async-select],.praxis-dynamic-form [data-field-type=autocomplete],.praxis-dynamic-form [data-field-type=tree-select],.praxis-dynamic-form [data-field-type=multi-select-tree],.praxis-dynamic-form [data-field-type=priceRange],.praxis-dynamic-form [data-field-type=file-upload]{display:block;width:100%;min-width:0}.praxis-dynamic-form .mat-mdc-form-field-subscript-wrapper{min-height:var(--pfx-subscript-min-h, 22px)}.form-row:last-child{margin-bottom:0}.form-column{display:grid;align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media(max-width:768px){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:14px}}.section-title{display:flex;align-items:center;gap:8px}.section-title .section-title-icon{font-size:1.25em;line-height:1}.section-title-avatar{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-form-section-avatar-size);height:var(--_pfx-form-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-form-section-avatar-size);overflow:hidden}.section-title-avatar.size-sm{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-title-avatar.size-md{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-title-avatar.size-lg{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-title-avatar-image{object-fit:cover;border:1px solid color-mix(in srgb,var(--pfx-form-section-divider) 72%,transparent);background:var(--pfx-form-section-surface-flat)}.section-title-avatar-text,.section-title-avatar-placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent) 14%,var(--pfx-form-section-surface-flat));color:color-mix(in srgb,var(--pfx-editorial-form-accent) 82%,var(--pfx-form-label-strong) 18%);font-size:calc(var(--_pfx-form-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-title-avatar-placeholder mat-icon{font-size:calc(var(--_pfx-form-section-avatar-size) * .5625);width:calc(var(--_pfx-form-section-avatar-size) * .5625);height:calc(var(--_pfx-form-section-avatar-size) * .5625);line-height:calc(var(--_pfx-form-section-avatar-size) * .5625)}.section-title-avatar-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent"], exportAs: ["dynamicWidgetLoader"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i15.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i17.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: CanvasToolbarComponent, selector: "praxis-canvas-toolbar", inputs: ["selectedElement"], outputs: ["editMetadata", "delete", "moveUp", "moveDown", "selectPath", "requestClose", "toggleReadonly", "toggleRequired", "toggleHidden", "toggleDisabled"] }, { kind: "component", type: PraxisFormActionsComponent, selector: "praxis-form-actions", inputs: ["actions", "editorialVisualContext", "isSubmitting", "formIsValid", "submitError", "formId", "actionOverrides"], outputs: ["action"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone"] }, { kind: "component", type: PraxisAiAssistantComponent, selector: "praxis-ai-assistant", inputs: ["adapter", "riskPolicy", "allowManualPatchEdit"] }] });
|
|
11058
11247
|
}
|
|
11059
11248
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisDynamicForm, decorators: [{
|
|
11060
11249
|
type: Component,
|
|
@@ -11075,7 +11264,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
11075
11264
|
PraxisFormActionsComponent,
|
|
11076
11265
|
EmptyStateCardComponent,
|
|
11077
11266
|
PraxisAiAssistantComponent,
|
|
11078
|
-
], template: "@if (isLoading) {\n<!-- Loading State -->\n<div class=\"form-loading\">\n <mat-progress-spinner diameter=\"40\"></mat-progress-spinner>\n <p>Carregando formul\u00E1rio...</p>\n</div>\n} @else if (initializationStatus === 'error') {\n<!-- Error State -->\n<div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n</div>\n} @else if (initializationStatus === 'success') {\n<!-- Inline banner for schema change (only when customization is enabled) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n</div>\n}\n\n<!-- Configuration Controls -->\n@if (shouldShowConfigControls && enableCustomization) {\n<div class=\"form-config-controls\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n <button type=\"button\" mat-icon-button (click)=\"openConfigEditor()\" [disabled]=\"isLoading\" class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\" [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\">\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\">\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n}\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\n<praxis-empty-state-card icon=\"link\" [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"></praxis-empty-state-card>\n}\n<form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\" [class.readonly-mode]=\"effectiveReadonly\"\n [class.editorial-visual-context]=\"hasEditorialVisualContext()\"\n [class.pfx-mounting]=\"isMounting\" [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\" [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n [style.--pdx-form-mount-duration]=\"getMountDurationVar()\"\n [style.--pdx-form-mount-offset]=\"getMountOffsetVar()\"\n [style.--pdx-form-mount-stagger]=\"getMountStaggerVar()\"\n class=\"praxis-dynamic-form\">\n <praxis-canvas-toolbar (editMetadata)=\"openSelectedElementEditor()\" (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\" (moveDown)=\"onToolbarMove('down')\" (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\" (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\" (requestClose)=\"onToolbarRequestClose()\"\n *ngIf=\"enableCustomization && selectedElement\" [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\n\n @if (formBlocksBefore.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n @for (block of formBlocksBefore; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('before', $event)\">\n </ng-container>\n }\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"config.actions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @for (section of config.sections; track (section.id ?? $index); let sectionIndex = $index;\n let last = $last) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n @if (isSectionVisible(section)) {\n <div #sectionEl class=\"form-section canvas-element\" data-canvas-type=\"section\" [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\" (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [attr.data-section-appearance]=\"getSectionAppearance(section) || null\"\n [style.marginBottom.px]=\"!last ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(section)\">\n <div\n class=\"section-heading\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [class.step-appearance]=\"getSectionAppearance(section) === 'step'\"\n >\n <div class=\"section-heading-text\" [matTooltip]=\"getSectionHeaderTooltip(section) || null\"\n [matTooltipDisabled]=\"!getSectionHeaderTooltip(section)\">\n @if (getSectionStepLabel(section)) {\n <div class=\"section-step-label\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionStepLabel(section) }}\n </div>\n }\n @if (getSectionTitle(section)) {\n <h3 class=\"section-title\" [class.title-large]=\"getSectionTitleStyle(section) === 'titleLarge'\"\n [class.title-medium]=\"getSectionTitleStyle(section) === 'titleMedium'\"\n [class.title-small]=\"getSectionTitleStyle(section) === 'titleSmall'\"\n [class.headline-small]=\"getSectionTitleStyle(section) === 'headlineSmall'\"\n [style.marginBottom.px]=\"getSectionTitleGapBottom(section) ?? 20\" [style.color]=\"getSectionTitleColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [attr.id]=\"sectionPanelId(section, sectionIndex) + '-title'\">\n @let sectionHeaderVisual = getSectionHeaderVisual(section);\n @let sectionHeaderAvatarSize = getSectionHeaderAvatarSize(section);\n @if (sectionHeaderVisual.kind === 'icon') {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.kind === 'image') {\n <img class=\"section-title-avatar section-title-avatar-image\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\"\n [src]=\"sectionHeaderVisual.src\" [alt]=\"sectionHeaderVisual.alt\" />\n }\n @if (sectionHeaderVisual.kind === 'initials') {\n <span class=\"section-title-avatar section-title-avatar-text\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n {{ sectionHeaderVisual.text }}\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n @if (sectionHeaderVisual.kind === 'placeholder') {\n <span class=\"section-title-avatar section-title-avatar-placeholder\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n @if (sectionHeaderVisual.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.text) {\n <span>{{ sectionHeaderVisual.text }}</span>\n }\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n {{ getSectionTitle(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" mat-icon-button (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n </h3>\n }\n @if (getSectionDescription(section)) {\n <p class=\"section-description\" [class.body-large]=\"getSectionDescriptionStyle(section) === 'bodyLarge'\"\n [class.body-medium]=\"getSectionDescriptionStyle(section) === 'bodyMedium'\"\n [class.body-small]=\"getSectionDescriptionStyle(section) === 'bodySmall'\"\n [style.marginBottom.px]=\"getSectionDescriptionGapBottom(section) ?? 8\" [style.color]=\"getSectionDescriptionColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionDescription(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" mat-icon-button\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n </p>\n }\n </div>\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" mat-icon-button\n (click)=\"toggleSectionCollapse($event, section)\" [attr.aria-expanded]=\"!isSectionCollapsed(section)\"\n [attr.aria-controls]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-label]=\"isSectionCollapsed(section) ? 'Expandir se\u00E7\u00E3o' : 'Recolher se\u00E7\u00E3o'\">\n <mat-icon [praxisIcon]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\"></mat-icon>\n </button>\n }\n </div>\n\n <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-labelledby]=\"getSectionTitle(section) ? sectionPanelId(section, sectionIndex) + '-title' : null\">\n @if (!isSectionCollapsed(section)) {\n @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n @if (isRowVisible(row)) {\n <div class=\"row-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n <div #rowEl class=\"form-row grid-12 canvas-element\" data-canvas-type=\"row\" [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\" [style.--pfx-grid-gap.px]=\"getRowGap(row)\"\n [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [style.--pfx-mount-index]=\"rowIndex\"\n [style.marginBottom.px]=\"rowIndex < section.rows.length - 1 ? (getRowRowGap(row) ?? null) : null\"\n [ngClass]=\"getRowClasses(row)\" [ngStyle]=\"getRowStyles(row)\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\" (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\" [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\">\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div class=\"column-drop-wrapper\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\">\n <div #colEl class=\"form-column canvas-element\" [ngClass]=\"getColumnClasses(column)\"\n [style.padding.px]=\"getColumnPadding(column)\" [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [ngStyle]=\"getColumnStyles(column)\" [attr.data-testid]=\"column.testId || null\"\n [attr.data-row-gap]=\"getRowRowGap(row)\" data-canvas-type=\"column\" [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\" (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\">\n <ng-container dynamicFieldLoader [fields]=\"getColumnFields(column)\" [formGroup]=\"form\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"disabledModeGlobal === null ? null : disabledModeGlobal\"\n [presentationMode]=\"presentationForLoader\" [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"enableCustomization\" (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\" (canvasClick)=\"onFieldClick($event)\"\n (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n </div>\n </div>\n } }\n </div>\n </div>\n }\n }\n } @else {\n <div class=\"section-collapsed-placeholder\">\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'unfold_more'\"></mat-icon>\n <span>{{ getSectionCollapsedSummary(section) }}</span>\n </div>\n }\n @if (last && beforeActionsPlacement === 'insideLastSection' && formBlocksBeforeActions.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n @for (block of formBlocksBeforeActions; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('beforeActions', $event)\">\n </ng-container>\n }\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"config.actions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n </div>\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner diameter=\"40\" color=\"primary\"></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n\n @if (enableCustomization && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button mat-fab color=\"primary\" aria-label=\"Adicionar nova se\u00E7\u00E3o\" (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n }\n }\n </div>\n }\n\n @if (beforeActionsPlacement !== 'insideLastSection' && formBlocksBeforeActions.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n @for (block of formBlocksBeforeActions; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('beforeActions', $event)\">\n </ng-container>\n }\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"config.actions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n @for (block of formBlocksAfter; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('after', $event)\">\n </ng-container>\n }\n </section>\n }\n</form>\n@if (!enableCustomization && mode === 'view') {\n<div class=\"ai-floating-assistant\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n</div>\n}\n}\n", styles: ["@charset \"UTF-8\";.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@media(min-width:600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@media(min-width:900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@media(min-width:1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@media(min-width:1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: var(--md-sys-color-secondary)}.canvas-mode-enabled .canvas-element[data-canvas-type=column],.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: var(--md-sys-color-tertiary)}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:solid;box-shadow:0 0 0 2px var(--outline-color, var(--md-sys-color-primary))}.canvas-mode-enabled .canvas-element.hovered{z-index:1000}.canvas-mode-enabled .canvas-element.selected{z-index:2000}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:500}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}:host{display:block;position:relative}.form-config-controls{position:sticky;top:10px;margin-left:auto;margin-bottom:10px;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--md-sys-color-surface) 92%,transparent);padding:6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);border-radius:999px;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 10px 22px #0f172a14;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.88;transition:opacity .16s ease,box-shadow .16s ease,border-color .16s ease,transform .16s ease}.form-config-controls>*{pointer-events:auto}.praxis-dynamic-form:hover .form-config-controls,.praxis-dynamic-form:focus-within .form-config-controls{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%);box-shadow:0 14px 28px #0f172a1f;transform:translateY(-1px)}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 34px;width:34px;height:34px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);border:1px solid transparent}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent)}.ai-floating-assistant{position:sticky;right:0;bottom:12px;margin-top:14px;margin-left:auto;width:fit-content;z-index:70;pointer-events:none}.ai-floating-assistant praxis-ai-assistant{pointer-events:auto;display:inline-flex}.ai-floating-assistant .ai-trigger-btn{box-shadow:0 12px 28px #0f172a24}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-on-surface);gap:1rem}.form-loading p{margin:0;font-size:.875rem;opacity:.7}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem;box-shadow:0 12px 30px #7f1d1d1f}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.pfx-form-info-banner{margin-bottom:14px;padding:12px 14px;border-radius:16px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant) 82%);background:color-mix(in srgb,var(--md-sys-color-primary-container) 24%,var(--md-sys-color-surface) 76%);color:var(--md-sys-color-on-surface);display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.pfx-form-info-banner .text{font-size:.92rem;line-height:1.5;font-weight:600}.pfx-form-info-banner .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.praxis-dynamic-form{display:flex;flex-direction:column;transition:all .3s ease;position:relative;font-family:inherit;font-size:inherit;color:inherit;--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--md-sys-color-surface-container) );--pfx-editorial-form-surface-muted: var(--md-sys-color-surface-container-low);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--md-sys-color-outline-variant) );--pfx-editorial-form-text: var(--md-sys-color-on-surface);--pfx-editorial-form-text-muted: var(--md-sys-color-on-surface-variant);--pfx-editorial-form-field-surface: color-mix( in srgb, var(--pfx-editorial-form-surface-muted) 76%, var(--pfx-editorial-form-surface) 24% );--pfx-editorial-form-field-outline: color-mix( in srgb, var(--pfx-editorial-form-border) 88%, transparent );--pfx-editorial-form-accent: var(--md-sys-color-primary);--pfx-editorial-form-accent-text: var(--md-sys-color-on-primary);--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-field-radius: var(--pfx-form-field-radius, 4px);--pfx-editorial-form-border-width: 1px;--pfx-editorial-form-field-border-width: 1px;--pfx-editorial-form-shadow: none;--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-surface-flat: color-mix( in srgb, var(--pfx-editorial-form-surface) 78%, var(--pfx-editorial-form-surface-muted) 22% );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-label-strong: color-mix( in srgb, var(--pfx-editorial-form-text) 96%, white 4% );--pfx-form-label-muted: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 92%, var(--pfx-editorial-form-text) 8% );--pfx-form-field-surface-rest: color-mix( in srgb, var(--pfx-editorial-form-field-surface) 82%, var(--pfx-editorial-form-surface) 18% );--pfx-form-field-surface-focus: color-mix( in srgb, var(--pfx-editorial-form-accent) 4%, var(--pfx-form-field-surface-rest) 96% );--pfx-form-field-min-height: 48px;--pfx-form-section-padding: clamp(1.1rem, 1.8vw, 1.5rem);--pfx-form-section-gap: 22px;--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent )}.praxis-dynamic-form.editorial-visual-context{font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--editorial-text-primary, var(--md-sys-color-on-surface));--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--md-sys-color-primary)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--md-sys-color-on-primary)) );--pfx-editorial-form-radius: var(--editorial-card-radius, 18px);--pfx-editorial-form-field-radius: var( --editorial-field-radius, var(--editorial-card-radius, 14px) );--pfx-editorial-form-border-width: var(--editorial-card-border-width, 1px);--pfx-editorial-form-field-border-width: var(--editorial-field-border-width, 1px);--pfx-editorial-form-shadow: var(--editorial-card-shadow, none);--md-sys-color-surface: var( --pfx-editorial-form-surface, var(--md-sys-color-surface) );--md-sys-color-surface-container: var( --pfx-editorial-form-surface, var(--md-sys-color-surface-container) );--md-sys-color-surface-container-low: var( --pfx-editorial-form-surface-muted, var(--md-sys-color-surface-container-low) );--md-sys-color-surface-variant: var( --pfx-editorial-form-field-surface, var(--md-sys-color-surface-variant) );--md-sys-color-outline: var( --pfx-editorial-form-field-outline, var(--md-sys-color-outline) );--md-sys-color-outline-variant: var( --pfx-editorial-form-border, var(--md-sys-color-outline-variant) );--md-sys-color-on-surface: var( --pfx-editorial-form-text, var(--md-sys-color-on-surface) );--md-sys-color-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant) );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--md-sys-color-on-primary: var( --pfx-editorial-form-accent-text, var(--md-sys-color-on-primary) );--md-sys-color-on-surface-rgb: var( --editorial-text-primary-rgb, var(--md-sys-color-on-surface-rgb) );--mat-sys-on-surface: var( --pfx-editorial-form-text, var(--mat-sys-on-surface) );--mat-sys-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--mat-sys-on-surface-variant) );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, var(--mat-sys-on-surface-rgb, var(--md-sys-color-on-surface-rgb)) );color:var(--pfx-editorial-form-text);color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);box-shadow:none;transition:all .2s ease;position:relative}.praxis-dynamic-form.editorial-visual-context .form-section{border:var(--pfx-editorial-form-border-width) solid var(--pfx-editorial-form-border)!important;background:var(--pfx-editorial-form-surface)!important;box-shadow:var(--editorial-card-shadow, none)}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{background-color:var(--pfx-editorial-form-surface)!important;background-image:linear-gradient(180deg,color-mix(in srgb,var(--editorial-accent, var(--md-sys-color-primary)) 6%,transparent) 0%,transparent 132px)!important;background-repeat:no-repeat!important}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}.section-title{margin:0 0 var(--pfx-section-title-mb, 12px) 0;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-size:var(--editorial-step-title-size, 1.12rem);font-weight:700;color:var(--pfx-form-label-strong)}.section-heading{display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--pfx-form-section-divider)}.section-heading.align-center{flex-direction:column;align-items:center;text-align:center}.section-heading.align-center .section-heading-text{display:grid;justify-items:center}.section-step-label{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;margin:0 0 8px;border-radius:999px;background:color-mix(in srgb,var(--pfx-editorial-form-accent) 10%,transparent);color:color-mix(in srgb,var(--pfx-editorial-form-accent) 84%,var(--pfx-form-label-strong) 16%);font-size:.72rem;font-weight:800;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));letter-spacing:.08em;text-transform:uppercase}.section-heading-text{flex:1 1 auto;min-width:0}.section-collapse-btn{margin-left:4px;color:var(--pfx-form-label-muted)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-title.title-large,.section-title.title-medium,.section-title.title-small,.section-title.headline-small{font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-weight:var(--editorial-title-weight, 600)}.section-description{margin:0;font-family:var(--editorial-body-font-family, inherit);font-size:.93rem;color:var(--pfx-form-label-muted);line-height:1.6}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.section-description.body-large,.section-description.body-medium,.section-description.body-small{font-family:var(--editorial-body-font-family, inherit);font-weight:var(--editorial-body-weight, 400)}.section-title.align-center,.section-description.align-center,.section-step-label.align-center{text-align:center}.form-section.section-appearance-plain{border-color:transparent;border-radius:0;padding:0;background:transparent}.form-section.section-appearance-plain .section-heading{margin-bottom:14px}.form-section.section-appearance-step{border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);border-color:var(--pfx-form-section-divider);box-shadow:none}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{border-radius:var(--editorial-card-radius, 20px);box-shadow:none}.form-section.section-appearance-step .section-heading{margin-bottom:22px;padding-bottom:16px;border-bottom:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .section-title{font:var(--mdc-typography-title-large, 700 22px/28px system-ui);color:var(--pfx-form-label-strong);margin-bottom:8px}.form-section.section-appearance-step .section-description{color:var(--pfx-form-label-muted);max-width:60ch}.form-section.section-appearance-step .section-step-label{min-height:24px;padding:0 10px;margin-bottom:10px;box-shadow:none}.form-section.section-appearance-step .section-heading.align-center .section-description{max-width:52ch}.form-section.section-appearance-step .section-body{display:grid;gap:8px;padding-top:0}.form-section.section-appearance-step .form-row{margin-bottom:var(--pfx-field-gap, 1rem)}.form-section.section-appearance-step .form-column{gap:var(--pfx-field-gap, 12px)}.form-section .form-editorial-blocks{display:grid;gap:16px}.form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{margin-top:24px;padding-top:18px;border-top:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]{gap:18px}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]>*+*{margin-top:2px}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:18px;padding-top:0}.praxis-dynamic-form>.form-editorial-blocks[data-editorial-placement=after]{margin-top:6px}:host-context(.mdc-theme-dark) .form-section.section-appearance-step,:host-context(.theme-dark) .form-section.section-appearance-step{border-color:color-mix(in srgb,var(--pfx-editorial-form-border) 82%,transparent);box-shadow:none}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-title,:host-context(.theme-dark) .form-section.section-appearance-step .section-title{color:color-mix(in srgb,var(--pfx-editorial-form-text) 96%,white)}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-description,:host-context(.theme-dark) .form-section.section-appearance-step .section-description{color:color-mix(in srgb,var(--pfx-editorial-form-text-muted) 86%,var(--pfx-editorial-form-text) 14%)}:host-context(.mdc-theme-dark) .section-step-label,:host-context(.theme-dark) .section-step-label{background:color-mix(in srgb,var(--md-sys-color-primary-container) 54%,transparent);color:color-mix(in srgb,var(--md-sys-color-primary) 88%,white)}:host-context(.mdc-theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions],:host-context(.theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{border-top-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 90%,transparent)}.inline-edit-btn{margin-left:6px;vertical-align:middle;--mdc-icon-button-size: 28px;--mdc-icon-button-icon-size: 16px}.inline-edit-btn mat-icon{font-size:16px;width:16px;height:16px}.section-body.collapsed{border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);border-radius:6px;padding:8px 10px}.section-collapsed-placeholder{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:.95rem}.section-collapsed-placeholder mat-icon{font-size:20px;width:20px;height:20px}.form-row{display:flex;gap:1.1rem;margin-bottom:var(--pfx-field-gap, 1.1rem);transition:all .2s ease;border-radius:6px;position:relative}.praxis-dynamic-form.pfx-mounting .form-row{opacity:0;transform:translateY(var(--pdx-form-mount-offset, 6px));animation:pdxFormMount var(--pdx-form-mount-duration, .16s) ease-out both;animation-delay:calc(var(--pfx-mount-index, 0) * var(--pdx-form-mount-stagger, 20ms))}@media(prefers-reduced-motion:reduce){.praxis-dynamic-form.pfx-mounting .form-row{animation:none;opacity:1;transform:none}}@keyframes pdxFormMount{to{opacity:1;transform:translateY(0)}}.praxis-dynamic-form .mat-mdc-form-field{width:100%;margin-bottom:var(--pfx-field-gap, 10px);font-family:inherit;--mdc-filled-text-field-container-color: var(--pfx-form-field-surface-rest);--mdc-filled-text-field-focus-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-active-indicator-color: var(--pfx-editorial-form-field-outline);--mdc-filled-text-field-hover-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-filled-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-caret-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-input-text-placeholder-color: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 82%, transparent );--mdc-outlined-text-field-outline-color: var(--pfx-editorial-form-field-outline);--mdc-outlined-text-field-hover-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-outlined-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-outlined-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-filled-text-field-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-filled-text-field-focus-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-outline-width: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-focus-outline-width: var(--pfx-editorial-form-field-border-width);--mat-select-enabled-trigger-text-color: var(--pfx-editorial-form-text);--mat-select-enabled-arrow-color: var(--pfx-form-label-muted);--mat-form-field-enabled-select-arrow-color: var(--pfx-form-label-muted);--mat-form-field-focus-select-arrow-color: var(--pfx-editorial-form-accent);--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field{font-family:var(--editorial-body-font-family, inherit)}.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{background:var(--pfx-form-field-surface-rest);border-radius:var(--pfx-editorial-form-field-radius);min-height:var(--pfx-form-field-min-height);transition:background-color .16s ease,box-shadow .16s ease,border-color .16s ease}.praxis-dynamic-form.editorial-visual-context .mat-mdc-text-field-wrapper,.praxis-dynamic-form.editorial-visual-context .mdc-text-field,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--filled,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--outlined{background-color:var(--pfx-form-field-surface-rest)!important;background:var(--pfx-form-field-surface-rest)!important}.praxis-dynamic-form .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-form-label-muted)}.praxis-dynamic-form .mat-mdc-input-element,.praxis-dynamic-form .mat-mdc-select-value-text,.praxis-dynamic-form .mat-mdc-form-field-infix,.praxis-dynamic-form .mat-mdc-select-min-line{color:var(--pfx-editorial-form-text)}.praxis-dynamic-form .mat-mdc-form-field:hover .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field:hover .mdc-text-field,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mdc-text-field{background:var(--pfx-form-field-surface-focus)}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-value-text,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field-infix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-min-line,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input{color:var(--pfx-editorial-form-text)!important;-webkit-text-fill-color:var(--pfx-editorial-form-text)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-editorial-form-text-muted)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 68%,transparent)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element::placeholder,.praxis-dynamic-form.editorial-visual-context textarea.mat-mdc-input-element::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 58%,transparent)!important}.praxis-dynamic-form .mat-mdc-radio-button,.praxis-dynamic-form .mat-mdc-checkbox,.praxis-dynamic-form .mat-mdc-slide-toggle{--mdc-radio-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-checkmark-color: var(--pfx-editorial-form-accent-text);--mdc-checkbox-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-focus-state-layer-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-handle-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-track-color: color-mix(in srgb, var(--pfx-editorial-form-accent) 45%, #fff)}.praxis-dynamic-form [data-field-type=input],.praxis-dynamic-form [data-field-type=textarea],.praxis-dynamic-form [data-field-type=email],.praxis-dynamic-form [data-field-type=password],.praxis-dynamic-form [data-field-type=url],.praxis-dynamic-form [data-field-type=search],.praxis-dynamic-form [data-field-type=phone],.praxis-dynamic-form [data-field-type=numericTextBox],.praxis-dynamic-form [data-field-type=currency],.praxis-dynamic-form [data-field-type=cpfCnpj],.praxis-dynamic-form [data-field-type=date],.praxis-dynamic-form [data-field-type=dateInput],.praxis-dynamic-form [data-field-type=dateRange],.praxis-dynamic-form [data-field-type=dateTimeLocal],.praxis-dynamic-form [data-field-type=time],.praxis-dynamic-form [data-field-type=timePicker],.praxis-dynamic-form [data-field-type=timeRange],.praxis-dynamic-form [data-field-type=month],.praxis-dynamic-form [data-field-type=week],.praxis-dynamic-form [data-field-type=yearInput],.praxis-dynamic-form [data-field-type=select],.praxis-dynamic-form [data-field-type=multi-select],.praxis-dynamic-form [data-field-type=searchable-select],.praxis-dynamic-form [data-field-type=async-select],.praxis-dynamic-form [data-field-type=autocomplete],.praxis-dynamic-form [data-field-type=tree-select],.praxis-dynamic-form [data-field-type=multi-select-tree],.praxis-dynamic-form [data-field-type=priceRange],.praxis-dynamic-form [data-field-type=file-upload]{display:block;width:100%;min-width:0}.praxis-dynamic-form .mat-mdc-form-field-subscript-wrapper{min-height:var(--pfx-subscript-min-h, 22px)}.form-row:last-child{margin-bottom:0}.form-column{display:grid;align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media(max-width:768px){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:14px}}.section-title{display:flex;align-items:center;gap:8px}.section-title .section-title-icon{font-size:1.25em;line-height:1}.section-title-avatar{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-form-section-avatar-size);height:var(--_pfx-form-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-form-section-avatar-size);overflow:hidden}.section-title-avatar.size-sm{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-title-avatar.size-md{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-title-avatar.size-lg{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-title-avatar-image{object-fit:cover;border:1px solid color-mix(in srgb,var(--pfx-form-section-divider) 72%,transparent);background:var(--pfx-form-section-surface-flat)}.section-title-avatar-text,.section-title-avatar-placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent) 14%,var(--pfx-form-section-surface-flat));color:color-mix(in srgb,var(--pfx-editorial-form-accent) 82%,var(--pfx-form-label-strong) 18%);font-size:calc(var(--_pfx-form-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-title-avatar-placeholder mat-icon{font-size:calc(var(--_pfx-form-section-avatar-size) * .5625);width:calc(var(--_pfx-form-section-avatar-size) * .5625);height:calc(var(--_pfx-form-section-avatar-size) * .5625);line-height:calc(var(--_pfx-form-section-avatar-size) * .5625)}.section-title-avatar-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
|
|
11267
|
+
], template: "@if (isLoading) {\n<!-- Loading State -->\n<div class=\"form-loading\">\n <mat-progress-spinner diameter=\"40\"></mat-progress-spinner>\n <p>Carregando formul\u00E1rio...</p>\n</div>\n} @else if (initializationStatus === 'error') {\n<!-- Error State -->\n<div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n</div>\n} @else if (initializationStatus === 'success') {\n<!-- Inline banner for schema change (only when customization is enabled) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n</div>\n}\n\n<!-- Configuration Controls -->\n@if (shouldShowConfigControls && enableCustomization) {\n<div class=\"form-config-controls\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n <button type=\"button\" mat-icon-button (click)=\"openConfigEditor()\" [disabled]=\"isLoading\" class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\" [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\">\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\">\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n}\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\n<praxis-empty-state-card icon=\"link\" [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"></praxis-empty-state-card>\n}\n<form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\" [class.readonly-mode]=\"effectiveReadonly\"\n [class.editorial-visual-context]=\"hasEditorialVisualContext()\"\n [class.pfx-mounting]=\"isMounting\" [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\" [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n [style.--pdx-form-mount-duration]=\"getMountDurationVar()\"\n [style.--pdx-form-mount-offset]=\"getMountOffsetVar()\"\n [style.--pdx-form-mount-stagger]=\"getMountStaggerVar()\"\n class=\"praxis-dynamic-form\">\n <praxis-canvas-toolbar (editMetadata)=\"openSelectedElementEditor()\" (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\" (moveDown)=\"onToolbarMove('down')\" (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\" (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\" (requestClose)=\"onToolbarRequestClose()\"\n *ngIf=\"enableCustomization && selectedElement\" [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\n\n @if (formBlocksBefore.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n @for (block of formBlocksBefore; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('before', $event)\">\n </ng-container>\n }\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"config.actions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @for (section of config.sections; track (section.id ?? $index); let sectionIndex = $index;\n let last = $last) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n @if (isSectionVisible(section)) {\n <div #sectionEl class=\"form-section canvas-element\" data-canvas-type=\"section\" [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\" (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [attr.data-section-appearance]=\"getSectionAppearance(section) || null\"\n [style.marginBottom.px]=\"!last ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(section)\">\n <div\n class=\"section-heading\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [class.step-appearance]=\"getSectionAppearance(section) === 'step'\"\n >\n <div class=\"section-heading-text\" [matTooltip]=\"getSectionHeaderTooltip(section) || null\"\n [matTooltipDisabled]=\"!getSectionHeaderTooltip(section)\">\n @if (getSectionStepLabel(section)) {\n <div class=\"section-step-label\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionStepLabel(section) }}\n </div>\n }\n @if (getSectionTitle(section)) {\n <h3 class=\"section-title\" [class.title-large]=\"getSectionTitleStyle(section) === 'titleLarge'\"\n [class.title-medium]=\"getSectionTitleStyle(section) === 'titleMedium'\"\n [class.title-small]=\"getSectionTitleStyle(section) === 'titleSmall'\"\n [class.headline-small]=\"getSectionTitleStyle(section) === 'headlineSmall'\"\n [style.marginBottom.px]=\"getSectionTitleGapBottom(section) ?? 20\" [style.color]=\"getSectionTitleColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [attr.id]=\"sectionPanelId(section, sectionIndex) + '-title'\">\n @let sectionHeaderVisual = getSectionHeaderVisual(section);\n @let sectionHeaderAvatarSize = getSectionHeaderAvatarSize(section);\n @if (sectionHeaderVisual.kind === 'icon') {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.kind === 'image') {\n <img class=\"section-title-avatar section-title-avatar-image\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\"\n [src]=\"sectionHeaderVisual.src\" [alt]=\"sectionHeaderVisual.alt\" />\n }\n @if (sectionHeaderVisual.kind === 'initials') {\n <span class=\"section-title-avatar section-title-avatar-text\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n {{ sectionHeaderVisual.text }}\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n @if (sectionHeaderVisual.kind === 'placeholder') {\n <span class=\"section-title-avatar section-title-avatar-placeholder\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n @if (sectionHeaderVisual.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.text) {\n <span>{{ sectionHeaderVisual.text }}</span>\n }\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n {{ getSectionTitle(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" mat-icon-button (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n </h3>\n }\n @if (getSectionDescription(section)) {\n <p class=\"section-description\" [class.body-large]=\"getSectionDescriptionStyle(section) === 'bodyLarge'\"\n [class.body-medium]=\"getSectionDescriptionStyle(section) === 'bodyMedium'\"\n [class.body-small]=\"getSectionDescriptionStyle(section) === 'bodySmall'\"\n [style.marginBottom.px]=\"getSectionDescriptionGapBottom(section) ?? 8\" [style.color]=\"getSectionDescriptionColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionDescription(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" mat-icon-button\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n <mat-icon>edit</mat-icon>\n </button>\n }\n </p>\n }\n </div>\n @if (getSectionHeaderActions(section).length) {\n <div class=\"section-heading-actions\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n @for (action of getSectionHeaderActions(section); track action.id) {\n <button\n type=\"button\"\n class=\"section-heading-action-btn\"\n mat-icon-button\n [color]=\"getSectionHeaderActionColor(action)\"\n [disabled]=\"isSectionHeaderActionDisabled(action)\"\n [matTooltip]=\"getSectionHeaderActionTooltip(action)\"\n [attr.aria-label]=\"action.label\"\n [attr.aria-busy]=\"action.loading ? 'true' : null\"\n [ngClass]=\"getSectionHeaderActionNgClass(action)\"\n [ngStyle]=\"getSectionHeaderActionStyles(action)\"\n (click)=\"onSectionHeaderActionClick(section, action, $event)\"\n >\n @if (action.loading) {\n <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\"></mat-progress-spinner>\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\"></mat-icon>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" mat-icon-button\n (click)=\"toggleSectionCollapse($event, section)\" [attr.aria-expanded]=\"!isSectionCollapsed(section)\"\n [attr.aria-controls]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-label]=\"isSectionCollapsed(section) ? 'Expandir se\u00E7\u00E3o' : 'Recolher se\u00E7\u00E3o'\">\n <mat-icon [praxisIcon]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\"></mat-icon>\n </button>\n }\n </div>\n\n <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-labelledby]=\"getSectionTitle(section) ? sectionPanelId(section, sectionIndex) + '-title' : null\">\n @if (!isSectionCollapsed(section)) {\n @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n @if (isRowVisible(row)) {\n <div class=\"row-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n <div #rowEl class=\"form-row grid-12 canvas-element\" data-canvas-type=\"row\" [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\" [style.--pfx-grid-gap.px]=\"getRowGap(row)\"\n [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [style.--pfx-mount-index]=\"rowIndex\"\n [style.marginBottom.px]=\"rowIndex < section.rows.length - 1 ? (getRowRowGap(row) ?? null) : null\"\n [ngClass]=\"getRowClasses(row)\" [ngStyle]=\"getRowStyles(row)\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\" (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\" [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\">\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div class=\"column-drop-wrapper\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\">\n <div #colEl class=\"form-column canvas-element\" [ngClass]=\"getColumnClasses(column)\"\n [style.padding.px]=\"getColumnPadding(column)\" [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [ngStyle]=\"getColumnStyles(column)\" [attr.data-testid]=\"column.testId || null\"\n [attr.data-row-gap]=\"getRowRowGap(row)\" data-canvas-type=\"column\" [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\" (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\">\n <ng-container dynamicFieldLoader [fields]=\"getColumnFields(column)\" [formGroup]=\"form\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"disabledModeGlobal === null ? null : disabledModeGlobal\"\n [presentationMode]=\"presentationForLoader\" [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"enableCustomization\" (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\" (canvasClick)=\"onFieldClick($event)\"\n (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n </div>\n </div>\n } }\n </div>\n </div>\n }\n }\n } @else {\n <div class=\"section-collapsed-placeholder\">\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'unfold_more'\"></mat-icon>\n <span>{{ getSectionCollapsedSummary(section) }}</span>\n </div>\n }\n @if (last && beforeActionsPlacement === 'insideLastSection' && formBlocksBeforeActions.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n @for (block of formBlocksBeforeActions; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('beforeActions', $event)\">\n </ng-container>\n }\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"config.actions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n </div>\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner diameter=\"40\" color=\"primary\"></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n\n @if (enableCustomization && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button mat-fab color=\"primary\" aria-label=\"Adicionar nova se\u00E7\u00E3o\" (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n }\n }\n </div>\n }\n\n @if (beforeActionsPlacement !== 'insideLastSection' && formBlocksBeforeActions.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n @for (block of formBlocksBeforeActions; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('beforeActions', $event)\">\n </ng-container>\n }\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"config.actions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"form.valid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n @for (block of formBlocksAfter; track (block.id ?? $index)) {\n <ng-container\n [dynamicWidgetLoader]=\"block\"\n [context]=\"getEditorialWidgetContext()\"\n [strictValidation]=\"true\"\n [autoWireOutputs]=\"true\"\n (widgetEvent)=\"onEditorialWidgetEvent('after', $event)\">\n </ng-container>\n }\n </section>\n }\n</form>\n@if (!enableCustomization && mode === 'view') {\n<div class=\"ai-floating-assistant\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n</div>\n}\n}\n", styles: ["@charset \"UTF-8\";.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@media(min-width:600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@media(min-width:900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@media(min-width:1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@media(min-width:1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: var(--md-sys-color-secondary)}.canvas-mode-enabled .canvas-element[data-canvas-type=column],.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: var(--md-sys-color-tertiary)}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:solid;box-shadow:0 0 0 2px var(--outline-color, var(--md-sys-color-primary))}.canvas-mode-enabled .canvas-element.hovered{z-index:1000}.canvas-mode-enabled .canvas-element.selected{z-index:2000}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:500}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}:host{display:block;position:relative}.form-config-controls{position:sticky;top:10px;margin-left:auto;margin-bottom:10px;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--md-sys-color-surface) 92%,transparent);padding:6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);border-radius:999px;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 10px 22px #0f172a14;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.88;transition:opacity .16s ease,box-shadow .16s ease,border-color .16s ease,transform .16s ease}.form-config-controls>*{pointer-events:auto}.praxis-dynamic-form:hover .form-config-controls,.praxis-dynamic-form:focus-within .form-config-controls{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%);box-shadow:0 14px 28px #0f172a1f;transform:translateY(-1px)}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 34px;width:34px;height:34px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);border:1px solid transparent}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent)}.ai-floating-assistant{position:sticky;right:0;bottom:12px;margin-top:14px;margin-left:auto;width:fit-content;z-index:70;pointer-events:none}.ai-floating-assistant praxis-ai-assistant{pointer-events:auto;display:inline-flex}.ai-floating-assistant .ai-trigger-btn{box-shadow:0 12px 28px #0f172a24}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-on-surface);gap:1rem}.form-loading p{margin:0;font-size:.875rem;opacity:.7}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem;box-shadow:0 12px 30px #7f1d1d1f}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.pfx-form-info-banner{margin-bottom:14px;padding:12px 14px;border-radius:16px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant) 82%);background:color-mix(in srgb,var(--md-sys-color-primary-container) 24%,var(--md-sys-color-surface) 76%);color:var(--md-sys-color-on-surface);display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.pfx-form-info-banner .text{font-size:.92rem;line-height:1.5;font-weight:600}.pfx-form-info-banner .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.praxis-dynamic-form{display:flex;flex-direction:column;transition:all .3s ease;position:relative;font-family:inherit;font-size:inherit;color:inherit;--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--md-sys-color-surface-container) );--pfx-editorial-form-surface-muted: var(--md-sys-color-surface-container-low);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--md-sys-color-outline-variant) );--pfx-editorial-form-text: var(--md-sys-color-on-surface);--pfx-editorial-form-text-muted: var(--md-sys-color-on-surface-variant);--pfx-editorial-form-field-surface: color-mix( in srgb, var(--pfx-editorial-form-surface-muted) 76%, var(--pfx-editorial-form-surface) 24% );--pfx-editorial-form-field-outline: color-mix( in srgb, var(--pfx-editorial-form-border) 88%, transparent );--pfx-editorial-form-accent: var(--md-sys-color-primary);--pfx-editorial-form-accent-text: var(--md-sys-color-on-primary);--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-field-radius: var(--pfx-form-field-radius, 4px);--pfx-editorial-form-border-width: 1px;--pfx-editorial-form-field-border-width: 1px;--pfx-editorial-form-shadow: none;--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-surface-flat: color-mix( in srgb, var(--pfx-editorial-form-surface) 78%, var(--pfx-editorial-form-surface-muted) 22% );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-label-strong: color-mix( in srgb, var(--pfx-editorial-form-text) 96%, white 4% );--pfx-form-label-muted: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 92%, var(--pfx-editorial-form-text) 8% );--pfx-form-field-surface-rest: color-mix( in srgb, var(--pfx-editorial-form-field-surface) 82%, var(--pfx-editorial-form-surface) 18% );--pfx-form-field-surface-focus: color-mix( in srgb, var(--pfx-editorial-form-accent) 4%, var(--pfx-form-field-surface-rest) 96% );--pfx-form-field-min-height: 48px;--pfx-form-section-padding: clamp(1.1rem, 1.8vw, 1.5rem);--pfx-form-section-gap: 22px;--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent )}.praxis-dynamic-form.editorial-visual-context{font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--editorial-text-primary, var(--md-sys-color-on-surface));--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--md-sys-color-primary)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--md-sys-color-on-primary)) );--pfx-editorial-form-radius: var(--editorial-card-radius, 18px);--pfx-editorial-form-field-radius: var( --editorial-field-radius, var(--editorial-card-radius, 14px) );--pfx-editorial-form-border-width: var(--editorial-card-border-width, 1px);--pfx-editorial-form-field-border-width: var(--editorial-field-border-width, 1px);--pfx-editorial-form-shadow: var(--editorial-card-shadow, none);--md-sys-color-surface: var( --pfx-editorial-form-surface, var(--md-sys-color-surface) );--md-sys-color-surface-container: var( --pfx-editorial-form-surface, var(--md-sys-color-surface-container) );--md-sys-color-surface-container-low: var( --pfx-editorial-form-surface-muted, var(--md-sys-color-surface-container-low) );--md-sys-color-surface-variant: var( --pfx-editorial-form-field-surface, var(--md-sys-color-surface-variant) );--md-sys-color-outline: var( --pfx-editorial-form-field-outline, var(--md-sys-color-outline) );--md-sys-color-outline-variant: var( --pfx-editorial-form-border, var(--md-sys-color-outline-variant) );--md-sys-color-on-surface: var( --pfx-editorial-form-text, var(--md-sys-color-on-surface) );--md-sys-color-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant) );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--md-sys-color-on-primary: var( --pfx-editorial-form-accent-text, var(--md-sys-color-on-primary) );--md-sys-color-on-surface-rgb: var( --editorial-text-primary-rgb, var(--md-sys-color-on-surface-rgb) );--mat-sys-on-surface: var( --pfx-editorial-form-text, var(--mat-sys-on-surface) );--mat-sys-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--mat-sys-on-surface-variant) );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, var(--mat-sys-on-surface-rgb, var(--md-sys-color-on-surface-rgb)) );color:var(--pfx-editorial-form-text);color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);box-shadow:none;transition:all .2s ease;position:relative}.praxis-dynamic-form.editorial-visual-context .form-section{border:var(--pfx-editorial-form-border-width) solid var(--pfx-editorial-form-border)!important;background:var(--pfx-editorial-form-surface)!important;box-shadow:var(--editorial-card-shadow, none)}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{background-color:var(--pfx-editorial-form-surface)!important;background-image:linear-gradient(180deg,color-mix(in srgb,var(--editorial-accent, var(--md-sys-color-primary)) 6%,transparent) 0%,transparent 132px)!important;background-repeat:no-repeat!important}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}.section-title{margin:0 0 var(--pfx-section-title-mb, 12px) 0;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-size:var(--editorial-step-title-size, 1.12rem);font-weight:700;color:var(--pfx-form-label-strong)}.section-heading{display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--pfx-form-section-divider)}.section-heading.align-center{flex-direction:column;align-items:center;text-align:center}.section-heading.align-center .section-heading-text{display:grid;justify-items:center}.section-step-label{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;margin:0 0 8px;border-radius:999px;background:color-mix(in srgb,var(--pfx-editorial-form-accent) 10%,transparent);color:color-mix(in srgb,var(--pfx-editorial-form-accent) 84%,var(--pfx-form-label-strong) 16%);font-size:.72rem;font-weight:800;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));letter-spacing:.08em;text-transform:uppercase}.section-heading-text{flex:1 1 auto;min-width:0}.section-heading-actions{display:inline-flex;align-items:center;align-self:flex-start;flex-wrap:wrap;gap:4px;margin-left:auto}.section-heading-actions.align-center{align-self:center;margin-left:0}.section-heading-action-btn{color:var(--pfx-form-label-muted)}.section-heading-action-btn .mat-mdc-progress-spinner,.section-heading-action-btn mat-progress-spinner{--mdc-circular-progress-active-indicator-color: currentColor}.section-heading-action-btn.loading{opacity:.72;pointer-events:none}.section-heading-action-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.section-collapse-btn{margin-left:4px;color:var(--pfx-form-label-muted)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-title.title-large,.section-title.title-medium,.section-title.title-small,.section-title.headline-small{font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-weight:var(--editorial-title-weight, 600)}.section-description{margin:0;font-family:var(--editorial-body-font-family, inherit);font-size:.93rem;color:var(--pfx-form-label-muted);line-height:1.6}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.section-description.body-large,.section-description.body-medium,.section-description.body-small{font-family:var(--editorial-body-font-family, inherit);font-weight:var(--editorial-body-weight, 400)}.section-title.align-center,.section-description.align-center,.section-step-label.align-center{text-align:center}.form-section.section-appearance-plain{border-color:transparent;border-radius:0;padding:0;background:transparent}.form-section.section-appearance-plain .section-heading{margin-bottom:14px}.form-section.section-appearance-step{border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);border-color:var(--pfx-form-section-divider);box-shadow:none}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{border-radius:var(--editorial-card-radius, 20px);box-shadow:none}.form-section.section-appearance-step .section-heading{margin-bottom:22px;padding-bottom:16px;border-bottom:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .section-title{font:var(--mdc-typography-title-large, 700 22px/28px system-ui);color:var(--pfx-form-label-strong);margin-bottom:8px}.form-section.section-appearance-step .section-description{color:var(--pfx-form-label-muted);max-width:60ch}.form-section.section-appearance-step .section-step-label{min-height:24px;padding:0 10px;margin-bottom:10px;box-shadow:none}.form-section.section-appearance-step .section-heading.align-center .section-description{max-width:52ch}.form-section.section-appearance-step .section-body{display:grid;gap:8px;padding-top:0}.form-section.section-appearance-step .form-row{margin-bottom:var(--pfx-field-gap, 1rem)}.form-section.section-appearance-step .form-column{gap:var(--pfx-field-gap, 12px)}.form-section .form-editorial-blocks{display:grid;gap:16px}.form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{margin-top:24px;padding-top:18px;border-top:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]{gap:18px}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]>*+*{margin-top:2px}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:18px;padding-top:0}.praxis-dynamic-form>.form-editorial-blocks[data-editorial-placement=after]{margin-top:6px}:host-context(.mdc-theme-dark) .form-section.section-appearance-step,:host-context(.theme-dark) .form-section.section-appearance-step{border-color:color-mix(in srgb,var(--pfx-editorial-form-border) 82%,transparent);box-shadow:none}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-title,:host-context(.theme-dark) .form-section.section-appearance-step .section-title{color:color-mix(in srgb,var(--pfx-editorial-form-text) 96%,white)}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-description,:host-context(.theme-dark) .form-section.section-appearance-step .section-description{color:color-mix(in srgb,var(--pfx-editorial-form-text-muted) 86%,var(--pfx-editorial-form-text) 14%)}:host-context(.mdc-theme-dark) .section-step-label,:host-context(.theme-dark) .section-step-label{background:color-mix(in srgb,var(--md-sys-color-primary-container) 54%,transparent);color:color-mix(in srgb,var(--md-sys-color-primary) 88%,white)}:host-context(.mdc-theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions],:host-context(.theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{border-top-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 90%,transparent)}.inline-edit-btn{margin-left:6px;vertical-align:middle;--mdc-icon-button-size: 28px;--mdc-icon-button-icon-size: 16px}.inline-edit-btn mat-icon{font-size:16px;width:16px;height:16px}.section-body.collapsed{border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);border-radius:6px;padding:8px 10px}.section-collapsed-placeholder{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:.95rem}.section-collapsed-placeholder mat-icon{font-size:20px;width:20px;height:20px}.form-row{display:flex;gap:1.1rem;margin-bottom:var(--pfx-field-gap, 1.1rem);transition:all .2s ease;border-radius:6px;position:relative}.praxis-dynamic-form.pfx-mounting .form-row{opacity:0;transform:translateY(var(--pdx-form-mount-offset, 6px));animation:pdxFormMount var(--pdx-form-mount-duration, .16s) ease-out both;animation-delay:calc(var(--pfx-mount-index, 0) * var(--pdx-form-mount-stagger, 20ms))}@media(prefers-reduced-motion:reduce){.praxis-dynamic-form.pfx-mounting .form-row{animation:none;opacity:1;transform:none}}@keyframes pdxFormMount{to{opacity:1;transform:translateY(0)}}.praxis-dynamic-form .mat-mdc-form-field{width:100%;margin-bottom:var(--pfx-field-gap, 10px);font-family:inherit;--mdc-filled-text-field-container-color: var(--pfx-form-field-surface-rest);--mdc-filled-text-field-focus-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-active-indicator-color: var(--pfx-editorial-form-field-outline);--mdc-filled-text-field-hover-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-filled-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-caret-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-input-text-placeholder-color: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 82%, transparent );--mdc-outlined-text-field-outline-color: var(--pfx-editorial-form-field-outline);--mdc-outlined-text-field-hover-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-outlined-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-outlined-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-filled-text-field-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-filled-text-field-focus-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-outline-width: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-focus-outline-width: var(--pfx-editorial-form-field-border-width);--mat-select-enabled-trigger-text-color: var(--pfx-editorial-form-text);--mat-select-enabled-arrow-color: var(--pfx-form-label-muted);--mat-form-field-enabled-select-arrow-color: var(--pfx-form-label-muted);--mat-form-field-focus-select-arrow-color: var(--pfx-editorial-form-accent);--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field{font-family:var(--editorial-body-font-family, inherit)}.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{background:var(--pfx-form-field-surface-rest);border-radius:var(--pfx-editorial-form-field-radius);min-height:var(--pfx-form-field-min-height);transition:background-color .16s ease,box-shadow .16s ease,border-color .16s ease}.praxis-dynamic-form.editorial-visual-context .mat-mdc-text-field-wrapper,.praxis-dynamic-form.editorial-visual-context .mdc-text-field,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--filled,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--outlined{background-color:var(--pfx-form-field-surface-rest)!important;background:var(--pfx-form-field-surface-rest)!important}.praxis-dynamic-form .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-form-label-muted)}.praxis-dynamic-form .mat-mdc-input-element,.praxis-dynamic-form .mat-mdc-select-value-text,.praxis-dynamic-form .mat-mdc-form-field-infix,.praxis-dynamic-form .mat-mdc-select-min-line{color:var(--pfx-editorial-form-text)}.praxis-dynamic-form .mat-mdc-form-field:hover .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field:hover .mdc-text-field,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mdc-text-field{background:var(--pfx-form-field-surface-focus)}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-value-text,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field-infix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-min-line,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input{color:var(--pfx-editorial-form-text)!important;-webkit-text-fill-color:var(--pfx-editorial-form-text)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-editorial-form-text-muted)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 68%,transparent)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element::placeholder,.praxis-dynamic-form.editorial-visual-context textarea.mat-mdc-input-element::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 58%,transparent)!important}.praxis-dynamic-form .mat-mdc-radio-button,.praxis-dynamic-form .mat-mdc-checkbox,.praxis-dynamic-form .mat-mdc-slide-toggle{--mdc-radio-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-checkmark-color: var(--pfx-editorial-form-accent-text);--mdc-checkbox-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-focus-state-layer-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-handle-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-track-color: color-mix(in srgb, var(--pfx-editorial-form-accent) 45%, #fff)}.praxis-dynamic-form [data-field-type=input],.praxis-dynamic-form [data-field-type=textarea],.praxis-dynamic-form [data-field-type=email],.praxis-dynamic-form [data-field-type=password],.praxis-dynamic-form [data-field-type=url],.praxis-dynamic-form [data-field-type=search],.praxis-dynamic-form [data-field-type=phone],.praxis-dynamic-form [data-field-type=numericTextBox],.praxis-dynamic-form [data-field-type=currency],.praxis-dynamic-form [data-field-type=cpfCnpj],.praxis-dynamic-form [data-field-type=date],.praxis-dynamic-form [data-field-type=dateInput],.praxis-dynamic-form [data-field-type=dateRange],.praxis-dynamic-form [data-field-type=dateTimeLocal],.praxis-dynamic-form [data-field-type=time],.praxis-dynamic-form [data-field-type=timePicker],.praxis-dynamic-form [data-field-type=timeRange],.praxis-dynamic-form [data-field-type=month],.praxis-dynamic-form [data-field-type=week],.praxis-dynamic-form [data-field-type=yearInput],.praxis-dynamic-form [data-field-type=select],.praxis-dynamic-form [data-field-type=multi-select],.praxis-dynamic-form [data-field-type=searchable-select],.praxis-dynamic-form [data-field-type=async-select],.praxis-dynamic-form [data-field-type=autocomplete],.praxis-dynamic-form [data-field-type=tree-select],.praxis-dynamic-form [data-field-type=multi-select-tree],.praxis-dynamic-form [data-field-type=priceRange],.praxis-dynamic-form [data-field-type=file-upload]{display:block;width:100%;min-width:0}.praxis-dynamic-form .mat-mdc-form-field-subscript-wrapper{min-height:var(--pfx-subscript-min-h, 22px)}.form-row:last-child{margin-bottom:0}.form-column{display:grid;align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media(max-width:768px){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:14px}}.section-title{display:flex;align-items:center;gap:8px}.section-title .section-title-icon{font-size:1.25em;line-height:1}.section-title-avatar{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-form-section-avatar-size);height:var(--_pfx-form-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-form-section-avatar-size);overflow:hidden}.section-title-avatar.size-sm{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-title-avatar.size-md{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-title-avatar.size-lg{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-title-avatar-image{object-fit:cover;border:1px solid color-mix(in srgb,var(--pfx-form-section-divider) 72%,transparent);background:var(--pfx-form-section-surface-flat)}.section-title-avatar-text,.section-title-avatar-placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent) 14%,var(--pfx-form-section-surface-flat));color:color-mix(in srgb,var(--pfx-editorial-form-accent) 82%,var(--pfx-form-label-strong) 18%);font-size:calc(var(--_pfx-form-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-title-avatar-placeholder mat-icon{font-size:calc(var(--_pfx-form-section-avatar-size) * .5625);width:calc(var(--_pfx-form-section-avatar-size) * .5625);height:calc(var(--_pfx-form-section-avatar-size) * .5625);line-height:calc(var(--_pfx-form-section-avatar-size) * .5625)}.section-title-avatar-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
|
|
11079
11268
|
}], ctorParameters: () => [{ type: i1$2.GenericCrudService }, { type: i1$3.FormBuilder }, { type: i0.ChangeDetectorRef }, { type: FormLayoutService }, { type: FormContextService }, { type: FormRulesService }, { type: i6$1.SettingsPanelService }, { type: i2.MatDialog }, { type: undefined, decorators: [{
|
|
11080
11269
|
type: Inject,
|
|
11081
11270
|
args: [ASYNC_CONFIG_STORAGE]
|
|
@@ -13765,11 +13954,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
13765
13954
|
type: Output
|
|
13766
13955
|
}] } });
|
|
13767
13956
|
|
|
13957
|
+
const ACTIONS_EDITOR_I18N_NAMESPACE = 'praxisDynamicFormActionsEditor';
|
|
13958
|
+
const ACTIONS_EDITOR_I18N_CONFIG = {
|
|
13959
|
+
namespaces: {
|
|
13960
|
+
[ACTIONS_EDITOR_I18N_NAMESPACE]: {
|
|
13961
|
+
'pt-BR': {
|
|
13962
|
+
'custom.variant': 'Variante',
|
|
13963
|
+
'custom.size': 'Tamanho',
|
|
13964
|
+
'custom.size.small': 'Pequeno',
|
|
13965
|
+
'custom.size.medium': 'Médio',
|
|
13966
|
+
'custom.size.large': 'Grande',
|
|
13967
|
+
'custom.tooltip': 'Tooltip',
|
|
13968
|
+
'custom.shortcut': 'Atalho de Teclado',
|
|
13969
|
+
'custom.shortcut.placeholder': 'Ex.: ctrl+shift+a',
|
|
13970
|
+
'custom.className': 'Classe CSS',
|
|
13971
|
+
'custom.disabled': 'Desabilitado',
|
|
13972
|
+
'custom.loading': 'Loading',
|
|
13973
|
+
'custom.style': 'Estilos do botão (JSON)',
|
|
13974
|
+
'custom.style.placeholder': '{"borderRadius":"999px"}',
|
|
13975
|
+
'custom.order.moveUp': 'Mover "{{label}}" para cima',
|
|
13976
|
+
'custom.order.moveDown': 'Mover "{{label}}" para baixo',
|
|
13977
|
+
'custom.order.moveUp.tooltip': 'Mover para cima',
|
|
13978
|
+
'custom.order.moveDown.tooltip': 'Mover para baixo',
|
|
13979
|
+
'custom.validation.invalidJson': 'JSON inválido.',
|
|
13980
|
+
'custom.validation.objectJson': 'Informe um objeto JSON válido.',
|
|
13981
|
+
},
|
|
13982
|
+
'en-US': {
|
|
13983
|
+
'custom.variant': 'Variant',
|
|
13984
|
+
'custom.size': 'Size',
|
|
13985
|
+
'custom.size.small': 'Small',
|
|
13986
|
+
'custom.size.medium': 'Medium',
|
|
13987
|
+
'custom.size.large': 'Large',
|
|
13988
|
+
'custom.tooltip': 'Tooltip',
|
|
13989
|
+
'custom.shortcut': 'Keyboard shortcut',
|
|
13990
|
+
'custom.shortcut.placeholder': 'Example: ctrl+shift+a',
|
|
13991
|
+
'custom.className': 'CSS class',
|
|
13992
|
+
'custom.disabled': 'Disabled',
|
|
13993
|
+
'custom.loading': 'Loading',
|
|
13994
|
+
'custom.style': 'Button styles (JSON)',
|
|
13995
|
+
'custom.style.placeholder': '{"borderRadius":"999px"}',
|
|
13996
|
+
'custom.order.moveUp': 'Move "{{label}}" up',
|
|
13997
|
+
'custom.order.moveDown': 'Move "{{label}}" down',
|
|
13998
|
+
'custom.order.moveUp.tooltip': 'Move up',
|
|
13999
|
+
'custom.order.moveDown.tooltip': 'Move down',
|
|
14000
|
+
'custom.validation.invalidJson': 'Invalid JSON.',
|
|
14001
|
+
'custom.validation.objectJson': 'Provide a valid JSON object.',
|
|
14002
|
+
},
|
|
14003
|
+
},
|
|
14004
|
+
},
|
|
14005
|
+
};
|
|
14006
|
+
|
|
13768
14007
|
let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
13769
14008
|
config;
|
|
13770
14009
|
configChange = new EventEmitter();
|
|
13771
14010
|
containerStylesText = '';
|
|
14011
|
+
customActionStyleTexts = new Map();
|
|
14012
|
+
customActionStyleErrors = new Map();
|
|
13772
14013
|
globalActionCatalogSource = inject(GLOBAL_ACTION_CATALOG, { optional: true }) ?? [];
|
|
14014
|
+
i18n = inject(PraxisI18nService);
|
|
13773
14015
|
legacyActionSpecs = GLOBAL_ACTION_SPEC_CATALOG;
|
|
13774
14016
|
globalActionCatalog = this.buildGlobalActionCatalog();
|
|
13775
14017
|
customActionValue = '__custom__';
|
|
@@ -13789,7 +14031,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
13789
14031
|
onGapTopInput(val) {
|
|
13790
14032
|
let num = Number(val);
|
|
13791
14033
|
if (!isFinite(num)) {
|
|
13792
|
-
// limpar volta ao
|
|
14034
|
+
// limpar volta ao padrão
|
|
13793
14035
|
const styles = { ...this.actions?.containerStyles };
|
|
13794
14036
|
if (styles) {
|
|
13795
14037
|
delete styles.marginTop;
|
|
@@ -13831,11 +14073,28 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
13831
14073
|
}
|
|
13832
14074
|
ngOnChanges() {
|
|
13833
14075
|
this.syncContainerStylesText();
|
|
14076
|
+
this.syncCustomActionStyleTexts();
|
|
13834
14077
|
}
|
|
13835
14078
|
syncContainerStylesText() {
|
|
13836
14079
|
const styles = this.config.actions?.containerStyles;
|
|
13837
14080
|
this.containerStylesText = styles ? JSON.stringify(styles, null, 2) : '';
|
|
13838
14081
|
}
|
|
14082
|
+
syncCustomActionStyleTexts() {
|
|
14083
|
+
const activeKeys = new Set();
|
|
14084
|
+
for (const [index, action] of (this.actions.custom || []).entries()) {
|
|
14085
|
+
const key = this.getCustomActionStyleKey(action, index);
|
|
14086
|
+
activeKeys.add(key);
|
|
14087
|
+
if (!this.customActionStyleTexts.has(key)) {
|
|
14088
|
+
this.customActionStyleTexts.set(key, this.stringifyJson(action.style));
|
|
14089
|
+
}
|
|
14090
|
+
}
|
|
14091
|
+
for (const key of Array.from(this.customActionStyleTexts.keys())) {
|
|
14092
|
+
if (!activeKeys.has(key)) {
|
|
14093
|
+
this.customActionStyleTexts.delete(key);
|
|
14094
|
+
this.customActionStyleErrors.delete(key);
|
|
14095
|
+
}
|
|
14096
|
+
}
|
|
14097
|
+
}
|
|
13839
14098
|
getActionSpecById(id) {
|
|
13840
14099
|
return this.globalActionCatalog.find((item) => item.id === id);
|
|
13841
14100
|
}
|
|
@@ -13918,19 +14177,47 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
13918
14177
|
}
|
|
13919
14178
|
return Array.from(merged.values());
|
|
13920
14179
|
}
|
|
14180
|
+
getActionCatalogLabel(spec) {
|
|
14181
|
+
if (spec?.id === 'surface.open') {
|
|
14182
|
+
return this.i18n.t('action.surfaceOpen.label', undefined, spec.label || '', SURFACE_OPEN_I18N_NAMESPACE);
|
|
14183
|
+
}
|
|
14184
|
+
return spec?.label || '';
|
|
14185
|
+
}
|
|
14186
|
+
tx(key, fallback, params) {
|
|
14187
|
+
return this.i18n.t(key, params, fallback, ACTIONS_EDITOR_I18N_NAMESPACE);
|
|
14188
|
+
}
|
|
14189
|
+
getCustomActionTitle(action) {
|
|
14190
|
+
return action.label || 'Novo Botão Customizado';
|
|
14191
|
+
}
|
|
14192
|
+
getMoveCustomActionAriaLabel(direction, action) {
|
|
14193
|
+
const key = direction === 'up' ? 'custom.order.moveUp' : 'custom.order.moveDown';
|
|
14194
|
+
const fallback = direction === 'up'
|
|
14195
|
+
? `Mover "${this.getCustomActionTitle(action)}" para cima`
|
|
14196
|
+
: `Mover "${this.getCustomActionTitle(action)}" para baixo`;
|
|
14197
|
+
return this.tx(key, fallback, { label: this.getCustomActionTitle(action) });
|
|
14198
|
+
}
|
|
14199
|
+
getCustomStylePlaceholder() {
|
|
14200
|
+
return this.tx('custom.style.placeholder', '{"borderRadius":"999px"}');
|
|
14201
|
+
}
|
|
14202
|
+
getActionCatalogDescription(spec) {
|
|
14203
|
+
if (spec?.id === 'surface.open') {
|
|
14204
|
+
return this.i18n.t('action.surfaceOpen.description', undefined, spec.description || '', SURFACE_OPEN_I18N_NAMESPACE);
|
|
14205
|
+
}
|
|
14206
|
+
return spec?.description || '';
|
|
14207
|
+
}
|
|
13921
14208
|
mapCatalogEntryToActionSpec(entry) {
|
|
13922
14209
|
const hasPayloadSchema = !!entry.payloadSchema;
|
|
13923
14210
|
return {
|
|
13924
14211
|
id: entry.id,
|
|
13925
|
-
label: entry
|
|
13926
|
-
description: entry
|
|
14212
|
+
label: this.getActionCatalogLabel(entry),
|
|
14213
|
+
description: this.getActionCatalogDescription(entry),
|
|
13927
14214
|
param: hasPayloadSchema
|
|
13928
14215
|
? {
|
|
13929
14216
|
label: 'Payload (JSON opcional)',
|
|
13930
14217
|
placeholder: entry.payloadSchema?.example
|
|
13931
14218
|
? JSON.stringify(entry.payloadSchema.example)
|
|
13932
14219
|
: '{ }',
|
|
13933
|
-
hint: 'Use JSON quando a
|
|
14220
|
+
hint: 'Use JSON quando a ação global do app exigir payload estruturado.',
|
|
13934
14221
|
required: !!entry.payloadSchema?.required?.length,
|
|
13935
14222
|
}
|
|
13936
14223
|
: undefined,
|
|
@@ -13942,6 +14229,16 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
13942
14229
|
return undefined;
|
|
13943
14230
|
return getGlobalActionUiSchema(parsed.id);
|
|
13944
14231
|
}
|
|
14232
|
+
getSurfaceOpenActionPayload(action) {
|
|
14233
|
+
const info = this.getActionParamInfo(action.action);
|
|
14234
|
+
const payload = info.isJson && info.json && typeof info.json === 'object' && !Array.isArray(info.json)
|
|
14235
|
+
? info.json
|
|
14236
|
+
: undefined;
|
|
14237
|
+
return this.normalizeSurfaceOpenPayload(payload);
|
|
14238
|
+
}
|
|
14239
|
+
onSurfaceOpenActionPayloadChange(action, payload, index) {
|
|
14240
|
+
this.updateCustomAction(index, 'action', `surface.open:${JSON.stringify(this.normalizeSurfaceOpenPayload(payload))}`);
|
|
14241
|
+
}
|
|
13945
14242
|
shouldShowGlobalActionField(action, field) {
|
|
13946
14243
|
if (!field.dependsOnKey)
|
|
13947
14244
|
return true;
|
|
@@ -14093,7 +14390,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14093
14390
|
this.clearActionFieldError(action, field.key);
|
|
14094
14391
|
}
|
|
14095
14392
|
catch {
|
|
14096
|
-
this.setActionFieldError(action, field.key, 'JSON
|
|
14393
|
+
this.setActionFieldError(action, field.key, 'JSON inválido.');
|
|
14097
14394
|
return;
|
|
14098
14395
|
}
|
|
14099
14396
|
}
|
|
@@ -14151,6 +14448,30 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14151
14448
|
return '';
|
|
14152
14449
|
}
|
|
14153
14450
|
}
|
|
14451
|
+
normalizeSurfaceOpenPayload(payload) {
|
|
14452
|
+
return {
|
|
14453
|
+
presentation: payload?.presentation === 'drawer' ? 'drawer' : 'modal',
|
|
14454
|
+
title: payload?.title,
|
|
14455
|
+
subtitle: payload?.subtitle,
|
|
14456
|
+
icon: payload?.icon,
|
|
14457
|
+
size: payload?.size && Object.keys(payload.size).length
|
|
14458
|
+
? { ...payload.size }
|
|
14459
|
+
: undefined,
|
|
14460
|
+
widget: {
|
|
14461
|
+
id: String(payload?.widget?.id || ''),
|
|
14462
|
+
inputs: { ...(payload?.widget?.inputs || {}) },
|
|
14463
|
+
bindingOrder: payload?.widget?.bindingOrder?.length
|
|
14464
|
+
? [...payload.widget.bindingOrder]
|
|
14465
|
+
: undefined,
|
|
14466
|
+
},
|
|
14467
|
+
bindings: payload?.bindings?.length
|
|
14468
|
+
? payload.bindings.map((binding) => ({ ...binding }))
|
|
14469
|
+
: [],
|
|
14470
|
+
context: payload?.context && typeof payload.context === 'object' && !Array.isArray(payload.context)
|
|
14471
|
+
? { ...payload.context }
|
|
14472
|
+
: undefined,
|
|
14473
|
+
};
|
|
14474
|
+
}
|
|
14154
14475
|
setActionFieldError(action, key, message) {
|
|
14155
14476
|
const draftKey = this.getActionDraftKey(action);
|
|
14156
14477
|
const errors = this.actionFieldErrors.get(draftKey) || {};
|
|
@@ -14479,11 +14800,14 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14479
14800
|
},
|
|
14480
14801
|
};
|
|
14481
14802
|
this.configChange.emit(newConfig);
|
|
14803
|
+
if (key === 'style') {
|
|
14804
|
+
this.syncCustomActionStyleTexts();
|
|
14805
|
+
}
|
|
14482
14806
|
}
|
|
14483
14807
|
addCustomButton() {
|
|
14484
14808
|
const newButton = {
|
|
14485
14809
|
id: `custom_${Date.now()}`,
|
|
14486
|
-
label: 'Novo
|
|
14810
|
+
label: 'Novo Botão',
|
|
14487
14811
|
visible: true,
|
|
14488
14812
|
color: 'basic',
|
|
14489
14813
|
action: `custom_action_${Date.now()}`,
|
|
@@ -14498,6 +14822,38 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14498
14822
|
};
|
|
14499
14823
|
this.configChange.emit(newConfig);
|
|
14500
14824
|
}
|
|
14825
|
+
canMoveCustomActionUp(index) {
|
|
14826
|
+
return index > 0;
|
|
14827
|
+
}
|
|
14828
|
+
canMoveCustomActionDown(index) {
|
|
14829
|
+
return index >= 0 && index < (this.actions.custom?.length || 0) - 1;
|
|
14830
|
+
}
|
|
14831
|
+
moveCustomActionUp(index) {
|
|
14832
|
+
this.reorderCustomAction(index, index - 1);
|
|
14833
|
+
}
|
|
14834
|
+
moveCustomActionDown(index) {
|
|
14835
|
+
this.reorderCustomAction(index, index + 1);
|
|
14836
|
+
}
|
|
14837
|
+
reorderCustomAction(fromIndex, toIndex) {
|
|
14838
|
+
const customActions = [...(this.actions.custom || [])];
|
|
14839
|
+
if (fromIndex < 0
|
|
14840
|
+
|| toIndex < 0
|
|
14841
|
+
|| fromIndex >= customActions.length
|
|
14842
|
+
|| toIndex >= customActions.length
|
|
14843
|
+
|| fromIndex === toIndex) {
|
|
14844
|
+
return;
|
|
14845
|
+
}
|
|
14846
|
+
const [moved] = customActions.splice(fromIndex, 1);
|
|
14847
|
+
customActions.splice(toIndex, 0, moved);
|
|
14848
|
+
const newConfig = {
|
|
14849
|
+
...this.config,
|
|
14850
|
+
actions: {
|
|
14851
|
+
...this.actions,
|
|
14852
|
+
custom: customActions,
|
|
14853
|
+
},
|
|
14854
|
+
};
|
|
14855
|
+
this.configChange.emit(newConfig);
|
|
14856
|
+
}
|
|
14501
14857
|
removeCustomButton(index) {
|
|
14502
14858
|
const customActions = [...(this.actions.custom || [])];
|
|
14503
14859
|
customActions.splice(index, 1);
|
|
@@ -14549,12 +14905,70 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14549
14905
|
// keep text; no update on parse error
|
|
14550
14906
|
}
|
|
14551
14907
|
}
|
|
14908
|
+
getCustomActionStyleText(action, index) {
|
|
14909
|
+
const key = this.getCustomActionStyleKey(action, index);
|
|
14910
|
+
if (this.customActionStyleTexts.has(key)) {
|
|
14911
|
+
return this.customActionStyleTexts.get(key) || '';
|
|
14912
|
+
}
|
|
14913
|
+
const text = this.stringifyJson(action.style);
|
|
14914
|
+
this.customActionStyleTexts.set(key, text);
|
|
14915
|
+
return text;
|
|
14916
|
+
}
|
|
14917
|
+
onCustomActionStyleTextChange(index, value) {
|
|
14918
|
+
const action = this.actions.custom?.[index];
|
|
14919
|
+
if (!action)
|
|
14920
|
+
return;
|
|
14921
|
+
const key = this.getCustomActionStyleKey(action, index);
|
|
14922
|
+
this.customActionStyleTexts.set(key, value);
|
|
14923
|
+
}
|
|
14924
|
+
applyCustomActionStyleText(action, index) {
|
|
14925
|
+
const key = this.getCustomActionStyleKey(action, index);
|
|
14926
|
+
const raw = (this.customActionStyleTexts.get(key) || '').trim();
|
|
14927
|
+
if (!raw) {
|
|
14928
|
+
this.customActionStyleErrors.delete(key);
|
|
14929
|
+
this.updateCustomAction(index, 'style', undefined);
|
|
14930
|
+
return;
|
|
14931
|
+
}
|
|
14932
|
+
try {
|
|
14933
|
+
const parsed = JSON.parse(raw);
|
|
14934
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
14935
|
+
this.customActionStyleErrors.set(key, this.tx('custom.validation.objectJson', 'Informe um objeto JSON válido.'));
|
|
14936
|
+
return;
|
|
14937
|
+
}
|
|
14938
|
+
this.customActionStyleErrors.delete(key);
|
|
14939
|
+
this.updateCustomAction(index, 'style', parsed);
|
|
14940
|
+
}
|
|
14941
|
+
catch {
|
|
14942
|
+
this.customActionStyleErrors.set(key, this.tx('custom.validation.invalidJson', 'JSON inválido.'));
|
|
14943
|
+
}
|
|
14944
|
+
}
|
|
14945
|
+
hasCustomActionStyleError(action, index) {
|
|
14946
|
+
const key = this.getCustomActionStyleKey(action, index);
|
|
14947
|
+
return this.customActionStyleErrors.has(key);
|
|
14948
|
+
}
|
|
14949
|
+
getCustomActionStyleError(action, index) {
|
|
14950
|
+
const key = this.getCustomActionStyleKey(action, index);
|
|
14951
|
+
return this.customActionStyleErrors.get(key) || '';
|
|
14952
|
+
}
|
|
14953
|
+
getCustomActionStyleKey(action, index) {
|
|
14954
|
+
return `custom:${action.id || action.action || action.label || `index-${index}`}`;
|
|
14955
|
+
}
|
|
14552
14956
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ActionsEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14553
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: ActionsEditorComponent, isStandalone: true, selector: "praxis-actions-editor", inputs: { config: "config" }, outputs: { configChange: "configChange" },
|
|
14957
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: ActionsEditorComponent, isStandalone: true, selector: "praxis-actions-editor", inputs: { config: "config" }, outputs: { configChange: "configChange" }, providers: [
|
|
14958
|
+
providePraxisI18nConfig(SURFACE_OPEN_I18N_CONFIG),
|
|
14959
|
+
providePraxisI18nConfig(ACTIONS_EDITOR_I18N_CONFIG),
|
|
14960
|
+
], usesOnChanges: true, ngImport: i0, template: `
|
|
14554
14961
|
<ng-template #globalActionFields let-action let-index="index">
|
|
14555
14962
|
@if (getGlobalActionSchema(action); as schema) {
|
|
14556
14963
|
<div class="action-global-fields">
|
|
14557
|
-
<div class="action-global-title">
|
|
14964
|
+
<div class="action-global-title">Configuração da ação global</div>
|
|
14965
|
+
@if (schema.editorMode === 'surface-open') {
|
|
14966
|
+
<praxis-surface-open-action-editor
|
|
14967
|
+
[value]="getSurfaceOpenActionPayload(action)"
|
|
14968
|
+
hostKind="form"
|
|
14969
|
+
(valueChange)="onSurfaceOpenActionPayloadChange(action, $event, index)"
|
|
14970
|
+
></praxis-surface-open-action-editor>
|
|
14971
|
+
} @else {
|
|
14558
14972
|
<div class="action-global-grid">
|
|
14559
14973
|
@for (field of schema.fields; track field.key) {
|
|
14560
14974
|
@if (shouldShowGlobalActionField(action, field)) {
|
|
@@ -14562,7 +14976,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14562
14976
|
<div class="action-section-title">Essencial</div>
|
|
14563
14977
|
}
|
|
14564
14978
|
@if (schema.id === 'showAlert' && field.key === 'title') {
|
|
14565
|
-
<div class="action-section-title">
|
|
14979
|
+
<div class="action-section-title">Diálogo (opcional)</div>
|
|
14566
14980
|
}
|
|
14567
14981
|
@if (field.type === 'toggle') {
|
|
14568
14982
|
<mat-slide-toggle
|
|
@@ -14621,7 +15035,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14621
15035
|
matSuffix
|
|
14622
15036
|
type="button"
|
|
14623
15037
|
class="help-icon-button"
|
|
14624
|
-
matTooltip="Informe um JSON
|
|
15038
|
+
matTooltip="Informe um JSON válido."
|
|
14625
15039
|
>
|
|
14626
15040
|
<mat-icon>help_outline</mat-icon>
|
|
14627
15041
|
</button>
|
|
@@ -14680,23 +15094,24 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14680
15094
|
}
|
|
14681
15095
|
}
|
|
14682
15096
|
</div>
|
|
15097
|
+
}
|
|
14683
15098
|
</div>
|
|
14684
15099
|
}
|
|
14685
15100
|
</ng-template>
|
|
14686
15101
|
<mat-tab-group>
|
|
14687
|
-
<mat-tab label="
|
|
15102
|
+
<mat-tab label="Botões Padrão">
|
|
14688
15103
|
<div class="editor-container">
|
|
14689
15104
|
<mat-accordion multi>
|
|
14690
15105
|
<mat-expansion-panel>
|
|
14691
15106
|
<mat-expansion-panel-header>
|
|
14692
|
-
|
|
15107
|
+
Botão de Submeter (Submit)
|
|
14693
15108
|
</mat-expansion-panel-header>
|
|
14694
15109
|
<ng-template matExpansionPanelContent>
|
|
14695
15110
|
<div class="action-fields">
|
|
14696
15111
|
<mat-slide-toggle
|
|
14697
15112
|
[checked]="actions.submit.visible"
|
|
14698
15113
|
(change)="updateAction('submit', 'visible', $event.checked)"
|
|
14699
|
-
>
|
|
15114
|
+
>VisÃvel</mat-slide-toggle
|
|
14700
15115
|
>
|
|
14701
15116
|
<mat-form-field>
|
|
14702
15117
|
<mat-label>Label</mat-label>
|
|
@@ -14713,7 +15128,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14713
15128
|
/>
|
|
14714
15129
|
</mat-form-field>
|
|
14715
15130
|
<mat-form-field>
|
|
14716
|
-
<mat-label
|
|
15131
|
+
<mat-label>Ãcone</mat-label>
|
|
14717
15132
|
<input
|
|
14718
15133
|
matInput
|
|
14719
15134
|
[value]="actions.submit.icon"
|
|
@@ -14775,14 +15190,14 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14775
15190
|
<!-- Repetir para Cancel e Reset -->
|
|
14776
15191
|
<mat-expansion-panel>
|
|
14777
15192
|
<mat-expansion-panel-header>
|
|
14778
|
-
|
|
15193
|
+
Botão de Cancelar (Cancel)
|
|
14779
15194
|
</mat-expansion-panel-header>
|
|
14780
15195
|
<ng-template matExpansionPanelContent>
|
|
14781
15196
|
<div class="action-fields">
|
|
14782
15197
|
<mat-slide-toggle
|
|
14783
15198
|
[checked]="actions.cancel.visible"
|
|
14784
15199
|
(change)="updateAction('cancel', 'visible', $event.checked)"
|
|
14785
|
-
>
|
|
15200
|
+
>VisÃvel</mat-slide-toggle
|
|
14786
15201
|
>
|
|
14787
15202
|
<mat-form-field>
|
|
14788
15203
|
<mat-label>Label</mat-label>
|
|
@@ -14799,7 +15214,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14799
15214
|
/>
|
|
14800
15215
|
</mat-form-field>
|
|
14801
15216
|
<mat-form-field>
|
|
14802
|
-
<mat-label
|
|
15217
|
+
<mat-label>Ãcone</mat-label>
|
|
14803
15218
|
<input
|
|
14804
15219
|
matInput
|
|
14805
15220
|
[value]="actions.cancel.icon"
|
|
@@ -14856,14 +15271,14 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14856
15271
|
</mat-expansion-panel>
|
|
14857
15272
|
<mat-expansion-panel>
|
|
14858
15273
|
<mat-expansion-panel-header>
|
|
14859
|
-
|
|
15274
|
+
Botão de Limpar (Reset)
|
|
14860
15275
|
</mat-expansion-panel-header>
|
|
14861
15276
|
<ng-template matExpansionPanelContent>
|
|
14862
15277
|
<div class="action-fields">
|
|
14863
15278
|
<mat-slide-toggle
|
|
14864
15279
|
[checked]="actions.reset.visible"
|
|
14865
15280
|
(change)="updateAction('reset', 'visible', $event.checked)"
|
|
14866
|
-
>
|
|
15281
|
+
>VisÃvel</mat-slide-toggle
|
|
14867
15282
|
>
|
|
14868
15283
|
<mat-form-field>
|
|
14869
15284
|
<mat-label>Label</mat-label>
|
|
@@ -14876,7 +15291,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14876
15291
|
/>
|
|
14877
15292
|
</mat-form-field>
|
|
14878
15293
|
<mat-form-field>
|
|
14879
|
-
<mat-label
|
|
15294
|
+
<mat-label>Ãcone</mat-label>
|
|
14880
15295
|
<input
|
|
14881
15296
|
matInput
|
|
14882
15297
|
[value]="actions.reset.icon"
|
|
@@ -14935,7 +15350,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14935
15350
|
</div>
|
|
14936
15351
|
</mat-tab>
|
|
14937
15352
|
|
|
14938
|
-
<mat-tab label="
|
|
15353
|
+
<mat-tab label="Botões Customizados">
|
|
14939
15354
|
<div class="editor-container">
|
|
14940
15355
|
<button
|
|
14941
15356
|
mat-stroked-button
|
|
@@ -14943,7 +15358,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14943
15358
|
(click)="addCustomButton()"
|
|
14944
15359
|
class="add-button"
|
|
14945
15360
|
>
|
|
14946
|
-
<mat-icon>add</mat-icon> Adicionar
|
|
15361
|
+
<mat-icon>add</mat-icon> Adicionar Botão
|
|
14947
15362
|
</button>
|
|
14948
15363
|
<mat-accordion multi>
|
|
14949
15364
|
@for (
|
|
@@ -14951,9 +15366,36 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14951
15366
|
track customAction.id || customAction.action || $index;
|
|
14952
15367
|
let i = $index
|
|
14953
15368
|
) {
|
|
14954
|
-
<
|
|
15369
|
+
<div class="custom-action-panel-shell">
|
|
15370
|
+
<div class="custom-action-panel-toolbar">
|
|
15371
|
+
<div class="custom-action-order-controls">
|
|
15372
|
+
<button
|
|
15373
|
+
mat-icon-button
|
|
15374
|
+
type="button"
|
|
15375
|
+
[attr.aria-label]="getMoveCustomActionAriaLabel('up', customAction)"
|
|
15376
|
+
[matTooltip]="tx('custom.order.moveUp.tooltip', 'Mover para cima')"
|
|
15377
|
+
[disabled]="!canMoveCustomActionUp(i)"
|
|
15378
|
+
(click)="moveCustomActionUp(i)"
|
|
15379
|
+
>
|
|
15380
|
+
<mat-icon>arrow_upward</mat-icon>
|
|
15381
|
+
</button>
|
|
15382
|
+
<button
|
|
15383
|
+
mat-icon-button
|
|
15384
|
+
type="button"
|
|
15385
|
+
[attr.aria-label]="getMoveCustomActionAriaLabel('down', customAction)"
|
|
15386
|
+
[matTooltip]="tx('custom.order.moveDown.tooltip', 'Mover para baixo')"
|
|
15387
|
+
[disabled]="!canMoveCustomActionDown(i)"
|
|
15388
|
+
(click)="moveCustomActionDown(i)"
|
|
15389
|
+
>
|
|
15390
|
+
<mat-icon>arrow_downward</mat-icon>
|
|
15391
|
+
</button>
|
|
15392
|
+
</div>
|
|
15393
|
+
</div>
|
|
15394
|
+
<mat-expansion-panel>
|
|
14955
15395
|
<mat-expansion-panel-header>
|
|
14956
|
-
|
|
15396
|
+
<mat-panel-title>
|
|
15397
|
+
{{ getCustomActionTitle(customAction) }}
|
|
15398
|
+
</mat-panel-title>
|
|
14957
15399
|
</mat-expansion-panel-header>
|
|
14958
15400
|
<ng-template matExpansionPanelContent>
|
|
14959
15401
|
<div class="action-fields">
|
|
@@ -14962,10 +15404,10 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14962
15404
|
(change)="
|
|
14963
15405
|
updateCustomAction(i, 'visible', $event.checked)
|
|
14964
15406
|
"
|
|
14965
|
-
>
|
|
15407
|
+
>VisÃvel</mat-slide-toggle
|
|
14966
15408
|
>
|
|
14967
15409
|
<mat-form-field>
|
|
14968
|
-
<mat-label>ID da
|
|
15410
|
+
<mat-label>ID da Ação</mat-label>
|
|
14969
15411
|
<input
|
|
14970
15412
|
matInput
|
|
14971
15413
|
[value]="customAction.id"
|
|
@@ -14976,7 +15418,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14976
15418
|
/>
|
|
14977
15419
|
</mat-form-field>
|
|
14978
15420
|
<mat-form-field>
|
|
14979
|
-
<mat-label>
|
|
15421
|
+
<mat-label>Ação</mat-label>
|
|
14980
15422
|
<mat-select
|
|
14981
15423
|
[value]="getCustomActionSelectValue(customAction.action)"
|
|
14982
15424
|
(selectionChange)="onCustomActionSelectChange(i, $event.value)"
|
|
@@ -14984,7 +15426,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14984
15426
|
<mat-option [value]="customActionValue">Customizada</mat-option>
|
|
14985
15427
|
<mat-optgroup label="Acoes globais">
|
|
14986
15428
|
@for (spec of globalActionCatalog; track spec.id) {
|
|
14987
|
-
<mat-option [value]="spec.id">{{ spec
|
|
15429
|
+
<mat-option [value]="spec.id">{{ getActionCatalogLabel(spec) }}</mat-option>
|
|
14988
15430
|
}
|
|
14989
15431
|
</mat-optgroup>
|
|
14990
15432
|
</mat-select>
|
|
@@ -14993,14 +15435,14 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
14993
15435
|
matSuffix
|
|
14994
15436
|
type="button"
|
|
14995
15437
|
class="help-icon-button"
|
|
14996
|
-
matTooltip="
|
|
15438
|
+
matTooltip="Ações globais exigem executor no app (ActionResolver). Customizadas só emitem evento. Cor/posição afetam o botão."
|
|
14997
15439
|
>
|
|
14998
15440
|
<mat-icon>help_outline</mat-icon>
|
|
14999
15441
|
</button>
|
|
15000
15442
|
</mat-form-field>
|
|
15001
15443
|
@if (getCustomActionSelectValue(customAction.action) === customActionValue) {
|
|
15002
15444
|
<mat-form-field>
|
|
15003
|
-
<mat-label>
|
|
15445
|
+
<mat-label>Ação customizada</mat-label>
|
|
15004
15446
|
<input
|
|
15005
15447
|
matInput
|
|
15006
15448
|
[value]="getCustomActionCustomValue(customAction.action)"
|
|
@@ -15018,7 +15460,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15018
15460
|
@if (getActionSpecById(getCustomActionSelectValue(customAction.action)); as actionSpec) {
|
|
15019
15461
|
@if (actionSpec.param) {
|
|
15020
15462
|
<mat-form-field>
|
|
15021
|
-
<mat-label>{{ actionSpec.param.label || '
|
|
15463
|
+
<mat-label>{{ actionSpec.param.label || 'Parâmetro' }}</mat-label>
|
|
15022
15464
|
<input
|
|
15023
15465
|
matInput
|
|
15024
15466
|
[value]="getCustomActionParam(customAction.action)"
|
|
@@ -15048,7 +15490,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15048
15490
|
/>
|
|
15049
15491
|
</mat-form-field>
|
|
15050
15492
|
<mat-form-field>
|
|
15051
|
-
<mat-label
|
|
15493
|
+
<mat-label>Ãcone</mat-label>
|
|
15052
15494
|
<input
|
|
15053
15495
|
matInput
|
|
15054
15496
|
[value]="customAction.icon"
|
|
@@ -15062,7 +15504,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15062
15504
|
/>
|
|
15063
15505
|
</mat-form-field>
|
|
15064
15506
|
<mat-form-field>
|
|
15065
|
-
<mat-label>Cor do
|
|
15507
|
+
<mat-label>Cor do botão</mat-label>
|
|
15066
15508
|
<mat-select
|
|
15067
15509
|
[value]="customAction.color"
|
|
15068
15510
|
(selectionChange)="
|
|
@@ -15075,17 +15517,118 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15075
15517
|
<mat-option value="basic">Basic</mat-option>
|
|
15076
15518
|
</mat-select>
|
|
15077
15519
|
</mat-form-field>
|
|
15520
|
+
<mat-form-field>
|
|
15521
|
+
<mat-label>{{ tx('custom.variant', 'Variante') }}</mat-label>
|
|
15522
|
+
<mat-select
|
|
15523
|
+
[value]="customAction.variant"
|
|
15524
|
+
(selectionChange)="
|
|
15525
|
+
updateCustomAction(i, 'variant', $event.value)
|
|
15526
|
+
"
|
|
15527
|
+
>
|
|
15528
|
+
<mat-option value="raised">Elevado (raised)</mat-option>
|
|
15529
|
+
<mat-option value="stroked">Contornado (stroked)</mat-option>
|
|
15530
|
+
<mat-option value="flat">Plano (flat)</mat-option>
|
|
15531
|
+
<mat-option value="fab">Flutuante (fab)</mat-option>
|
|
15532
|
+
</mat-select>
|
|
15533
|
+
</mat-form-field>
|
|
15534
|
+
<mat-form-field>
|
|
15535
|
+
<mat-label>{{ tx('custom.size', 'Tamanho') }}</mat-label>
|
|
15536
|
+
<mat-select
|
|
15537
|
+
[value]="customAction.size"
|
|
15538
|
+
(selectionChange)="
|
|
15539
|
+
updateCustomAction(i, 'size', $event.value)
|
|
15540
|
+
"
|
|
15541
|
+
>
|
|
15542
|
+
<mat-option value="small">{{ tx('custom.size.small', 'Pequeno') }}</mat-option>
|
|
15543
|
+
<mat-option value="medium">{{ tx('custom.size.medium', 'Médio') }}</mat-option>
|
|
15544
|
+
<mat-option value="large">{{ tx('custom.size.large', 'Grande') }}</mat-option>
|
|
15545
|
+
</mat-select>
|
|
15546
|
+
</mat-form-field>
|
|
15547
|
+
<mat-form-field>
|
|
15548
|
+
<mat-label>{{ tx('custom.tooltip', 'Tooltip') }}</mat-label>
|
|
15549
|
+
<input
|
|
15550
|
+
matInput
|
|
15551
|
+
[value]="customAction.tooltip"
|
|
15552
|
+
(input)="
|
|
15553
|
+
updateCustomAction(
|
|
15554
|
+
i,
|
|
15555
|
+
'tooltip',
|
|
15556
|
+
$any($event.target).value
|
|
15557
|
+
)
|
|
15558
|
+
"
|
|
15559
|
+
/>
|
|
15560
|
+
</mat-form-field>
|
|
15561
|
+
<mat-form-field>
|
|
15562
|
+
<mat-label>{{ tx('custom.shortcut', 'Atalho de Teclado') }}</mat-label>
|
|
15563
|
+
<input
|
|
15564
|
+
matInput
|
|
15565
|
+
[value]="customAction.shortcut"
|
|
15566
|
+
(input)="
|
|
15567
|
+
updateCustomAction(
|
|
15568
|
+
i,
|
|
15569
|
+
'shortcut',
|
|
15570
|
+
$any($event.target).value
|
|
15571
|
+
)
|
|
15572
|
+
"
|
|
15573
|
+
[placeholder]="tx('custom.shortcut.placeholder', 'Ex.: ctrl+shift+a')"
|
|
15574
|
+
/>
|
|
15575
|
+
</mat-form-field>
|
|
15576
|
+
<mat-form-field>
|
|
15577
|
+
<mat-label>{{ tx('custom.className', 'Classe CSS') }}</mat-label>
|
|
15578
|
+
<input
|
|
15579
|
+
matInput
|
|
15580
|
+
[value]="$any(customAction).className"
|
|
15581
|
+
(input)="
|
|
15582
|
+
updateCustomAction(
|
|
15583
|
+
i,
|
|
15584
|
+
'className',
|
|
15585
|
+
$any($event.target).value
|
|
15586
|
+
)
|
|
15587
|
+
"
|
|
15588
|
+
/>
|
|
15589
|
+
</mat-form-field>
|
|
15590
|
+
<mat-slide-toggle
|
|
15591
|
+
[checked]="!!customAction.disabled"
|
|
15592
|
+
(change)="
|
|
15593
|
+
updateCustomAction(i, 'disabled', $event.checked)
|
|
15594
|
+
"
|
|
15595
|
+
>
|
|
15596
|
+
{{ tx('custom.disabled', 'Desabilitado') }}
|
|
15597
|
+
</mat-slide-toggle>
|
|
15598
|
+
<mat-slide-toggle
|
|
15599
|
+
[checked]="!!customAction.loading"
|
|
15600
|
+
(change)="
|
|
15601
|
+
updateCustomAction(i, 'loading', $event.checked)
|
|
15602
|
+
"
|
|
15603
|
+
>
|
|
15604
|
+
{{ tx('custom.loading', 'Loading') }}
|
|
15605
|
+
</mat-slide-toggle>
|
|
15606
|
+
<mat-form-field class="w-100">
|
|
15607
|
+
<mat-label>{{ tx('custom.style', 'Estilos do botão (JSON)') }}</mat-label>
|
|
15608
|
+
<textarea
|
|
15609
|
+
matInput
|
|
15610
|
+
rows="4"
|
|
15611
|
+
[ngModel]="getCustomActionStyleText(customAction, i)"
|
|
15612
|
+
(ngModelChange)="onCustomActionStyleTextChange(i, $event)"
|
|
15613
|
+
(blur)="applyCustomActionStyleText(customAction, i)"
|
|
15614
|
+
[placeholder]="getCustomStylePlaceholder()"
|
|
15615
|
+
></textarea>
|
|
15616
|
+
@if (hasCustomActionStyleError(customAction, i)) {
|
|
15617
|
+
<mat-error>{{ getCustomActionStyleError(customAction, i) }}</mat-error>
|
|
15618
|
+
}
|
|
15619
|
+
</mat-form-field>
|
|
15078
15620
|
</div>
|
|
15079
15621
|
<button
|
|
15080
15622
|
mat-icon-button
|
|
15081
15623
|
color="warn"
|
|
15082
15624
|
(click)="removeCustomButton(i)"
|
|
15083
|
-
matTooltip="Remover este
|
|
15625
|
+
matTooltip="Remover este botão"
|
|
15084
15626
|
>
|
|
15085
15627
|
<mat-icon>delete</mat-icon>
|
|
15086
15628
|
</button>
|
|
15087
15629
|
</ng-template>
|
|
15088
15630
|
</mat-expansion-panel>
|
|
15631
|
+
</div>
|
|
15089
15632
|
}
|
|
15090
15633
|
</mat-accordion>
|
|
15091
15634
|
</div>
|
|
@@ -15094,19 +15637,19 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15094
15637
|
<mat-tab label="Layout">
|
|
15095
15638
|
<div class="editor-container action-fields">
|
|
15096
15639
|
<mat-form-field>
|
|
15097
|
-
<mat-label>
|
|
15640
|
+
<mat-label>Posição estrutural</mat-label>
|
|
15098
15641
|
<mat-select [value]="actions.placement || 'afterSections'" (selectionChange)="updateLayout('placement', $event.value)">
|
|
15099
|
-
<mat-option value="insideLastSection">Dentro da
|
|
15100
|
-
<mat-option value="afterSections">
|
|
15101
|
-
<mat-option value="top">Antes das
|
|
15642
|
+
<mat-option value="insideLastSection">Dentro da última seção</mat-option>
|
|
15643
|
+
<mat-option value="afterSections">Após as seções</mat-option>
|
|
15644
|
+
<mat-option value="top">Antes das seções</mat-option>
|
|
15102
15645
|
</mat-select>
|
|
15103
15646
|
</mat-form-field>
|
|
15104
15647
|
<mat-form-field>
|
|
15105
|
-
<mat-label>
|
|
15106
|
-
<input matInput type="number" [value]="getGapTopPx()" (input)="onGapTopInput($any($event.target).value)" placeholder="(
|
|
15648
|
+
<mat-label>Espaço acima (px)</mat-label>
|
|
15649
|
+
<input matInput type="number" [value]="getGapTopPx()" (input)="onGapTopInput($any($event.target).value)" placeholder="(padrão)" />
|
|
15107
15650
|
</mat-form-field>
|
|
15108
15651
|
<mat-form-field>
|
|
15109
|
-
<mat-label>Alinhamento dos
|
|
15652
|
+
<mat-label>Alinhamento dos Botões</mat-label>
|
|
15110
15653
|
<mat-select
|
|
15111
15654
|
[value]="actions.position"
|
|
15112
15655
|
(selectionChange)="updateLayout('position', $event.value)"
|
|
@@ -15119,7 +15662,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15119
15662
|
</mat-select>
|
|
15120
15663
|
</mat-form-field>
|
|
15121
15664
|
<mat-form-field>
|
|
15122
|
-
<mat-label>
|
|
15665
|
+
<mat-label>Orientação</mat-label>
|
|
15123
15666
|
<mat-select
|
|
15124
15667
|
[value]="actions.orientation"
|
|
15125
15668
|
(selectionChange)="updateLayout('orientation', $event.value)"
|
|
@@ -15129,14 +15672,14 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15129
15672
|
</mat-select>
|
|
15130
15673
|
</mat-form-field>
|
|
15131
15674
|
<mat-form-field>
|
|
15132
|
-
<mat-label>
|
|
15675
|
+
<mat-label>Espaçamento</mat-label>
|
|
15133
15676
|
<mat-select
|
|
15134
15677
|
[value]="actions.spacing"
|
|
15135
15678
|
(selectionChange)="updateLayout('spacing', $event.value)"
|
|
15136
15679
|
>
|
|
15137
15680
|
<mat-option value="compact">Compacto</mat-option>
|
|
15138
15681
|
<mat-option value="normal">Normal</mat-option>
|
|
15139
|
-
<mat-option value="spacious">
|
|
15682
|
+
<mat-option value="spacious">Espaçado</mat-option>
|
|
15140
15683
|
</mat-select>
|
|
15141
15684
|
</mat-form-field>
|
|
15142
15685
|
<mat-slide-toggle
|
|
@@ -15155,11 +15698,11 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15155
15698
|
<mat-slide-toggle
|
|
15156
15699
|
[checked]="actions.sticky"
|
|
15157
15700
|
(change)="updateLayout('sticky', $event.checked)"
|
|
15158
|
-
>Barra de
|
|
15701
|
+
>Barra de Ações Fixa (Sticky)</mat-slide-toggle
|
|
15159
15702
|
>
|
|
15160
15703
|
<mat-expansion-panel>
|
|
15161
15704
|
<mat-expansion-panel-header>
|
|
15162
|
-
|
|
15705
|
+
Configurações Mobile
|
|
15163
15706
|
</mat-expansion-panel-header>
|
|
15164
15707
|
<ng-template matExpansionPanelContent>
|
|
15165
15708
|
<div class="action-fields">
|
|
@@ -15176,7 +15719,7 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15176
15719
|
updateLayoutMobile('position', $event.value)
|
|
15177
15720
|
"
|
|
15178
15721
|
>
|
|
15179
|
-
<mat-option [value]="undefined">
|
|
15722
|
+
<mat-option [value]="undefined">Padrão</mat-option>
|
|
15180
15723
|
<mat-option value="left">Esquerda</mat-option>
|
|
15181
15724
|
<mat-option value="center">Centro</mat-option>
|
|
15182
15725
|
<mat-option value="right">Direita</mat-option>
|
|
@@ -15184,14 +15727,14 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15184
15727
|
</mat-select>
|
|
15185
15728
|
</mat-form-field>
|
|
15186
15729
|
<mat-form-field>
|
|
15187
|
-
<mat-label>
|
|
15730
|
+
<mat-label>Orientação (mobile)</mat-label>
|
|
15188
15731
|
<mat-select
|
|
15189
15732
|
[value]="actions.mobile?.orientation"
|
|
15190
15733
|
(selectionChange)="
|
|
15191
15734
|
updateLayoutMobile('orientation', $event.value)
|
|
15192
15735
|
"
|
|
15193
15736
|
>
|
|
15194
|
-
<mat-option [value]="undefined">
|
|
15737
|
+
<mat-option [value]="undefined">Padrão</mat-option>
|
|
15195
15738
|
<mat-option value="horizontal">Horizontal</mat-option>
|
|
15196
15739
|
<mat-option value="vertical">Vertical</mat-option>
|
|
15197
15740
|
</mat-select>
|
|
@@ -15202,11 +15745,14 @@ let ActionsEditorComponent$1 = class ActionsEditorComponent {
|
|
|
15202
15745
|
</div>
|
|
15203
15746
|
</mat-tab>
|
|
15204
15747
|
</mat-tab-group>
|
|
15205
|
-
`, isInline: true, styles: [".editor-container{padding:16px;display:flex;flex-direction:column;gap:16px}.action-fields{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:16px;align-items:center}.action-global-fields{grid-column:1 / -1;padding:12px 14px;border:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .12));border-radius:10px;background:var(--md-sys-color-surface-container-low)}.action-global-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #9aa0a6);margin-bottom:10px}.action-global-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px 16px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.action-global-fields .mat-mdc-form-field-icon-suffix{align-self:center}.action-section-title{width:100%;margin:10px 0 2px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #9aa0a6)}.add-button{margin-bottom:16px;align-self:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "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.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatSlideToggleModule }, { kind: "component", type: i6$3.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: MatSelectModule }, { kind: "component", type: i6$4.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$4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i6$4.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i3$1.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i3$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i3$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i3$1.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
15748
|
+
`, isInline: true, styles: [".editor-container{padding:16px;display:flex;flex-direction:column;gap:16px}.action-fields{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:16px;align-items:center}.action-global-fields{grid-column:1 / -1;padding:12px 14px;border:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .12));border-radius:10px;background:var(--md-sys-color-surface-container-low)}.action-global-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #9aa0a6);margin-bottom:10px}.action-global-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px 16px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.action-global-fields .mat-mdc-form-field-icon-suffix{align-self:center}.action-section-title{width:100%;margin:10px 0 2px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #9aa0a6)}.add-button{margin-bottom:16px;align-self:flex-start}.custom-action-panel-shell{display:grid;gap:8px}.custom-action-panel-toolbar{display:flex;justify-content:flex-end}.custom-action-order-controls{display:inline-flex;align-items:center;gap:4px;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "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.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatSlideToggleModule }, { kind: "component", type: i6$3.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: MatSelectModule }, { kind: "component", type: i6$4.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$4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i6$4.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i3$1.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i3$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i3$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i3$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i3$1.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SurfaceOpenActionEditorComponent, selector: "praxis-surface-open-action-editor", inputs: ["value", "hostKind"], outputs: ["valueChange"] }] });
|
|
15206
15749
|
};
|
|
15207
15750
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ActionsEditorComponent$1, decorators: [{
|
|
15208
15751
|
type: Component,
|
|
15209
|
-
args: [{ selector: 'praxis-actions-editor', standalone: true,
|
|
15752
|
+
args: [{ selector: 'praxis-actions-editor', standalone: true, providers: [
|
|
15753
|
+
providePraxisI18nConfig(SURFACE_OPEN_I18N_CONFIG),
|
|
15754
|
+
providePraxisI18nConfig(ACTIONS_EDITOR_I18N_CONFIG),
|
|
15755
|
+
], imports: [
|
|
15210
15756
|
CommonModule,
|
|
15211
15757
|
FormsModule,
|
|
15212
15758
|
MatFormFieldModule,
|
|
@@ -15218,11 +15764,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15218
15764
|
MatIconModule,
|
|
15219
15765
|
MatButtonModule,
|
|
15220
15766
|
MatTooltipModule,
|
|
15767
|
+
SurfaceOpenActionEditorComponent,
|
|
15221
15768
|
], template: `
|
|
15222
15769
|
<ng-template #globalActionFields let-action let-index="index">
|
|
15223
15770
|
@if (getGlobalActionSchema(action); as schema) {
|
|
15224
15771
|
<div class="action-global-fields">
|
|
15225
|
-
<div class="action-global-title">
|
|
15772
|
+
<div class="action-global-title">Configuração da ação global</div>
|
|
15773
|
+
@if (schema.editorMode === 'surface-open') {
|
|
15774
|
+
<praxis-surface-open-action-editor
|
|
15775
|
+
[value]="getSurfaceOpenActionPayload(action)"
|
|
15776
|
+
hostKind="form"
|
|
15777
|
+
(valueChange)="onSurfaceOpenActionPayloadChange(action, $event, index)"
|
|
15778
|
+
></praxis-surface-open-action-editor>
|
|
15779
|
+
} @else {
|
|
15226
15780
|
<div class="action-global-grid">
|
|
15227
15781
|
@for (field of schema.fields; track field.key) {
|
|
15228
15782
|
@if (shouldShowGlobalActionField(action, field)) {
|
|
@@ -15230,7 +15784,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15230
15784
|
<div class="action-section-title">Essencial</div>
|
|
15231
15785
|
}
|
|
15232
15786
|
@if (schema.id === 'showAlert' && field.key === 'title') {
|
|
15233
|
-
<div class="action-section-title">
|
|
15787
|
+
<div class="action-section-title">Diálogo (opcional)</div>
|
|
15234
15788
|
}
|
|
15235
15789
|
@if (field.type === 'toggle') {
|
|
15236
15790
|
<mat-slide-toggle
|
|
@@ -15289,7 +15843,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15289
15843
|
matSuffix
|
|
15290
15844
|
type="button"
|
|
15291
15845
|
class="help-icon-button"
|
|
15292
|
-
matTooltip="Informe um JSON
|
|
15846
|
+
matTooltip="Informe um JSON válido."
|
|
15293
15847
|
>
|
|
15294
15848
|
<mat-icon>help_outline</mat-icon>
|
|
15295
15849
|
</button>
|
|
@@ -15348,23 +15902,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15348
15902
|
}
|
|
15349
15903
|
}
|
|
15350
15904
|
</div>
|
|
15905
|
+
}
|
|
15351
15906
|
</div>
|
|
15352
15907
|
}
|
|
15353
15908
|
</ng-template>
|
|
15354
15909
|
<mat-tab-group>
|
|
15355
|
-
<mat-tab label="
|
|
15910
|
+
<mat-tab label="Botões Padrão">
|
|
15356
15911
|
<div class="editor-container">
|
|
15357
15912
|
<mat-accordion multi>
|
|
15358
15913
|
<mat-expansion-panel>
|
|
15359
15914
|
<mat-expansion-panel-header>
|
|
15360
|
-
|
|
15915
|
+
Botão de Submeter (Submit)
|
|
15361
15916
|
</mat-expansion-panel-header>
|
|
15362
15917
|
<ng-template matExpansionPanelContent>
|
|
15363
15918
|
<div class="action-fields">
|
|
15364
15919
|
<mat-slide-toggle
|
|
15365
15920
|
[checked]="actions.submit.visible"
|
|
15366
15921
|
(change)="updateAction('submit', 'visible', $event.checked)"
|
|
15367
|
-
>
|
|
15922
|
+
>VisÃvel</mat-slide-toggle
|
|
15368
15923
|
>
|
|
15369
15924
|
<mat-form-field>
|
|
15370
15925
|
<mat-label>Label</mat-label>
|
|
@@ -15381,7 +15936,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15381
15936
|
/>
|
|
15382
15937
|
</mat-form-field>
|
|
15383
15938
|
<mat-form-field>
|
|
15384
|
-
<mat-label
|
|
15939
|
+
<mat-label>Ãcone</mat-label>
|
|
15385
15940
|
<input
|
|
15386
15941
|
matInput
|
|
15387
15942
|
[value]="actions.submit.icon"
|
|
@@ -15443,14 +15998,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15443
15998
|
<!-- Repetir para Cancel e Reset -->
|
|
15444
15999
|
<mat-expansion-panel>
|
|
15445
16000
|
<mat-expansion-panel-header>
|
|
15446
|
-
|
|
16001
|
+
Botão de Cancelar (Cancel)
|
|
15447
16002
|
</mat-expansion-panel-header>
|
|
15448
16003
|
<ng-template matExpansionPanelContent>
|
|
15449
16004
|
<div class="action-fields">
|
|
15450
16005
|
<mat-slide-toggle
|
|
15451
16006
|
[checked]="actions.cancel.visible"
|
|
15452
16007
|
(change)="updateAction('cancel', 'visible', $event.checked)"
|
|
15453
|
-
>
|
|
16008
|
+
>VisÃvel</mat-slide-toggle
|
|
15454
16009
|
>
|
|
15455
16010
|
<mat-form-field>
|
|
15456
16011
|
<mat-label>Label</mat-label>
|
|
@@ -15467,7 +16022,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15467
16022
|
/>
|
|
15468
16023
|
</mat-form-field>
|
|
15469
16024
|
<mat-form-field>
|
|
15470
|
-
<mat-label
|
|
16025
|
+
<mat-label>Ãcone</mat-label>
|
|
15471
16026
|
<input
|
|
15472
16027
|
matInput
|
|
15473
16028
|
[value]="actions.cancel.icon"
|
|
@@ -15524,14 +16079,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15524
16079
|
</mat-expansion-panel>
|
|
15525
16080
|
<mat-expansion-panel>
|
|
15526
16081
|
<mat-expansion-panel-header>
|
|
15527
|
-
|
|
16082
|
+
Botão de Limpar (Reset)
|
|
15528
16083
|
</mat-expansion-panel-header>
|
|
15529
16084
|
<ng-template matExpansionPanelContent>
|
|
15530
16085
|
<div class="action-fields">
|
|
15531
16086
|
<mat-slide-toggle
|
|
15532
16087
|
[checked]="actions.reset.visible"
|
|
15533
16088
|
(change)="updateAction('reset', 'visible', $event.checked)"
|
|
15534
|
-
>
|
|
16089
|
+
>VisÃvel</mat-slide-toggle
|
|
15535
16090
|
>
|
|
15536
16091
|
<mat-form-field>
|
|
15537
16092
|
<mat-label>Label</mat-label>
|
|
@@ -15544,7 +16099,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15544
16099
|
/>
|
|
15545
16100
|
</mat-form-field>
|
|
15546
16101
|
<mat-form-field>
|
|
15547
|
-
<mat-label
|
|
16102
|
+
<mat-label>Ãcone</mat-label>
|
|
15548
16103
|
<input
|
|
15549
16104
|
matInput
|
|
15550
16105
|
[value]="actions.reset.icon"
|
|
@@ -15603,7 +16158,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15603
16158
|
</div>
|
|
15604
16159
|
</mat-tab>
|
|
15605
16160
|
|
|
15606
|
-
<mat-tab label="
|
|
16161
|
+
<mat-tab label="Botões Customizados">
|
|
15607
16162
|
<div class="editor-container">
|
|
15608
16163
|
<button
|
|
15609
16164
|
mat-stroked-button
|
|
@@ -15611,7 +16166,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15611
16166
|
(click)="addCustomButton()"
|
|
15612
16167
|
class="add-button"
|
|
15613
16168
|
>
|
|
15614
|
-
<mat-icon>add</mat-icon> Adicionar
|
|
16169
|
+
<mat-icon>add</mat-icon> Adicionar Botão
|
|
15615
16170
|
</button>
|
|
15616
16171
|
<mat-accordion multi>
|
|
15617
16172
|
@for (
|
|
@@ -15619,9 +16174,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15619
16174
|
track customAction.id || customAction.action || $index;
|
|
15620
16175
|
let i = $index
|
|
15621
16176
|
) {
|
|
15622
|
-
<
|
|
16177
|
+
<div class="custom-action-panel-shell">
|
|
16178
|
+
<div class="custom-action-panel-toolbar">
|
|
16179
|
+
<div class="custom-action-order-controls">
|
|
16180
|
+
<button
|
|
16181
|
+
mat-icon-button
|
|
16182
|
+
type="button"
|
|
16183
|
+
[attr.aria-label]="getMoveCustomActionAriaLabel('up', customAction)"
|
|
16184
|
+
[matTooltip]="tx('custom.order.moveUp.tooltip', 'Mover para cima')"
|
|
16185
|
+
[disabled]="!canMoveCustomActionUp(i)"
|
|
16186
|
+
(click)="moveCustomActionUp(i)"
|
|
16187
|
+
>
|
|
16188
|
+
<mat-icon>arrow_upward</mat-icon>
|
|
16189
|
+
</button>
|
|
16190
|
+
<button
|
|
16191
|
+
mat-icon-button
|
|
16192
|
+
type="button"
|
|
16193
|
+
[attr.aria-label]="getMoveCustomActionAriaLabel('down', customAction)"
|
|
16194
|
+
[matTooltip]="tx('custom.order.moveDown.tooltip', 'Mover para baixo')"
|
|
16195
|
+
[disabled]="!canMoveCustomActionDown(i)"
|
|
16196
|
+
(click)="moveCustomActionDown(i)"
|
|
16197
|
+
>
|
|
16198
|
+
<mat-icon>arrow_downward</mat-icon>
|
|
16199
|
+
</button>
|
|
16200
|
+
</div>
|
|
16201
|
+
</div>
|
|
16202
|
+
<mat-expansion-panel>
|
|
15623
16203
|
<mat-expansion-panel-header>
|
|
15624
|
-
|
|
16204
|
+
<mat-panel-title>
|
|
16205
|
+
{{ getCustomActionTitle(customAction) }}
|
|
16206
|
+
</mat-panel-title>
|
|
15625
16207
|
</mat-expansion-panel-header>
|
|
15626
16208
|
<ng-template matExpansionPanelContent>
|
|
15627
16209
|
<div class="action-fields">
|
|
@@ -15630,10 +16212,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15630
16212
|
(change)="
|
|
15631
16213
|
updateCustomAction(i, 'visible', $event.checked)
|
|
15632
16214
|
"
|
|
15633
|
-
>
|
|
16215
|
+
>VisÃvel</mat-slide-toggle
|
|
15634
16216
|
>
|
|
15635
16217
|
<mat-form-field>
|
|
15636
|
-
<mat-label>ID da
|
|
16218
|
+
<mat-label>ID da Ação</mat-label>
|
|
15637
16219
|
<input
|
|
15638
16220
|
matInput
|
|
15639
16221
|
[value]="customAction.id"
|
|
@@ -15644,7 +16226,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15644
16226
|
/>
|
|
15645
16227
|
</mat-form-field>
|
|
15646
16228
|
<mat-form-field>
|
|
15647
|
-
<mat-label>
|
|
16229
|
+
<mat-label>Ação</mat-label>
|
|
15648
16230
|
<mat-select
|
|
15649
16231
|
[value]="getCustomActionSelectValue(customAction.action)"
|
|
15650
16232
|
(selectionChange)="onCustomActionSelectChange(i, $event.value)"
|
|
@@ -15652,7 +16234,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15652
16234
|
<mat-option [value]="customActionValue">Customizada</mat-option>
|
|
15653
16235
|
<mat-optgroup label="Acoes globais">
|
|
15654
16236
|
@for (spec of globalActionCatalog; track spec.id) {
|
|
15655
|
-
<mat-option [value]="spec.id">{{ spec
|
|
16237
|
+
<mat-option [value]="spec.id">{{ getActionCatalogLabel(spec) }}</mat-option>
|
|
15656
16238
|
}
|
|
15657
16239
|
</mat-optgroup>
|
|
15658
16240
|
</mat-select>
|
|
@@ -15661,14 +16243,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15661
16243
|
matSuffix
|
|
15662
16244
|
type="button"
|
|
15663
16245
|
class="help-icon-button"
|
|
15664
|
-
matTooltip="
|
|
16246
|
+
matTooltip="Ações globais exigem executor no app (ActionResolver). Customizadas só emitem evento. Cor/posição afetam o botão."
|
|
15665
16247
|
>
|
|
15666
16248
|
<mat-icon>help_outline</mat-icon>
|
|
15667
16249
|
</button>
|
|
15668
16250
|
</mat-form-field>
|
|
15669
16251
|
@if (getCustomActionSelectValue(customAction.action) === customActionValue) {
|
|
15670
16252
|
<mat-form-field>
|
|
15671
|
-
<mat-label>
|
|
16253
|
+
<mat-label>Ação customizada</mat-label>
|
|
15672
16254
|
<input
|
|
15673
16255
|
matInput
|
|
15674
16256
|
[value]="getCustomActionCustomValue(customAction.action)"
|
|
@@ -15686,7 +16268,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15686
16268
|
@if (getActionSpecById(getCustomActionSelectValue(customAction.action)); as actionSpec) {
|
|
15687
16269
|
@if (actionSpec.param) {
|
|
15688
16270
|
<mat-form-field>
|
|
15689
|
-
<mat-label>{{ actionSpec.param.label || '
|
|
16271
|
+
<mat-label>{{ actionSpec.param.label || 'Parâmetro' }}</mat-label>
|
|
15690
16272
|
<input
|
|
15691
16273
|
matInput
|
|
15692
16274
|
[value]="getCustomActionParam(customAction.action)"
|
|
@@ -15716,7 +16298,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15716
16298
|
/>
|
|
15717
16299
|
</mat-form-field>
|
|
15718
16300
|
<mat-form-field>
|
|
15719
|
-
<mat-label
|
|
16301
|
+
<mat-label>Ãcone</mat-label>
|
|
15720
16302
|
<input
|
|
15721
16303
|
matInput
|
|
15722
16304
|
[value]="customAction.icon"
|
|
@@ -15730,7 +16312,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15730
16312
|
/>
|
|
15731
16313
|
</mat-form-field>
|
|
15732
16314
|
<mat-form-field>
|
|
15733
|
-
<mat-label>Cor do
|
|
16315
|
+
<mat-label>Cor do botão</mat-label>
|
|
15734
16316
|
<mat-select
|
|
15735
16317
|
[value]="customAction.color"
|
|
15736
16318
|
(selectionChange)="
|
|
@@ -15743,38 +16325,139 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15743
16325
|
<mat-option value="basic">Basic</mat-option>
|
|
15744
16326
|
</mat-select>
|
|
15745
16327
|
</mat-form-field>
|
|
15746
|
-
|
|
15747
|
-
|
|
15748
|
-
|
|
15749
|
-
|
|
15750
|
-
|
|
15751
|
-
|
|
15752
|
-
|
|
15753
|
-
|
|
15754
|
-
|
|
15755
|
-
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
15759
|
-
|
|
16328
|
+
<mat-form-field>
|
|
16329
|
+
<mat-label>{{ tx('custom.variant', 'Variante') }}</mat-label>
|
|
16330
|
+
<mat-select
|
|
16331
|
+
[value]="customAction.variant"
|
|
16332
|
+
(selectionChange)="
|
|
16333
|
+
updateCustomAction(i, 'variant', $event.value)
|
|
16334
|
+
"
|
|
16335
|
+
>
|
|
16336
|
+
<mat-option value="raised">Elevado (raised)</mat-option>
|
|
16337
|
+
<mat-option value="stroked">Contornado (stroked)</mat-option>
|
|
16338
|
+
<mat-option value="flat">Plano (flat)</mat-option>
|
|
16339
|
+
<mat-option value="fab">Flutuante (fab)</mat-option>
|
|
16340
|
+
</mat-select>
|
|
16341
|
+
</mat-form-field>
|
|
16342
|
+
<mat-form-field>
|
|
16343
|
+
<mat-label>{{ tx('custom.size', 'Tamanho') }}</mat-label>
|
|
16344
|
+
<mat-select
|
|
16345
|
+
[value]="customAction.size"
|
|
16346
|
+
(selectionChange)="
|
|
16347
|
+
updateCustomAction(i, 'size', $event.value)
|
|
16348
|
+
"
|
|
16349
|
+
>
|
|
16350
|
+
<mat-option value="small">{{ tx('custom.size.small', 'Pequeno') }}</mat-option>
|
|
16351
|
+
<mat-option value="medium">{{ tx('custom.size.medium', 'Médio') }}</mat-option>
|
|
16352
|
+
<mat-option value="large">{{ tx('custom.size.large', 'Grande') }}</mat-option>
|
|
16353
|
+
</mat-select>
|
|
16354
|
+
</mat-form-field>
|
|
16355
|
+
<mat-form-field>
|
|
16356
|
+
<mat-label>{{ tx('custom.tooltip', 'Tooltip') }}</mat-label>
|
|
16357
|
+
<input
|
|
16358
|
+
matInput
|
|
16359
|
+
[value]="customAction.tooltip"
|
|
16360
|
+
(input)="
|
|
16361
|
+
updateCustomAction(
|
|
16362
|
+
i,
|
|
16363
|
+
'tooltip',
|
|
16364
|
+
$any($event.target).value
|
|
16365
|
+
)
|
|
16366
|
+
"
|
|
16367
|
+
/>
|
|
16368
|
+
</mat-form-field>
|
|
16369
|
+
<mat-form-field>
|
|
16370
|
+
<mat-label>{{ tx('custom.shortcut', 'Atalho de Teclado') }}</mat-label>
|
|
16371
|
+
<input
|
|
16372
|
+
matInput
|
|
16373
|
+
[value]="customAction.shortcut"
|
|
16374
|
+
(input)="
|
|
16375
|
+
updateCustomAction(
|
|
16376
|
+
i,
|
|
16377
|
+
'shortcut',
|
|
16378
|
+
$any($event.target).value
|
|
16379
|
+
)
|
|
16380
|
+
"
|
|
16381
|
+
[placeholder]="tx('custom.shortcut.placeholder', 'Ex.: ctrl+shift+a')"
|
|
16382
|
+
/>
|
|
16383
|
+
</mat-form-field>
|
|
16384
|
+
<mat-form-field>
|
|
16385
|
+
<mat-label>{{ tx('custom.className', 'Classe CSS') }}</mat-label>
|
|
16386
|
+
<input
|
|
16387
|
+
matInput
|
|
16388
|
+
[value]="$any(customAction).className"
|
|
16389
|
+
(input)="
|
|
16390
|
+
updateCustomAction(
|
|
16391
|
+
i,
|
|
16392
|
+
'className',
|
|
16393
|
+
$any($event.target).value
|
|
16394
|
+
)
|
|
16395
|
+
"
|
|
16396
|
+
/>
|
|
16397
|
+
</mat-form-field>
|
|
16398
|
+
<mat-slide-toggle
|
|
16399
|
+
[checked]="!!customAction.disabled"
|
|
16400
|
+
(change)="
|
|
16401
|
+
updateCustomAction(i, 'disabled', $event.checked)
|
|
16402
|
+
"
|
|
16403
|
+
>
|
|
16404
|
+
{{ tx('custom.disabled', 'Desabilitado') }}
|
|
16405
|
+
</mat-slide-toggle>
|
|
16406
|
+
<mat-slide-toggle
|
|
16407
|
+
[checked]="!!customAction.loading"
|
|
16408
|
+
(change)="
|
|
16409
|
+
updateCustomAction(i, 'loading', $event.checked)
|
|
16410
|
+
"
|
|
16411
|
+
>
|
|
16412
|
+
{{ tx('custom.loading', 'Loading') }}
|
|
16413
|
+
</mat-slide-toggle>
|
|
16414
|
+
<mat-form-field class="w-100">
|
|
16415
|
+
<mat-label>{{ tx('custom.style', 'Estilos do botão (JSON)') }}</mat-label>
|
|
16416
|
+
<textarea
|
|
16417
|
+
matInput
|
|
16418
|
+
rows="4"
|
|
16419
|
+
[ngModel]="getCustomActionStyleText(customAction, i)"
|
|
16420
|
+
(ngModelChange)="onCustomActionStyleTextChange(i, $event)"
|
|
16421
|
+
(blur)="applyCustomActionStyleText(customAction, i)"
|
|
16422
|
+
[placeholder]="getCustomStylePlaceholder()"
|
|
16423
|
+
></textarea>
|
|
16424
|
+
@if (hasCustomActionStyleError(customAction, i)) {
|
|
16425
|
+
<mat-error>{{ getCustomActionStyleError(customAction, i) }}</mat-error>
|
|
16426
|
+
}
|
|
16427
|
+
</mat-form-field>
|
|
16428
|
+
</div>
|
|
16429
|
+
<button
|
|
16430
|
+
mat-icon-button
|
|
16431
|
+
color="warn"
|
|
16432
|
+
(click)="removeCustomButton(i)"
|
|
16433
|
+
matTooltip="Remover este botão"
|
|
16434
|
+
>
|
|
16435
|
+
<mat-icon>delete</mat-icon>
|
|
16436
|
+
</button>
|
|
16437
|
+
</ng-template>
|
|
16438
|
+
</mat-expansion-panel>
|
|
16439
|
+
</div>
|
|
16440
|
+
}
|
|
16441
|
+
</mat-accordion>
|
|
16442
|
+
</div>
|
|
15760
16443
|
</mat-tab>
|
|
15761
16444
|
|
|
15762
16445
|
<mat-tab label="Layout">
|
|
15763
16446
|
<div class="editor-container action-fields">
|
|
15764
16447
|
<mat-form-field>
|
|
15765
|
-
<mat-label>
|
|
16448
|
+
<mat-label>Posição estrutural</mat-label>
|
|
15766
16449
|
<mat-select [value]="actions.placement || 'afterSections'" (selectionChange)="updateLayout('placement', $event.value)">
|
|
15767
|
-
<mat-option value="insideLastSection">Dentro da
|
|
15768
|
-
<mat-option value="afterSections">
|
|
15769
|
-
<mat-option value="top">Antes das
|
|
16450
|
+
<mat-option value="insideLastSection">Dentro da última seção</mat-option>
|
|
16451
|
+
<mat-option value="afterSections">Após as seções</mat-option>
|
|
16452
|
+
<mat-option value="top">Antes das seções</mat-option>
|
|
15770
16453
|
</mat-select>
|
|
15771
16454
|
</mat-form-field>
|
|
15772
16455
|
<mat-form-field>
|
|
15773
|
-
<mat-label>
|
|
15774
|
-
<input matInput type="number" [value]="getGapTopPx()" (input)="onGapTopInput($any($event.target).value)" placeholder="(
|
|
16456
|
+
<mat-label>Espaço acima (px)</mat-label>
|
|
16457
|
+
<input matInput type="number" [value]="getGapTopPx()" (input)="onGapTopInput($any($event.target).value)" placeholder="(padrão)" />
|
|
15775
16458
|
</mat-form-field>
|
|
15776
16459
|
<mat-form-field>
|
|
15777
|
-
<mat-label>Alinhamento dos
|
|
16460
|
+
<mat-label>Alinhamento dos Botões</mat-label>
|
|
15778
16461
|
<mat-select
|
|
15779
16462
|
[value]="actions.position"
|
|
15780
16463
|
(selectionChange)="updateLayout('position', $event.value)"
|
|
@@ -15787,7 +16470,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15787
16470
|
</mat-select>
|
|
15788
16471
|
</mat-form-field>
|
|
15789
16472
|
<mat-form-field>
|
|
15790
|
-
<mat-label>
|
|
16473
|
+
<mat-label>Orientação</mat-label>
|
|
15791
16474
|
<mat-select
|
|
15792
16475
|
[value]="actions.orientation"
|
|
15793
16476
|
(selectionChange)="updateLayout('orientation', $event.value)"
|
|
@@ -15797,14 +16480,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15797
16480
|
</mat-select>
|
|
15798
16481
|
</mat-form-field>
|
|
15799
16482
|
<mat-form-field>
|
|
15800
|
-
<mat-label>
|
|
16483
|
+
<mat-label>Espaçamento</mat-label>
|
|
15801
16484
|
<mat-select
|
|
15802
16485
|
[value]="actions.spacing"
|
|
15803
16486
|
(selectionChange)="updateLayout('spacing', $event.value)"
|
|
15804
16487
|
>
|
|
15805
16488
|
<mat-option value="compact">Compacto</mat-option>
|
|
15806
16489
|
<mat-option value="normal">Normal</mat-option>
|
|
15807
|
-
<mat-option value="spacious">
|
|
16490
|
+
<mat-option value="spacious">Espaçado</mat-option>
|
|
15808
16491
|
</mat-select>
|
|
15809
16492
|
</mat-form-field>
|
|
15810
16493
|
<mat-slide-toggle
|
|
@@ -15823,11 +16506,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15823
16506
|
<mat-slide-toggle
|
|
15824
16507
|
[checked]="actions.sticky"
|
|
15825
16508
|
(change)="updateLayout('sticky', $event.checked)"
|
|
15826
|
-
>Barra de
|
|
16509
|
+
>Barra de Ações Fixa (Sticky)</mat-slide-toggle
|
|
15827
16510
|
>
|
|
15828
16511
|
<mat-expansion-panel>
|
|
15829
16512
|
<mat-expansion-panel-header>
|
|
15830
|
-
|
|
16513
|
+
Configurações Mobile
|
|
15831
16514
|
</mat-expansion-panel-header>
|
|
15832
16515
|
<ng-template matExpansionPanelContent>
|
|
15833
16516
|
<div class="action-fields">
|
|
@@ -15844,7 +16527,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15844
16527
|
updateLayoutMobile('position', $event.value)
|
|
15845
16528
|
"
|
|
15846
16529
|
>
|
|
15847
|
-
<mat-option [value]="undefined">
|
|
16530
|
+
<mat-option [value]="undefined">Padrão</mat-option>
|
|
15848
16531
|
<mat-option value="left">Esquerda</mat-option>
|
|
15849
16532
|
<mat-option value="center">Centro</mat-option>
|
|
15850
16533
|
<mat-option value="right">Direita</mat-option>
|
|
@@ -15852,14 +16535,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15852
16535
|
</mat-select>
|
|
15853
16536
|
</mat-form-field>
|
|
15854
16537
|
<mat-form-field>
|
|
15855
|
-
<mat-label>
|
|
16538
|
+
<mat-label>Orientação (mobile)</mat-label>
|
|
15856
16539
|
<mat-select
|
|
15857
16540
|
[value]="actions.mobile?.orientation"
|
|
15858
16541
|
(selectionChange)="
|
|
15859
16542
|
updateLayoutMobile('orientation', $event.value)
|
|
15860
16543
|
"
|
|
15861
16544
|
>
|
|
15862
|
-
<mat-option [value]="undefined">
|
|
16545
|
+
<mat-option [value]="undefined">Padrão</mat-option>
|
|
15863
16546
|
<mat-option value="horizontal">Horizontal</mat-option>
|
|
15864
16547
|
<mat-option value="vertical">Vertical</mat-option>
|
|
15865
16548
|
</mat-select>
|
|
@@ -15870,7 +16553,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15870
16553
|
</div>
|
|
15871
16554
|
</mat-tab>
|
|
15872
16555
|
</mat-tab-group>
|
|
15873
|
-
`, styles: [".editor-container{padding:16px;display:flex;flex-direction:column;gap:16px}.action-fields{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:16px;align-items:center}.action-global-fields{grid-column:1 / -1;padding:12px 14px;border:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .12));border-radius:10px;background:var(--md-sys-color-surface-container-low)}.action-global-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #9aa0a6);margin-bottom:10px}.action-global-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px 16px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.action-global-fields .mat-mdc-form-field-icon-suffix{align-self:center}.action-section-title{width:100%;margin:10px 0 2px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #9aa0a6)}.add-button{margin-bottom:16px;align-self:flex-start}\n"] }]
|
|
16556
|
+
`, styles: [".editor-container{padding:16px;display:flex;flex-direction:column;gap:16px}.action-fields{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:16px;align-items:center}.action-global-fields{grid-column:1 / -1;padding:12px 14px;border:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .12));border-radius:10px;background:var(--md-sys-color-surface-container-low)}.action-global-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #9aa0a6);margin-bottom:10px}.action-global-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px 16px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.action-global-fields .mat-mdc-form-field-icon-suffix{align-self:center}.action-section-title{width:100%;margin:10px 0 2px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #9aa0a6)}.add-button{margin-bottom:16px;align-self:flex-start}.custom-action-panel-shell{display:grid;gap:8px}.custom-action-panel-toolbar{display:flex;justify-content:flex-end}.custom-action-order-controls{display:inline-flex;align-items:center;gap:4px;justify-content:flex-end}\n"] }]
|
|
15874
16557
|
}], propDecorators: { config: [{
|
|
15875
16558
|
type: Input
|
|
15876
16559
|
}], configChange: [{
|
|
@@ -16930,6 +17613,9 @@ function normalizeTargets(rawTargets, explicitTargetType) {
|
|
|
16930
17613
|
};
|
|
16931
17614
|
}
|
|
16932
17615
|
function detectTarget(value) {
|
|
17616
|
+
if (isScopedSectionHeaderActionTarget(value) || isUnscopedSectionHeaderActionTarget(value)) {
|
|
17617
|
+
return { type: 'action', value };
|
|
17618
|
+
}
|
|
16933
17619
|
if (value?.startsWith('section:')) {
|
|
16934
17620
|
return { type: 'section', value: value.substring('section:'.length) };
|
|
16935
17621
|
}
|
|
@@ -16945,6 +17631,10 @@ function detectTarget(value) {
|
|
|
16945
17631
|
return { type: 'field', value };
|
|
16946
17632
|
}
|
|
16947
17633
|
function prefixTarget(targetType, value) {
|
|
17634
|
+
if (targetType === 'action' &&
|
|
17635
|
+
(isScopedSectionHeaderActionTarget(value) || isUnscopedSectionHeaderActionTarget(value))) {
|
|
17636
|
+
return value;
|
|
17637
|
+
}
|
|
16948
17638
|
if (targetType === 'section')
|
|
16949
17639
|
return `section:${value}`;
|
|
16950
17640
|
if (targetType === 'action')
|
|
@@ -16955,6 +17645,12 @@ function prefixTarget(targetType, value) {
|
|
|
16955
17645
|
return `column:${value}`;
|
|
16956
17646
|
return value;
|
|
16957
17647
|
}
|
|
17648
|
+
function isScopedSectionHeaderActionTarget(value) {
|
|
17649
|
+
return !!value && value.startsWith('section:') && value.includes(':header-action:');
|
|
17650
|
+
}
|
|
17651
|
+
function isUnscopedSectionHeaderActionTarget(value) {
|
|
17652
|
+
return !!value && value.startsWith('header-action:');
|
|
17653
|
+
}
|
|
16958
17654
|
function parseSimpleCondition(condition) {
|
|
16959
17655
|
const trimmed = condition.trim();
|
|
16960
17656
|
const match = trimmed.match(/^(.+?)\s+(eq|equals|==|=|neq|notequals|!=|<>|lt|lessthan|<|lte|lessthanorequal|<=|gt|greaterthan|>|gte|greaterthanorequal|>=|contains|startswith|endswith|in)\s+(.+)$/iu);
|
|
@@ -17475,6 +18171,21 @@ class PraxisDynamicFormConfigEditor {
|
|
|
17475
18171
|
});
|
|
17476
18172
|
// Expose actions as rule targets (prefixed)
|
|
17477
18173
|
const allActions = [];
|
|
18174
|
+
sections.forEach((section) => {
|
|
18175
|
+
(section.headerActions || []).forEach((action) => {
|
|
18176
|
+
const actionId = (action.action || action.id || '').trim();
|
|
18177
|
+
if (!actionId)
|
|
18178
|
+
return;
|
|
18179
|
+
const scopedActionId = section.id
|
|
18180
|
+
? `section:${section.id}:header-action:${actionId}`
|
|
18181
|
+
: `header-action:${actionId}`;
|
|
18182
|
+
allActions.push({
|
|
18183
|
+
id: scopedActionId,
|
|
18184
|
+
label: action.label ||
|
|
18185
|
+
`${section.title || section.id} • ${actionId}`,
|
|
18186
|
+
});
|
|
18187
|
+
});
|
|
18188
|
+
});
|
|
17478
18189
|
if (actions?.submit)
|
|
17479
18190
|
allActions.push({ id: actions.submit.id || 'submit', label: actions.submit.label });
|
|
17480
18191
|
if (actions?.cancel)
|
|
@@ -17994,7 +18705,7 @@ const PRAXIS_DYNAMIC_FORM_COMPONENT_METADATA = {
|
|
|
17994
18705
|
name: 'config',
|
|
17995
18706
|
type: 'FormConfig',
|
|
17996
18707
|
label: 'Configuração',
|
|
17997
|
-
description: 'Configuração completa do formulário (layout, metadados, ações, regras e headers de seção com `sectionHeader` para ícone/avatar dinâmico).',
|
|
18708
|
+
description: 'Configuração completa do formulário (layout, metadados, ações, regras e headers de seção com `sectionHeader` para ícone/avatar dinâmico e `headerActions` para ações contextuais).',
|
|
17998
18709
|
},
|
|
17999
18710
|
{ name: 'schemaSource', type: "'resource' | 'filter'", default: 'resource', description: 'Fonte do schema de campos' },
|
|
18000
18711
|
{ name: 'enableCustomization', type: 'boolean', default: false, description: 'Habilita modo de customização do layout (canvas)' },
|
|
@@ -18079,9 +18790,10 @@ const PRAXIS_DYNAMIC_FORM_COMPONENT_METADATA = {
|
|
|
18079
18790
|
formData: { type: 'object', description: 'Dados do formulário' },
|
|
18080
18791
|
isValid: { type: 'boolean', description: 'Validade do formulário' },
|
|
18081
18792
|
source: { type: 'string', description: 'Origem da ação' },
|
|
18793
|
+
sectionId: { type: 'string', description: 'ID da seção quando a ação veio do header de uma seção' },
|
|
18082
18794
|
},
|
|
18083
18795
|
required: ['actionId', 'formData', 'isValid', 'source'],
|
|
18084
|
-
example: { actionId: '
|
|
18796
|
+
example: { actionId: 'help', formData: {}, isValid: true, source: 'section-header', sectionId: 'identification' },
|
|
18085
18797
|
},
|
|
18086
18798
|
scope: 'shell',
|
|
18087
18799
|
},
|
|
@@ -18163,6 +18875,134 @@ function provideSettingsPanelDynamicForm() {
|
|
|
18163
18875
|
return SETTINGS_PANEL_DYNAMIC_FORM_PROVIDER;
|
|
18164
18876
|
}
|
|
18165
18877
|
|
|
18878
|
+
const SECTION_EDITOR_I18N_NAMESPACE = 'praxisDynamicFormSectionEditor';
|
|
18879
|
+
const SECTION_EDITOR_I18N_CONFIG = {
|
|
18880
|
+
namespaces: {
|
|
18881
|
+
[SECTION_EDITOR_I18N_NAMESPACE]: {
|
|
18882
|
+
'pt-BR': {
|
|
18883
|
+
'dynamicForm.sectionEditor.header.presets.title': 'Presets rápidos',
|
|
18884
|
+
'dynamicForm.sectionEditor.header.presets.default': 'Padrão',
|
|
18885
|
+
'dynamicForm.sectionEditor.header.presets.simple': 'Simples',
|
|
18886
|
+
'dynamicForm.sectionEditor.header.presets.collapsible': 'Colapsável',
|
|
18887
|
+
'dynamicForm.sectionEditor.header.fields.title': 'Título',
|
|
18888
|
+
'dynamicForm.sectionEditor.header.fields.description': 'Descrição',
|
|
18889
|
+
'dynamicForm.sectionEditor.header.fields.appearance': 'Aparência',
|
|
18890
|
+
'dynamicForm.sectionEditor.header.fields.titleColor': 'Cor do título',
|
|
18891
|
+
'dynamicForm.sectionEditor.header.fields.descriptionColor': 'Cor da descrição',
|
|
18892
|
+
'dynamicForm.sectionEditor.header.fields.customColor': 'Cor personalizada (CSS)',
|
|
18893
|
+
'dynamicForm.sectionEditor.header.fields.titleGapBottom': 'Gap do título (px)',
|
|
18894
|
+
'dynamicForm.sectionEditor.header.fields.descriptionGapBottom': 'Gap da descrição (px)',
|
|
18895
|
+
'dynamicForm.sectionEditor.header.fields.gapBottom': 'Gap abaixo da seção (px)',
|
|
18896
|
+
'dynamicForm.sectionEditor.header.fields.collapsible': 'Colapsável',
|
|
18897
|
+
'dynamicForm.sectionEditor.header.fields.collapsed': 'Iniciar recolhida',
|
|
18898
|
+
'dynamicForm.sectionEditor.header.fields.headerTooltip': 'Tooltip do cabeçalho',
|
|
18899
|
+
'dynamicForm.sectionEditor.header.placeholders.description': 'Resumo curto do conteúdo da seção',
|
|
18900
|
+
'dynamicForm.sectionEditor.header.placeholders.customColor': 'ex.: #3366ff ou rgb(...)',
|
|
18901
|
+
'dynamicForm.sectionEditor.header.placeholders.headerTooltip': 'Dica ao passar o mouse no título',
|
|
18902
|
+
'dynamicForm.sectionEditor.header.options.titleColor.default': 'Padrão (on-surface)',
|
|
18903
|
+
'dynamicForm.sectionEditor.header.options.titleColor.primary': 'Primária',
|
|
18904
|
+
'dynamicForm.sectionEditor.header.options.titleColor.secondary': 'Secundária',
|
|
18905
|
+
'dynamicForm.sectionEditor.header.options.descriptionColor.default': 'Padrão (on-surface-variant)',
|
|
18906
|
+
'dynamicForm.sectionEditor.header.options.descriptionColor.primary': 'Primária',
|
|
18907
|
+
'dynamicForm.sectionEditor.header.options.descriptionColor.secondary': 'Secundária',
|
|
18908
|
+
'headerActions.title': 'Ações do cabeçalho',
|
|
18909
|
+
'headerActions.description': 'Adicione ícones acionáveis no canto direito do cabeçalho da seção para affordances contextuais como ajuda, refresh ou drill-down.',
|
|
18910
|
+
'headerActions.add': 'Adicionar ação',
|
|
18911
|
+
'headerActions.empty': 'Nenhuma ação configurada para este cabeçalho.',
|
|
18912
|
+
'headerActions.item': 'Ação {{index}}',
|
|
18913
|
+
'headerActions.remove': 'Remover ação',
|
|
18914
|
+
'headerActions.moveUp': 'Mover ação para cima',
|
|
18915
|
+
'headerActions.moveDown': 'Mover ação para baixo',
|
|
18916
|
+
'headerActions.fields.id': 'ID',
|
|
18917
|
+
'headerActions.fields.label': 'Label acessível',
|
|
18918
|
+
'headerActions.fields.icon': 'Ícone',
|
|
18919
|
+
'headerActions.fields.action': 'Action emitida',
|
|
18920
|
+
'headerActions.fields.tooltip': 'Tooltip',
|
|
18921
|
+
'headerActions.fields.color': 'Cor',
|
|
18922
|
+
'headerActions.fields.color.default': 'Padrão',
|
|
18923
|
+
'headerActions.fields.color.basic': 'Basic',
|
|
18924
|
+
'headerActions.fields.color.primary': 'Primária',
|
|
18925
|
+
'headerActions.fields.color.accent': 'Accent',
|
|
18926
|
+
'headerActions.fields.color.warn': 'Warn',
|
|
18927
|
+
'headerActions.fields.visible': 'Visível',
|
|
18928
|
+
'headerActions.fields.disabled': 'Desabilitada',
|
|
18929
|
+
'headerActions.fields.loading': 'Loading',
|
|
18930
|
+
'headerActions.fields.className': 'Classe CSS',
|
|
18931
|
+
'headerActions.fields.style': 'Estilo (JSON)',
|
|
18932
|
+
'headerActions.validation.invalidJson': 'JSON inválido.',
|
|
18933
|
+
'headerActions.validation.objectJson': 'Informe um objeto JSON válido.',
|
|
18934
|
+
'headerActions.placeholders.id': 'ex.: help',
|
|
18935
|
+
'headerActions.placeholders.label': 'ex.: Ajuda da seção',
|
|
18936
|
+
'headerActions.placeholders.icon': 'ex.: help_outline',
|
|
18937
|
+
'headerActions.placeholders.action': 'Opcional. Se vazio, usa o ID',
|
|
18938
|
+
'headerActions.placeholders.tooltip': 'Opcional. Se vazio, usa a label',
|
|
18939
|
+
'headerActions.placeholders.className': 'ex.: section-help-action',
|
|
18940
|
+
'headerActions.placeholders.style': '{"marginLeft":"4px"}',
|
|
18941
|
+
},
|
|
18942
|
+
'en-US': {
|
|
18943
|
+
'dynamicForm.sectionEditor.header.presets.title': 'Quick presets',
|
|
18944
|
+
'dynamicForm.sectionEditor.header.presets.default': 'Default',
|
|
18945
|
+
'dynamicForm.sectionEditor.header.presets.simple': 'Simple',
|
|
18946
|
+
'dynamicForm.sectionEditor.header.presets.collapsible': 'Collapsible',
|
|
18947
|
+
'dynamicForm.sectionEditor.header.fields.title': 'Title',
|
|
18948
|
+
'dynamicForm.sectionEditor.header.fields.description': 'Description',
|
|
18949
|
+
'dynamicForm.sectionEditor.header.fields.appearance': 'Appearance',
|
|
18950
|
+
'dynamicForm.sectionEditor.header.fields.titleColor': 'Title color',
|
|
18951
|
+
'dynamicForm.sectionEditor.header.fields.descriptionColor': 'Description color',
|
|
18952
|
+
'dynamicForm.sectionEditor.header.fields.customColor': 'Custom color (CSS)',
|
|
18953
|
+
'dynamicForm.sectionEditor.header.fields.titleGapBottom': 'Title gap (px)',
|
|
18954
|
+
'dynamicForm.sectionEditor.header.fields.descriptionGapBottom': 'Description gap (px)',
|
|
18955
|
+
'dynamicForm.sectionEditor.header.fields.gapBottom': 'Section bottom gap (px)',
|
|
18956
|
+
'dynamicForm.sectionEditor.header.fields.collapsible': 'Collapsible',
|
|
18957
|
+
'dynamicForm.sectionEditor.header.fields.collapsed': 'Start collapsed',
|
|
18958
|
+
'dynamicForm.sectionEditor.header.fields.headerTooltip': 'Header tooltip',
|
|
18959
|
+
'dynamicForm.sectionEditor.header.placeholders.description': 'Short summary of the section content',
|
|
18960
|
+
'dynamicForm.sectionEditor.header.placeholders.customColor': 'e.g. #3366ff or rgb(...)',
|
|
18961
|
+
'dynamicForm.sectionEditor.header.placeholders.headerTooltip': 'Hint shown when hovering the title',
|
|
18962
|
+
'dynamicForm.sectionEditor.header.options.titleColor.default': 'Default (on-surface)',
|
|
18963
|
+
'dynamicForm.sectionEditor.header.options.titleColor.primary': 'Primary',
|
|
18964
|
+
'dynamicForm.sectionEditor.header.options.titleColor.secondary': 'Secondary',
|
|
18965
|
+
'dynamicForm.sectionEditor.header.options.descriptionColor.default': 'Default (on-surface-variant)',
|
|
18966
|
+
'dynamicForm.sectionEditor.header.options.descriptionColor.primary': 'Primary',
|
|
18967
|
+
'dynamicForm.sectionEditor.header.options.descriptionColor.secondary': 'Secondary',
|
|
18968
|
+
'headerActions.title': 'Header actions',
|
|
18969
|
+
'headerActions.description': 'Add clickable icons to the right side of the section header for contextual affordances such as help, refresh or drill-down.',
|
|
18970
|
+
'headerActions.add': 'Add action',
|
|
18971
|
+
'headerActions.empty': 'No actions configured for this header.',
|
|
18972
|
+
'headerActions.item': 'Action {{index}}',
|
|
18973
|
+
'headerActions.remove': 'Remove action',
|
|
18974
|
+
'headerActions.moveUp': 'Move action up',
|
|
18975
|
+
'headerActions.moveDown': 'Move action down',
|
|
18976
|
+
'headerActions.fields.id': 'ID',
|
|
18977
|
+
'headerActions.fields.label': 'Accessible label',
|
|
18978
|
+
'headerActions.fields.icon': 'Icon',
|
|
18979
|
+
'headerActions.fields.action': 'Emitted action',
|
|
18980
|
+
'headerActions.fields.tooltip': 'Tooltip',
|
|
18981
|
+
'headerActions.fields.color': 'Color',
|
|
18982
|
+
'headerActions.fields.color.default': 'Default',
|
|
18983
|
+
'headerActions.fields.color.basic': 'Basic',
|
|
18984
|
+
'headerActions.fields.color.primary': 'Primary',
|
|
18985
|
+
'headerActions.fields.color.accent': 'Accent',
|
|
18986
|
+
'headerActions.fields.color.warn': 'Warn',
|
|
18987
|
+
'headerActions.fields.visible': 'Visible',
|
|
18988
|
+
'headerActions.fields.disabled': 'Disabled',
|
|
18989
|
+
'headerActions.fields.loading': 'Loading',
|
|
18990
|
+
'headerActions.fields.className': 'CSS class',
|
|
18991
|
+
'headerActions.fields.style': 'Style (JSON)',
|
|
18992
|
+
'headerActions.validation.invalidJson': 'Invalid JSON.',
|
|
18993
|
+
'headerActions.validation.objectJson': 'Provide a valid JSON object.',
|
|
18994
|
+
'headerActions.placeholders.id': 'e.g. help',
|
|
18995
|
+
'headerActions.placeholders.label': 'e.g. Section help',
|
|
18996
|
+
'headerActions.placeholders.icon': 'e.g. help_outline',
|
|
18997
|
+
'headerActions.placeholders.action': 'Optional. If empty, the ID is used',
|
|
18998
|
+
'headerActions.placeholders.tooltip': 'Optional. If empty, the label is used',
|
|
18999
|
+
'headerActions.placeholders.className': 'e.g. section-help-action',
|
|
19000
|
+
'headerActions.placeholders.style': '{"marginLeft":"4px"}',
|
|
19001
|
+
},
|
|
19002
|
+
},
|
|
19003
|
+
},
|
|
19004
|
+
};
|
|
19005
|
+
|
|
18166
19006
|
class SectionEditorComponent {
|
|
18167
19007
|
fb;
|
|
18168
19008
|
data;
|
|
@@ -18231,6 +19071,7 @@ class SectionEditorComponent {
|
|
|
18231
19071
|
className: [this.section.className ?? ''],
|
|
18232
19072
|
testId: [this.section.testId ?? ''],
|
|
18233
19073
|
headerTooltip: [this.section.headerTooltip ?? ''],
|
|
19074
|
+
headerActions: this.fb.array((this.normalizeHeaderActions(this.section.headerActions) ?? []).map((action) => this.createHeaderActionGroup(action))),
|
|
18234
19075
|
});
|
|
18235
19076
|
this.syncCollapsedControlState(!!this.form.get('collapsible')?.value);
|
|
18236
19077
|
this.form.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
@@ -18262,6 +19103,12 @@ class SectionEditorComponent {
|
|
|
18262
19103
|
getSettingsValue() {
|
|
18263
19104
|
return this.normalizeSectionFormValue(this.form.getRawValue());
|
|
18264
19105
|
}
|
|
19106
|
+
get headerActionsArray() {
|
|
19107
|
+
return this.form.get('headerActions');
|
|
19108
|
+
}
|
|
19109
|
+
getHeaderActionStylePlaceholder() {
|
|
19110
|
+
return this.tx('headerActions.placeholders.style', '{"marginLeft":"4px"}');
|
|
19111
|
+
}
|
|
18265
19112
|
async pickIcon() {
|
|
18266
19113
|
const current = this.form.value.icon;
|
|
18267
19114
|
// Use dialog to avoid replacing the settings panel content.
|
|
@@ -18287,6 +19134,30 @@ class SectionEditorComponent {
|
|
|
18287
19134
|
clearFallbackIcon() {
|
|
18288
19135
|
this.form.get('sectionHeader.fallbackIcon')?.setValue('');
|
|
18289
19136
|
}
|
|
19137
|
+
addHeaderAction() {
|
|
19138
|
+
this.headerActionsArray.push(this.createHeaderActionGroup({
|
|
19139
|
+
id: '',
|
|
19140
|
+
label: '',
|
|
19141
|
+
icon: '',
|
|
19142
|
+
visible: true,
|
|
19143
|
+
disabled: false,
|
|
19144
|
+
}));
|
|
19145
|
+
this.applyNormalizedFormValue();
|
|
19146
|
+
this.isDirty$.next(true);
|
|
19147
|
+
}
|
|
19148
|
+
removeHeaderAction(index) {
|
|
19149
|
+
if (index < 0 || index >= this.headerActionsArray.length)
|
|
19150
|
+
return;
|
|
19151
|
+
this.headerActionsArray.removeAt(index);
|
|
19152
|
+
this.applyNormalizedFormValue();
|
|
19153
|
+
this.isDirty$.next(true);
|
|
19154
|
+
}
|
|
19155
|
+
moveHeaderActionUp(index) {
|
|
19156
|
+
this.moveHeaderAction(index, index - 1);
|
|
19157
|
+
}
|
|
19158
|
+
moveHeaderActionDown(index) {
|
|
19159
|
+
this.moveHeaderAction(index, index + 1);
|
|
19160
|
+
}
|
|
18290
19161
|
syncCollapsedControlState(canCollapse) {
|
|
18291
19162
|
const collapsedControl = this.form.get('collapsed');
|
|
18292
19163
|
if (!collapsedControl)
|
|
@@ -18379,8 +19250,8 @@ class SectionEditorComponent {
|
|
|
18379
19250
|
trackFieldOption(index, field) {
|
|
18380
19251
|
return field.value || String(index);
|
|
18381
19252
|
}
|
|
18382
|
-
tx(key, fallback) {
|
|
18383
|
-
return this.i18n.t(key,
|
|
19253
|
+
tx(key, fallback, params) {
|
|
19254
|
+
return this.i18n.t(key, params, fallback, SECTION_EDITOR_I18N_NAMESPACE);
|
|
18384
19255
|
}
|
|
18385
19256
|
applyNormalizedFormValue() {
|
|
18386
19257
|
const normalized = this.normalizeSectionFormValue(this.form.getRawValue());
|
|
@@ -18406,6 +19277,7 @@ class SectionEditorComponent {
|
|
|
18406
19277
|
'className',
|
|
18407
19278
|
'testId',
|
|
18408
19279
|
'headerTooltip',
|
|
19280
|
+
'headerActions',
|
|
18409
19281
|
];
|
|
18410
19282
|
for (const key of managedKeys) {
|
|
18411
19283
|
const value = normalized[key];
|
|
@@ -18440,12 +19312,138 @@ class SectionEditorComponent {
|
|
|
18440
19312
|
className: this.normalizeOptionalString(raw.className),
|
|
18441
19313
|
testId: this.normalizeOptionalString(raw.testId),
|
|
18442
19314
|
headerTooltip: this.normalizeOptionalString(raw.headerTooltip),
|
|
19315
|
+
headerActions: this.normalizeHeaderActions(raw.headerActions),
|
|
18443
19316
|
};
|
|
18444
19317
|
return normalized;
|
|
18445
19318
|
}
|
|
18446
19319
|
normalizeSectionHeader(raw) {
|
|
18447
19320
|
return normalizeSectionHeaderConfig(raw);
|
|
18448
19321
|
}
|
|
19322
|
+
createHeaderActionGroup(action) {
|
|
19323
|
+
return this.fb.group({
|
|
19324
|
+
id: [action?.id ?? ''],
|
|
19325
|
+
label: [action?.label ?? ''],
|
|
19326
|
+
icon: [action?.icon ?? ''],
|
|
19327
|
+
action: [action?.action ?? ''],
|
|
19328
|
+
tooltip: [action?.tooltip ?? ''],
|
|
19329
|
+
color: [action?.color ?? ''],
|
|
19330
|
+
visible: [action?.visible ?? true],
|
|
19331
|
+
disabled: [action?.disabled ?? false],
|
|
19332
|
+
loading: [action?.loading ?? false],
|
|
19333
|
+
className: [action?.className ?? ''],
|
|
19334
|
+
styleJson: [
|
|
19335
|
+
this.stringifyHeaderActionStyle(action?.style),
|
|
19336
|
+
this.headerActionStyleValidator,
|
|
19337
|
+
],
|
|
19338
|
+
});
|
|
19339
|
+
}
|
|
19340
|
+
moveHeaderAction(fromIndex, toIndex) {
|
|
19341
|
+
if (fromIndex < 0 ||
|
|
19342
|
+
fromIndex >= this.headerActionsArray.length ||
|
|
19343
|
+
toIndex < 0 ||
|
|
19344
|
+
toIndex >= this.headerActionsArray.length ||
|
|
19345
|
+
fromIndex === toIndex) {
|
|
19346
|
+
return;
|
|
19347
|
+
}
|
|
19348
|
+
const control = this.headerActionsArray.at(fromIndex);
|
|
19349
|
+
this.headerActionsArray.removeAt(fromIndex);
|
|
19350
|
+
this.headerActionsArray.insert(toIndex, control);
|
|
19351
|
+
this.applyNormalizedFormValue();
|
|
19352
|
+
this.isDirty$.next(true);
|
|
19353
|
+
}
|
|
19354
|
+
normalizeHeaderActions(raw) {
|
|
19355
|
+
if (!Array.isArray(raw))
|
|
19356
|
+
return undefined;
|
|
19357
|
+
const normalized = [];
|
|
19358
|
+
raw.forEach((item) => {
|
|
19359
|
+
const id = this.normalizeOptionalString(item?.id);
|
|
19360
|
+
const icon = this.normalizeOptionalString(item?.icon);
|
|
19361
|
+
const label = this.normalizeOptionalString(item?.label) || id;
|
|
19362
|
+
if (!id || !icon || !label)
|
|
19363
|
+
return;
|
|
19364
|
+
const color = this.normalizeOptionalString(item?.color);
|
|
19365
|
+
const nextAction = {
|
|
19366
|
+
id,
|
|
19367
|
+
label,
|
|
19368
|
+
icon,
|
|
19369
|
+
};
|
|
19370
|
+
const action = this.normalizeOptionalString(item?.action);
|
|
19371
|
+
const tooltip = this.normalizeOptionalString(item?.tooltip);
|
|
19372
|
+
const normalizedColor = color === 'primary' ||
|
|
19373
|
+
color === 'accent' ||
|
|
19374
|
+
color === 'warn' ||
|
|
19375
|
+
color === 'basic'
|
|
19376
|
+
? color
|
|
19377
|
+
: undefined;
|
|
19378
|
+
const className = this.normalizeOptionalString(item?.className);
|
|
19379
|
+
const style = this.parseHeaderActionStyle(item?.styleJson ?? item?.style);
|
|
19380
|
+
if (action !== undefined)
|
|
19381
|
+
nextAction.action = action;
|
|
19382
|
+
if (tooltip !== undefined)
|
|
19383
|
+
nextAction.tooltip = tooltip;
|
|
19384
|
+
if (normalizedColor !== undefined)
|
|
19385
|
+
nextAction.color = normalizedColor;
|
|
19386
|
+
if (item?.visible === false)
|
|
19387
|
+
nextAction.visible = false;
|
|
19388
|
+
if (item?.disabled === true)
|
|
19389
|
+
nextAction.disabled = true;
|
|
19390
|
+
if (item?.loading === true)
|
|
19391
|
+
nextAction.loading = true;
|
|
19392
|
+
if (className !== undefined)
|
|
19393
|
+
nextAction.className = className;
|
|
19394
|
+
if (style !== undefined)
|
|
19395
|
+
nextAction.style = style;
|
|
19396
|
+
normalized.push(nextAction);
|
|
19397
|
+
});
|
|
19398
|
+
return normalized.length ? normalized : undefined;
|
|
19399
|
+
}
|
|
19400
|
+
headerActionStyleValidator = (control) => {
|
|
19401
|
+
const rawValue = control.value;
|
|
19402
|
+
if (rawValue === null || rawValue === undefined || rawValue === '') {
|
|
19403
|
+
return null;
|
|
19404
|
+
}
|
|
19405
|
+
try {
|
|
19406
|
+
const parsed = typeof rawValue === 'string' ? JSON.parse(rawValue) : rawValue;
|
|
19407
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
19408
|
+
return { invalidObjectJson: true };
|
|
19409
|
+
}
|
|
19410
|
+
return null;
|
|
19411
|
+
}
|
|
19412
|
+
catch {
|
|
19413
|
+
return { invalidJson: true };
|
|
19414
|
+
}
|
|
19415
|
+
};
|
|
19416
|
+
stringifyHeaderActionStyle(value) {
|
|
19417
|
+
if (!value || !Object.keys(value).length)
|
|
19418
|
+
return '';
|
|
19419
|
+
try {
|
|
19420
|
+
return JSON.stringify(value, null, 2);
|
|
19421
|
+
}
|
|
19422
|
+
catch {
|
|
19423
|
+
return '';
|
|
19424
|
+
}
|
|
19425
|
+
}
|
|
19426
|
+
parseHeaderActionStyle(value) {
|
|
19427
|
+
if (value === null || value === undefined || value === '')
|
|
19428
|
+
return undefined;
|
|
19429
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
19430
|
+
return Object.keys(value).length
|
|
19431
|
+
? value
|
|
19432
|
+
: undefined;
|
|
19433
|
+
}
|
|
19434
|
+
if (typeof value !== 'string')
|
|
19435
|
+
return undefined;
|
|
19436
|
+
try {
|
|
19437
|
+
const parsed = JSON.parse(value);
|
|
19438
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
19439
|
+
return undefined;
|
|
19440
|
+
}
|
|
19441
|
+
return Object.keys(parsed).length ? parsed : undefined;
|
|
19442
|
+
}
|
|
19443
|
+
catch {
|
|
19444
|
+
return undefined;
|
|
19445
|
+
}
|
|
19446
|
+
}
|
|
18449
19447
|
normalizeOptionalString(value) {
|
|
18450
19448
|
if (typeof value !== 'string')
|
|
18451
19449
|
return undefined;
|
|
@@ -18459,7 +19457,7 @@ class SectionEditorComponent {
|
|
|
18459
19457
|
return Number.isFinite(numeric) ? numeric : undefined;
|
|
18460
19458
|
}
|
|
18461
19459
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SectionEditorComponent, deps: [{ token: i1$3.FormBuilder }, { token: SETTINGS_PANEL_DATA }, { token: i1$2.IconPickerService }, { token: i1$2.PraxisI18nService }], target: i0.ɵɵFactoryTarget.Component });
|
|
18462
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
19460
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: SectionEditorComponent, isStandalone: true, selector: "praxis-section-editor", inputs: { focusTarget: "focusTarget", fieldMetadata: "fieldMetadata" }, providers: [providePraxisI18nConfig(SECTION_EDITOR_I18N_CONFIG)], viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }, { propertyName: "descriptionInput", first: true, predicate: ["descriptionInput"], descendants: true }], ngImport: i0, template: `
|
|
18463
19461
|
<div class="editor-container" *ngIf="form">
|
|
18464
19462
|
<mat-tab-group>
|
|
18465
19463
|
<mat-tab [label]="tx('dynamicForm.sectionEditor.tabs.header', 'Cabeçalho')">
|
|
@@ -18469,15 +19467,15 @@ class SectionEditorComponent {
|
|
|
18469
19467
|
</div>
|
|
18470
19468
|
<form [formGroup]="form" class="stack">
|
|
18471
19469
|
<div class="preset-row">
|
|
18472
|
-
<span class="preset-title">Presets rápidos</span>
|
|
18473
|
-
<button mat-stroked-button type="button" (click)="applyPreset('default')">Padrão</button>
|
|
18474
|
-
<button mat-stroked-button type="button" (click)="applyPreset('simple')">Simples</button>
|
|
18475
|
-
<button mat-stroked-button type="button" (click)="applyPreset('collapsible')">Colapsável</button>
|
|
19470
|
+
<span class="preset-title">{{ tx('dynamicForm.sectionEditor.header.presets.title', 'Presets rápidos') }}</span>
|
|
19471
|
+
<button mat-stroked-button type="button" (click)="applyPreset('default')">{{ tx('dynamicForm.sectionEditor.header.presets.default', 'Padrão') }}</button>
|
|
19472
|
+
<button mat-stroked-button type="button" (click)="applyPreset('simple')">{{ tx('dynamicForm.sectionEditor.header.presets.simple', 'Simples') }}</button>
|
|
19473
|
+
<button mat-stroked-button type="button" (click)="applyPreset('collapsible')">{{ tx('dynamicForm.sectionEditor.header.presets.collapsible', 'Colapsável') }}</button>
|
|
18476
19474
|
</div>
|
|
18477
19475
|
|
|
18478
19476
|
<div class="row-2">
|
|
18479
19477
|
<mat-form-field appearance="fill">
|
|
18480
|
-
<mat-label>Título</mat-label>
|
|
19478
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.title', 'Título') }}</mat-label>
|
|
18481
19479
|
<input matInput #titleInput formControlName="title" />
|
|
18482
19480
|
</mat-form-field>
|
|
18483
19481
|
|
|
@@ -18523,13 +19521,13 @@ class SectionEditorComponent {
|
|
|
18523
19521
|
</div>
|
|
18524
19522
|
|
|
18525
19523
|
<mat-form-field appearance="fill">
|
|
18526
|
-
<mat-label>Descrição</mat-label>
|
|
18527
|
-
<textarea matInput #descriptionInput formControlName="description" placeholder="Resumo curto do conteúdo da seção"></textarea>
|
|
19524
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.description', 'Descrição') }}</mat-label>
|
|
19525
|
+
<textarea matInput #descriptionInput formControlName="description" [placeholder]="tx('dynamicForm.sectionEditor.header.placeholders.description', 'Resumo curto do conteúdo da seção')"></textarea>
|
|
18528
19526
|
</mat-form-field>
|
|
18529
19527
|
|
|
18530
19528
|
<div class="row-3">
|
|
18531
19529
|
<mat-form-field appearance="fill">
|
|
18532
|
-
<mat-label>Aparência</mat-label>
|
|
19530
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.appearance', 'Aparência') }}</mat-label>
|
|
18533
19531
|
<mat-select formControlName="appearance">
|
|
18534
19532
|
<mat-option value="card">Card</mat-option>
|
|
18535
19533
|
<mat-option value="plain">Plain</mat-option>
|
|
@@ -18572,40 +19570,40 @@ class SectionEditorComponent {
|
|
|
18572
19570
|
<mat-divider></mat-divider>
|
|
18573
19571
|
<div class="row-3">
|
|
18574
19572
|
<mat-form-field appearance="fill">
|
|
18575
|
-
<mat-label>Cor do título</mat-label>
|
|
19573
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.titleColor', 'Cor do título') }}</mat-label>
|
|
18576
19574
|
<mat-select formControlName="titleColor">
|
|
18577
|
-
<mat-option value="">Padrão (on-surface)</mat-option>
|
|
18578
|
-
<mat-option value="var(--md-sys-color-primary)">Primária</mat-option>
|
|
18579
|
-
<mat-option value="var(--md-sys-color-secondary)">Secundária</mat-option>
|
|
19575
|
+
<mat-option value="">{{ tx('dynamicForm.sectionEditor.header.options.titleColor.default', 'Padrão (on-surface)') }}</mat-option>
|
|
19576
|
+
<mat-option value="var(--md-sys-color-primary)">{{ tx('dynamicForm.sectionEditor.header.options.titleColor.primary', 'Primária') }}</mat-option>
|
|
19577
|
+
<mat-option value="var(--md-sys-color-secondary)">{{ tx('dynamicForm.sectionEditor.header.options.titleColor.secondary', 'Secundária') }}</mat-option>
|
|
18580
19578
|
<mat-option value="var(--md-sys-color-on-surface-variant)">On surface variant</mat-option>
|
|
18581
19579
|
</mat-select>
|
|
18582
19580
|
</mat-form-field>
|
|
18583
19581
|
<mat-form-field appearance="fill">
|
|
18584
|
-
<mat-label>Cor da descrição</mat-label>
|
|
19582
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.descriptionColor', 'Cor da descrição') }}</mat-label>
|
|
18585
19583
|
<mat-select formControlName="descriptionColor">
|
|
18586
|
-
<mat-option value="">Padrão (on-surface-variant)</mat-option>
|
|
18587
|
-
<mat-option value="var(--md-sys-color-primary)">Primária</mat-option>
|
|
18588
|
-
<mat-option value="var(--md-sys-color-secondary)">Secundária</mat-option>
|
|
19584
|
+
<mat-option value="">{{ tx('dynamicForm.sectionEditor.header.options.descriptionColor.default', 'Padrão (on-surface-variant)') }}</mat-option>
|
|
19585
|
+
<mat-option value="var(--md-sys-color-primary)">{{ tx('dynamicForm.sectionEditor.header.options.descriptionColor.primary', 'Primária') }}</mat-option>
|
|
19586
|
+
<mat-option value="var(--md-sys-color-secondary)">{{ tx('dynamicForm.sectionEditor.header.options.descriptionColor.secondary', 'Secundária') }}</mat-option>
|
|
18589
19587
|
<mat-option value="var(--md-sys-color-on-surface)">On surface</mat-option>
|
|
18590
19588
|
</mat-select>
|
|
18591
19589
|
</mat-form-field>
|
|
18592
19590
|
<mat-form-field appearance="fill">
|
|
18593
|
-
<mat-label>Cor personalizada (CSS)</mat-label>
|
|
18594
|
-
<input matInput placeholder="ex.: #3366ff ou rgb(...)" (input)="setCustomColors($any($event.target).value)" />
|
|
19591
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.customColor', 'Cor personalizada (CSS)') }}</mat-label>
|
|
19592
|
+
<input matInput [placeholder]="tx('dynamicForm.sectionEditor.header.placeholders.customColor', 'ex.: #3366ff ou rgb(...)')" (input)="setCustomColors($any($event.target).value)" />
|
|
18595
19593
|
</mat-form-field>
|
|
18596
19594
|
</div>
|
|
18597
19595
|
|
|
18598
19596
|
<div class="row-3">
|
|
18599
19597
|
<mat-form-field appearance="fill">
|
|
18600
|
-
<mat-label>Gap do título (px)</mat-label>
|
|
19598
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.titleGapBottom', 'Gap do título (px)') }}</mat-label>
|
|
18601
19599
|
<input matInput type="number" formControlName="titleGapBottom" min="0" />
|
|
18602
19600
|
</mat-form-field>
|
|
18603
19601
|
<mat-form-field appearance="fill">
|
|
18604
|
-
<mat-label>Gap da descrição (px)</mat-label>
|
|
19602
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.descriptionGapBottom', 'Gap da descrição (px)') }}</mat-label>
|
|
18605
19603
|
<input matInput type="number" formControlName="descriptionGapBottom" min="0" />
|
|
18606
19604
|
</mat-form-field>
|
|
18607
19605
|
<mat-form-field appearance="fill">
|
|
18608
|
-
<mat-label>Gap abaixo da seção (px)</mat-label>
|
|
19606
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.gapBottom', 'Gap abaixo da seção (px)') }}</mat-label>
|
|
18609
19607
|
<input matInput type="number" min="0" formControlName="gapBottom" />
|
|
18610
19608
|
</mat-form-field>
|
|
18611
19609
|
</div>
|
|
@@ -18613,19 +19611,148 @@ class SectionEditorComponent {
|
|
|
18613
19611
|
<mat-divider></mat-divider>
|
|
18614
19612
|
<div class="row-2">
|
|
18615
19613
|
<mat-slide-toggle formControlName="collapsible">
|
|
18616
|
-
Colapsável
|
|
19614
|
+
{{ tx('dynamicForm.sectionEditor.header.fields.collapsible', 'Colapsável') }}
|
|
18617
19615
|
</mat-slide-toggle>
|
|
18618
19616
|
|
|
18619
19617
|
<mat-slide-toggle formControlName="collapsed">
|
|
18620
|
-
Iniciar recolhida
|
|
19618
|
+
{{ tx('dynamicForm.sectionEditor.header.fields.collapsed', 'Iniciar recolhida') }}
|
|
18621
19619
|
</mat-slide-toggle>
|
|
18622
19620
|
</div>
|
|
18623
19621
|
|
|
18624
19622
|
<mat-form-field appearance="fill">
|
|
18625
|
-
<mat-label>Tooltip do cabeçalho</mat-label>
|
|
18626
|
-
<input matInput formControlName="headerTooltip" placeholder="Dica ao passar o mouse no título" />
|
|
19623
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.headerTooltip', 'Tooltip do cabeçalho') }}</mat-label>
|
|
19624
|
+
<input matInput formControlName="headerTooltip" [placeholder]="tx('dynamicForm.sectionEditor.header.placeholders.headerTooltip', 'Dica ao passar o mouse no título')" />
|
|
18627
19625
|
</mat-form-field>
|
|
18628
19626
|
|
|
19627
|
+
<mat-divider></mat-divider>
|
|
19628
|
+
<div class="inline-section-header">
|
|
19629
|
+
<div>
|
|
19630
|
+
<div class="inline-section-title">{{ tx('headerActions.title', 'Ações do cabeçalho') }}</div>
|
|
19631
|
+
<p class="inline-section-description">
|
|
19632
|
+
{{ tx('headerActions.description', 'Adicione ícones acionáveis no canto direito do cabeçalho da seção para affordances contextuais como ajuda, refresh ou drill-down.') }}
|
|
19633
|
+
</p>
|
|
19634
|
+
</div>
|
|
19635
|
+
<button mat-stroked-button type="button" (click)="addHeaderAction()">
|
|
19636
|
+
{{ tx('headerActions.add', 'Adicionar ação') }}
|
|
19637
|
+
</button>
|
|
19638
|
+
</div>
|
|
19639
|
+
|
|
19640
|
+
@if (!headerActionsArray.length) {
|
|
19641
|
+
<p class="empty-inline-state">
|
|
19642
|
+
{{ tx('headerActions.empty', 'Nenhuma ação configurada para este cabeçalho.') }}
|
|
19643
|
+
</p>
|
|
19644
|
+
}
|
|
19645
|
+
|
|
19646
|
+
<div class="header-actions-list" formArrayName="headerActions">
|
|
19647
|
+
<div class="header-action-card" *ngFor="let actionGroup of headerActionsArray.controls; let index = index" [formGroupName]="index">
|
|
19648
|
+
<div class="header-action-toolbar">
|
|
19649
|
+
<div class="header-action-title">
|
|
19650
|
+
{{ tx('headerActions.item', 'Ação {{index}}', { index: index + 1 }) }}
|
|
19651
|
+
</div>
|
|
19652
|
+
<div class="header-action-toolbar-buttons">
|
|
19653
|
+
<button
|
|
19654
|
+
mat-icon-button
|
|
19655
|
+
type="button"
|
|
19656
|
+
(click)="moveHeaderActionUp(index)"
|
|
19657
|
+
[disabled]="index === 0"
|
|
19658
|
+
[attr.aria-label]="tx('headerActions.moveUp', 'Mover ação para cima')"
|
|
19659
|
+
>
|
|
19660
|
+
<mat-icon [praxisIcon]="'arrow_upward'"></mat-icon>
|
|
19661
|
+
</button>
|
|
19662
|
+
<button
|
|
19663
|
+
mat-icon-button
|
|
19664
|
+
type="button"
|
|
19665
|
+
(click)="moveHeaderActionDown(index)"
|
|
19666
|
+
[disabled]="index === headerActionsArray.length - 1"
|
|
19667
|
+
[attr.aria-label]="tx('headerActions.moveDown', 'Mover ação para baixo')"
|
|
19668
|
+
>
|
|
19669
|
+
<mat-icon [praxisIcon]="'arrow_downward'"></mat-icon>
|
|
19670
|
+
</button>
|
|
19671
|
+
<button
|
|
19672
|
+
mat-icon-button
|
|
19673
|
+
type="button"
|
|
19674
|
+
color="warn"
|
|
19675
|
+
(click)="removeHeaderAction(index)"
|
|
19676
|
+
[attr.aria-label]="tx('headerActions.remove', 'Remover ação')"
|
|
19677
|
+
>
|
|
19678
|
+
<mat-icon [praxisIcon]="'delete'"></mat-icon>
|
|
19679
|
+
</button>
|
|
19680
|
+
</div>
|
|
19681
|
+
</div>
|
|
19682
|
+
|
|
19683
|
+
<div class="row-3">
|
|
19684
|
+
<mat-form-field appearance="fill">
|
|
19685
|
+
<mat-label>{{ tx('headerActions.fields.id', 'ID') }}</mat-label>
|
|
19686
|
+
<input matInput formControlName="id" [placeholder]="tx('headerActions.placeholders.id', 'ex.: help')" />
|
|
19687
|
+
</mat-form-field>
|
|
19688
|
+
|
|
19689
|
+
<mat-form-field appearance="fill">
|
|
19690
|
+
<mat-label>{{ tx('headerActions.fields.label', 'Label acessível') }}</mat-label>
|
|
19691
|
+
<input matInput formControlName="label" [placeholder]="tx('headerActions.placeholders.label', 'ex.: Ajuda da seção')" />
|
|
19692
|
+
</mat-form-field>
|
|
19693
|
+
|
|
19694
|
+
<mat-form-field appearance="fill">
|
|
19695
|
+
<mat-label>{{ tx('headerActions.fields.icon', 'Ícone') }}</mat-label>
|
|
19696
|
+
<input matInput formControlName="icon" [placeholder]="tx('headerActions.placeholders.icon', 'ex.: help_outline')" />
|
|
19697
|
+
</mat-form-field>
|
|
19698
|
+
</div>
|
|
19699
|
+
|
|
19700
|
+
<div class="row-3">
|
|
19701
|
+
<mat-form-field appearance="fill">
|
|
19702
|
+
<mat-label>{{ tx('headerActions.fields.action', 'Action emitida') }}</mat-label>
|
|
19703
|
+
<input matInput formControlName="action" [placeholder]="tx('headerActions.placeholders.action', 'Opcional. Se vazio, usa o ID')" />
|
|
19704
|
+
</mat-form-field>
|
|
19705
|
+
|
|
19706
|
+
<mat-form-field appearance="fill">
|
|
19707
|
+
<mat-label>{{ tx('headerActions.fields.tooltip', 'Tooltip') }}</mat-label>
|
|
19708
|
+
<input matInput formControlName="tooltip" [placeholder]="tx('headerActions.placeholders.tooltip', 'Opcional. Se vazio, usa a label')" />
|
|
19709
|
+
</mat-form-field>
|
|
19710
|
+
|
|
19711
|
+
<mat-form-field appearance="fill">
|
|
19712
|
+
<mat-label>{{ tx('headerActions.fields.color', 'Cor') }}</mat-label>
|
|
19713
|
+
<mat-select formControlName="color">
|
|
19714
|
+
<mat-option value="">{{ tx('headerActions.fields.color.default', 'Padrão') }}</mat-option>
|
|
19715
|
+
<mat-option value="basic">{{ tx('headerActions.fields.color.basic', 'Basic') }}</mat-option>
|
|
19716
|
+
<mat-option value="primary">{{ tx('headerActions.fields.color.primary', 'Primária') }}</mat-option>
|
|
19717
|
+
<mat-option value="accent">{{ tx('headerActions.fields.color.accent', 'Accent') }}</mat-option>
|
|
19718
|
+
<mat-option value="warn">{{ tx('headerActions.fields.color.warn', 'Warn') }}</mat-option>
|
|
19719
|
+
</mat-select>
|
|
19720
|
+
</mat-form-field>
|
|
19721
|
+
</div>
|
|
19722
|
+
|
|
19723
|
+
<div class="row-2">
|
|
19724
|
+
<mat-form-field appearance="fill">
|
|
19725
|
+
<mat-label>{{ tx('headerActions.fields.className', 'Classe CSS') }}</mat-label>
|
|
19726
|
+
<input matInput formControlName="className" [placeholder]="tx('headerActions.placeholders.className', 'ex.: section-help-action')" />
|
|
19727
|
+
</mat-form-field>
|
|
19728
|
+
|
|
19729
|
+
<mat-form-field appearance="fill">
|
|
19730
|
+
<mat-label>{{ tx('headerActions.fields.style', 'Estilo (JSON)') }}</mat-label>
|
|
19731
|
+
<textarea matInput rows="3" formControlName="styleJson" [placeholder]="getHeaderActionStylePlaceholder()"></textarea>
|
|
19732
|
+
@if (actionGroup.get('styleJson')?.hasError('invalidJson')) {
|
|
19733
|
+
<mat-error>{{ tx('headerActions.validation.invalidJson', 'JSON inválido.') }}</mat-error>
|
|
19734
|
+
} @else if (actionGroup.get('styleJson')?.hasError('invalidObjectJson')) {
|
|
19735
|
+
<mat-error>{{ tx('headerActions.validation.objectJson', 'Informe um objeto JSON válido.') }}</mat-error>
|
|
19736
|
+
}
|
|
19737
|
+
</mat-form-field>
|
|
19738
|
+
</div>
|
|
19739
|
+
|
|
19740
|
+
<div class="row-3">
|
|
19741
|
+
<mat-slide-toggle formControlName="visible">
|
|
19742
|
+
{{ tx('headerActions.fields.visible', 'Visível') }}
|
|
19743
|
+
</mat-slide-toggle>
|
|
19744
|
+
|
|
19745
|
+
<mat-slide-toggle formControlName="disabled">
|
|
19746
|
+
{{ tx('headerActions.fields.disabled', 'Desabilitada') }}
|
|
19747
|
+
</mat-slide-toggle>
|
|
19748
|
+
|
|
19749
|
+
<mat-slide-toggle formControlName="loading">
|
|
19750
|
+
{{ tx('headerActions.fields.loading', 'Loading') }}
|
|
19751
|
+
</mat-slide-toggle>
|
|
19752
|
+
</div>
|
|
19753
|
+
</div>
|
|
19754
|
+
</div>
|
|
19755
|
+
|
|
18629
19756
|
<div class="row-2">
|
|
18630
19757
|
<mat-form-field appearance="fill">
|
|
18631
19758
|
<mat-label>Classe CSS</mat-label>
|
|
@@ -18775,11 +19902,11 @@ class SectionEditorComponent {
|
|
|
18775
19902
|
</mat-tab>
|
|
18776
19903
|
</mat-tab-group>
|
|
18777
19904
|
</div>
|
|
18778
|
-
`, isInline: true, styles: [".editor-container{padding:16px}.preset-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:12px}.preset-title{font-weight:600;color:var(--md-sys-color-on-surface-variant)}.bp-group{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0}.stack{display:flex;flex-direction:column;gap:12px}.row-2,.row-3{display:grid;gap:10px;align-items:start}.row-2{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.row-3{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}mat-form-field{width:100%;margin-bottom:12px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.avatar-guidance{border-radius:12px;padding:12px 14px;background:color-mix(in srgb,var(--md-sys-color-primary) 6%,white);border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent)}.avatar-guidance p{margin:0 0 6px;font-size:12px;line-height:1.5;color:var(--md-sys-color-on-surface-variant)}.avatar-guidance p:last-child{margin-bottom:0}.tips p{margin:0 0 6px;font-size:13px;color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { 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.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatTabsModule }, { kind: "directive", type: i7$2.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i7$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$3.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: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$4.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$4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }] });
|
|
19905
|
+
`, isInline: true, styles: [".editor-container{padding:16px}.preset-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:12px}.preset-title{font-weight:600;color:var(--md-sys-color-on-surface-variant)}.bp-group{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0}.inline-section-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}.inline-section-title{font-size:14px;font-weight:700;color:var(--md-sys-color-on-surface)}.inline-section-description{margin:4px 0 0;font-size:12px;line-height:1.5;color:var(--md-sys-color-on-surface-variant);max-width:72ch}.empty-inline-state{margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.header-actions-list{display:flex;flex-direction:column;gap:12px}.header-action-card{border:1px solid var(--md-sys-color-outline-variant);border-radius:14px;padding:12px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,white 18%)}.header-action-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.header-action-title{font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.header-action-toolbar-buttons{display:inline-flex;align-items:center;gap:4px}.stack{display:flex;flex-direction:column;gap:12px}.row-2,.row-3{display:grid;gap:10px;align-items:start}.row-2{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.row-3{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}mat-form-field{width:100%;margin-bottom:12px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.avatar-guidance{border-radius:12px;padding:12px 14px;background:color-mix(in srgb,var(--md-sys-color-primary) 6%,white);border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent)}.avatar-guidance p{margin:0 0 6px;font-size:12px;line-height:1.5;color:var(--md-sys-color-on-surface-variant)}.avatar-guidance p:last-child{margin-bottom:0}.tips p{margin:0 0 6px;font-size:13px;color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { 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.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatTabsModule }, { kind: "directive", type: i7$2.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i7$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$3.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: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$4.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$4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }] });
|
|
18779
19906
|
}
|
|
18780
19907
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SectionEditorComponent, decorators: [{
|
|
18781
19908
|
type: Component,
|
|
18782
|
-
args: [{ selector: 'praxis-section-editor', standalone: true, imports: [
|
|
19909
|
+
args: [{ selector: 'praxis-section-editor', standalone: true, providers: [providePraxisI18nConfig(SECTION_EDITOR_I18N_CONFIG)], imports: [
|
|
18783
19910
|
CommonModule,
|
|
18784
19911
|
ReactiveFormsModule,
|
|
18785
19912
|
MatFormFieldModule,
|
|
@@ -18803,15 +19930,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
18803
19930
|
</div>
|
|
18804
19931
|
<form [formGroup]="form" class="stack">
|
|
18805
19932
|
<div class="preset-row">
|
|
18806
|
-
<span class="preset-title">Presets rápidos</span>
|
|
18807
|
-
<button mat-stroked-button type="button" (click)="applyPreset('default')">Padrão</button>
|
|
18808
|
-
<button mat-stroked-button type="button" (click)="applyPreset('simple')">Simples</button>
|
|
18809
|
-
<button mat-stroked-button type="button" (click)="applyPreset('collapsible')">Colapsável</button>
|
|
19933
|
+
<span class="preset-title">{{ tx('dynamicForm.sectionEditor.header.presets.title', 'Presets rápidos') }}</span>
|
|
19934
|
+
<button mat-stroked-button type="button" (click)="applyPreset('default')">{{ tx('dynamicForm.sectionEditor.header.presets.default', 'Padrão') }}</button>
|
|
19935
|
+
<button mat-stroked-button type="button" (click)="applyPreset('simple')">{{ tx('dynamicForm.sectionEditor.header.presets.simple', 'Simples') }}</button>
|
|
19936
|
+
<button mat-stroked-button type="button" (click)="applyPreset('collapsible')">{{ tx('dynamicForm.sectionEditor.header.presets.collapsible', 'Colapsável') }}</button>
|
|
18810
19937
|
</div>
|
|
18811
19938
|
|
|
18812
19939
|
<div class="row-2">
|
|
18813
19940
|
<mat-form-field appearance="fill">
|
|
18814
|
-
<mat-label>Título</mat-label>
|
|
19941
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.title', 'Título') }}</mat-label>
|
|
18815
19942
|
<input matInput #titleInput formControlName="title" />
|
|
18816
19943
|
</mat-form-field>
|
|
18817
19944
|
|
|
@@ -18857,13 +19984,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
18857
19984
|
</div>
|
|
18858
19985
|
|
|
18859
19986
|
<mat-form-field appearance="fill">
|
|
18860
|
-
<mat-label>Descrição</mat-label>
|
|
18861
|
-
<textarea matInput #descriptionInput formControlName="description" placeholder="Resumo curto do conteúdo da seção"></textarea>
|
|
19987
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.description', 'Descrição') }}</mat-label>
|
|
19988
|
+
<textarea matInput #descriptionInput formControlName="description" [placeholder]="tx('dynamicForm.sectionEditor.header.placeholders.description', 'Resumo curto do conteúdo da seção')"></textarea>
|
|
18862
19989
|
</mat-form-field>
|
|
18863
19990
|
|
|
18864
19991
|
<div class="row-3">
|
|
18865
19992
|
<mat-form-field appearance="fill">
|
|
18866
|
-
<mat-label>Aparência</mat-label>
|
|
19993
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.appearance', 'Aparência') }}</mat-label>
|
|
18867
19994
|
<mat-select formControlName="appearance">
|
|
18868
19995
|
<mat-option value="card">Card</mat-option>
|
|
18869
19996
|
<mat-option value="plain">Plain</mat-option>
|
|
@@ -18906,40 +20033,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
18906
20033
|
<mat-divider></mat-divider>
|
|
18907
20034
|
<div class="row-3">
|
|
18908
20035
|
<mat-form-field appearance="fill">
|
|
18909
|
-
<mat-label>Cor do título</mat-label>
|
|
20036
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.titleColor', 'Cor do título') }}</mat-label>
|
|
18910
20037
|
<mat-select formControlName="titleColor">
|
|
18911
|
-
<mat-option value="">Padrão (on-surface)</mat-option>
|
|
18912
|
-
<mat-option value="var(--md-sys-color-primary)">Primária</mat-option>
|
|
18913
|
-
<mat-option value="var(--md-sys-color-secondary)">Secundária</mat-option>
|
|
20038
|
+
<mat-option value="">{{ tx('dynamicForm.sectionEditor.header.options.titleColor.default', 'Padrão (on-surface)') }}</mat-option>
|
|
20039
|
+
<mat-option value="var(--md-sys-color-primary)">{{ tx('dynamicForm.sectionEditor.header.options.titleColor.primary', 'Primária') }}</mat-option>
|
|
20040
|
+
<mat-option value="var(--md-sys-color-secondary)">{{ tx('dynamicForm.sectionEditor.header.options.titleColor.secondary', 'Secundária') }}</mat-option>
|
|
18914
20041
|
<mat-option value="var(--md-sys-color-on-surface-variant)">On surface variant</mat-option>
|
|
18915
20042
|
</mat-select>
|
|
18916
20043
|
</mat-form-field>
|
|
18917
20044
|
<mat-form-field appearance="fill">
|
|
18918
|
-
<mat-label>Cor da descrição</mat-label>
|
|
20045
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.descriptionColor', 'Cor da descrição') }}</mat-label>
|
|
18919
20046
|
<mat-select formControlName="descriptionColor">
|
|
18920
|
-
<mat-option value="">Padrão (on-surface-variant)</mat-option>
|
|
18921
|
-
<mat-option value="var(--md-sys-color-primary)">Primária</mat-option>
|
|
18922
|
-
<mat-option value="var(--md-sys-color-secondary)">Secundária</mat-option>
|
|
20047
|
+
<mat-option value="">{{ tx('dynamicForm.sectionEditor.header.options.descriptionColor.default', 'Padrão (on-surface-variant)') }}</mat-option>
|
|
20048
|
+
<mat-option value="var(--md-sys-color-primary)">{{ tx('dynamicForm.sectionEditor.header.options.descriptionColor.primary', 'Primária') }}</mat-option>
|
|
20049
|
+
<mat-option value="var(--md-sys-color-secondary)">{{ tx('dynamicForm.sectionEditor.header.options.descriptionColor.secondary', 'Secundária') }}</mat-option>
|
|
18923
20050
|
<mat-option value="var(--md-sys-color-on-surface)">On surface</mat-option>
|
|
18924
20051
|
</mat-select>
|
|
18925
20052
|
</mat-form-field>
|
|
18926
20053
|
<mat-form-field appearance="fill">
|
|
18927
|
-
<mat-label>Cor personalizada (CSS)</mat-label>
|
|
18928
|
-
<input matInput placeholder="ex.: #3366ff ou rgb(...)" (input)="setCustomColors($any($event.target).value)" />
|
|
20054
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.customColor', 'Cor personalizada (CSS)') }}</mat-label>
|
|
20055
|
+
<input matInput [placeholder]="tx('dynamicForm.sectionEditor.header.placeholders.customColor', 'ex.: #3366ff ou rgb(...)')" (input)="setCustomColors($any($event.target).value)" />
|
|
18929
20056
|
</mat-form-field>
|
|
18930
20057
|
</div>
|
|
18931
20058
|
|
|
18932
20059
|
<div class="row-3">
|
|
18933
20060
|
<mat-form-field appearance="fill">
|
|
18934
|
-
<mat-label>Gap do título (px)</mat-label>
|
|
20061
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.titleGapBottom', 'Gap do título (px)') }}</mat-label>
|
|
18935
20062
|
<input matInput type="number" formControlName="titleGapBottom" min="0" />
|
|
18936
20063
|
</mat-form-field>
|
|
18937
20064
|
<mat-form-field appearance="fill">
|
|
18938
|
-
<mat-label>Gap da descrição (px)</mat-label>
|
|
20065
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.descriptionGapBottom', 'Gap da descrição (px)') }}</mat-label>
|
|
18939
20066
|
<input matInput type="number" formControlName="descriptionGapBottom" min="0" />
|
|
18940
20067
|
</mat-form-field>
|
|
18941
20068
|
<mat-form-field appearance="fill">
|
|
18942
|
-
<mat-label>Gap abaixo da seção (px)</mat-label>
|
|
20069
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.gapBottom', 'Gap abaixo da seção (px)') }}</mat-label>
|
|
18943
20070
|
<input matInput type="number" min="0" formControlName="gapBottom" />
|
|
18944
20071
|
</mat-form-field>
|
|
18945
20072
|
</div>
|
|
@@ -18947,19 +20074,148 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
18947
20074
|
<mat-divider></mat-divider>
|
|
18948
20075
|
<div class="row-2">
|
|
18949
20076
|
<mat-slide-toggle formControlName="collapsible">
|
|
18950
|
-
Colapsável
|
|
20077
|
+
{{ tx('dynamicForm.sectionEditor.header.fields.collapsible', 'Colapsável') }}
|
|
18951
20078
|
</mat-slide-toggle>
|
|
18952
20079
|
|
|
18953
20080
|
<mat-slide-toggle formControlName="collapsed">
|
|
18954
|
-
Iniciar recolhida
|
|
20081
|
+
{{ tx('dynamicForm.sectionEditor.header.fields.collapsed', 'Iniciar recolhida') }}
|
|
18955
20082
|
</mat-slide-toggle>
|
|
18956
20083
|
</div>
|
|
18957
20084
|
|
|
18958
20085
|
<mat-form-field appearance="fill">
|
|
18959
|
-
<mat-label>Tooltip do cabeçalho</mat-label>
|
|
18960
|
-
<input matInput formControlName="headerTooltip" placeholder="Dica ao passar o mouse no título" />
|
|
20086
|
+
<mat-label>{{ tx('dynamicForm.sectionEditor.header.fields.headerTooltip', 'Tooltip do cabeçalho') }}</mat-label>
|
|
20087
|
+
<input matInput formControlName="headerTooltip" [placeholder]="tx('dynamicForm.sectionEditor.header.placeholders.headerTooltip', 'Dica ao passar o mouse no título')" />
|
|
18961
20088
|
</mat-form-field>
|
|
18962
20089
|
|
|
20090
|
+
<mat-divider></mat-divider>
|
|
20091
|
+
<div class="inline-section-header">
|
|
20092
|
+
<div>
|
|
20093
|
+
<div class="inline-section-title">{{ tx('headerActions.title', 'Ações do cabeçalho') }}</div>
|
|
20094
|
+
<p class="inline-section-description">
|
|
20095
|
+
{{ tx('headerActions.description', 'Adicione ícones acionáveis no canto direito do cabeçalho da seção para affordances contextuais como ajuda, refresh ou drill-down.') }}
|
|
20096
|
+
</p>
|
|
20097
|
+
</div>
|
|
20098
|
+
<button mat-stroked-button type="button" (click)="addHeaderAction()">
|
|
20099
|
+
{{ tx('headerActions.add', 'Adicionar ação') }}
|
|
20100
|
+
</button>
|
|
20101
|
+
</div>
|
|
20102
|
+
|
|
20103
|
+
@if (!headerActionsArray.length) {
|
|
20104
|
+
<p class="empty-inline-state">
|
|
20105
|
+
{{ tx('headerActions.empty', 'Nenhuma ação configurada para este cabeçalho.') }}
|
|
20106
|
+
</p>
|
|
20107
|
+
}
|
|
20108
|
+
|
|
20109
|
+
<div class="header-actions-list" formArrayName="headerActions">
|
|
20110
|
+
<div class="header-action-card" *ngFor="let actionGroup of headerActionsArray.controls; let index = index" [formGroupName]="index">
|
|
20111
|
+
<div class="header-action-toolbar">
|
|
20112
|
+
<div class="header-action-title">
|
|
20113
|
+
{{ tx('headerActions.item', 'Ação {{index}}', { index: index + 1 }) }}
|
|
20114
|
+
</div>
|
|
20115
|
+
<div class="header-action-toolbar-buttons">
|
|
20116
|
+
<button
|
|
20117
|
+
mat-icon-button
|
|
20118
|
+
type="button"
|
|
20119
|
+
(click)="moveHeaderActionUp(index)"
|
|
20120
|
+
[disabled]="index === 0"
|
|
20121
|
+
[attr.aria-label]="tx('headerActions.moveUp', 'Mover ação para cima')"
|
|
20122
|
+
>
|
|
20123
|
+
<mat-icon [praxisIcon]="'arrow_upward'"></mat-icon>
|
|
20124
|
+
</button>
|
|
20125
|
+
<button
|
|
20126
|
+
mat-icon-button
|
|
20127
|
+
type="button"
|
|
20128
|
+
(click)="moveHeaderActionDown(index)"
|
|
20129
|
+
[disabled]="index === headerActionsArray.length - 1"
|
|
20130
|
+
[attr.aria-label]="tx('headerActions.moveDown', 'Mover ação para baixo')"
|
|
20131
|
+
>
|
|
20132
|
+
<mat-icon [praxisIcon]="'arrow_downward'"></mat-icon>
|
|
20133
|
+
</button>
|
|
20134
|
+
<button
|
|
20135
|
+
mat-icon-button
|
|
20136
|
+
type="button"
|
|
20137
|
+
color="warn"
|
|
20138
|
+
(click)="removeHeaderAction(index)"
|
|
20139
|
+
[attr.aria-label]="tx('headerActions.remove', 'Remover ação')"
|
|
20140
|
+
>
|
|
20141
|
+
<mat-icon [praxisIcon]="'delete'"></mat-icon>
|
|
20142
|
+
</button>
|
|
20143
|
+
</div>
|
|
20144
|
+
</div>
|
|
20145
|
+
|
|
20146
|
+
<div class="row-3">
|
|
20147
|
+
<mat-form-field appearance="fill">
|
|
20148
|
+
<mat-label>{{ tx('headerActions.fields.id', 'ID') }}</mat-label>
|
|
20149
|
+
<input matInput formControlName="id" [placeholder]="tx('headerActions.placeholders.id', 'ex.: help')" />
|
|
20150
|
+
</mat-form-field>
|
|
20151
|
+
|
|
20152
|
+
<mat-form-field appearance="fill">
|
|
20153
|
+
<mat-label>{{ tx('headerActions.fields.label', 'Label acessível') }}</mat-label>
|
|
20154
|
+
<input matInput formControlName="label" [placeholder]="tx('headerActions.placeholders.label', 'ex.: Ajuda da seção')" />
|
|
20155
|
+
</mat-form-field>
|
|
20156
|
+
|
|
20157
|
+
<mat-form-field appearance="fill">
|
|
20158
|
+
<mat-label>{{ tx('headerActions.fields.icon', 'Ícone') }}</mat-label>
|
|
20159
|
+
<input matInput formControlName="icon" [placeholder]="tx('headerActions.placeholders.icon', 'ex.: help_outline')" />
|
|
20160
|
+
</mat-form-field>
|
|
20161
|
+
</div>
|
|
20162
|
+
|
|
20163
|
+
<div class="row-3">
|
|
20164
|
+
<mat-form-field appearance="fill">
|
|
20165
|
+
<mat-label>{{ tx('headerActions.fields.action', 'Action emitida') }}</mat-label>
|
|
20166
|
+
<input matInput formControlName="action" [placeholder]="tx('headerActions.placeholders.action', 'Opcional. Se vazio, usa o ID')" />
|
|
20167
|
+
</mat-form-field>
|
|
20168
|
+
|
|
20169
|
+
<mat-form-field appearance="fill">
|
|
20170
|
+
<mat-label>{{ tx('headerActions.fields.tooltip', 'Tooltip') }}</mat-label>
|
|
20171
|
+
<input matInput formControlName="tooltip" [placeholder]="tx('headerActions.placeholders.tooltip', 'Opcional. Se vazio, usa a label')" />
|
|
20172
|
+
</mat-form-field>
|
|
20173
|
+
|
|
20174
|
+
<mat-form-field appearance="fill">
|
|
20175
|
+
<mat-label>{{ tx('headerActions.fields.color', 'Cor') }}</mat-label>
|
|
20176
|
+
<mat-select formControlName="color">
|
|
20177
|
+
<mat-option value="">{{ tx('headerActions.fields.color.default', 'Padrão') }}</mat-option>
|
|
20178
|
+
<mat-option value="basic">{{ tx('headerActions.fields.color.basic', 'Basic') }}</mat-option>
|
|
20179
|
+
<mat-option value="primary">{{ tx('headerActions.fields.color.primary', 'Primária') }}</mat-option>
|
|
20180
|
+
<mat-option value="accent">{{ tx('headerActions.fields.color.accent', 'Accent') }}</mat-option>
|
|
20181
|
+
<mat-option value="warn">{{ tx('headerActions.fields.color.warn', 'Warn') }}</mat-option>
|
|
20182
|
+
</mat-select>
|
|
20183
|
+
</mat-form-field>
|
|
20184
|
+
</div>
|
|
20185
|
+
|
|
20186
|
+
<div class="row-2">
|
|
20187
|
+
<mat-form-field appearance="fill">
|
|
20188
|
+
<mat-label>{{ tx('headerActions.fields.className', 'Classe CSS') }}</mat-label>
|
|
20189
|
+
<input matInput formControlName="className" [placeholder]="tx('headerActions.placeholders.className', 'ex.: section-help-action')" />
|
|
20190
|
+
</mat-form-field>
|
|
20191
|
+
|
|
20192
|
+
<mat-form-field appearance="fill">
|
|
20193
|
+
<mat-label>{{ tx('headerActions.fields.style', 'Estilo (JSON)') }}</mat-label>
|
|
20194
|
+
<textarea matInput rows="3" formControlName="styleJson" [placeholder]="getHeaderActionStylePlaceholder()"></textarea>
|
|
20195
|
+
@if (actionGroup.get('styleJson')?.hasError('invalidJson')) {
|
|
20196
|
+
<mat-error>{{ tx('headerActions.validation.invalidJson', 'JSON inválido.') }}</mat-error>
|
|
20197
|
+
} @else if (actionGroup.get('styleJson')?.hasError('invalidObjectJson')) {
|
|
20198
|
+
<mat-error>{{ tx('headerActions.validation.objectJson', 'Informe um objeto JSON válido.') }}</mat-error>
|
|
20199
|
+
}
|
|
20200
|
+
</mat-form-field>
|
|
20201
|
+
</div>
|
|
20202
|
+
|
|
20203
|
+
<div class="row-3">
|
|
20204
|
+
<mat-slide-toggle formControlName="visible">
|
|
20205
|
+
{{ tx('headerActions.fields.visible', 'Visível') }}
|
|
20206
|
+
</mat-slide-toggle>
|
|
20207
|
+
|
|
20208
|
+
<mat-slide-toggle formControlName="disabled">
|
|
20209
|
+
{{ tx('headerActions.fields.disabled', 'Desabilitada') }}
|
|
20210
|
+
</mat-slide-toggle>
|
|
20211
|
+
|
|
20212
|
+
<mat-slide-toggle formControlName="loading">
|
|
20213
|
+
{{ tx('headerActions.fields.loading', 'Loading') }}
|
|
20214
|
+
</mat-slide-toggle>
|
|
20215
|
+
</div>
|
|
20216
|
+
</div>
|
|
20217
|
+
</div>
|
|
20218
|
+
|
|
18963
20219
|
<div class="row-2">
|
|
18964
20220
|
<mat-form-field appearance="fill">
|
|
18965
20221
|
<mat-label>Classe CSS</mat-label>
|
|
@@ -19109,7 +20365,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
19109
20365
|
</mat-tab>
|
|
19110
20366
|
</mat-tab-group>
|
|
19111
20367
|
</div>
|
|
19112
|
-
`, styles: [".editor-container{padding:16px}.preset-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:12px}.preset-title{font-weight:600;color:var(--md-sys-color-on-surface-variant)}.bp-group{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0}.stack{display:flex;flex-direction:column;gap:12px}.row-2,.row-3{display:grid;gap:10px;align-items:start}.row-2{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.row-3{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}mat-form-field{width:100%;margin-bottom:12px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.avatar-guidance{border-radius:12px;padding:12px 14px;background:color-mix(in srgb,var(--md-sys-color-primary) 6%,white);border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent)}.avatar-guidance p{margin:0 0 6px;font-size:12px;line-height:1.5;color:var(--md-sys-color-on-surface-variant)}.avatar-guidance p:last-child{margin-bottom:0}.tips p{margin:0 0 6px;font-size:13px;color:var(--md-sys-color-on-surface-variant)}\n"] }]
|
|
20368
|
+
`, styles: [".editor-container{padding:16px}.preset-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:12px}.preset-title{font-weight:600;color:var(--md-sys-color-on-surface-variant)}.bp-group{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0}.inline-section-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}.inline-section-title{font-size:14px;font-weight:700;color:var(--md-sys-color-on-surface)}.inline-section-description{margin:4px 0 0;font-size:12px;line-height:1.5;color:var(--md-sys-color-on-surface-variant);max-width:72ch}.empty-inline-state{margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.header-actions-list{display:flex;flex-direction:column;gap:12px}.header-action-card{border:1px solid var(--md-sys-color-outline-variant);border-radius:14px;padding:12px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,white 18%)}.header-action-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.header-action-title{font-size:13px;font-weight:700;color:var(--md-sys-color-on-surface)}.header-action-toolbar-buttons{display:inline-flex;align-items:center;gap:4px}.stack{display:flex;flex-direction:column;gap:12px}.row-2,.row-3{display:grid;gap:10px;align-items:start}.row-2{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.row-3{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}mat-form-field{width:100%;margin-bottom:12px}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.avatar-guidance{border-radius:12px;padding:12px 14px;background:color-mix(in srgb,var(--md-sys-color-primary) 6%,white);border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent)}.avatar-guidance p{margin:0 0 6px;font-size:12px;line-height:1.5;color:var(--md-sys-color-on-surface-variant)}.avatar-guidance p:last-child{margin-bottom:0}.tips p{margin:0 0 6px;font-size:13px;color:var(--md-sys-color-on-surface-variant)}\n"] }]
|
|
19113
20369
|
}], ctorParameters: () => [{ type: i1$3.FormBuilder }, { type: undefined, decorators: [{
|
|
19114
20370
|
type: Inject,
|
|
19115
20371
|
args: [SETTINGS_PANEL_DATA]
|