@praxisui/dynamic-form 8.0.0-beta.11 → 8.0.0-beta.13
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 +81 -12
- package/fesm2022/praxisui-dynamic-form.mjs +1395 -149
- package/index.d.ts +181 -8
- package/package.json +6 -6
|
@@ -23,16 +23,16 @@ import { MatBadgeModule } from '@angular/material/badge';
|
|
|
23
23
|
import { firstValueFrom, BehaviorSubject, Subject, throwError, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs';
|
|
24
24
|
import { map, take, takeUntil, timeout, tap, debounceTime, finalize } from 'rxjs/operators';
|
|
25
25
|
import * as i1$2 from '@praxisui/core';
|
|
26
|
-
import { PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, ASYNC_CONFIG_STORAGE, migrateFormLayoutRule, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, mapFieldDefinitionsToMetadata, reconcileFormConfig, syncWithServerMetadata, PRAXIS_LOADING_CTX, normalizeControlTypeKey, resolveSpan, resolveOffset, resolveOrder, resolveHidden, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, CONNECTION_STORAGE, API_URL, PRAXIS_LOADING_RENDERER, FORM_HOOKS_PRESETS, EmptyStateCardComponent, isValidFormConfig, ComponentMetadataRegistry, FieldControlType, isRequiredGlobalActionPayloadMissing, GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_ACTION_CATALOG, getGlobalActionCatalog, SURFACE_OPEN_I18N_NAMESPACE, getGlobalActionUiSchema, getRequiredGlobalActionPayloadKeys, hasMeaningfulGlobalActionPayloadValue, SurfaceOpenActionEditorComponent, SURFACE_OPEN_I18N_CONFIG, validateGlobalActionRefs, PraxisJsonLogicService } from '@praxisui/core';
|
|
26
|
+
import { PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, ASYNC_CONFIG_STORAGE, migrateFormLayoutRule, normalizeFormLayoutItems, createFieldLayoutItem, getFormLayoutFieldNames, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, mapFieldDefinitionsToMetadata, reconcileFormConfig, syncWithServerMetadata, PRAXIS_LOADING_CTX, normalizeControlTypeKey, getFormColumnFieldNames, resolveSpan, resolveOffset, resolveOrder, resolveHidden, buildSchemaIdStorageKeySegment, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, CONNECTION_STORAGE, API_URL, PRAXIS_LOADING_RENDERER, FORM_HOOKS_PRESETS, EmptyStateCardComponent, isValidFormConfig, ComponentMetadataRegistry, FieldControlType, isRequiredGlobalActionPayloadMissing, GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_ACTION_CATALOG, getGlobalActionCatalog, SURFACE_OPEN_I18N_NAMESPACE, getGlobalActionUiSchema, getRequiredGlobalActionPayloadKeys, hasMeaningfulGlobalActionPayloadValue, SurfaceOpenActionEditorComponent, SURFACE_OPEN_I18N_CONFIG, validateGlobalActionRefs, PraxisJsonLogicService } from '@praxisui/core';
|
|
27
27
|
import * as i1 from '@praxisui/dynamic-fields';
|
|
28
28
|
import { getControlTypeCatalog, ConfirmDialogComponent, DynamicFieldLoaderDirective } from '@praxisui/dynamic-fields';
|
|
29
29
|
import { BaseAiAdapter, PraxisAiAssistantComponent } from '@praxisui/ai';
|
|
30
|
-
import { PraxisRichContent } from '@praxisui/rich-content';
|
|
30
|
+
import { PraxisRichContent, PraxisRichContentConfigEditor } from '@praxisui/rich-content';
|
|
31
31
|
import * as i6 from '@angular/material/menu';
|
|
32
32
|
import { MatMenuModule } from '@angular/material/menu';
|
|
33
33
|
import { produce } from 'immer';
|
|
34
34
|
import * as i7 from '@praxisui/settings-panel';
|
|
35
|
-
import { SETTINGS_PANEL_DATA, GLOBAL_CONFIG_DYNAMIC_FORM_COMPONENT } from '@praxisui/settings-panel';
|
|
35
|
+
import { SettingsPanelService, SETTINGS_PANEL_DATA, GLOBAL_CONFIG_DYNAMIC_FORM_COMPONENT } from '@praxisui/settings-panel';
|
|
36
36
|
import * as i12 from '@angular/router';
|
|
37
37
|
import * as i7$3 from '@angular/material/tabs';
|
|
38
38
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
@@ -1053,6 +1053,7 @@ var FormRuleTargetType;
|
|
|
1053
1053
|
FormRuleTargetType["Action"] = "action";
|
|
1054
1054
|
FormRuleTargetType["Row"] = "row";
|
|
1055
1055
|
FormRuleTargetType["Column"] = "column";
|
|
1056
|
+
FormRuleTargetType["VisualBlock"] = "visualBlock";
|
|
1056
1057
|
})(FormRuleTargetType || (FormRuleTargetType = {}));
|
|
1057
1058
|
var FormRuleContext;
|
|
1058
1059
|
(function (FormRuleContext) {
|
|
@@ -1157,7 +1158,7 @@ function generateRulePropertyWhenFalseCapabilities(targetType, properties) {
|
|
|
1157
1158
|
return result;
|
|
1158
1159
|
}
|
|
1159
1160
|
const FORM_AI_CAPABILITIES = {
|
|
1160
|
-
version: 'v1.
|
|
1161
|
+
version: 'v1.11', // Publishes column layout items and visual block authoring paths.
|
|
1161
1162
|
enums: ENUMS$1,
|
|
1162
1163
|
targets: [
|
|
1163
1164
|
'praxis-dynamic-form',
|
|
@@ -1177,7 +1178,8 @@ const FORM_AI_CAPABILITIES = {
|
|
|
1177
1178
|
'Este catálogo foca em configurações de alto nÃvel (macro) do formulário e regras.',
|
|
1178
1179
|
'Detalhes de propriedades internas de campos individuais devem ser tratados em catálogos de microcomponentes.',
|
|
1179
1180
|
'Referencie campos pelo name em fieldMetadata[].name.',
|
|
1180
|
-
'Para hierarquia do layout use sections[].rows[].columns[].
|
|
1181
|
+
'Para hierarquia do layout use sections[].rows[].columns[].items como contrato canônico ordenado; items kind:"field" referenciam fieldMetadata e items kind:"richContent" são blocos visuais fora do payload.',
|
|
1182
|
+
'sections[].rows[].columns[].fields permanece como projeção/migração de campos; não use fields para criar blocos visuais.',
|
|
1181
1183
|
'POLICY: Ao alterar arrays de layout (sections, rows, columns), o patch deve ser tratado como merge/append, não replace total.',
|
|
1182
1184
|
'Condições booleanas declarativas devem usar Json Logic canônico. Funções, handlers e hooks continuam exigindo revisão de segurança ou wiring pelo host.',
|
|
1183
1185
|
'Regras condicionais devem usar JSON Logic canônico em rules.condition. Não utilize JS puro nem string ad hoc.',
|
|
@@ -1726,18 +1728,71 @@ const FORM_AI_CAPABILITIES = {
|
|
|
1726
1728
|
path: 'sections[].rows[].columns[].fields',
|
|
1727
1729
|
category: 'layout',
|
|
1728
1730
|
valueKind: 'array',
|
|
1729
|
-
description: '
|
|
1731
|
+
description: 'Projeção legada/derivada dos itens kind:"field" dentro da coluna.',
|
|
1730
1732
|
critical: true,
|
|
1731
1733
|
intentExamples: ['mover campo para a primeira coluna', 'reordenar campos na coluna'],
|
|
1732
|
-
safetyNotes: '
|
|
1734
|
+
safetyNotes: 'Use sections[].rows[].columns[].items para patches novos. fields não suporta blocos visuais.',
|
|
1733
1735
|
},
|
|
1734
1736
|
{
|
|
1735
1737
|
path: 'sections[].rows[].columns[].fields[]',
|
|
1736
1738
|
category: 'layout',
|
|
1737
1739
|
valueKind: 'string',
|
|
1738
|
-
description: 'Nome do campo dentro da coluna.',
|
|
1740
|
+
description: 'Nome do campo dentro da projeção legada/derivada da coluna.',
|
|
1739
1741
|
critical: true,
|
|
1740
|
-
safetyNotes: 'Apenas nomes de campos
|
|
1742
|
+
safetyNotes: 'Apenas nomes de campos. Para ordem mista entre campos e blocos visuais, use items[].',
|
|
1743
|
+
},
|
|
1744
|
+
{
|
|
1745
|
+
path: 'sections[].rows[].columns[].items',
|
|
1746
|
+
category: 'layout',
|
|
1747
|
+
valueKind: 'array',
|
|
1748
|
+
description: 'Lista canônica ordenada de itens da coluna: campos e blocos visuais.',
|
|
1749
|
+
critical: true,
|
|
1750
|
+
intentExamples: ['adicionar bloco visual na coluna', 'mover texto entre campos', 'reordenar campo e aviso visual'],
|
|
1751
|
+
safetyNotes: 'Itens kind:"field" devem apontar para fieldMetadata[].name. Itens kind:"richContent" não entram no payload de submit.',
|
|
1752
|
+
},
|
|
1753
|
+
{
|
|
1754
|
+
path: 'sections[].rows[].columns[].items[].kind',
|
|
1755
|
+
category: 'layout',
|
|
1756
|
+
valueKind: 'enum',
|
|
1757
|
+
allowedValues: ['field', 'richContent'],
|
|
1758
|
+
description: 'Tipo do item de layout da coluna.',
|
|
1759
|
+
critical: true,
|
|
1760
|
+
},
|
|
1761
|
+
{
|
|
1762
|
+
path: 'sections[].rows[].columns[].items[].id',
|
|
1763
|
+
category: 'layout',
|
|
1764
|
+
valueKind: 'string',
|
|
1765
|
+
description: 'ID estável do item de layout dentro do formulário.',
|
|
1766
|
+
critical: true,
|
|
1767
|
+
safetyNotes: 'Use IDs estáveis para mover/atualizar/remover itens; não use Ãndice como identidade.',
|
|
1768
|
+
},
|
|
1769
|
+
{
|
|
1770
|
+
path: 'sections[].rows[].columns[].items[].fieldName',
|
|
1771
|
+
category: 'layout',
|
|
1772
|
+
valueKind: 'string',
|
|
1773
|
+
description: 'Nome do campo quando kind é "field".',
|
|
1774
|
+
critical: true,
|
|
1775
|
+
safetyNotes: 'Deve existir em fieldMetadata[].name.',
|
|
1776
|
+
},
|
|
1777
|
+
{
|
|
1778
|
+
path: 'sections[].rows[].columns[].items[].document',
|
|
1779
|
+
category: 'editorial',
|
|
1780
|
+
valueKind: 'object',
|
|
1781
|
+
description: 'RichContentDocument do bloco visual quando kind é "richContent".',
|
|
1782
|
+
safetyNotes: 'Não participa do formData nem do payload HTTP de submissão.',
|
|
1783
|
+
},
|
|
1784
|
+
{
|
|
1785
|
+
path: 'sections[].rows[].columns[].items[].layout',
|
|
1786
|
+
category: 'editorial',
|
|
1787
|
+
valueKind: 'enum',
|
|
1788
|
+
allowedValues: ['block', 'inline'],
|
|
1789
|
+
description: 'Modo de renderização do bloco visual richContent dentro da coluna.',
|
|
1790
|
+
},
|
|
1791
|
+
{
|
|
1792
|
+
path: 'sections[].rows[].columns[].items[].rootClassName',
|
|
1793
|
+
category: 'appearance',
|
|
1794
|
+
valueKind: 'string',
|
|
1795
|
+
description: 'Classe CSS opcional aplicada ao bloco visual richContent.',
|
|
1741
1796
|
},
|
|
1742
1797
|
{
|
|
1743
1798
|
path: 'sections[].rows[].columns[].span.xs',
|
|
@@ -2701,11 +2756,13 @@ const FORM_AI_CAPABILITIES = {
|
|
|
2701
2756
|
...generateRulePropertyCapabilities(FormRuleTargetType.Action, RULE_PROPERTY_SCHEMA.action),
|
|
2702
2757
|
...generateRulePropertyCapabilities(FormRuleTargetType.Row, RULE_PROPERTY_SCHEMA.row),
|
|
2703
2758
|
...generateRulePropertyCapabilities(FormRuleTargetType.Column, RULE_PROPERTY_SCHEMA.column),
|
|
2759
|
+
...generateRulePropertyCapabilities(FormRuleTargetType.VisualBlock, RULE_PROPERTY_SCHEMA.visualBlock),
|
|
2704
2760
|
...generateRulePropertyWhenFalseCapabilities(FormRuleTargetType.Field, RULE_PROPERTY_SCHEMA.field),
|
|
2705
2761
|
...generateRulePropertyWhenFalseCapabilities(FormRuleTargetType.Section, RULE_PROPERTY_SCHEMA.section),
|
|
2706
2762
|
...generateRulePropertyWhenFalseCapabilities(FormRuleTargetType.Action, RULE_PROPERTY_SCHEMA.action),
|
|
2707
2763
|
...generateRulePropertyWhenFalseCapabilities(FormRuleTargetType.Row, RULE_PROPERTY_SCHEMA.row),
|
|
2708
2764
|
...generateRulePropertyWhenFalseCapabilities(FormRuleTargetType.Column, RULE_PROPERTY_SCHEMA.column),
|
|
2765
|
+
...generateRulePropertyWhenFalseCapabilities(FormRuleTargetType.VisualBlock, RULE_PROPERTY_SCHEMA.visualBlock),
|
|
2709
2766
|
{
|
|
2710
2767
|
path: 'formRulesState',
|
|
2711
2768
|
category: 'rules',
|
|
@@ -3020,6 +3077,13 @@ const TASK_PRESETS = {
|
|
|
3020
3077
|
'sections[].headerActions[].disabled',
|
|
3021
3078
|
'sections[].rows[].gap',
|
|
3022
3079
|
'sections[].rows[].rowGap',
|
|
3080
|
+
'sections[].rows[].columns[].items[]',
|
|
3081
|
+
'sections[].rows[].columns[].items[].kind',
|
|
3082
|
+
'sections[].rows[].columns[].items[].id',
|
|
3083
|
+
'sections[].rows[].columns[].items[].fieldName',
|
|
3084
|
+
'sections[].rows[].columns[].items[].document',
|
|
3085
|
+
'sections[].rows[].columns[].items[].layout',
|
|
3086
|
+
'sections[].rows[].columns[].items[].rootClassName',
|
|
3023
3087
|
'sections[].rows[].columns[].fields[]',
|
|
3024
3088
|
'sections[].rows[].columns[].span.*',
|
|
3025
3089
|
'sections[].rows[].columns[].offset.*',
|
|
@@ -4027,9 +4091,17 @@ function normalizeTargets$1(rule) {
|
|
|
4027
4091
|
: rawTargets.some((t) => t?.startsWith('action:')) ? 'action'
|
|
4028
4092
|
: rawTargets.some((t) => t?.startsWith('row:')) ? 'row'
|
|
4029
4093
|
: rawTargets.some((t) => t?.startsWith('column:')) ? 'column'
|
|
4030
|
-
:
|
|
4094
|
+
: rawTargets.some((t) => t?.startsWith('visualBlock:')) ? 'visualBlock'
|
|
4095
|
+
: rule.targetType || 'field';
|
|
4031
4096
|
const targets = rawTargets.map((t) => stripPrefix(t));
|
|
4032
|
-
const allowed = [
|
|
4097
|
+
const allowed = [
|
|
4098
|
+
'field',
|
|
4099
|
+
'section',
|
|
4100
|
+
'action',
|
|
4101
|
+
'row',
|
|
4102
|
+
'column',
|
|
4103
|
+
'visualBlock',
|
|
4104
|
+
];
|
|
4033
4105
|
const explicit = allowed.includes(rule.targetType)
|
|
4034
4106
|
? rule.targetType
|
|
4035
4107
|
: undefined;
|
|
@@ -4050,6 +4122,8 @@ function stripPrefix(value) {
|
|
|
4050
4122
|
return value.substring('row:'.length);
|
|
4051
4123
|
if (value?.startsWith('column:'))
|
|
4052
4124
|
return value.substring('column:'.length);
|
|
4125
|
+
if (value?.startsWith('visualBlock:'))
|
|
4126
|
+
return value.substring('visualBlock:'.length);
|
|
4053
4127
|
return value;
|
|
4054
4128
|
}
|
|
4055
4129
|
function isScopedSectionHeaderActionTarget$1(value) {
|
|
@@ -4186,6 +4260,7 @@ class FormRulesService {
|
|
|
4186
4260
|
actionProps: {},
|
|
4187
4261
|
rowProps: {},
|
|
4188
4262
|
columnProps: {},
|
|
4263
|
+
visualBlockProps: {},
|
|
4189
4264
|
};
|
|
4190
4265
|
if (!formRules || formRules.length === 0) {
|
|
4191
4266
|
return result;
|
|
@@ -4213,7 +4288,9 @@ class FormRulesService {
|
|
|
4213
4288
|
? result.rowProps
|
|
4214
4289
|
: rule.targetType === 'column'
|
|
4215
4290
|
? result.columnProps
|
|
4216
|
-
:
|
|
4291
|
+
: rule.targetType === 'visualBlock'
|
|
4292
|
+
? result.visualBlockProps
|
|
4293
|
+
: null;
|
|
4217
4294
|
if (!targetMap) {
|
|
4218
4295
|
continue;
|
|
4219
4296
|
}
|
|
@@ -4347,18 +4424,18 @@ class DynamicFormLayoutService {
|
|
|
4347
4424
|
this.changesSubject.next({ timestamp: Date.now(), op, config });
|
|
4348
4425
|
}
|
|
4349
4426
|
normalizeConfig(config) {
|
|
4350
|
-
return produce(config, (draft) => {
|
|
4427
|
+
return ensureIds(produce(config, (draft) => {
|
|
4351
4428
|
draft.sections = draft.sections || [];
|
|
4352
4429
|
draft.sections.forEach((section) => {
|
|
4353
4430
|
section.rows = section.rows || [];
|
|
4354
4431
|
section.rows.forEach((row) => {
|
|
4355
4432
|
row.columns = row.columns || [];
|
|
4356
4433
|
row.columns.forEach((col) => {
|
|
4357
|
-
|
|
4434
|
+
this.applyLayoutItemsToColumn(col, normalizeFormLayoutItems(col));
|
|
4358
4435
|
});
|
|
4359
4436
|
});
|
|
4360
4437
|
});
|
|
4361
|
-
});
|
|
4438
|
+
}));
|
|
4362
4439
|
}
|
|
4363
4440
|
validateConfig(config) {
|
|
4364
4441
|
const errors = [];
|
|
@@ -4373,11 +4450,23 @@ class DynamicFormLayoutService {
|
|
|
4373
4450
|
return;
|
|
4374
4451
|
}
|
|
4375
4452
|
row.columns.forEach((col, cIdx) => {
|
|
4376
|
-
|
|
4377
|
-
|
|
4453
|
+
const rawItems = col.items;
|
|
4454
|
+
if (Array.isArray(rawItems)) {
|
|
4455
|
+
rawItems.forEach((item, itemIdx) => {
|
|
4456
|
+
if (item?.kind === 'field' && !item.fieldName) {
|
|
4457
|
+
errors.push(`field item at section[${sIdx}].row[${rIdx}].column[${cIdx}].item[${itemIdx}] missing fieldName`);
|
|
4458
|
+
}
|
|
4459
|
+
else if (item?.kind === 'richContent' && !item.document) {
|
|
4460
|
+
errors.push(`richContent item at section[${sIdx}].row[${rIdx}].column[${cIdx}].item[${itemIdx}] missing document`);
|
|
4461
|
+
}
|
|
4462
|
+
else if (item?.kind !== 'field' && item?.kind !== 'richContent') {
|
|
4463
|
+
errors.push(`layout item at section[${sIdx}].row[${rIdx}].column[${cIdx}].item[${itemIdx}] has invalid kind`);
|
|
4464
|
+
}
|
|
4465
|
+
});
|
|
4378
4466
|
return;
|
|
4379
4467
|
}
|
|
4380
|
-
col.fields.
|
|
4468
|
+
const fields = Array.isArray(col.fields) ? col.fields : [];
|
|
4469
|
+
fields.forEach((field, fIdx) => {
|
|
4381
4470
|
const name = typeof field === 'string' ? field : field?.name;
|
|
4382
4471
|
if (!name) {
|
|
4383
4472
|
errors.push(`field at section[${sIdx}].row[${rIdx}].column[${cIdx}].field[${fIdx}] missing name`);
|
|
@@ -4641,11 +4730,15 @@ class DynamicFormLayoutService {
|
|
|
4641
4730
|
// Objetivo: 2 campos por linha em telas md+ (6/12 cada) e 1 por linha em xs/sm (12/12)
|
|
4642
4731
|
const perRow = Math.max(1, fieldsPerRow || 2);
|
|
4643
4732
|
const base = Math.max(1, Math.floor(12 / perRow));
|
|
4644
|
-
const columns = rowFields.map((field) =>
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4733
|
+
const columns = rowFields.map((field, index) => {
|
|
4734
|
+
const items = [createFieldLayoutItem(field.name, index)];
|
|
4735
|
+
return {
|
|
4736
|
+
id: this.genId('col'),
|
|
4737
|
+
items,
|
|
4738
|
+
fields: getFormLayoutFieldNames(items),
|
|
4739
|
+
span: { xs: 12, sm: 12, md: base, lg: base, xl: base },
|
|
4740
|
+
};
|
|
4741
|
+
});
|
|
4649
4742
|
rows.push({ id: this.genId('row'), columns });
|
|
4650
4743
|
}
|
|
4651
4744
|
return rows;
|
|
@@ -4671,6 +4764,89 @@ class DynamicFormLayoutService {
|
|
|
4671
4764
|
this.emit(op, next);
|
|
4672
4765
|
return { config: next, op };
|
|
4673
4766
|
}
|
|
4767
|
+
getFieldName(field) {
|
|
4768
|
+
if (typeof field === 'string')
|
|
4769
|
+
return field;
|
|
4770
|
+
if (field && typeof field === 'object') {
|
|
4771
|
+
const name = field.name;
|
|
4772
|
+
return typeof name === 'string' ? name : null;
|
|
4773
|
+
}
|
|
4774
|
+
return null;
|
|
4775
|
+
}
|
|
4776
|
+
findFieldLayoutItemIndex(items, fieldName, fieldIndex) {
|
|
4777
|
+
let visibleFieldIndex = 0;
|
|
4778
|
+
for (let index = 0; index < items.length; index++) {
|
|
4779
|
+
const item = items[index];
|
|
4780
|
+
if (item.kind !== 'field')
|
|
4781
|
+
continue;
|
|
4782
|
+
if (fieldIndex !== undefined && visibleFieldIndex === fieldIndex) {
|
|
4783
|
+
return index;
|
|
4784
|
+
}
|
|
4785
|
+
if (fieldIndex === undefined && fieldName && item.fieldName === fieldName) {
|
|
4786
|
+
return index;
|
|
4787
|
+
}
|
|
4788
|
+
visibleFieldIndex++;
|
|
4789
|
+
}
|
|
4790
|
+
return fieldName
|
|
4791
|
+
? items.findIndex((item) => item.kind === 'field' && item.fieldName === fieldName)
|
|
4792
|
+
: -1;
|
|
4793
|
+
}
|
|
4794
|
+
getLayoutInsertIndexForFieldIndex(items, fieldIndex) {
|
|
4795
|
+
let visibleFieldIndex = 0;
|
|
4796
|
+
for (let index = 0; index < items.length; index++) {
|
|
4797
|
+
if (items[index].kind !== 'field')
|
|
4798
|
+
continue;
|
|
4799
|
+
if (visibleFieldIndex === fieldIndex)
|
|
4800
|
+
return index;
|
|
4801
|
+
visibleFieldIndex++;
|
|
4802
|
+
}
|
|
4803
|
+
return items.length;
|
|
4804
|
+
}
|
|
4805
|
+
applyLayoutItemsToColumn(column, items) {
|
|
4806
|
+
column.items = items;
|
|
4807
|
+
column.fields = getFormLayoutFieldNames(items);
|
|
4808
|
+
}
|
|
4809
|
+
insertFieldLayoutItem(column, field, fieldIndex) {
|
|
4810
|
+
const fieldName = this.getFieldName(field);
|
|
4811
|
+
if (!fieldName)
|
|
4812
|
+
return;
|
|
4813
|
+
const items = normalizeFormLayoutItems(column);
|
|
4814
|
+
const layoutIndex = this.getLayoutInsertIndexForFieldIndex(items, fieldIndex);
|
|
4815
|
+
items.splice(layoutIndex, 0, createFieldLayoutItem(fieldName, fieldIndex));
|
|
4816
|
+
this.applyLayoutItemsToColumn(column, items);
|
|
4817
|
+
}
|
|
4818
|
+
removeFieldLayoutItem(column, fieldIndex) {
|
|
4819
|
+
const items = normalizeFormLayoutItems(column);
|
|
4820
|
+
const layoutIndex = this.findFieldLayoutItemIndex(items, null, fieldIndex);
|
|
4821
|
+
if (layoutIndex >= 0) {
|
|
4822
|
+
items.splice(layoutIndex, 1);
|
|
4823
|
+
}
|
|
4824
|
+
this.applyLayoutItemsToColumn(column, items);
|
|
4825
|
+
}
|
|
4826
|
+
hasLayoutItems(column) {
|
|
4827
|
+
return normalizeFormLayoutItems(column).length > 0;
|
|
4828
|
+
}
|
|
4829
|
+
moveFieldLayoutItem(sourceColumn, destinationColumn, movedField, fromFieldIndex, toFieldIndex) {
|
|
4830
|
+
const fieldName = this.getFieldName(movedField);
|
|
4831
|
+
if (!fieldName)
|
|
4832
|
+
return;
|
|
4833
|
+
const sourceItems = normalizeFormLayoutItems(sourceColumn);
|
|
4834
|
+
const sourceItemIndex = this.findFieldLayoutItemIndex(sourceItems, fieldName, fromFieldIndex);
|
|
4835
|
+
const [movedItem] = sourceItemIndex >= 0
|
|
4836
|
+
? sourceItems.splice(sourceItemIndex, 1)
|
|
4837
|
+
: [createFieldLayoutItem(fieldName, toFieldIndex)];
|
|
4838
|
+
if (sourceColumn === destinationColumn) {
|
|
4839
|
+
const destinationIndex = this.getLayoutInsertIndexForFieldIndex(sourceItems, toFieldIndex);
|
|
4840
|
+
sourceItems.splice(destinationIndex, 0, movedItem);
|
|
4841
|
+
this.applyLayoutItemsToColumn(sourceColumn, sourceItems);
|
|
4842
|
+
return;
|
|
4843
|
+
}
|
|
4844
|
+
const destinationItems = normalizeFormLayoutItems(destinationColumn);
|
|
4845
|
+
const destinationIndex = this.getLayoutInsertIndexForFieldIndex(destinationItems, toFieldIndex);
|
|
4846
|
+
destinationItems.splice(destinationIndex, 0, movedItem);
|
|
4847
|
+
this.applyLayoutItemsToColumn(sourceColumn, sourceItems);
|
|
4848
|
+
this.applyLayoutItemsToColumn(destinationColumn, destinationItems);
|
|
4849
|
+
}
|
|
4674
4850
|
moveSection(config, fromIndex, toIndex) {
|
|
4675
4851
|
const op = { type: 'moveSection', fromIndex, toIndex };
|
|
4676
4852
|
if (fromIndex === toIndex) {
|
|
@@ -4858,12 +5034,12 @@ class DynamicFormLayoutService {
|
|
|
4858
5034
|
columnId: dstCols[to.colIndex].id,
|
|
4859
5035
|
};
|
|
4860
5036
|
return this.mutate(config, op, (draft) => {
|
|
4861
|
-
const
|
|
4862
|
-
.columns[from.colIndex]
|
|
4863
|
-
const
|
|
4864
|
-
const
|
|
4865
|
-
|
|
4866
|
-
if (policy === 'pruneEmptyContainers' &&
|
|
5037
|
+
const srcColumn = draft.sections[from.sectionIndex].rows[from.rowIndex]
|
|
5038
|
+
.columns[from.colIndex];
|
|
5039
|
+
const dstColumn = draft.sections[to.sectionIndex].rows[to.rowIndex].columns[to.colIndex];
|
|
5040
|
+
const moved = srcColumn.fields[from.fieldIndex];
|
|
5041
|
+
this.moveFieldLayoutItem(srcColumn, dstColumn, moved, from.fieldIndex, to.toFieldIndex);
|
|
5042
|
+
if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(srcColumn)) {
|
|
4867
5043
|
draft.sections[from.sectionIndex].rows[from.rowIndex].columns.splice(from.colIndex, 1);
|
|
4868
5044
|
pruned.push('column');
|
|
4869
5045
|
const draftRow = draft.sections[from.sectionIndex].rows[from.rowIndex];
|
|
@@ -4892,8 +5068,8 @@ class DynamicFormLayoutService {
|
|
|
4892
5068
|
this.assertIndex(atIdx, fields.length, 'atIdx', true);
|
|
4893
5069
|
const op = { type: 'insertField', target, field, atIdx };
|
|
4894
5070
|
return this.mutate(config, op, (draft) => {
|
|
4895
|
-
const
|
|
4896
|
-
|
|
5071
|
+
const draftColumn = draft.sections[target.sectionIndex].rows[target.rowIndex].columns[target.colIndex];
|
|
5072
|
+
this.insertFieldLayoutItem(draftColumn, field, atIdx);
|
|
4897
5073
|
});
|
|
4898
5074
|
}
|
|
4899
5075
|
removeField(config, secIdx, rowIdx, colIdx, fieldIndex, options = {}) {
|
|
@@ -4928,10 +5104,9 @@ class DynamicFormLayoutService {
|
|
|
4928
5104
|
};
|
|
4929
5105
|
const pruned = [];
|
|
4930
5106
|
return this.mutate(config, op, (draft) => {
|
|
4931
|
-
const
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
if (policy === 'pruneEmptyContainers' && draftFields.length === 0) {
|
|
5107
|
+
const draftColumn = draft.sections[secIdx].rows[rowIdx].columns[colIdx];
|
|
5108
|
+
this.removeFieldLayoutItem(draftColumn, fieldIndex);
|
|
5109
|
+
if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(draftColumn)) {
|
|
4935
5110
|
draft.sections[secIdx].rows[rowIdx].columns.splice(colIdx, 1);
|
|
4936
5111
|
pruned.push('column');
|
|
4937
5112
|
if (draft.sections[secIdx].rows[rowIdx].columns.length === 0) {
|
|
@@ -5135,13 +5310,13 @@ class DynamicFormLayoutService {
|
|
|
5135
5310
|
this.assertIndex(to.toIndex, dstFields.length, 'to.toIndex', true);
|
|
5136
5311
|
const pruned = [];
|
|
5137
5312
|
return this.mutate(config, op, (draft) => {
|
|
5138
|
-
const
|
|
5139
|
-
.columns[fromPath.colIndex]
|
|
5140
|
-
const
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
if (policy === 'pruneEmptyContainers' &&
|
|
5313
|
+
const srcColumn = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex]
|
|
5314
|
+
.columns[fromPath.colIndex];
|
|
5315
|
+
const dstColumn = draft.sections[toPath.sectionIndex].rows[toPath.rowIndex]
|
|
5316
|
+
.columns[toPath.colIndex];
|
|
5317
|
+
const moved = srcColumn.fields[fromPath.fieldIndex];
|
|
5318
|
+
this.moveFieldLayoutItem(srcColumn, dstColumn, moved, fromPath.fieldIndex, to.toIndex);
|
|
5319
|
+
if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(srcColumn)) {
|
|
5145
5320
|
draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex].columns.splice(fromPath.colIndex, 1);
|
|
5146
5321
|
pruned.push('column');
|
|
5147
5322
|
const draftRow = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex];
|
|
@@ -5167,9 +5342,159 @@ class DynamicFormLayoutService {
|
|
|
5167
5342
|
this.assertIndex(index, fields.length, 'atIndex', true);
|
|
5168
5343
|
const op = { type: 'insertField', target, field, atIndex: index };
|
|
5169
5344
|
return this.mutate(config, op, (draft) => {
|
|
5170
|
-
const
|
|
5171
|
-
.columns[path.colIndex]
|
|
5172
|
-
|
|
5345
|
+
const draftColumn = draft.sections[path.sectionIndex].rows[path.rowIndex]
|
|
5346
|
+
.columns[path.colIndex];
|
|
5347
|
+
this.insertFieldLayoutItem(draftColumn, field, index);
|
|
5348
|
+
});
|
|
5349
|
+
}
|
|
5350
|
+
insertLayoutItemById(config, target, item, atIndex) {
|
|
5351
|
+
const path = this.resolvePathByIds(config, target);
|
|
5352
|
+
const column = config.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
|
|
5353
|
+
const items = normalizeFormLayoutItems(column);
|
|
5354
|
+
const index = atIndex ?? items.length;
|
|
5355
|
+
this.assertIndex(index, items.length, 'atIndex', true);
|
|
5356
|
+
const op = {
|
|
5357
|
+
type: 'insertLayoutItem',
|
|
5358
|
+
target,
|
|
5359
|
+
itemId: item.id,
|
|
5360
|
+
atIndex: index,
|
|
5361
|
+
};
|
|
5362
|
+
return this.mutate(config, op, (draft) => {
|
|
5363
|
+
const draftColumn = draft.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
|
|
5364
|
+
const draftItems = normalizeFormLayoutItems(draftColumn);
|
|
5365
|
+
draftItems.splice(index, 0, item);
|
|
5366
|
+
this.applyLayoutItemsToColumn(draftColumn, draftItems);
|
|
5367
|
+
});
|
|
5368
|
+
}
|
|
5369
|
+
moveLayoutItemById(config, from, to, options = {}) {
|
|
5370
|
+
const fromPath = this.resolvePathByIds(config, from);
|
|
5371
|
+
const toPath = this.resolvePathByIds(config, to);
|
|
5372
|
+
const sourceColumn = config.sections[fromPath.sectionIndex].rows[fromPath.rowIndex].columns[fromPath.colIndex];
|
|
5373
|
+
const sourceItems = normalizeFormLayoutItems(sourceColumn);
|
|
5374
|
+
const fromIndex = sourceItems.findIndex((item) => item.id === from.itemId);
|
|
5375
|
+
if (fromIndex < 0) {
|
|
5376
|
+
throw new Error(`itemId not found: ${from.itemId}`);
|
|
5377
|
+
}
|
|
5378
|
+
const destinationColumn = config.sections[toPath.sectionIndex].rows[toPath.rowIndex].columns[toPath.colIndex];
|
|
5379
|
+
const destinationLength = from.sectionId === to.sectionId &&
|
|
5380
|
+
from.rowId === to.rowId &&
|
|
5381
|
+
from.columnId === to.columnId
|
|
5382
|
+
? sourceItems.length - 1
|
|
5383
|
+
: normalizeFormLayoutItems(destinationColumn).length;
|
|
5384
|
+
this.assertIndex(to.toIndex, destinationLength, 'to.toIndex', true);
|
|
5385
|
+
const policy = options.policy ?? 'keepEmptyContainers';
|
|
5386
|
+
const op = {
|
|
5387
|
+
type: 'moveLayoutItem',
|
|
5388
|
+
correlationId: options.correlationId,
|
|
5389
|
+
origin: options.origin,
|
|
5390
|
+
from: {
|
|
5391
|
+
sectionId: from.sectionId,
|
|
5392
|
+
rowId: from.rowId,
|
|
5393
|
+
columnId: from.columnId,
|
|
5394
|
+
itemId: from.itemId,
|
|
5395
|
+
},
|
|
5396
|
+
to: {
|
|
5397
|
+
sectionId: to.sectionId,
|
|
5398
|
+
rowId: to.rowId,
|
|
5399
|
+
columnId: to.columnId,
|
|
5400
|
+
toIndex: to.toIndex,
|
|
5401
|
+
},
|
|
5402
|
+
policy,
|
|
5403
|
+
};
|
|
5404
|
+
const pruned = [];
|
|
5405
|
+
return this.mutate(config, op, (draft) => {
|
|
5406
|
+
const draftSourceColumn = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex].columns[fromPath.colIndex];
|
|
5407
|
+
const draftSourceItems = normalizeFormLayoutItems(draftSourceColumn);
|
|
5408
|
+
const draftFromIndex = draftSourceItems.findIndex((item) => item.id === from.itemId);
|
|
5409
|
+
const [movedItem] = draftSourceItems.splice(draftFromIndex, 1);
|
|
5410
|
+
if (from.sectionId === to.sectionId &&
|
|
5411
|
+
from.rowId === to.rowId &&
|
|
5412
|
+
from.columnId === to.columnId) {
|
|
5413
|
+
draftSourceItems.splice(to.toIndex, 0, movedItem);
|
|
5414
|
+
this.applyLayoutItemsToColumn(draftSourceColumn, draftSourceItems);
|
|
5415
|
+
}
|
|
5416
|
+
else {
|
|
5417
|
+
const draftDestinationColumn = draft.sections[toPath.sectionIndex].rows[toPath.rowIndex].columns[toPath.colIndex];
|
|
5418
|
+
const draftDestinationItems = normalizeFormLayoutItems(draftDestinationColumn);
|
|
5419
|
+
draftDestinationItems.splice(to.toIndex, 0, movedItem);
|
|
5420
|
+
this.applyLayoutItemsToColumn(draftSourceColumn, draftSourceItems);
|
|
5421
|
+
this.applyLayoutItemsToColumn(draftDestinationColumn, draftDestinationItems);
|
|
5422
|
+
}
|
|
5423
|
+
if (policy === 'pruneEmptyContainers' &&
|
|
5424
|
+
!this.hasLayoutItems(draftSourceColumn)) {
|
|
5425
|
+
draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex].columns.splice(fromPath.colIndex, 1);
|
|
5426
|
+
pruned.push('column');
|
|
5427
|
+
const draftRow = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex];
|
|
5428
|
+
if (draftRow.columns.length === 0) {
|
|
5429
|
+
draft.sections[fromPath.sectionIndex].rows.splice(fromPath.rowIndex, 1);
|
|
5430
|
+
pruned.push('row');
|
|
5431
|
+
if (draft.sections[fromPath.sectionIndex].rows.length === 0) {
|
|
5432
|
+
draft.sections.splice(fromPath.sectionIndex, 1);
|
|
5433
|
+
pruned.push('section');
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5436
|
+
}
|
|
5437
|
+
if (pruned.length) {
|
|
5438
|
+
op.meta = { ...(op.meta || {}), pruned };
|
|
5439
|
+
}
|
|
5440
|
+
});
|
|
5441
|
+
}
|
|
5442
|
+
updateLayoutItemById(config, target, item) {
|
|
5443
|
+
const path = this.resolvePathByIds(config, target);
|
|
5444
|
+
const column = config.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
|
|
5445
|
+
const itemIndex = normalizeFormLayoutItems(column).findIndex((candidate) => candidate.id === target.itemId);
|
|
5446
|
+
if (itemIndex < 0) {
|
|
5447
|
+
throw new Error(`itemId not found: ${target.itemId}`);
|
|
5448
|
+
}
|
|
5449
|
+
const op = {
|
|
5450
|
+
type: 'updateLayoutItem',
|
|
5451
|
+
target,
|
|
5452
|
+
itemId: target.itemId,
|
|
5453
|
+
};
|
|
5454
|
+
return this.mutate(config, op, (draft) => {
|
|
5455
|
+
const draftColumn = draft.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
|
|
5456
|
+
const items = normalizeFormLayoutItems(draftColumn);
|
|
5457
|
+
items[itemIndex] = { ...item, id: target.itemId };
|
|
5458
|
+
this.applyLayoutItemsToColumn(draftColumn, items);
|
|
5459
|
+
});
|
|
5460
|
+
}
|
|
5461
|
+
removeLayoutItemById(config, sectionId, rowId, columnId, itemId, options = {}) {
|
|
5462
|
+
const path = this.resolvePathByIds(config, { sectionId, rowId, columnId });
|
|
5463
|
+
const column = config.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
|
|
5464
|
+
const itemIndex = normalizeFormLayoutItems(column).findIndex((item) => item.id === itemId);
|
|
5465
|
+
if (itemIndex < 0) {
|
|
5466
|
+
throw new Error(`itemId not found: ${itemId}`);
|
|
5467
|
+
}
|
|
5468
|
+
const policy = options.policy ?? 'keepEmptyContainers';
|
|
5469
|
+
const op = {
|
|
5470
|
+
type: 'removeLayoutItem',
|
|
5471
|
+
correlationId: options.correlationId,
|
|
5472
|
+
origin: options.origin,
|
|
5473
|
+
from: { sectionId, rowId, columnId, itemId },
|
|
5474
|
+
policy,
|
|
5475
|
+
};
|
|
5476
|
+
const pruned = [];
|
|
5477
|
+
return this.mutate(config, op, (draft) => {
|
|
5478
|
+
const draftColumn = draft.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
|
|
5479
|
+
const items = normalizeFormLayoutItems(draftColumn);
|
|
5480
|
+
items.splice(itemIndex, 1);
|
|
5481
|
+
this.applyLayoutItemsToColumn(draftColumn, items);
|
|
5482
|
+
if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(draftColumn)) {
|
|
5483
|
+
draft.sections[path.sectionIndex].rows[path.rowIndex].columns.splice(path.colIndex, 1);
|
|
5484
|
+
pruned.push('column');
|
|
5485
|
+
const row = draft.sections[path.sectionIndex].rows[path.rowIndex];
|
|
5486
|
+
if (row.columns.length === 0) {
|
|
5487
|
+
draft.sections[path.sectionIndex].rows.splice(path.rowIndex, 1);
|
|
5488
|
+
pruned.push('row');
|
|
5489
|
+
if (draft.sections[path.sectionIndex].rows.length === 0) {
|
|
5490
|
+
draft.sections.splice(path.sectionIndex, 1);
|
|
5491
|
+
pruned.push('section');
|
|
5492
|
+
}
|
|
5493
|
+
}
|
|
5494
|
+
}
|
|
5495
|
+
if (pruned.length) {
|
|
5496
|
+
op.meta = { ...(op.meta || {}), pruned };
|
|
5497
|
+
}
|
|
5173
5498
|
});
|
|
5174
5499
|
}
|
|
5175
5500
|
removeFieldById(config, sectionId, rowId, columnId, fieldName, options = {}) {
|
|
@@ -5198,10 +5523,10 @@ class DynamicFormLayoutService {
|
|
|
5198
5523
|
};
|
|
5199
5524
|
const pruned = [];
|
|
5200
5525
|
return this.mutate(config, op, (draft) => {
|
|
5201
|
-
const
|
|
5202
|
-
.columns[path.colIndex]
|
|
5203
|
-
|
|
5204
|
-
if (policy === 'pruneEmptyContainers' &&
|
|
5526
|
+
const column = draft.sections[path.sectionIndex].rows[path.rowIndex]
|
|
5527
|
+
.columns[path.colIndex];
|
|
5528
|
+
this.removeFieldLayoutItem(column, path.fieldIndex);
|
|
5529
|
+
if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(column)) {
|
|
5205
5530
|
draft.sections[path.sectionIndex].rows[path.rowIndex].columns.splice(path.colIndex, 1);
|
|
5206
5531
|
pruned.push('column');
|
|
5207
5532
|
const row = draft.sections[path.sectionIndex].rows[path.rowIndex];
|
|
@@ -5228,7 +5553,7 @@ class DynamicFormLayoutService {
|
|
|
5228
5553
|
const pruned = this.mutate(config, op, (draft) => {
|
|
5229
5554
|
draft.sections = (draft.sections || []).filter((section) => {
|
|
5230
5555
|
section.rows = (section.rows || []).filter((row) => {
|
|
5231
|
-
row.columns = (row.columns || []).filter((col) => col
|
|
5556
|
+
row.columns = (row.columns || []).filter((col) => this.hasLayoutItems(col));
|
|
5232
5557
|
return row.columns.length > 0;
|
|
5233
5558
|
});
|
|
5234
5559
|
return section.rows.length > 0;
|
|
@@ -5505,6 +5830,7 @@ class PraxisDynamicForm {
|
|
|
5505
5830
|
actionRuleProps = {};
|
|
5506
5831
|
rowRuleProps = {};
|
|
5507
5832
|
columnRuleProps = {};
|
|
5833
|
+
visualBlockRuleProps = {};
|
|
5508
5834
|
pendingEntityId = null;
|
|
5509
5835
|
loadedEntityId = null;
|
|
5510
5836
|
hydratedEntityId = null;
|
|
@@ -7202,6 +7528,7 @@ class PraxisDynamicForm {
|
|
|
7202
7528
|
this.actionRuleProps = {};
|
|
7203
7529
|
this.rowRuleProps = {};
|
|
7204
7530
|
this.columnRuleProps = {};
|
|
7531
|
+
this.visualBlockRuleProps = {};
|
|
7205
7532
|
this.columnFieldsCache.clear();
|
|
7206
7533
|
return;
|
|
7207
7534
|
}
|
|
@@ -7211,6 +7538,7 @@ class PraxisDynamicForm {
|
|
|
7211
7538
|
this.actionRuleProps = evaluated.actionProps || {};
|
|
7212
7539
|
this.rowRuleProps = evaluated.rowProps || {};
|
|
7213
7540
|
this.columnRuleProps = evaluated.columnProps || {};
|
|
7541
|
+
this.visualBlockRuleProps = evaluated.visualBlockProps || {};
|
|
7214
7542
|
this.columnFieldsCache.clear();
|
|
7215
7543
|
const fieldMetadata = this.config.fieldMetadata || [];
|
|
7216
7544
|
const fieldByName = new Map(fieldMetadata.map((f) => [f.name, f]));
|
|
@@ -7495,7 +7823,7 @@ class PraxisDynamicForm {
|
|
|
7495
7823
|
return true;
|
|
7496
7824
|
}
|
|
7497
7825
|
if (Array.isArray(row.columns) && row.columns.length > 0) {
|
|
7498
|
-
const columnsWithFields = row.columns.filter((column) =>
|
|
7826
|
+
const columnsWithFields = row.columns.filter((column) => getFormColumnFieldNames(column).length > 0);
|
|
7499
7827
|
if (columnsWithFields.length === 0) {
|
|
7500
7828
|
return true;
|
|
7501
7829
|
}
|
|
@@ -7513,7 +7841,7 @@ class PraxisDynamicForm {
|
|
|
7513
7841
|
}
|
|
7514
7842
|
getRowClasses(row) {
|
|
7515
7843
|
const props = this.getRowRuleProps(row);
|
|
7516
|
-
const key = row?.id || JSON.stringify(row?.columns?.map((column) => column.id || column
|
|
7844
|
+
const key = row?.id || JSON.stringify(row?.columns?.map((column) => column.id || this.getColumnItemsSignature(column)) || []);
|
|
7517
7845
|
const signature = String(props.className || '');
|
|
7518
7846
|
const cached = this.rowClassesCache.get(key);
|
|
7519
7847
|
if (cached?.signature === signature) {
|
|
@@ -7527,7 +7855,7 @@ class PraxisDynamicForm {
|
|
|
7527
7855
|
}
|
|
7528
7856
|
getRowStyles(row) {
|
|
7529
7857
|
const props = this.getRowRuleProps(row);
|
|
7530
|
-
const key = row?.id || JSON.stringify(row?.columns?.map((column) => column.id || column
|
|
7858
|
+
const key = row?.id || JSON.stringify(row?.columns?.map((column) => column.id || this.getColumnItemsSignature(column)) || []);
|
|
7531
7859
|
const signature = JSON.stringify(props.style || {});
|
|
7532
7860
|
const cached = this.rowStylesCache.get(key);
|
|
7533
7861
|
if (cached?.signature === signature) {
|
|
@@ -7886,15 +8214,66 @@ class PraxisDynamicForm {
|
|
|
7886
8214
|
const rows = section?.rows || [];
|
|
7887
8215
|
const fieldCount = rows.reduce((acc, row) => {
|
|
7888
8216
|
const cols = row?.columns || [];
|
|
7889
|
-
const colFields = cols.reduce((cAcc, col) => cAcc + (
|
|
8217
|
+
const colFields = cols.reduce((cAcc, col) => cAcc + getFormColumnFieldNames(col).length, 0);
|
|
7890
8218
|
return acc + colFields;
|
|
7891
8219
|
}, 0);
|
|
7892
8220
|
const rowLabel = rows.length === 1 ? 'linha' : 'linhas';
|
|
7893
8221
|
const fieldLabel = fieldCount === 1 ? 'campo' : 'campos';
|
|
7894
8222
|
return `${rows.length} ${rowLabel}, ${fieldCount} ${fieldLabel}`;
|
|
7895
8223
|
}
|
|
8224
|
+
getColumnItems(column) {
|
|
8225
|
+
return normalizeFormLayoutItems(column);
|
|
8226
|
+
}
|
|
8227
|
+
getColumnRenderItems(column) {
|
|
8228
|
+
const renderItems = [];
|
|
8229
|
+
let fieldBatch = [];
|
|
8230
|
+
const flushFieldBatch = () => {
|
|
8231
|
+
if (!fieldBatch.length)
|
|
8232
|
+
return;
|
|
8233
|
+
const batchItems = fieldBatch;
|
|
8234
|
+
fieldBatch = [];
|
|
8235
|
+
const id = `${column.id || 'column'}:fields:${renderItems.length}:${batchItems
|
|
8236
|
+
.map((item) => item.id)
|
|
8237
|
+
.join(',')}`;
|
|
8238
|
+
renderItems.push({
|
|
8239
|
+
kind: 'fields',
|
|
8240
|
+
id,
|
|
8241
|
+
fields: this.getColumnFields({ id, items: batchItems }),
|
|
8242
|
+
});
|
|
8243
|
+
};
|
|
8244
|
+
for (const item of this.getColumnItems(column)) {
|
|
8245
|
+
if (item.kind === 'field') {
|
|
8246
|
+
fieldBatch.push(item);
|
|
8247
|
+
continue;
|
|
8248
|
+
}
|
|
8249
|
+
flushFieldBatch();
|
|
8250
|
+
const document = this.getRichContentLayoutItemDocument(item);
|
|
8251
|
+
if (!document)
|
|
8252
|
+
continue;
|
|
8253
|
+
if (!this.isRichContentLayoutItemVisible(item))
|
|
8254
|
+
continue;
|
|
8255
|
+
const props = this.getVisualBlockRuleProps(item.id);
|
|
8256
|
+
const rootClassName = [item.rootClassName, props.rootClassName]
|
|
8257
|
+
.filter((value) => typeof value === 'string' && !!value.trim())
|
|
8258
|
+
.join(' ') || null;
|
|
8259
|
+
renderItems.push({
|
|
8260
|
+
kind: 'richContent',
|
|
8261
|
+
id: `${column.id || 'column'}:${item.id}`,
|
|
8262
|
+
document,
|
|
8263
|
+
layout: props.layout === 'inline' || props.layout === 'block'
|
|
8264
|
+
? props.layout
|
|
8265
|
+
: this.getRichContentLayoutItemLayout(item),
|
|
8266
|
+
rootClassName,
|
|
8267
|
+
className: props.className ?? null,
|
|
8268
|
+
style: props.style && typeof props.style === 'object' ? props.style : null,
|
|
8269
|
+
});
|
|
8270
|
+
}
|
|
8271
|
+
flushFieldBatch();
|
|
8272
|
+
return renderItems;
|
|
8273
|
+
}
|
|
7896
8274
|
getColumnFields(column) {
|
|
7897
|
-
const
|
|
8275
|
+
const fieldNames = getFormColumnFieldNames(column);
|
|
8276
|
+
const key = column.id || JSON.stringify(fieldNames);
|
|
7898
8277
|
const signature = this.getColumnFieldsSignature(column);
|
|
7899
8278
|
const cached = this.columnFieldsCache.get(key);
|
|
7900
8279
|
if (cached?.signature === signature) {
|
|
@@ -7903,7 +8282,7 @@ class PraxisDynamicForm {
|
|
|
7903
8282
|
const fieldMetadata = this.config.fieldMetadata || [];
|
|
7904
8283
|
const byName = new Map(fieldMetadata.map((f) => [f.name, f]));
|
|
7905
8284
|
const ordered = [];
|
|
7906
|
-
for (const name of
|
|
8285
|
+
for (const name of fieldNames) {
|
|
7907
8286
|
if (this.fieldVisibility[name] === false)
|
|
7908
8287
|
continue;
|
|
7909
8288
|
const meta = byName.get(name);
|
|
@@ -7929,8 +8308,26 @@ class PraxisDynamicForm {
|
|
|
7929
8308
|
this.columnFieldsCache.set(key, { signature, value: ordered });
|
|
7930
8309
|
return ordered;
|
|
7931
8310
|
}
|
|
8311
|
+
getRichContentLayoutItemDocument(item) {
|
|
8312
|
+
return item.kind === 'richContent' && item.document?.kind === 'praxis.rich-content'
|
|
8313
|
+
? item.document
|
|
8314
|
+
: null;
|
|
8315
|
+
}
|
|
8316
|
+
getRichContentLayoutItemLayout(item) {
|
|
8317
|
+
return item.kind === 'richContent' ? item.layout ?? 'block' : 'block';
|
|
8318
|
+
}
|
|
8319
|
+
getVisualBlockRuleProps(itemId) {
|
|
8320
|
+
if (!itemId)
|
|
8321
|
+
return {};
|
|
8322
|
+
return this.visualBlockRuleProps[itemId] || {};
|
|
8323
|
+
}
|
|
8324
|
+
isRichContentLayoutItemVisible(item) {
|
|
8325
|
+
if (item.kind !== 'richContent')
|
|
8326
|
+
return false;
|
|
8327
|
+
return this.resolveRuleVisibility(this.getVisualBlockRuleProps(item.id), true);
|
|
8328
|
+
}
|
|
7932
8329
|
getColumnFieldsSignature(column) {
|
|
7933
|
-
return column
|
|
8330
|
+
return getFormColumnFieldNames(column)
|
|
7934
8331
|
.map((name) => {
|
|
7935
8332
|
const visible = this.fieldVisibility[name] === false ? '0' : '1';
|
|
7936
8333
|
const overrides = this.fieldRuleProps[name];
|
|
@@ -7939,6 +8336,18 @@ class PraxisDynamicForm {
|
|
|
7939
8336
|
})
|
|
7940
8337
|
.join('|');
|
|
7941
8338
|
}
|
|
8339
|
+
getColumnItemsSignature(column) {
|
|
8340
|
+
return normalizeFormLayoutItems(column)
|
|
8341
|
+
.map((item) => {
|
|
8342
|
+
if (item.kind === 'field') {
|
|
8343
|
+
return `field:${item.id}:${item.fieldName}`;
|
|
8344
|
+
}
|
|
8345
|
+
const nodeCount = item.document?.nodes?.length ?? 0;
|
|
8346
|
+
const props = this.getVisualBlockRuleProps(item.id);
|
|
8347
|
+
return `richContent:${item.id}:${item.layout ?? 'block'}:${nodeCount}:${JSON.stringify(props)}`;
|
|
8348
|
+
})
|
|
8349
|
+
.join('|');
|
|
8350
|
+
}
|
|
7942
8351
|
getColumnRuleProps(column) {
|
|
7943
8352
|
if (!column || !column.id)
|
|
7944
8353
|
return {};
|
|
@@ -8138,8 +8547,12 @@ class PraxisDynamicForm {
|
|
|
8138
8547
|
return !this.isResponsiveHiddenActive(props.hidden);
|
|
8139
8548
|
}
|
|
8140
8549
|
}
|
|
8550
|
+
const items = this.getColumnItems(column);
|
|
8551
|
+
if (items.some((item) => item.kind === 'richContent' && this.isRichContentLayoutItemVisible(item))) {
|
|
8552
|
+
return true;
|
|
8553
|
+
}
|
|
8141
8554
|
// A column is visible if at least one of its fields is visible.
|
|
8142
|
-
return
|
|
8555
|
+
return getFormLayoutFieldNames(items).some((fieldName) => this.fieldVisibility[fieldName]);
|
|
8143
8556
|
}
|
|
8144
8557
|
isResponsiveHiddenActive(hidden) {
|
|
8145
8558
|
if (!hidden || typeof hidden !== 'object' || Array.isArray(hidden)) {
|
|
@@ -8719,7 +9132,8 @@ class PraxisDynamicForm {
|
|
|
8719
9132
|
const id = String(schemaId || '').trim();
|
|
8720
9133
|
if (!scopeKey || !id)
|
|
8721
9134
|
return null;
|
|
8722
|
-
|
|
9135
|
+
const storageSegment = buildSchemaIdStorageKeySegment(id);
|
|
9136
|
+
return storageSegment ? `${scopeKey}:schema:${storageSegment}` : null;
|
|
8723
9137
|
}
|
|
8724
9138
|
getSchemaMetaKeyForContext(context) {
|
|
8725
9139
|
try {
|
|
@@ -12282,7 +12696,7 @@ class PraxisDynamicForm {
|
|
|
12282
12696
|
}
|
|
12283
12697
|
}
|
|
12284
12698
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisDynamicForm, deps: [{ token: i1$2.GenericCrudService }, { token: i2.HttpClient }, { token: i1$3.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: FormLayoutService }, { token: FormContextService }, { token: FormRulesService }, { token: i7.SettingsPanelService }, { token: i2$1.MatDialog }, { token: ASYNC_CONFIG_STORAGE }, { token: CONNECTION_STORAGE }, { token: i1$2.DynamicFormService }, { token: i9$1.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: i0.NgZone }, { token: API_URL }, { token: PRAXIS_LOADING_RENDERER, optional: true }, { token: i12.Router, optional: true }, { token: i12.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 });
|
|
12285
|
-
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", initialValue: "initialValue", editorialContext: "editorialContext", mode: "mode", config: "config", actions: "actions", schemaSource: "schemaSource", schemaUrl: "schemaUrl", submitUrl: "submitUrl", submitMethod: "submitMethod", responseSchemaUrl: "responseSchemaUrl", apiEndpointKey: "apiEndpointKey", apiUrlEntry: "apiUrlEntry", 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" }, providers: [providePraxisI18nConfig(PRAXIS_DYNAMIC_FORM_I18N_CONFIG)], 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\" role=\"status\" aria-live=\"polite\" aria-label=\"Carregando formul\u00E1rio\">\n <div class=\"form-loading-header\">\n <mat-progress-spinner diameter=\"32\"></mat-progress-spinner>\n <div class=\"form-loading-copy\">\n <p class=\"form-loading-title\">Carregando formul\u00E1rio...</p>\n <p class=\"form-loading-subtitle\">Preparando campos e op\u00E7\u00F5es do cadastro.</p>\n </div>\n </div>\n <div class=\"form-loading-skeleton\" aria-hidden=\"true\">\n <span class=\"form-loading-line form-loading-line-title\"></span>\n <span class=\"form-loading-line\"></span>\n <span class=\"form-loading-line form-loading-line-short\"></span>\n <span class=\"form-loading-field\"></span>\n <span class=\"form-loading-field form-loading-field-wide\"></span>\n </div>\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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\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 [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"effectiveDisabledMode\"\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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"effectiveActions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n <praxis-rich-content\n [document]=\"formBlocksAfterDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\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:var(--praxis-layer-authoring-hover, 300)}.canvas-mode-enabled .canvas-element.selected{z-index:var(--praxis-layer-authoring-selected, 320)}.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:var(--praxis-layer-authoring-insert, 280)}.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:stretch;justify-content:center;padding:1.25rem;text-align:left;color:var(--md-sys-color-on-surface);gap:1rem;min-height:220px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,var(--md-sys-color-outline-variant) 86%);border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent 42%),color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,var(--md-sys-color-surface) 22%);box-shadow:0 12px 28px #0f172a14}.form-loading-header{display:flex;align-items:center;gap:.85rem}.form-loading-copy{min-width:0}.form-loading p{margin:0}.form-loading-title{font-weight:700;color:var(--md-sys-color-on-surface)}.form-loading-subtitle{margin-top:.2rem;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.form-loading-skeleton{display:grid;gap:.7rem}.form-loading-line,.form-loading-field{display:block;overflow:hidden;position:relative;border-radius:6px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,var(--md-sys-color-primary) 6%)}.form-loading-line:after,.form-loading-field:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 16%,white 18%),transparent);animation:form-loading-shimmer 1.4s ease-in-out infinite}.form-loading-line{height:12px}.form-loading-line-title{width:min(42%,240px)}.form-loading-line-short{width:min(64%,360px)}.form-loading-field{height:44px}.form-loading-field-wide{height:72px}@keyframes form-loading-shimmer{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){.form-loading-line:after,.form-loading-field:after{animation:none;transform:none;opacity:.28}}.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: "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: i16.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: i18.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", "invalidRequiredFieldLabels", "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"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"] }] });
|
|
12699
|
+
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", initialValue: "initialValue", editorialContext: "editorialContext", mode: "mode", config: "config", actions: "actions", schemaSource: "schemaSource", schemaUrl: "schemaUrl", submitUrl: "submitUrl", submitMethod: "submitMethod", responseSchemaUrl: "responseSchemaUrl", apiEndpointKey: "apiEndpointKey", apiUrlEntry: "apiUrlEntry", 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" }, providers: [providePraxisI18nConfig(PRAXIS_DYNAMIC_FORM_I18N_CONFIG)], 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\" role=\"status\" aria-live=\"polite\" aria-label=\"Carregando formul\u00E1rio\">\n <div class=\"form-loading-header\">\n <mat-progress-spinner diameter=\"32\"></mat-progress-spinner>\n <div class=\"form-loading-copy\">\n <p class=\"form-loading-title\">Carregando formul\u00E1rio...</p>\n <p class=\"form-loading-subtitle\">Preparando campos e op\u00E7\u00F5es do cadastro.</p>\n </div>\n </div>\n <div class=\"form-loading-skeleton\" aria-hidden=\"true\">\n <span class=\"form-loading-line form-loading-line-title\"></span>\n <span class=\"form-loading-line\"></span>\n <span class=\"form-loading-line form-loading-line-short\"></span>\n <span class=\"form-loading-field\"></span>\n <span class=\"form-loading-field form-loading-field-wide\"></span>\n </div>\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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\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 @for (renderItem of getColumnRenderItems(column); track renderItem.id) {\n @if (renderItem.kind === 'fields') {\n <ng-container dynamicFieldLoader [fields]=\"renderItem.fields\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"effectiveDisabledMode\"\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 } @else {\n <praxis-rich-content\n class=\"form-layout-rich-content\"\n [ngClass]=\"renderItem.className || null\"\n [ngStyle]=\"renderItem.style || null\"\n [document]=\"renderItem.document\"\n [layout]=\"renderItem.layout\"\n [rootClassName]=\"renderItem.rootClassName || ''\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n }\n }\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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"effectiveActions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n <praxis-rich-content\n [document]=\"formBlocksAfterDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\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:var(--praxis-layer-authoring-hover, 300)}.canvas-mode-enabled .canvas-element.selected{z-index:var(--praxis-layer-authoring-selected, 320)}.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:var(--praxis-layer-authoring-insert, 280)}.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:stretch;justify-content:center;padding:1.25rem;text-align:left;color:var(--md-sys-color-on-surface);gap:1rem;min-height:220px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,var(--md-sys-color-outline-variant) 86%);border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent 42%),color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,var(--md-sys-color-surface) 22%);box-shadow:0 12px 28px #0f172a14}.form-loading-header{display:flex;align-items:center;gap:.85rem}.form-loading-copy{min-width:0}.form-loading p{margin:0}.form-loading-title{font-weight:700;color:var(--md-sys-color-on-surface)}.form-loading-subtitle{margin-top:.2rem;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.form-loading-skeleton{display:grid;gap:.7rem}.form-loading-line,.form-loading-field{display:block;overflow:hidden;position:relative;border-radius:6px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,var(--md-sys-color-primary) 6%)}.form-loading-line:after,.form-loading-field:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 16%,white 18%),transparent);animation:form-loading-shimmer 1.4s ease-in-out infinite}.form-loading-line{height:12px}.form-loading-line-title{width:min(42%,240px)}.form-loading-line-short{width:min(64%,360px)}.form-loading-field{height:44px}.form-loading-field-wide{height:72px}@keyframes form-loading-shimmer{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){.form-loading-line:after,.form-loading-field:after{animation:none;transform:none;opacity:.28}}.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;max-width:100%;min-width:0;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);max-width:100%;min-width:0;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);max-width:100%;min-width:0;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;grid-template-columns:minmax(0,1fr);align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;max-width:100%;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-layout-rich-content{display:block;width:100%;max-width:100%;min-width:0;color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-body-medium, 400 14px/20px system-ui);overflow-wrap:anywhere}:host ::ng-deep .form-layout-rich-content .prx-rich-content-root{display:grid;gap:8px;min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-node{min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-text{color:inherit;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 12%,var(--md-sys-color-outline-variant) 88%);border-left:3px solid var(--md-sys-color-primary);border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 12%,var(--md-sys-color-surface-container-low, var(--md-sys-color-surface)) 88%)}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;align-items:flex-start;padding:11px 12px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note:before{content:\"info\";display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;color:var(--md-sys-color-primary);font-family:Material Symbols Outlined;font-size:20px;font-weight:400;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note .prx-rich-text{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{padding:10px 12px;color:var(--md-sys-color-on-surface)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-compose{align-items:flex-start;gap:10px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-icon{color:var(--md-sys-color-primary);font-size:20px;line-height:20px;margin-top:1px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider{display:grid;grid-template-columns:minmax(24px,1fr) auto minmax(24px,1fr);align-items:center;gap:10px;color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-small, 600 12px/16px system-ui);text-transform:uppercase}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:before,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:after{content:\"\";height:1px;background:var(--md-sys-color-outline-variant)}:host ::ng-deep .form-layout-rich-content .prx-rich-card{gap:6px;padding:12px 14px;border-color:var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface));box-shadow:none}:host ::ng-deep .form-layout-rich-content .prx-rich-card-title{color:var(--md-sys-color-on-surface);font:var(--mdc-typography-title-small, 600 14px/20px system-ui)}:host ::ng-deep .form-layout-rich-content .prx-rich-card .prx-rich-text{color:var(--md-sys-color-on-surface-variant)}.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-row.grid-12{grid-template-columns:minmax(0,1fr)}.form-row.grid-12>.column-drop-wrapper,.form-row.grid-12>.form-column,.form-row.grid-12 .form-column{grid-column:1/-1!important;margin-left:0;width:100%;max-width:100%;min-width:0}.column-drop-wrapper,.row-drop-wrapper,.form-layout-rich-content,.praxis-dynamic-form .mat-mdc-form-field,.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{max-width:100%;min-width:0}:host ::ng-deep .praxis-dynamic-form .pfx-field-shell,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-wrapper,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-host,:host ::ng-deep .praxis-dynamic-form .mat-mdc-form-field,:host ::ng-deep .praxis-dynamic-form .mat-mdc-text-field-wrapper,:host ::ng-deep .praxis-dynamic-form .mdc-text-field{width:100%;max-width:100%;min-width:0}.form-section{padding:clamp(.75rem,4vw,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: "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: i16.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: i18.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", "invalidRequiredFieldLabels", "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"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"] }] });
|
|
12286
12700
|
}
|
|
12287
12701
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisDynamicForm, decorators: [{
|
|
12288
12702
|
type: Component,
|
|
@@ -12303,7 +12717,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
12303
12717
|
EmptyStateCardComponent,
|
|
12304
12718
|
PraxisAiAssistantComponent,
|
|
12305
12719
|
PraxisRichContent,
|
|
12306
|
-
], template: "@if (isLoading) {\n<!-- Loading State -->\n<div class=\"form-loading\" role=\"status\" aria-live=\"polite\" aria-label=\"Carregando formul\u00E1rio\">\n <div class=\"form-loading-header\">\n <mat-progress-spinner diameter=\"32\"></mat-progress-spinner>\n <div class=\"form-loading-copy\">\n <p class=\"form-loading-title\">Carregando formul\u00E1rio...</p>\n <p class=\"form-loading-subtitle\">Preparando campos e op\u00E7\u00F5es do cadastro.</p>\n </div>\n </div>\n <div class=\"form-loading-skeleton\" aria-hidden=\"true\">\n <span class=\"form-loading-line form-loading-line-title\"></span>\n <span class=\"form-loading-line\"></span>\n <span class=\"form-loading-line form-loading-line-short\"></span>\n <span class=\"form-loading-field\"></span>\n <span class=\"form-loading-field form-loading-field-wide\"></span>\n </div>\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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\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 [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"effectiveDisabledMode\"\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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"effectiveActions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n <praxis-rich-content\n [document]=\"formBlocksAfterDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\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:var(--praxis-layer-authoring-hover, 300)}.canvas-mode-enabled .canvas-element.selected{z-index:var(--praxis-layer-authoring-selected, 320)}.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:var(--praxis-layer-authoring-insert, 280)}.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:stretch;justify-content:center;padding:1.25rem;text-align:left;color:var(--md-sys-color-on-surface);gap:1rem;min-height:220px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,var(--md-sys-color-outline-variant) 86%);border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent 42%),color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,var(--md-sys-color-surface) 22%);box-shadow:0 12px 28px #0f172a14}.form-loading-header{display:flex;align-items:center;gap:.85rem}.form-loading-copy{min-width:0}.form-loading p{margin:0}.form-loading-title{font-weight:700;color:var(--md-sys-color-on-surface)}.form-loading-subtitle{margin-top:.2rem;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.form-loading-skeleton{display:grid;gap:.7rem}.form-loading-line,.form-loading-field{display:block;overflow:hidden;position:relative;border-radius:6px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,var(--md-sys-color-primary) 6%)}.form-loading-line:after,.form-loading-field:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 16%,white 18%),transparent);animation:form-loading-shimmer 1.4s ease-in-out infinite}.form-loading-line{height:12px}.form-loading-line-title{width:min(42%,240px)}.form-loading-line-short{width:min(64%,360px)}.form-loading-field{height:44px}.form-loading-field-wide{height:72px}@keyframes form-loading-shimmer{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){.form-loading-line:after,.form-loading-field:after{animation:none;transform:none;opacity:.28}}.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"] }]
|
|
12720
|
+
], template: "@if (isLoading) {\n<!-- Loading State -->\n<div class=\"form-loading\" role=\"status\" aria-live=\"polite\" aria-label=\"Carregando formul\u00E1rio\">\n <div class=\"form-loading-header\">\n <mat-progress-spinner diameter=\"32\"></mat-progress-spinner>\n <div class=\"form-loading-copy\">\n <p class=\"form-loading-title\">Carregando formul\u00E1rio...</p>\n <p class=\"form-loading-subtitle\">Preparando campos e op\u00E7\u00F5es do cadastro.</p>\n </div>\n </div>\n <div class=\"form-loading-skeleton\" aria-hidden=\"true\">\n <span class=\"form-loading-line form-loading-line-title\"></span>\n <span class=\"form-loading-line\"></span>\n <span class=\"form-loading-line form-loading-line-short\"></span>\n <span class=\"form-loading-field\"></span>\n <span class=\"form-loading-field form-loading-field-wide\"></span>\n </div>\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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\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 @for (renderItem of getColumnRenderItems(column); track renderItem.id) {\n @if (renderItem.kind === 'fields') {\n <ng-container dynamicFieldLoader [fields]=\"renderItem.fields\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\n [disabledMode]=\"effectiveDisabledMode\"\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 } @else {\n <praxis-rich-content\n class=\"form-layout-rich-content\"\n [ngClass]=\"renderItem.className || null\"\n [ngStyle]=\"renderItem.style || null\"\n [document]=\"renderItem.document\"\n [layout]=\"renderItem.layout\"\n [rootClassName]=\"renderItem.rootClassName || ''\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n }\n }\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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"effectiveActions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [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?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n <praxis-rich-content\n [document]=\"formBlocksAfterDocument\"\n [context]=\"getEditorialRichContentContext()\"\n ></praxis-rich-content>\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:var(--praxis-layer-authoring-hover, 300)}.canvas-mode-enabled .canvas-element.selected{z-index:var(--praxis-layer-authoring-selected, 320)}.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:var(--praxis-layer-authoring-insert, 280)}.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:stretch;justify-content:center;padding:1.25rem;text-align:left;color:var(--md-sys-color-on-surface);gap:1rem;min-height:220px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,var(--md-sys-color-outline-variant) 86%);border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent 42%),color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,var(--md-sys-color-surface) 22%);box-shadow:0 12px 28px #0f172a14}.form-loading-header{display:flex;align-items:center;gap:.85rem}.form-loading-copy{min-width:0}.form-loading p{margin:0}.form-loading-title{font-weight:700;color:var(--md-sys-color-on-surface)}.form-loading-subtitle{margin-top:.2rem;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.form-loading-skeleton{display:grid;gap:.7rem}.form-loading-line,.form-loading-field{display:block;overflow:hidden;position:relative;border-radius:6px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,var(--md-sys-color-primary) 6%)}.form-loading-line:after,.form-loading-field:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 16%,white 18%),transparent);animation:form-loading-shimmer 1.4s ease-in-out infinite}.form-loading-line{height:12px}.form-loading-line-title{width:min(42%,240px)}.form-loading-line-short{width:min(64%,360px)}.form-loading-field{height:44px}.form-loading-field-wide{height:72px}@keyframes form-loading-shimmer{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){.form-loading-line:after,.form-loading-field:after{animation:none;transform:none;opacity:.28}}.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;max-width:100%;min-width:0;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);max-width:100%;min-width:0;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);max-width:100%;min-width:0;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;grid-template-columns:minmax(0,1fr);align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;max-width:100%;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-layout-rich-content{display:block;width:100%;max-width:100%;min-width:0;color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-body-medium, 400 14px/20px system-ui);overflow-wrap:anywhere}:host ::ng-deep .form-layout-rich-content .prx-rich-content-root{display:grid;gap:8px;min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-node{min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-text{color:inherit;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 12%,var(--md-sys-color-outline-variant) 88%);border-left:3px solid var(--md-sys-color-primary);border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 12%,var(--md-sys-color-surface-container-low, var(--md-sys-color-surface)) 88%)}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;align-items:flex-start;padding:11px 12px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note:before{content:\"info\";display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;color:var(--md-sys-color-primary);font-family:Material Symbols Outlined;font-size:20px;font-weight:400;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note .prx-rich-text{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{padding:10px 12px;color:var(--md-sys-color-on-surface)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-compose{align-items:flex-start;gap:10px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-icon{color:var(--md-sys-color-primary);font-size:20px;line-height:20px;margin-top:1px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider{display:grid;grid-template-columns:minmax(24px,1fr) auto minmax(24px,1fr);align-items:center;gap:10px;color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-small, 600 12px/16px system-ui);text-transform:uppercase}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:before,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:after{content:\"\";height:1px;background:var(--md-sys-color-outline-variant)}:host ::ng-deep .form-layout-rich-content .prx-rich-card{gap:6px;padding:12px 14px;border-color:var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface));box-shadow:none}:host ::ng-deep .form-layout-rich-content .prx-rich-card-title{color:var(--md-sys-color-on-surface);font:var(--mdc-typography-title-small, 600 14px/20px system-ui)}:host ::ng-deep .form-layout-rich-content .prx-rich-card .prx-rich-text{color:var(--md-sys-color-on-surface-variant)}.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-row.grid-12{grid-template-columns:minmax(0,1fr)}.form-row.grid-12>.column-drop-wrapper,.form-row.grid-12>.form-column,.form-row.grid-12 .form-column{grid-column:1/-1!important;margin-left:0;width:100%;max-width:100%;min-width:0}.column-drop-wrapper,.row-drop-wrapper,.form-layout-rich-content,.praxis-dynamic-form .mat-mdc-form-field,.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{max-width:100%;min-width:0}:host ::ng-deep .praxis-dynamic-form .pfx-field-shell,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-wrapper,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-host,:host ::ng-deep .praxis-dynamic-form .mat-mdc-form-field,:host ::ng-deep .praxis-dynamic-form .mat-mdc-text-field-wrapper,:host ::ng-deep .praxis-dynamic-form .mdc-text-field{width:100%;max-width:100%;min-width:0}.form-section{padding:clamp(.75rem,4vw,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"] }]
|
|
12307
12721
|
}], ctorParameters: () => [{ type: i1$2.GenericCrudService }, { type: i2.HttpClient }, { type: i1$3.FormBuilder }, { type: i0.ChangeDetectorRef }, { type: FormLayoutService }, { type: FormContextService }, { type: FormRulesService }, { type: i7.SettingsPanelService }, { type: i2$1.MatDialog }, { type: undefined, decorators: [{
|
|
12308
12722
|
type: Inject,
|
|
12309
12723
|
args: [ASYNC_CONFIG_STORAGE]
|
|
@@ -13086,7 +13500,7 @@ class FieldConfiguratorComponent {
|
|
|
13086
13500
|
<span class="field-type-label">{{ typeLabel }}</span>
|
|
13087
13501
|
</div>
|
|
13088
13502
|
</div>
|
|
13089
|
-
`, isInline: true, styles: [":host{--pdx-surface: var(--md-sys-color-surface);--pdx-surface-variant: var(--md-sys-color-surface-container);--pdx-outline: var(--md-sys-color-outline-variant);--pdx-cat-text: var(--md-sys-color-primary);--pdx-cat-select: var(--md-sys-color-secondary);--pdx-cat-number: var(--md-sys-color-tertiary);--pdx-cat-datetime: var(--md-sys-color-primary);--pdx-cat-boolean: var(--md-sys-color-secondary);--pdx-cat-slider: var(--md-sys-color-tertiary);--pdx-cat-file: var(--md-sys-color-primary);--pdx-cat-color: var(--md-sys-color-secondary);--pdx-cat-id: var(--md-sys-color-secondary)}.field-item{display:grid;grid-template-columns:24px 24px 1fr;grid-auto-rows:min-content;column-gap:6px;row-gap:2px;padding:6px 8px;border:1px solid var(--pdx-outline);border-radius:4px;background:var(--pdx-surface-variant);cursor:grab;border-left-width:4px;border-left-style:solid;border-left-color:var(--pdx-outline)}.field-item.cdk-drag-dragging{cursor:grabbing}.drag-handle,.field-icon{font-size:20px;line-height:1;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;align-self:start;grid-row:1 / span 2}.drag-handle{cursor:grab;grid-column:1}.field-icon{grid-column:2}.field-item.cdk-drag-preview{box-shadow:var(--md-sys-elevation-
|
|
13503
|
+
`, isInline: true, styles: [":host{--pdx-surface: var(--md-sys-color-surface);--pdx-surface-variant: var(--md-sys-color-surface-container);--pdx-outline: var(--md-sys-color-outline-variant);--pdx-cat-text: var(--md-sys-color-primary);--pdx-cat-select: var(--md-sys-color-secondary);--pdx-cat-number: var(--md-sys-color-tertiary);--pdx-cat-datetime: var(--md-sys-color-primary);--pdx-cat-boolean: var(--md-sys-color-secondary);--pdx-cat-slider: var(--md-sys-color-tertiary);--pdx-cat-file: var(--md-sys-color-primary);--pdx-cat-color: var(--md-sys-color-secondary);--pdx-cat-id: var(--md-sys-color-secondary)}.field-item{display:grid;grid-template-columns:24px 24px 1fr;grid-auto-rows:min-content;column-gap:6px;row-gap:2px;padding:6px 8px;border:1px solid var(--pdx-outline);border-radius:4px;background:var(--pdx-surface-variant);cursor:grab;border-left-width:4px;border-left-style:solid;border-left-color:var(--pdx-outline)}.field-item.cdk-drag-dragging{cursor:grabbing}.drag-handle,.field-icon{font-size:20px;line-height:1;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;align-self:start;grid-row:1 / span 2}.drag-handle{cursor:grab;grid-column:1}.field-icon{grid-column:2}.field-item.cdk-drag-preview{box-sizing:border-box;box-shadow:var(--md-sys-elevation-level3);border-color:var(--md-sys-color-primary);background:var(--pdx-surface-variant);cursor:grabbing}.field-item.cdk-drag-placeholder{position:relative;min-height:42px;border-color:transparent;border-left-color:transparent;background:transparent;opacity:1}.field-item.cdk-drag-placeholder>*{visibility:hidden}.field-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.field-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}.field-texts{display:flex;flex-direction:column;grid-column:3;grid-row:1 / span 2;line-height:1.2}.field-label{line-height:24px}.field-type-label{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.field-item.text-type{border-left-color:var(--pdx-cat-text)}.field-item.text-type .field-icon{color:var(--pdx-cat-text)}.field-item.date-type{border-left-color:var(--pdx-cat-datetime)}.field-item.date-type .field-icon{color:var(--pdx-cat-datetime)}.field-item.numeric-type{border-left-color:var(--pdx-cat-number)}.field-item.numeric-type .field-icon{color:var(--pdx-cat-number)}.field-item.select-type{border-left-color:var(--pdx-cat-select)}.field-item.select-type .field-icon{color:var(--pdx-cat-select)}.field-item.boolean-type{border-left-color:var(--pdx-cat-boolean)}.field-item.boolean-type .field-icon{color:var(--pdx-cat-boolean)}.field-item.slider-type{border-left-color:var(--pdx-cat-slider)}.field-item.slider-type .field-icon{color:var(--pdx-cat-slider)}.field-item.file-type{border-left-color:var(--pdx-cat-file)}.field-item.file-type .field-icon{color:var(--pdx-cat-file)}.field-item.color-type{border-left-color:var(--pdx-cat-color)}.field-item.color-type .field-icon{color:var(--pdx-cat-color)}.field-item.id-type{border-left-color:var(--pdx-cat-id)}.field-item.id-type .field-icon{color:var(--pdx-cat-id)}.field-item.unknown-type{border-left-color:var(--md-sys-color-outline)}.field-item.unknown-type .field-icon{color:var(--md-sys-color-outline)}.field-item.ft-input{border-left-color:var(--pdx-cat-text)}.field-item.ft-input .field-icon{color:var(--pdx-cat-text)}.field-item.ft-textarea{border-left-color:var(--pdx-cat-text)}.field-item.ft-textarea .field-icon{color:var(--pdx-cat-text)}.field-item.ft-email{border-left-color:var(--pdx-cat-select)}.field-item.ft-email .field-icon{color:var(--pdx-cat-select)}.field-item.ft-password{border-left-color:var(--pdx-cat-number)}.field-item.ft-password .field-icon{color:var(--pdx-cat-number)}.field-item.ft-url{border-left-color:var(--pdx-cat-text)}.field-item.ft-url .field-icon{color:var(--pdx-cat-text)}.field-item.ft-search{border-left-color:var(--pdx-cat-select)}.field-item.ft-search .field-icon{color:var(--pdx-cat-select)}.field-item.ft-phone{border-left-color:var(--pdx-cat-select)}.field-item.ft-phone .field-icon{color:var(--pdx-cat-select)}.field-item.ft-chip-input{border-left-color:var(--pdx-cat-select)}.field-item.ft-chip-input .field-icon{color:var(--pdx-cat-select)}.field-item.ft-numeric-text-box{border-left-color:var(--pdx-cat-number)}.field-item.ft-numeric-text-box .field-icon{color:var(--pdx-cat-number)}.field-item.ft-currency{border-left-color:var(--pdx-cat-number)}.field-item.ft-currency .field-icon{color:var(--pdx-cat-number)}.field-item.ft-year{border-left-color:var(--pdx-cat-number)}.field-item.ft-year .field-icon{color:var(--pdx-cat-number)}.field-item.ft-cpf-cnpj{border-left-color:var(--pdx-cat-id)}.field-item.ft-cpf-cnpj .field-icon{color:var(--pdx-cat-id)}.field-item.ft-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-auto-complete{border-left-color:var(--pdx-cat-select)}.field-item.ft-auto-complete .field-icon{color:var(--pdx-cat-select)}.field-item.ft-selection-list{border-left-color:var(--pdx-cat-select)}.field-item.ft-selection-list .field-icon{color:var(--pdx-cat-select)}.field-item.ft-tree-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-tree-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree .field-icon{color:var(--pdx-cat-select)}.field-item.ft-transfer-list{border-left-color:var(--pdx-cat-text)}.field-item.ft-transfer-list .field-icon{color:var(--pdx-cat-text)}.field-item.ft-date-input{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-input .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-picker{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-picker .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-month{border-left-color:var(--pdx-cat-select)}.field-item.ft-month .field-icon{color:var(--pdx-cat-select)}.field-item.ft-week{border-left-color:var(--pdx-cat-select)}.field-item.ft-week .field-icon{color:var(--pdx-cat-select)}.field-item.ft-checkbox{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-checkbox .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-radio{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-radio .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-toggle{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-toggle .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-range-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-range-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-color{border-left-color:var(--pdx-cat-color)}.field-item.ft-color .field-icon{color:var(--pdx-cat-color)}.field-item.ft-color-picker{border-left-color:var(--pdx-cat-color)}.field-item.ft-color-picker .field-icon{color:var(--pdx-cat-color)}.field-item.ft-upload{border-left-color:var(--pdx-cat-file)}.field-item.ft-upload .field-icon{color:var(--pdx-cat-file)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
13090
13504
|
}
|
|
13091
13505
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: FieldConfiguratorComponent, decorators: [{
|
|
13092
13506
|
type: Component,
|
|
@@ -13105,14 +13519,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
13105
13519
|
<span class="field-type-label">{{ typeLabel }}</span>
|
|
13106
13520
|
</div>
|
|
13107
13521
|
</div>
|
|
13108
|
-
`, styles: [":host{--pdx-surface: var(--md-sys-color-surface);--pdx-surface-variant: var(--md-sys-color-surface-container);--pdx-outline: var(--md-sys-color-outline-variant);--pdx-cat-text: var(--md-sys-color-primary);--pdx-cat-select: var(--md-sys-color-secondary);--pdx-cat-number: var(--md-sys-color-tertiary);--pdx-cat-datetime: var(--md-sys-color-primary);--pdx-cat-boolean: var(--md-sys-color-secondary);--pdx-cat-slider: var(--md-sys-color-tertiary);--pdx-cat-file: var(--md-sys-color-primary);--pdx-cat-color: var(--md-sys-color-secondary);--pdx-cat-id: var(--md-sys-color-secondary)}.field-item{display:grid;grid-template-columns:24px 24px 1fr;grid-auto-rows:min-content;column-gap:6px;row-gap:2px;padding:6px 8px;border:1px solid var(--pdx-outline);border-radius:4px;background:var(--pdx-surface-variant);cursor:grab;border-left-width:4px;border-left-style:solid;border-left-color:var(--pdx-outline)}.field-item.cdk-drag-dragging{cursor:grabbing}.drag-handle,.field-icon{font-size:20px;line-height:1;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;align-self:start;grid-row:1 / span 2}.drag-handle{cursor:grab;grid-column:1}.field-icon{grid-column:2}.field-item.cdk-drag-preview{box-shadow:var(--md-sys-elevation-
|
|
13522
|
+
`, styles: [":host{--pdx-surface: var(--md-sys-color-surface);--pdx-surface-variant: var(--md-sys-color-surface-container);--pdx-outline: var(--md-sys-color-outline-variant);--pdx-cat-text: var(--md-sys-color-primary);--pdx-cat-select: var(--md-sys-color-secondary);--pdx-cat-number: var(--md-sys-color-tertiary);--pdx-cat-datetime: var(--md-sys-color-primary);--pdx-cat-boolean: var(--md-sys-color-secondary);--pdx-cat-slider: var(--md-sys-color-tertiary);--pdx-cat-file: var(--md-sys-color-primary);--pdx-cat-color: var(--md-sys-color-secondary);--pdx-cat-id: var(--md-sys-color-secondary)}.field-item{display:grid;grid-template-columns:24px 24px 1fr;grid-auto-rows:min-content;column-gap:6px;row-gap:2px;padding:6px 8px;border:1px solid var(--pdx-outline);border-radius:4px;background:var(--pdx-surface-variant);cursor:grab;border-left-width:4px;border-left-style:solid;border-left-color:var(--pdx-outline)}.field-item.cdk-drag-dragging{cursor:grabbing}.drag-handle,.field-icon{font-size:20px;line-height:1;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;align-self:start;grid-row:1 / span 2}.drag-handle{cursor:grab;grid-column:1}.field-icon{grid-column:2}.field-item.cdk-drag-preview{box-sizing:border-box;box-shadow:var(--md-sys-elevation-level3);border-color:var(--md-sys-color-primary);background:var(--pdx-surface-variant);cursor:grabbing}.field-item.cdk-drag-placeholder{position:relative;min-height:42px;border-color:transparent;border-left-color:transparent;background:transparent;opacity:1}.field-item.cdk-drag-placeholder>*{visibility:hidden}.field-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.field-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}.field-texts{display:flex;flex-direction:column;grid-column:3;grid-row:1 / span 2;line-height:1.2}.field-label{line-height:24px}.field-type-label{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.field-item.text-type{border-left-color:var(--pdx-cat-text)}.field-item.text-type .field-icon{color:var(--pdx-cat-text)}.field-item.date-type{border-left-color:var(--pdx-cat-datetime)}.field-item.date-type .field-icon{color:var(--pdx-cat-datetime)}.field-item.numeric-type{border-left-color:var(--pdx-cat-number)}.field-item.numeric-type .field-icon{color:var(--pdx-cat-number)}.field-item.select-type{border-left-color:var(--pdx-cat-select)}.field-item.select-type .field-icon{color:var(--pdx-cat-select)}.field-item.boolean-type{border-left-color:var(--pdx-cat-boolean)}.field-item.boolean-type .field-icon{color:var(--pdx-cat-boolean)}.field-item.slider-type{border-left-color:var(--pdx-cat-slider)}.field-item.slider-type .field-icon{color:var(--pdx-cat-slider)}.field-item.file-type{border-left-color:var(--pdx-cat-file)}.field-item.file-type .field-icon{color:var(--pdx-cat-file)}.field-item.color-type{border-left-color:var(--pdx-cat-color)}.field-item.color-type .field-icon{color:var(--pdx-cat-color)}.field-item.id-type{border-left-color:var(--pdx-cat-id)}.field-item.id-type .field-icon{color:var(--pdx-cat-id)}.field-item.unknown-type{border-left-color:var(--md-sys-color-outline)}.field-item.unknown-type .field-icon{color:var(--md-sys-color-outline)}.field-item.ft-input{border-left-color:var(--pdx-cat-text)}.field-item.ft-input .field-icon{color:var(--pdx-cat-text)}.field-item.ft-textarea{border-left-color:var(--pdx-cat-text)}.field-item.ft-textarea .field-icon{color:var(--pdx-cat-text)}.field-item.ft-email{border-left-color:var(--pdx-cat-select)}.field-item.ft-email .field-icon{color:var(--pdx-cat-select)}.field-item.ft-password{border-left-color:var(--pdx-cat-number)}.field-item.ft-password .field-icon{color:var(--pdx-cat-number)}.field-item.ft-url{border-left-color:var(--pdx-cat-text)}.field-item.ft-url .field-icon{color:var(--pdx-cat-text)}.field-item.ft-search{border-left-color:var(--pdx-cat-select)}.field-item.ft-search .field-icon{color:var(--pdx-cat-select)}.field-item.ft-phone{border-left-color:var(--pdx-cat-select)}.field-item.ft-phone .field-icon{color:var(--pdx-cat-select)}.field-item.ft-chip-input{border-left-color:var(--pdx-cat-select)}.field-item.ft-chip-input .field-icon{color:var(--pdx-cat-select)}.field-item.ft-numeric-text-box{border-left-color:var(--pdx-cat-number)}.field-item.ft-numeric-text-box .field-icon{color:var(--pdx-cat-number)}.field-item.ft-currency{border-left-color:var(--pdx-cat-number)}.field-item.ft-currency .field-icon{color:var(--pdx-cat-number)}.field-item.ft-year{border-left-color:var(--pdx-cat-number)}.field-item.ft-year .field-icon{color:var(--pdx-cat-number)}.field-item.ft-cpf-cnpj{border-left-color:var(--pdx-cat-id)}.field-item.ft-cpf-cnpj .field-icon{color:var(--pdx-cat-id)}.field-item.ft-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-auto-complete{border-left-color:var(--pdx-cat-select)}.field-item.ft-auto-complete .field-icon{color:var(--pdx-cat-select)}.field-item.ft-selection-list{border-left-color:var(--pdx-cat-select)}.field-item.ft-selection-list .field-icon{color:var(--pdx-cat-select)}.field-item.ft-tree-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-tree-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree .field-icon{color:var(--pdx-cat-select)}.field-item.ft-transfer-list{border-left-color:var(--pdx-cat-text)}.field-item.ft-transfer-list .field-icon{color:var(--pdx-cat-text)}.field-item.ft-date-input{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-input .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-picker{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-picker .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-month{border-left-color:var(--pdx-cat-select)}.field-item.ft-month .field-icon{color:var(--pdx-cat-select)}.field-item.ft-week{border-left-color:var(--pdx-cat-select)}.field-item.ft-week .field-icon{color:var(--pdx-cat-select)}.field-item.ft-checkbox{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-checkbox .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-radio{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-radio .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-toggle{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-toggle .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-range-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-range-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-color{border-left-color:var(--pdx-cat-color)}.field-item.ft-color .field-icon{color:var(--pdx-cat-color)}.field-item.ft-color-picker{border-left-color:var(--pdx-cat-color)}.field-item.ft-color-picker .field-icon{color:var(--pdx-cat-color)}.field-item.ft-upload{border-left-color:var(--pdx-cat-file)}.field-item.ft-upload .field-icon{color:var(--pdx-cat-file)}\n"] }]
|
|
13109
13523
|
}], propDecorators: { field: [{
|
|
13110
13524
|
type: Input
|
|
13111
13525
|
}] } });
|
|
13112
13526
|
|
|
13527
|
+
const LAYOUT_EDITOR_I18N_NAMESPACE = 'praxisDynamicFormLayoutEditor';
|
|
13528
|
+
const LAYOUT_EDITOR_DEFAULT_COPY = {
|
|
13529
|
+
'apiFields.heading': 'Campos da API',
|
|
13530
|
+
'apiFields.hint': 'Campos do fieldMetadata ainda não alocados no layout.',
|
|
13531
|
+
'apiFields.addAction': 'Adicionar campo da API',
|
|
13532
|
+
'apiFields.empty': 'Nenhum campo da API disponível',
|
|
13533
|
+
'apiFields.addTooltip': 'Adicionar campo existente da API nesta coluna',
|
|
13534
|
+
'visualBlock.label': 'Bloco visual',
|
|
13535
|
+
'visualBlock.previewEyebrow': 'Bloco visual',
|
|
13536
|
+
'visualBlock.addAction': 'Adicionar bloco visual',
|
|
13537
|
+
'visualBlock.addTooltip': 'Adicionar texto ou bloco visual nesta coluna',
|
|
13538
|
+
'visualBlock.editTitle': 'Editar bloco visual',
|
|
13539
|
+
'visualBlock.editAction': 'Editar bloco visual',
|
|
13540
|
+
'visualBlock.dragHandle': 'Arrastar para reordenar',
|
|
13541
|
+
'visualBlock.moreActions': 'Mais ações do bloco visual',
|
|
13542
|
+
'visualBlock.removeAction': 'Remover bloco visual',
|
|
13543
|
+
'visualBlock.moveUp': 'Mover bloco visual para cima',
|
|
13544
|
+
'visualBlock.moveDown': 'Mover bloco visual para baixo',
|
|
13545
|
+
'visualBlock.movePreviousColumn': 'Mover bloco visual para a coluna anterior',
|
|
13546
|
+
'visualBlock.moveNextColumn': 'Mover bloco visual para a próxima coluna',
|
|
13547
|
+
'visualBlock.preset.text': 'Texto',
|
|
13548
|
+
'visualBlock.preset.notice': 'Aviso',
|
|
13549
|
+
'visualBlock.preset.divider': 'Separador',
|
|
13550
|
+
'visualBlock.preset.infoCard': 'Card informativo',
|
|
13551
|
+
'visualBlock.preset.text.default': 'Novo texto',
|
|
13552
|
+
'visualBlock.preset.notice.default': 'Revise as informações antes de continuar.',
|
|
13553
|
+
'visualBlock.preset.divider.default': 'Separador',
|
|
13554
|
+
'visualBlock.preset.infoCard.title': 'Informação importante',
|
|
13555
|
+
'visualBlock.preset.infoCard.body': 'Use este espaço para orientar o preenchimento.',
|
|
13556
|
+
};
|
|
13557
|
+
const LAYOUT_EDITOR_I18N_CONFIG = {
|
|
13558
|
+
namespaces: {
|
|
13559
|
+
[LAYOUT_EDITOR_I18N_NAMESPACE]: {
|
|
13560
|
+
'pt-BR': LAYOUT_EDITOR_DEFAULT_COPY,
|
|
13561
|
+
'en-US': {
|
|
13562
|
+
'apiFields.heading': 'API fields',
|
|
13563
|
+
'apiFields.hint': 'fieldMetadata fields not yet allocated in the layout.',
|
|
13564
|
+
'apiFields.addAction': 'Add API field',
|
|
13565
|
+
'apiFields.empty': 'No API field available',
|
|
13566
|
+
'apiFields.addTooltip': 'Add an existing API field to this column',
|
|
13567
|
+
'visualBlock.label': 'Visual block',
|
|
13568
|
+
'visualBlock.previewEyebrow': 'Visual block',
|
|
13569
|
+
'visualBlock.addAction': 'Add visual block',
|
|
13570
|
+
'visualBlock.addTooltip': 'Add text or a visual block to this column',
|
|
13571
|
+
'visualBlock.editTitle': 'Edit visual block',
|
|
13572
|
+
'visualBlock.editAction': 'Edit visual block',
|
|
13573
|
+
'visualBlock.dragHandle': 'Drag to reorder',
|
|
13574
|
+
'visualBlock.moreActions': 'More visual block actions',
|
|
13575
|
+
'visualBlock.removeAction': 'Remove visual block',
|
|
13576
|
+
'visualBlock.moveUp': 'Move visual block up',
|
|
13577
|
+
'visualBlock.moveDown': 'Move visual block down',
|
|
13578
|
+
'visualBlock.movePreviousColumn': 'Move visual block to the previous column',
|
|
13579
|
+
'visualBlock.moveNextColumn': 'Move visual block to the next column',
|
|
13580
|
+
'visualBlock.preset.text': 'Text',
|
|
13581
|
+
'visualBlock.preset.notice': 'Notice',
|
|
13582
|
+
'visualBlock.preset.divider': 'Divider',
|
|
13583
|
+
'visualBlock.preset.infoCard': 'Info card',
|
|
13584
|
+
'visualBlock.preset.text.default': 'New text',
|
|
13585
|
+
'visualBlock.preset.notice.default': 'Review the information before continuing.',
|
|
13586
|
+
'visualBlock.preset.divider.default': 'Divider',
|
|
13587
|
+
'visualBlock.preset.infoCard.title': 'Important information',
|
|
13588
|
+
'visualBlock.preset.infoCard.body': 'Use this space to guide completion.',
|
|
13589
|
+
},
|
|
13590
|
+
},
|
|
13591
|
+
},
|
|
13592
|
+
};
|
|
13593
|
+
|
|
13594
|
+
const VISUAL_BLOCK_PRESETS = [
|
|
13595
|
+
{ id: 'text', labelKey: 'visualBlock.preset.text', icon: 'short_text' },
|
|
13596
|
+
{ id: 'notice', labelKey: 'visualBlock.preset.notice', icon: 'error_outline' },
|
|
13597
|
+
{ id: 'divider', labelKey: 'visualBlock.preset.divider', icon: 'horizontal_rule' },
|
|
13598
|
+
{ id: 'infoCard', labelKey: 'visualBlock.preset.infoCard', icon: 'info' },
|
|
13599
|
+
];
|
|
13600
|
+
function createVisualBlockItemFromPreset(presetId, id, copy) {
|
|
13601
|
+
return {
|
|
13602
|
+
kind: 'richContent',
|
|
13603
|
+
id,
|
|
13604
|
+
document: createVisualBlockDocument(presetId, copy),
|
|
13605
|
+
layout: 'block',
|
|
13606
|
+
};
|
|
13607
|
+
}
|
|
13608
|
+
function createVisualBlockDocument(presetId, copy) {
|
|
13609
|
+
return {
|
|
13610
|
+
kind: 'praxis.rich-content',
|
|
13611
|
+
version: '1.0.0',
|
|
13612
|
+
nodes: [createPresetNode(presetId, copy)],
|
|
13613
|
+
};
|
|
13614
|
+
}
|
|
13615
|
+
function createPresetNode(presetId, copy) {
|
|
13616
|
+
switch (presetId) {
|
|
13617
|
+
case 'notice':
|
|
13618
|
+
return {
|
|
13619
|
+
type: 'compose',
|
|
13620
|
+
direction: 'row',
|
|
13621
|
+
gap: 'sm',
|
|
13622
|
+
className: 'praxis-rich-content-notice',
|
|
13623
|
+
items: [
|
|
13624
|
+
{ type: 'icon', icon: 'error_outline', ariaLabel: copy.notice },
|
|
13625
|
+
{ type: 'text', text: copy.notice },
|
|
13626
|
+
],
|
|
13627
|
+
};
|
|
13628
|
+
case 'divider':
|
|
13629
|
+
return {
|
|
13630
|
+
type: 'text',
|
|
13631
|
+
text: copy.divider,
|
|
13632
|
+
className: 'praxis-rich-content-divider',
|
|
13633
|
+
};
|
|
13634
|
+
case 'infoCard':
|
|
13635
|
+
return {
|
|
13636
|
+
type: 'card',
|
|
13637
|
+
title: copy.infoCardTitle,
|
|
13638
|
+
content: [{ type: 'text', text: copy.infoCardBody }],
|
|
13639
|
+
};
|
|
13640
|
+
case 'text':
|
|
13641
|
+
default:
|
|
13642
|
+
return { type: 'text', text: copy.text };
|
|
13643
|
+
}
|
|
13644
|
+
}
|
|
13645
|
+
|
|
13113
13646
|
class RowConfiguratorComponent {
|
|
13114
13647
|
row;
|
|
13115
13648
|
fieldMetadata = [];
|
|
13649
|
+
availableFields = [];
|
|
13116
13650
|
sectionIndex;
|
|
13117
13651
|
rowIndex;
|
|
13118
13652
|
isLastRow = false;
|
|
@@ -13125,9 +13659,17 @@ class RowConfiguratorComponent {
|
|
|
13125
13659
|
remove = new EventEmitter();
|
|
13126
13660
|
applyRowGapAll = new EventEmitter();
|
|
13127
13661
|
fieldDrop = new EventEmitter();
|
|
13662
|
+
addVisualBlock = new EventEmitter();
|
|
13663
|
+
addApiField = new EventEmitter();
|
|
13664
|
+
editVisualBlock = new EventEmitter();
|
|
13665
|
+
moveVisualBlock = new EventEmitter();
|
|
13666
|
+
moveVisualBlockToColumn = new EventEmitter();
|
|
13667
|
+
removeVisualBlock = new EventEmitter();
|
|
13128
13668
|
select = new EventEmitter();
|
|
13129
13669
|
// Debounced dropzone highlight
|
|
13130
13670
|
activeDropIndex = null;
|
|
13671
|
+
visualBlockPresets = VISUAL_BLOCK_PRESETS;
|
|
13672
|
+
i18n = inject(PraxisI18nService);
|
|
13131
13673
|
hoverTimer = null;
|
|
13132
13674
|
breakpoints = ['xs', 'sm', 'md', 'lg', 'xl'];
|
|
13133
13675
|
previewBreakpoint = 'md';
|
|
@@ -13174,6 +13716,110 @@ class RowConfiguratorComponent {
|
|
|
13174
13716
|
controlType: FieldControlType.INPUT,
|
|
13175
13717
|
});
|
|
13176
13718
|
}
|
|
13719
|
+
getColumnLayoutItems(column) {
|
|
13720
|
+
return normalizeFormLayoutItems(column);
|
|
13721
|
+
}
|
|
13722
|
+
trackLayoutItem(_, item) {
|
|
13723
|
+
return item.id;
|
|
13724
|
+
}
|
|
13725
|
+
hasColumnContent(column) {
|
|
13726
|
+
return this.getColumnLayoutItems(column).length > 0;
|
|
13727
|
+
}
|
|
13728
|
+
getVisualBlockLabel(item) {
|
|
13729
|
+
if (item.kind !== 'richContent')
|
|
13730
|
+
return '';
|
|
13731
|
+
return this.findRichContentLabel(item.document?.nodes) || this.t('visualBlock.label');
|
|
13732
|
+
}
|
|
13733
|
+
findRichContentLabel(nodes) {
|
|
13734
|
+
if (!Array.isArray(nodes))
|
|
13735
|
+
return null;
|
|
13736
|
+
for (const node of nodes) {
|
|
13737
|
+
const label = this.findRichNodeLabel(node);
|
|
13738
|
+
if (label)
|
|
13739
|
+
return label;
|
|
13740
|
+
}
|
|
13741
|
+
return null;
|
|
13742
|
+
}
|
|
13743
|
+
findRichNodeLabel(node) {
|
|
13744
|
+
if (!node || typeof node !== 'object')
|
|
13745
|
+
return null;
|
|
13746
|
+
const richNode = node;
|
|
13747
|
+
for (const value of [richNode.text, richNode.label, richNode.title, richNode.subtitle]) {
|
|
13748
|
+
if (typeof value === 'string' && value.trim())
|
|
13749
|
+
return value.trim();
|
|
13750
|
+
}
|
|
13751
|
+
for (const nested of [richNode.items, richNode.content, richNode.trailing]) {
|
|
13752
|
+
const label = this.findRichContentLabel(nested);
|
|
13753
|
+
if (label)
|
|
13754
|
+
return label;
|
|
13755
|
+
}
|
|
13756
|
+
return this.findRichNodeLabel(richNode.avatar) || this.findRichNodeLabel(richNode.meta);
|
|
13757
|
+
}
|
|
13758
|
+
t(key, params) {
|
|
13759
|
+
return this.i18n.t(key, params, LAYOUT_EDITOR_DEFAULT_COPY[key] ?? key, LAYOUT_EDITOR_I18N_NAMESPACE);
|
|
13760
|
+
}
|
|
13761
|
+
getFieldLabel(field) {
|
|
13762
|
+
return field.label || field.name;
|
|
13763
|
+
}
|
|
13764
|
+
selectVisualBlock(columnIndex, item, event) {
|
|
13765
|
+
event.stopPropagation();
|
|
13766
|
+
if (item.kind !== 'richContent')
|
|
13767
|
+
return;
|
|
13768
|
+
this.select.emit({
|
|
13769
|
+
type: 'visualBlock',
|
|
13770
|
+
sectionIndex: this.sectionIndex,
|
|
13771
|
+
rowIndex: this.rowIndex,
|
|
13772
|
+
columnIndex,
|
|
13773
|
+
itemId: item.id,
|
|
13774
|
+
});
|
|
13775
|
+
}
|
|
13776
|
+
openVisualBlockEditor(columnIndex, item, event) {
|
|
13777
|
+
this.selectVisualBlock(columnIndex, item, event);
|
|
13778
|
+
if (item.kind !== 'richContent')
|
|
13779
|
+
return;
|
|
13780
|
+
this.editVisualBlock.emit({
|
|
13781
|
+
rowIndex: this.rowIndex,
|
|
13782
|
+
columnIndex,
|
|
13783
|
+
itemId: item.id,
|
|
13784
|
+
});
|
|
13785
|
+
}
|
|
13786
|
+
moveVisualBlockItem(columnIndex, item, direction, event) {
|
|
13787
|
+
this.selectVisualBlock(columnIndex, item, event);
|
|
13788
|
+
if (item.kind !== 'richContent')
|
|
13789
|
+
return;
|
|
13790
|
+
this.moveVisualBlock.emit({
|
|
13791
|
+
rowIndex: this.rowIndex,
|
|
13792
|
+
columnIndex,
|
|
13793
|
+
itemId: item.id,
|
|
13794
|
+
direction,
|
|
13795
|
+
});
|
|
13796
|
+
}
|
|
13797
|
+
canMoveVisualBlockToColumn(columnIndex, direction) {
|
|
13798
|
+
const targetColumnIndex = columnIndex + direction;
|
|
13799
|
+
return targetColumnIndex >= 0 && targetColumnIndex < (this.row?.columns?.length ?? 0);
|
|
13800
|
+
}
|
|
13801
|
+
moveVisualBlockToAdjacentColumn(columnIndex, item, direction, event) {
|
|
13802
|
+
this.selectVisualBlock(columnIndex, item, event);
|
|
13803
|
+
if (item.kind !== 'richContent' || !this.canMoveVisualBlockToColumn(columnIndex, direction)) {
|
|
13804
|
+
return;
|
|
13805
|
+
}
|
|
13806
|
+
this.moveVisualBlockToColumn.emit({
|
|
13807
|
+
rowIndex: this.rowIndex,
|
|
13808
|
+
columnIndex,
|
|
13809
|
+
targetColumnIndex: columnIndex + direction,
|
|
13810
|
+
itemId: item.id,
|
|
13811
|
+
});
|
|
13812
|
+
}
|
|
13813
|
+
removeVisualBlockItem(columnIndex, item, event) {
|
|
13814
|
+
this.selectVisualBlock(columnIndex, item, event);
|
|
13815
|
+
if (item.kind !== 'richContent')
|
|
13816
|
+
return;
|
|
13817
|
+
this.removeVisualBlock.emit({
|
|
13818
|
+
rowIndex: this.rowIndex,
|
|
13819
|
+
columnIndex,
|
|
13820
|
+
itemId: item.id,
|
|
13821
|
+
});
|
|
13822
|
+
}
|
|
13177
13823
|
drop(event) {
|
|
13178
13824
|
this.fieldDrop.emit(event);
|
|
13179
13825
|
}
|
|
@@ -13293,13 +13939,30 @@ class RowConfiguratorComponent {
|
|
|
13293
13939
|
this.rowChange.emit(updated);
|
|
13294
13940
|
}
|
|
13295
13941
|
clearColumn(index) {
|
|
13296
|
-
if (!confirm('Tem certeza que deseja remover
|
|
13942
|
+
if (!confirm('Tem certeza que deseja remover todo o conteudo desta coluna?'))
|
|
13297
13943
|
return;
|
|
13298
13944
|
const updated = produce(this.row, (draft) => {
|
|
13299
13945
|
draft.columns[index].fields = [];
|
|
13946
|
+
draft.columns[index].items = [];
|
|
13300
13947
|
});
|
|
13301
13948
|
this.rowChange.emit(updated);
|
|
13302
13949
|
}
|
|
13950
|
+
addVisualBlockToColumn(index, presetId) {
|
|
13951
|
+
this.addVisualBlock.emit({
|
|
13952
|
+
rowIndex: this.rowIndex,
|
|
13953
|
+
columnIndex: index,
|
|
13954
|
+
presetId,
|
|
13955
|
+
});
|
|
13956
|
+
}
|
|
13957
|
+
addApiFieldToColumn(index, fieldName) {
|
|
13958
|
+
if (!fieldName)
|
|
13959
|
+
return;
|
|
13960
|
+
this.addApiField.emit({
|
|
13961
|
+
rowIndex: this.rowIndex,
|
|
13962
|
+
columnIndex: index,
|
|
13963
|
+
fieldName,
|
|
13964
|
+
});
|
|
13965
|
+
}
|
|
13303
13966
|
addFieldToColumn(index) {
|
|
13304
13967
|
if (!this.fieldMetadata || this.fieldMetadata.length === 0)
|
|
13305
13968
|
return;
|
|
@@ -13502,7 +14165,7 @@ class RowConfiguratorComponent {
|
|
|
13502
14165
|
return null;
|
|
13503
14166
|
}
|
|
13504
14167
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: RowConfiguratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13505
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: RowConfiguratorComponent, isStandalone: true, selector: "praxis-row-configurator", inputs: { row: "row", fieldMetadata: "fieldMetadata", sectionIndex: "sectionIndex", rowIndex: "rowIndex", isLastRow: "isLastRow", selected: "selected", availableFieldsListId: "availableFieldsListId", connectedDropListIds: "connectedDropListIds", gapGlobal: "gapGlobal" }, outputs: { rowChange: "rowChange", remove: "remove", applyRowGapAll: "applyRowGapAll", fieldDrop: "fieldDrop", select: "select" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"row-meta\" *ngIf=\"row\">\n <div class=\"bp-toggle\" role=\"group\" aria-label=\"Breakpoint de visualiza\u00E7\u00E3o\">\n <button\n *ngFor=\"let bp of breakpoints\"\n type=\"button\"\n mat-stroked-button\n class=\"bp-toggle__btn\"\n [class.active]=\"previewBreakpoint === bp\"\n (click)=\"previewBreakpoint = bp\"\n >\n {{ bp }}\n </button>\n </div>\n <div class=\"gap-controls\">\n <div class=\"gap-chip\" *ngIf=\"hasMultipleColumns()\" matTooltip=\"Gap entre colunas (px)\"\n aria-label=\"Gap entre colunas\">\n <span class=\"chip-title\">Colunas</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', -2)\"\n aria-label=\"Reduzir gap de colunas\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.gap ?? gapGlobal\"\n (ngModelChange)=\"updateRowGap('gap', $event)\" aria-label=\"Valor do gap entre colunas\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', 2)\"\n aria-label=\"Aumentar gap de colunas\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n <div class=\"gap-chip\" matTooltip=\"Gap abaixo da linha (px)\" aria-label=\"Gap abaixo da linha\">\n <span class=\"chip-title\">Linha</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', -2)\"\n aria-label=\"Reduzir espa\u00E7o entre campos da linha\" matTooltip=\"Reduz o espa\u00E7o entre campos desta linha\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.rowGap ?? 0\"\n (ngModelChange)=\"updateRowGap('rowGap', $event)\" aria-label=\"Espa\u00E7o entre campos desta linha\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', 2)\"\n aria-label=\"Aumentar espa\u00E7o entre campos da linha\" matTooltip=\"Aumenta o espa\u00E7o entre campos desta linha\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-icon-button class=\"gap-chip__btn\" [matMenuTriggerFor]=\"rowGapMenu\"\n matTooltip=\"Mais op\u00E7\u00F5es para aplicar este espa\u00E7o\" aria-label=\"Mais op\u00E7\u00F5es de aplica\u00E7\u00E3o\">\n <mat-icon>done_all</mat-icon>\n </button>\n <mat-menu #rowGapMenu=\"matMenu\">\n <button mat-menu-item (click)=\"applyRowGapToAll()\">\n <mat-icon>done_all</mat-icon>\n <span>Aplicar em todas as linhas da se\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item (click)=\"clearRowGap()\">\n <mat-icon>undo</mat-icon>\n <span>Voltar ao padr\u00E3o</span>\n </button>\n </mat-menu>\n </div>\n <div class=\"gap-pill\" aria-label=\"Resumo de espa\u00E7amentos\">\n Campos: {{ (row.rowGap ?? 'padr\u00E3o') }}px \u00B7 Colunas: {{ (row.gap ?? gapGlobal) }}px\n </div>\n <div class=\"row-actions-meta\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" (click)=\"openRowMenu()\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\" (closed)=\"onMenuClosed()\">\n <ng-container *ngIf=\"menuContext?.type === 'column'; else rowMenuContent\">\n <button mat-menu-item (click)=\"toggleHidden(menuContext!.columnIndex!)\">\n <mat-icon>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'visibility' : 'visibility_off'\n }}</mat-icon>\n <span>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'Mostrar neste breakpoint' : 'Ocultar neste\n breakpoint' }}</span>\n </button>\n <button mat-menu-item (click)=\"removeColumn(menuContext!.columnIndex!)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </ng-container>\n <ng-template #rowMenuContent>\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014\n 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014\n 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014\n 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </ng-template>\n </mat-menu>\n </div>\n </div>\n <div class=\"span-warning\" *ngIf=\"getSpanTotal(previewBreakpoint) !== 12\">\n <mat-icon color=\"warn\">warning</mat-icon>\n Soma de spans = {{ getSpanTotal(previewBreakpoint) }} (ideal: 12)\n </div>\n</div>\n\n<div class=\"row-container\" [style.marginBottom.px]=\"!isLastRow ? (row.rowGap || null) : null\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div class=\"row grid-12\" cdkDropListGroup (click)=\"selectRow()\" [class.selected]=\"isRowSelected()\" tabindex=\"0\"\n role=\"button\" [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\" [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\" [style.--px-row-field-gap.px]=\"row.rowGap ?? null\">\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div *ngFor=\"let column of row.columns; let i = index\" class=\"column\" [id]=\"getColumnId(i)\" cdkDropList\n [cdkDropListData]=\"column.fields\" [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\" (cdkDropListEntered)=\"onDropEnter(i)\" (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\" [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\" [ngClass]=\"getColumnClassList(column)\"\n [style.grid-column]=\"'span ' + getSpanFor(column)\" tabindex=\"0\" role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanFor(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\">\n <div class=\"column-header\">\n <div class=\"column-status-pill\" [matMenuTriggerFor]=\"columnSettingsMenu\"\n matTooltip=\"Clique para ajustar largura e offset\" [class.active]=\"isColumnSelected(i)\">\n <span class=\"status-bp\">{{ previewBreakpoint }}</span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-span\">\n <mat-icon>view_column</mat-icon>\n {{ getSpanFor(column) }}/12\n </span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-offset\">\n off {{ getOffsetFor(column) }}\n </span>\n <span class=\"status-hidden\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon>visibility_off</mat-icon>\n </span>\n </div>\n\n <div class=\"column-actions\">\n <button mat-icon-button class=\"action-btn\" [matMenuTriggerFor]=\"columnOverflowMenu\"\n (click)=\"$event.stopPropagation()\" matTooltip=\"Op\u00E7\u00F5es da coluna\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n\n <mat-menu #columnSettingsMenu=\"matMenu\" class=\"column-settings-popover\">\n <div class=\"popover-content\" (click)=\"$event.stopPropagation()\">\n <div class=\"control-group\" *ngIf=\"getSuggestedSpan(i) as suggested\">\n <button mat-flat-button color=\"primary\" (click)=\"setSpan(i, suggested)\"\n matTooltip=\"Ajustar largura para completar 12 colunas\">\n <mat-icon>auto_fix_high</mat-icon>\n Ajustar para {{ suggested }} (Total 12)\n </button>\n </div>\n <div class=\"control-group\">\n <label>Largura ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustSpan(i, -1)\"><mat-icon>remove</mat-icon></button>\n <span class=\"value-display\">{{ getSpanFor(column) }} / 12</span>\n <button mat-icon-button (click)=\"adjustSpan(i, 1)\"><mat-icon>add</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <label>Offset ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustOffset(i, -1)\"><mat-icon>chevron_left</mat-icon></button>\n <span class=\"value-display\">{{ getOffsetFor(column) }}</span>\n <button mat-icon-button (click)=\"adjustOffset(i, 1)\"><mat-icon>chevron_right</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <button mat-stroked-button (click)=\"toggleHidden(i)\" [color]=\"getHiddenFor(column) ? 'warn' : ''\">\n <mat-icon>{{ getHiddenFor(column) ? 'visibility' : 'visibility_off' }}</mat-icon>\n {{ getHiddenFor(column) ? 'Mostrar' : 'Ocultar' }}\n </button>\n </div>\n </div>\n </mat-menu>\n\n <mat-menu #columnOverflowMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openColumnConfig(i)\" matTooltip=\"Abrir painel de configura\u00E7\u00E3o completa\">\n <mat-icon>tune</mat-icon>\n <span>Configurar coluna</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"moveColumn(i, -1)\" [disabled]=\"i === 0\"\n matTooltip=\"Mover coluna para a esquerda\">\n <mat-icon>arrow_back</mat-icon>\n <span>Mover para esquerda</span>\n </button>\n <button mat-menu-item (click)=\"moveColumn(i, 1)\" [disabled]=\"i === row.columns.length - 1\"\n matTooltip=\"Mover coluna para a direita\">\n <mat-icon>arrow_forward</mat-icon>\n <span>Mover para direita</span>\n </button>\n\n <button mat-menu-item (click)=\"clearColumn(i)\" [disabled]=\"column.fields.length === 0\"\n matTooltip=\"Remover todos os campos desta coluna\">\n <mat-icon>backspace</mat-icon>\n <span>Limpar conte\u00FAdo</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeColumn(i)\" matTooltip=\"Excluir esta coluna\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </mat-menu>\n <div class=\"column-content\">\n <div class=\"hidden-overlay\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon aria-hidden=\"true\">visibility_off</mat-icon>\n <span>Oculta em {{ previewBreakpoint }}</span>\n </div>\n <ng-container *ngIf=\"column.fields.length > 0; else emptyColumn\">\n <div *ngFor=\"let fieldName of column.fields\" (click)=\"selectField(fieldName, $event)\"\n [class.selected]=\"isFieldSelected(fieldName)\">\n <praxis-field-configurator [field]=\"getFieldByName(fieldName)\"></praxis-field-configurator>\n </div>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou remova.</span>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou remova.</span>\n <div class=\"row-placeholder-actions\">\n <button mat-stroked-button (click)=\"addColumn()\" matTooltip=\"Adicionar coluna\">\n <mat-icon>add</mat-icon> Adicionar coluna\n </button>\n <button mat-stroked-button color=\"warn\" (click)=\"removeRow()\" matTooltip=\"Remover linha\">\n <mat-icon>delete</mat-icon> Remover linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.bp-toggle{display:inline-flex;gap:4px;align-items:center}.bp-toggle__btn{min-width:34px;height:30px;line-height:30px;padding:0 8px;text-transform:uppercase}.bp-toggle__btn.active{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.gap-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.gap-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.chip-title{font:var(--mdc-typography-label-medium, 600 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;letter-spacing:.03em}.span-warning{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-error);background:var(--md-sys-color-error-container);border:1px solid var(--md-sys-color-error);border-radius:6px;padding:4px 8px}.row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:0;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.row-actions-meta{margin-left:auto}.column{position:relative;flex:1;display:flex;flex-direction:column;border:1px dashed var(--md-sys-color-outline-variant);margin:0;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease;border-radius:8px;overflow:hidden}.column-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--md-sys-color-surface-variant);border-bottom:1px solid var(--md-sys-color-outline-variant);min-height:36px}.column-content{flex:1;display:grid;align-content:start;gap:var(--px-row-field-gap, 6px);padding:8px}.column-status-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:12px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none}.column-status-pill:hover,.column-status-pill.active{background:var(--md-sys-color-surface-variant);border-color:var(--md-sys-color-outline)}.status-bp{font-weight:700;text-transform:uppercase;font-size:11px;color:var(--md-sys-color-primary)}.status-divider{color:var(--md-sys-color-outline-variant)}.status-span,.status-offset{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--md-sys-color-on-surface)}.status-span mat-icon{font-size:14px;width:14px;height:14px}.status-hidden{color:var(--md-sys-color-error);display:flex;align-items:center}.status-hidden mat-icon{font-size:14px;width:14px;height:14px}.column-actions{display:flex;align-items:center;opacity:0;transition:opacity .2s ease}.column:hover .column-actions,.column.selected .column-actions,.column-actions:focus-within{opacity:1}.action-btn{width:24px;height:24px;line-height:24px;padding:0}.action-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.popover-content{padding:12px;display:flex;flex-direction:column;gap:12px;min-width:200px}.control-group{display:flex;flex-direction:column;gap:4px}.control-group label{font-size:11px;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;font-weight:600}.control-row{display:flex;align-items:center;justify-content:space-between;background:var(--md-sys-color-surface-container-high);border-radius:8px;padding:2px}.value-display{font-weight:600;font-size:13px}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}.hidden-overlay{position:absolute;inset:0;background:var(--md-sys-color-surface-container-low);border:1px dashed var(--md-sys-color-outline);display:flex;align-items:center;justify-content:center;gap:6px;color:var(--md-sys-color-on-surface-variant);z-index:2;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { 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.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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
|
|
14168
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: RowConfiguratorComponent, isStandalone: true, selector: "praxis-row-configurator", inputs: { row: "row", fieldMetadata: "fieldMetadata", availableFields: "availableFields", sectionIndex: "sectionIndex", rowIndex: "rowIndex", isLastRow: "isLastRow", selected: "selected", availableFieldsListId: "availableFieldsListId", connectedDropListIds: "connectedDropListIds", gapGlobal: "gapGlobal" }, outputs: { rowChange: "rowChange", remove: "remove", applyRowGapAll: "applyRowGapAll", fieldDrop: "fieldDrop", addVisualBlock: "addVisualBlock", addApiField: "addApiField", editVisualBlock: "editVisualBlock", moveVisualBlock: "moveVisualBlock", moveVisualBlockToColumn: "moveVisualBlockToColumn", removeVisualBlock: "removeVisualBlock", select: "select" }, providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], usesOnChanges: true, ngImport: i0, template: "<div class=\"row-meta\" *ngIf=\"row\">\n <div class=\"bp-toggle\" role=\"group\" aria-label=\"Breakpoint de visualiza\u00E7\u00E3o\">\n <button\n *ngFor=\"let bp of breakpoints\"\n type=\"button\"\n mat-stroked-button\n class=\"bp-toggle__btn\"\n [class.active]=\"previewBreakpoint === bp\"\n (click)=\"previewBreakpoint = bp\"\n >\n {{ bp }}\n </button>\n </div>\n <div class=\"gap-controls\">\n <div class=\"gap-chip\" *ngIf=\"hasMultipleColumns()\" matTooltip=\"Gap entre colunas (px)\"\n aria-label=\"Gap entre colunas\">\n <span class=\"chip-title\">Colunas</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', -2)\"\n aria-label=\"Reduzir gap de colunas\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.gap ?? gapGlobal\"\n (ngModelChange)=\"updateRowGap('gap', $event)\" aria-label=\"Valor do gap entre colunas\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', 2)\"\n aria-label=\"Aumentar gap de colunas\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n <div class=\"gap-chip\" matTooltip=\"Gap abaixo da linha (px)\" aria-label=\"Gap abaixo da linha\">\n <span class=\"chip-title\">Linha</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', -2)\"\n aria-label=\"Reduzir espa\u00E7o entre campos da linha\" matTooltip=\"Reduz o espa\u00E7o entre campos desta linha\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.rowGap ?? 0\"\n (ngModelChange)=\"updateRowGap('rowGap', $event)\" aria-label=\"Espa\u00E7o entre campos desta linha\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', 2)\"\n aria-label=\"Aumentar espa\u00E7o entre campos da linha\" matTooltip=\"Aumenta o espa\u00E7o entre campos desta linha\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-icon-button class=\"gap-chip__btn\" [matMenuTriggerFor]=\"rowGapMenu\"\n matTooltip=\"Mais op\u00E7\u00F5es para aplicar este espa\u00E7o\" aria-label=\"Mais op\u00E7\u00F5es de aplica\u00E7\u00E3o\">\n <mat-icon>done_all</mat-icon>\n </button>\n <mat-menu #rowGapMenu=\"matMenu\">\n <button mat-menu-item (click)=\"applyRowGapToAll()\">\n <mat-icon>done_all</mat-icon>\n <span>Aplicar em todas as linhas da se\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item (click)=\"clearRowGap()\">\n <mat-icon>undo</mat-icon>\n <span>Voltar ao padr\u00E3o</span>\n </button>\n </mat-menu>\n </div>\n <div class=\"gap-pill\" aria-label=\"Resumo de espa\u00E7amentos\">\n Campos: {{ (row.rowGap ?? 'padr\u00E3o') }}px \u00B7 Colunas: {{ (row.gap ?? gapGlobal) }}px\n </div>\n <div class=\"row-actions-meta\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" (click)=\"openRowMenu()\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\" (closed)=\"onMenuClosed()\">\n <ng-container *ngIf=\"menuContext?.type === 'column'; else rowMenuContent\">\n <button mat-menu-item (click)=\"toggleHidden(menuContext!.columnIndex!)\">\n <mat-icon>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'visibility' : 'visibility_off'\n }}</mat-icon>\n <span>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'Mostrar neste breakpoint' : 'Ocultar neste\n breakpoint' }}</span>\n </button>\n <button mat-menu-item (click)=\"removeColumn(menuContext!.columnIndex!)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </ng-container>\n <ng-template #rowMenuContent>\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014\n 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014\n 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014\n 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </ng-template>\n </mat-menu>\n </div>\n </div>\n <div class=\"span-warning\" *ngIf=\"getSpanTotal(previewBreakpoint) !== 12\">\n <mat-icon color=\"warn\">warning</mat-icon>\n Soma de spans = {{ getSpanTotal(previewBreakpoint) }} (ideal: 12)\n </div>\n</div>\n\n<div class=\"row-container\" [style.marginBottom.px]=\"!isLastRow ? (row.rowGap || null) : null\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div class=\"row grid-12\" cdkDropListGroup (click)=\"selectRow()\" [class.selected]=\"isRowSelected()\" tabindex=\"0\"\n role=\"button\" [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\" [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\" [style.--px-row-field-gap.px]=\"row.rowGap ?? null\">\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div *ngFor=\"let column of row.columns; let i = index\" class=\"column\" [id]=\"getColumnId(i)\" cdkDropList\n [cdkDropListData]=\"getColumnLayoutItems(column)\" [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\" (cdkDropListEntered)=\"onDropEnter(i)\" (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\" [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\" [ngClass]=\"getColumnClassList(column)\"\n [style.grid-column]=\"'span ' + getSpanFor(column)\" tabindex=\"0\" role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanFor(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\">\n <div class=\"column-header\">\n <div class=\"column-status-pill\" [matMenuTriggerFor]=\"columnSettingsMenu\"\n matTooltip=\"Clique para ajustar largura e offset\" [class.active]=\"isColumnSelected(i)\">\n <span class=\"status-bp\">{{ previewBreakpoint }}</span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-span\">\n <mat-icon>view_column</mat-icon>\n {{ getSpanFor(column) }}/12\n </span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-offset\">\n off {{ getOffsetFor(column) }}\n </span>\n <span class=\"status-hidden\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon>visibility_off</mat-icon>\n </span>\n </div>\n\n <div class=\"column-actions\">\n <button mat-icon-button class=\"action-btn\" [matMenuTriggerFor]=\"columnOverflowMenu\"\n (click)=\"$event.stopPropagation()\" matTooltip=\"Op\u00E7\u00F5es da coluna\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n\n <mat-menu #columnSettingsMenu=\"matMenu\" class=\"column-settings-popover\">\n <div class=\"popover-content\" (click)=\"$event.stopPropagation()\">\n <div class=\"control-group\" *ngIf=\"getSuggestedSpan(i) as suggested\">\n <button mat-flat-button color=\"primary\" (click)=\"setSpan(i, suggested)\"\n matTooltip=\"Ajustar largura para completar 12 colunas\">\n <mat-icon>auto_fix_high</mat-icon>\n Ajustar para {{ suggested }} (Total 12)\n </button>\n </div>\n <div class=\"control-group\">\n <label>Largura ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustSpan(i, -1)\"><mat-icon>remove</mat-icon></button>\n <span class=\"value-display\">{{ getSpanFor(column) }} / 12</span>\n <button mat-icon-button (click)=\"adjustSpan(i, 1)\"><mat-icon>add</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <label>Offset ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustOffset(i, -1)\"><mat-icon>chevron_left</mat-icon></button>\n <span class=\"value-display\">{{ getOffsetFor(column) }}</span>\n <button mat-icon-button (click)=\"adjustOffset(i, 1)\"><mat-icon>chevron_right</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <button mat-stroked-button (click)=\"toggleHidden(i)\" [color]=\"getHiddenFor(column) ? 'warn' : ''\">\n <mat-icon>{{ getHiddenFor(column) ? 'visibility' : 'visibility_off' }}</mat-icon>\n {{ getHiddenFor(column) ? 'Mostrar' : 'Ocultar' }}\n </button>\n </div>\n </div>\n </mat-menu>\n\n <mat-menu #columnOverflowMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openColumnConfig(i)\" matTooltip=\"Abrir painel de configura\u00E7\u00E3o completa\">\n <mat-icon>tune</mat-icon>\n <span>Configurar coluna</span>\n </button>\n <button mat-menu-item [matMenuTriggerFor]=\"apiFieldMenu\" [matTooltip]=\"t('apiFields.addTooltip')\">\n <mat-icon>input</mat-icon>\n <span>{{ t('apiFields.addAction') }}</span>\n </button>\n <mat-menu #apiFieldMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let field of availableFields\"\n (click)=\"addApiFieldToColumn(i, field.name)\"\n >\n <mat-icon>short_text</mat-icon>\n <span>{{ getFieldLabel(field) }}</span>\n </button>\n <button mat-menu-item disabled *ngIf=\"!availableFields.length\">\n <span>{{ t('apiFields.empty') }}</span>\n </button>\n </mat-menu>\n <button mat-menu-item [matMenuTriggerFor]=\"visualBlockPresetMenu\" [matTooltip]=\"t('visualBlock.addTooltip')\">\n <mat-icon>notes</mat-icon>\n <span>{{ t('visualBlock.addAction') }}</span>\n </button>\n <mat-menu #visualBlockPresetMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let preset of visualBlockPresets\"\n (click)=\"addVisualBlockToColumn(i, preset.id)\"\n >\n <mat-icon>{{ preset.icon }}</mat-icon>\n <span>{{ t(preset.labelKey) }}</span>\n </button>\n </mat-menu>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"moveColumn(i, -1)\" [disabled]=\"i === 0\"\n matTooltip=\"Mover coluna para a esquerda\">\n <mat-icon>arrow_back</mat-icon>\n <span>Mover para esquerda</span>\n </button>\n <button mat-menu-item (click)=\"moveColumn(i, 1)\" [disabled]=\"i === row.columns.length - 1\"\n matTooltip=\"Mover coluna para a direita\">\n <mat-icon>arrow_forward</mat-icon>\n <span>Mover para direita</span>\n </button>\n\n <button mat-menu-item (click)=\"clearColumn(i)\" [disabled]=\"!hasColumnContent(column)\"\n matTooltip=\"Remover todo o conte\u00C3\u00BAdo desta coluna\">\n <mat-icon>backspace</mat-icon>\n <span>Limpar conte\u00FAdo</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeColumn(i)\" matTooltip=\"Excluir esta coluna\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </mat-menu>\n <div class=\"column-content\">\n <div class=\"hidden-overlay\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon aria-hidden=\"true\">visibility_off</mat-icon>\n <span>Oculta em {{ previewBreakpoint }}</span>\n </div>\n <ng-container *ngIf=\"hasColumnContent(column); else emptyColumn\">\n <ng-container *ngFor=\"let item of getColumnLayoutItems(column); let itemIndex = index; trackBy: trackLayoutItem\">\n <div *ngIf=\"item.kind === 'field'; else visualBlockItem\" (click)=\"selectField(item.fieldName, $event)\"\n [class.selected]=\"isFieldSelected(item.fieldName)\">\n <praxis-field-configurator [field]=\"getFieldByName(item.fieldName)\"></praxis-field-configurator>\n </div>\n <ng-template #visualBlockItem>\n <div\n class=\"visual-block-preview\"\n *ngIf=\"item.kind === 'richContent'\"\n cdkDrag\n [cdkDragData]=\"item\"\n role=\"button\"\n tabindex=\"0\"\n [class.selected]=\"selected?.type === 'visualBlock' && selected?.itemId === item.id\"\n (click)=\"selectVisualBlock(i, item, $event)\"\n (dblclick)=\"openVisualBlockEditor(i, item, $event)\"\n (keydown.enter)=\"openVisualBlockEditor(i, item, $event)\"\n (keydown.space)=\"selectVisualBlock(i, item, $event); $event.preventDefault()\"\n >\n <button\n class=\"visual-block-preview__drag-handle\"\n type=\"button\"\n cdkDragHandle\n [matTooltip]=\"t('visualBlock.dragHandle')\"\n [attr.aria-label]=\"t('visualBlock.dragHandle')\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </button>\n <mat-icon aria-hidden=\"true\">notes</mat-icon>\n <span class=\"visual-block-preview__text\">\n <span class=\"visual-block-preview__eyebrow\">{{ t('visualBlock.previewEyebrow') }}</span>\n <span class=\"visual-block-preview__label\">{{ getVisualBlockLabel(item) }}</span>\n </span>\n <span class=\"visual-block-preview__actions\">\n <button\n mat-icon-button\n class=\"visual-block-preview__action visual-block-preview__quick-action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveUp')\"\n [attr.aria-label]=\"t('visualBlock.moveUp')\"\n [disabled]=\"itemIndex === 0\"\n (click)=\"moveVisualBlockItem(i, item, -1, $event)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action visual-block-preview__quick-action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveDown')\"\n [attr.aria-label]=\"t('visualBlock.moveDown')\"\n [disabled]=\"itemIndex === getColumnLayoutItems(column).length - 1\"\n (click)=\"moveVisualBlockItem(i, item, 1, $event)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.editAction')\"\n [attr.aria-label]=\"t('visualBlock.editAction')\"\n (click)=\"openVisualBlockEditor(i, item, $event)\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matMenuTriggerFor]=\"visualBlockActionsMenu\"\n [matTooltip]=\"t('visualBlock.moreActions')\"\n [attr.aria-label]=\"t('visualBlock.moreActions')\"\n >\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #visualBlockActionsMenu=\"matMenu\">\n <button\n mat-menu-item\n [disabled]=\"itemIndex === 0\"\n (click)=\"moveVisualBlockItem(i, item, -1, $event)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n <span>{{ t('visualBlock.moveUp') }}</span>\n </button>\n <button\n mat-menu-item\n [disabled]=\"itemIndex === getColumnLayoutItems(column).length - 1\"\n (click)=\"moveVisualBlockItem(i, item, 1, $event)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n <span>{{ t('visualBlock.moveDown') }}</span>\n </button>\n <button\n mat-menu-item\n [disabled]=\"!canMoveVisualBlockToColumn(i, -1)\"\n (click)=\"moveVisualBlockToAdjacentColumn(i, item, -1, $event)\"\n >\n <mat-icon>arrow_back</mat-icon>\n <span>{{ t('visualBlock.movePreviousColumn') }}</span>\n </button>\n <button\n mat-menu-item\n [disabled]=\"!canMoveVisualBlockToColumn(i, 1)\"\n (click)=\"moveVisualBlockToAdjacentColumn(i, item, 1, $event)\"\n >\n <mat-icon>arrow_forward</mat-icon>\n <span>{{ t('visualBlock.moveNextColumn') }}</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeVisualBlockItem(i, item, $event)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>{{ t('visualBlock.removeAction') }}</span>\n </button>\n </mat-menu>\n </span>\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou remova.</span>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou remova.</span>\n <div class=\"row-placeholder-actions\">\n <button mat-stroked-button (click)=\"addColumn()\" matTooltip=\"Adicionar coluna\">\n <mat-icon>add</mat-icon> Adicionar coluna\n </button>\n <button mat-stroked-button color=\"warn\" (click)=\"removeRow()\" matTooltip=\"Remover linha\">\n <mat-icon>delete</mat-icon> Remover linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.bp-toggle{display:inline-flex;gap:4px;align-items:center}.bp-toggle__btn{min-width:34px;height:30px;line-height:30px;padding:0 8px;text-transform:uppercase}.bp-toggle__btn.active{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.gap-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.gap-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.chip-title{font:var(--mdc-typography-label-medium, 600 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;letter-spacing:.03em}.span-warning{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-error);background:var(--md-sys-color-error-container);border:1px solid var(--md-sys-color-error);border-radius:6px;padding:4px 8px}.row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:0;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.row-actions-meta{margin-left:auto}.column{position:relative;flex:1;display:flex;flex-direction:column;border:1px dashed var(--md-sys-color-outline-variant);margin:0;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease;border-radius:8px;overflow:hidden}.column-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--md-sys-color-surface-variant);border-bottom:1px solid var(--md-sys-color-outline-variant);min-height:36px}.column-content{flex:1;display:grid;align-content:start;gap:var(--px-row-field-gap, 6px);padding:8px}.column-status-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:12px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none}.column-status-pill:hover,.column-status-pill.active{background:var(--md-sys-color-surface-variant);border-color:var(--md-sys-color-outline)}.status-bp{font-weight:700;text-transform:uppercase;font-size:11px;color:var(--md-sys-color-primary)}.status-divider{color:var(--md-sys-color-outline-variant)}.status-span,.status-offset{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--md-sys-color-on-surface)}.status-span mat-icon{font-size:14px;width:14px;height:14px}.status-hidden{color:var(--md-sys-color-error);display:flex;align-items:center}.status-hidden mat-icon{font-size:14px;width:14px;height:14px}.column-actions{display:flex;align-items:center;opacity:0;transition:opacity .2s ease}.column:hover .column-actions,.column.selected .column-actions,.column-actions:focus-within{opacity:1}.action-btn{width:24px;height:24px;line-height:24px;padding:0}.action-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.popover-content{padding:12px;display:flex;flex-direction:column;gap:12px;min-width:200px}.control-group{display:flex;flex-direction:column;gap:4px}.control-group label{font-size:11px;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;font-weight:600}.control-row{display:flex;align-items:center;justify-content:space-between;background:var(--md-sys-color-surface-container-high);border-radius:8px;padding:2px}.value-display{font-weight:600;font-size:13px}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.visual-block-preview{display:flex;align-items:center;gap:8px;min-height:44px;min-width:0;padding:8px 10px;border:1px solid var(--md-sys-color-outline-variant);border-left:3px solid color-mix(in srgb,var(--md-sys-color-primary) 54%,var(--md-sys-color-outline-variant) 46%);border-radius:8px;background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface);font-size:13px;cursor:pointer}.visual-block-preview:hover{border-color:color-mix(in srgb,var(--md-sys-color-primary) 38%,var(--md-sys-color-outline-variant) 62%);border-left-color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 10%,var(--md-sys-color-surface-container-low, var(--md-sys-color-surface)) 90%)}.visual-block-preview.selected{border-color:var(--md-sys-color-primary);border-left-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.visual-block-preview.cdk-drag-dragging{cursor:grabbing}.visual-block-preview.cdk-drag-preview{box-sizing:border-box;border-color:var(--md-sys-color-primary);border-left-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-container, var(--md-sys-color-surface));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.visual-block-preview.cdk-drag-placeholder{position:relative;min-height:44px;border-color:transparent;border-left-color:transparent;background:transparent;box-shadow:none;opacity:1}.visual-block-preview.cdk-drag-placeholder>*{visibility:hidden}.visual-block-preview.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.visual-block-preview.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}.visual-block-preview mat-icon{font-size:18px;width:18px;height:18px}.visual-block-preview__drag-handle{border:0;border-radius:50%;padding:0;background:transparent;display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;color:var(--md-sys-color-on-surface-variant);cursor:grab;opacity:.72;flex:0 0 auto}.visual-block-preview__drag-handle:hover,.visual-block-preview__drag-handle:focus-visible{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 52%,transparent);opacity:1;outline:none}.visual-block-preview__drag-handle:active{cursor:grabbing}.visual-block-preview.selected .visual-block-preview__drag-handle,.visual-block-preview.cdk-drag-dragging .visual-block-preview__drag-handle,.visual-block-preview.cdk-drag-preview .visual-block-preview__drag-handle{color:var(--md-sys-color-primary);opacity:1}.visual-block-preview__text{display:grid;gap:1px;min-width:0}.visual-block-preview__eyebrow{color:var(--md-sys-color-primary);font:var(--mdc-typography-label-small, 700 11px/14px system-ui);text-transform:uppercase}.visual-block-preview__label{overflow:hidden;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 500 13px/18px system-ui);text-overflow:ellipsis;white-space:nowrap}.visual-block-preview__actions{margin-left:auto;display:inline-flex;align-items:center;gap:2px;flex:0 0 auto}.visual-block-preview__action{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;line-height:1;min-width:30px;--mdc-icon-button-size: 30px;--mdc-icon-button-state-layer-size: 30px;--mdc-icon-button-icon-size: 18px;--mat-icon-button-state-layer-size: 30px;--mat-icon-button-icon-size: 18px}.visual-block-preview__action mat-icon{display:inline-flex;align-items:center;justify-content:center;margin:0;line-height:18px}:host ::ng-deep .visual-block-preview__action .mat-mdc-button-touch-target{width:30px;height:30px}:host ::ng-deep .visual-block-preview__action .mat-mdc-button-persistent-ripple,:host ::ng-deep .visual-block-preview__action .mat-mdc-button-persistent-ripple:before,:host ::ng-deep .visual-block-preview__action .mat-ripple{inset:0;border-radius:50%}.visual-block-preview__quick-action{color:var(--md-sys-color-on-surface-variant);opacity:0;visibility:hidden;transition:opacity .12s ease,visibility .12s ease}.visual-block-preview:hover .visual-block-preview__quick-action,.visual-block-preview:focus-within .visual-block-preview__quick-action,.visual-block-preview.selected .visual-block-preview__quick-action{opacity:1;visibility:visible}.visual-block-preview__quick-action[disabled]{opacity:.28}@media(max-width:768px),(pointer:coarse){.visual-block-preview__quick-action{display:none}}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}.hidden-overlay{position:absolute;inset:0;background:var(--md-sys-color-surface-container-low);border:1px dashed var(--md-sys-color-outline);display:flex;align-items:center;justify-content:center;gap:6px;color:var(--md-sys-color-on-surface-variant);z-index:2;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { 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.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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
|
|
13506
14169
|
}
|
|
13507
14170
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: RowConfiguratorComponent, decorators: [{
|
|
13508
14171
|
type: Component,
|
|
@@ -13516,11 +14179,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
13516
14179
|
MatTooltipModule,
|
|
13517
14180
|
MatMenuModule,
|
|
13518
14181
|
MatDividerModule,
|
|
13519
|
-
], template: "<div class=\"row-meta\" *ngIf=\"row\">\n <div class=\"bp-toggle\" role=\"group\" aria-label=\"Breakpoint de visualiza\u00E7\u00E3o\">\n <button\n *ngFor=\"let bp of breakpoints\"\n type=\"button\"\n mat-stroked-button\n class=\"bp-toggle__btn\"\n [class.active]=\"previewBreakpoint === bp\"\n (click)=\"previewBreakpoint = bp\"\n >\n {{ bp }}\n </button>\n </div>\n <div class=\"gap-controls\">\n <div class=\"gap-chip\" *ngIf=\"hasMultipleColumns()\" matTooltip=\"Gap entre colunas (px)\"\n aria-label=\"Gap entre colunas\">\n <span class=\"chip-title\">Colunas</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', -2)\"\n aria-label=\"Reduzir gap de colunas\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.gap ?? gapGlobal\"\n (ngModelChange)=\"updateRowGap('gap', $event)\" aria-label=\"Valor do gap entre colunas\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', 2)\"\n aria-label=\"Aumentar gap de colunas\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n <div class=\"gap-chip\" matTooltip=\"Gap abaixo da linha (px)\" aria-label=\"Gap abaixo da linha\">\n <span class=\"chip-title\">Linha</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', -2)\"\n aria-label=\"Reduzir espa\u00E7o entre campos da linha\" matTooltip=\"Reduz o espa\u00E7o entre campos desta linha\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.rowGap ?? 0\"\n (ngModelChange)=\"updateRowGap('rowGap', $event)\" aria-label=\"Espa\u00E7o entre campos desta linha\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', 2)\"\n aria-label=\"Aumentar espa\u00E7o entre campos da linha\" matTooltip=\"Aumenta o espa\u00E7o entre campos desta linha\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-icon-button class=\"gap-chip__btn\" [matMenuTriggerFor]=\"rowGapMenu\"\n matTooltip=\"Mais op\u00E7\u00F5es para aplicar este espa\u00E7o\" aria-label=\"Mais op\u00E7\u00F5es de aplica\u00E7\u00E3o\">\n <mat-icon>done_all</mat-icon>\n </button>\n <mat-menu #rowGapMenu=\"matMenu\">\n <button mat-menu-item (click)=\"applyRowGapToAll()\">\n <mat-icon>done_all</mat-icon>\n <span>Aplicar em todas as linhas da se\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item (click)=\"clearRowGap()\">\n <mat-icon>undo</mat-icon>\n <span>Voltar ao padr\u00E3o</span>\n </button>\n </mat-menu>\n </div>\n <div class=\"gap-pill\" aria-label=\"Resumo de espa\u00E7amentos\">\n Campos: {{ (row.rowGap ?? 'padr\u00E3o') }}px \u00B7 Colunas: {{ (row.gap ?? gapGlobal) }}px\n </div>\n <div class=\"row-actions-meta\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" (click)=\"openRowMenu()\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\" (closed)=\"onMenuClosed()\">\n <ng-container *ngIf=\"menuContext?.type === 'column'; else rowMenuContent\">\n <button mat-menu-item (click)=\"toggleHidden(menuContext!.columnIndex!)\">\n <mat-icon>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'visibility' : 'visibility_off'\n }}</mat-icon>\n <span>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'Mostrar neste breakpoint' : 'Ocultar neste\n breakpoint' }}</span>\n </button>\n <button mat-menu-item (click)=\"removeColumn(menuContext!.columnIndex!)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </ng-container>\n <ng-template #rowMenuContent>\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014\n 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014\n 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014\n 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </ng-template>\n </mat-menu>\n </div>\n </div>\n <div class=\"span-warning\" *ngIf=\"getSpanTotal(previewBreakpoint) !== 12\">\n <mat-icon color=\"warn\">warning</mat-icon>\n Soma de spans = {{ getSpanTotal(previewBreakpoint) }} (ideal: 12)\n </div>\n</div>\n\n<div class=\"row-container\" [style.marginBottom.px]=\"!isLastRow ? (row.rowGap || null) : null\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div class=\"row grid-12\" cdkDropListGroup (click)=\"selectRow()\" [class.selected]=\"isRowSelected()\" tabindex=\"0\"\n role=\"button\" [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\" [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\" [style.--px-row-field-gap.px]=\"row.rowGap ?? null\">\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div *ngFor=\"let column of row.columns; let i = index\" class=\"column\" [id]=\"getColumnId(i)\" cdkDropList\n [cdkDropListData]=\"column.fields\" [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\" (cdkDropListEntered)=\"onDropEnter(i)\" (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\" [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\" [ngClass]=\"getColumnClassList(column)\"\n [style.grid-column]=\"'span ' + getSpanFor(column)\" tabindex=\"0\" role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanFor(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\">\n <div class=\"column-header\">\n <div class=\"column-status-pill\" [matMenuTriggerFor]=\"columnSettingsMenu\"\n matTooltip=\"Clique para ajustar largura e offset\" [class.active]=\"isColumnSelected(i)\">\n <span class=\"status-bp\">{{ previewBreakpoint }}</span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-span\">\n <mat-icon>view_column</mat-icon>\n {{ getSpanFor(column) }}/12\n </span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-offset\">\n off {{ getOffsetFor(column) }}\n </span>\n <span class=\"status-hidden\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon>visibility_off</mat-icon>\n </span>\n </div>\n\n <div class=\"column-actions\">\n <button mat-icon-button class=\"action-btn\" [matMenuTriggerFor]=\"columnOverflowMenu\"\n (click)=\"$event.stopPropagation()\" matTooltip=\"Op\u00E7\u00F5es da coluna\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n\n <mat-menu #columnSettingsMenu=\"matMenu\" class=\"column-settings-popover\">\n <div class=\"popover-content\" (click)=\"$event.stopPropagation()\">\n <div class=\"control-group\" *ngIf=\"getSuggestedSpan(i) as suggested\">\n <button mat-flat-button color=\"primary\" (click)=\"setSpan(i, suggested)\"\n matTooltip=\"Ajustar largura para completar 12 colunas\">\n <mat-icon>auto_fix_high</mat-icon>\n Ajustar para {{ suggested }} (Total 12)\n </button>\n </div>\n <div class=\"control-group\">\n <label>Largura ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustSpan(i, -1)\"><mat-icon>remove</mat-icon></button>\n <span class=\"value-display\">{{ getSpanFor(column) }} / 12</span>\n <button mat-icon-button (click)=\"adjustSpan(i, 1)\"><mat-icon>add</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <label>Offset ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustOffset(i, -1)\"><mat-icon>chevron_left</mat-icon></button>\n <span class=\"value-display\">{{ getOffsetFor(column) }}</span>\n <button mat-icon-button (click)=\"adjustOffset(i, 1)\"><mat-icon>chevron_right</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <button mat-stroked-button (click)=\"toggleHidden(i)\" [color]=\"getHiddenFor(column) ? 'warn' : ''\">\n <mat-icon>{{ getHiddenFor(column) ? 'visibility' : 'visibility_off' }}</mat-icon>\n {{ getHiddenFor(column) ? 'Mostrar' : 'Ocultar' }}\n </button>\n </div>\n </div>\n </mat-menu>\n\n <mat-menu #columnOverflowMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openColumnConfig(i)\" matTooltip=\"Abrir painel de configura\u00E7\u00E3o completa\">\n <mat-icon>tune</mat-icon>\n <span>Configurar coluna</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"moveColumn(i, -1)\" [disabled]=\"i === 0\"\n matTooltip=\"Mover coluna para a esquerda\">\n <mat-icon>arrow_back</mat-icon>\n <span>Mover para esquerda</span>\n </button>\n <button mat-menu-item (click)=\"moveColumn(i, 1)\" [disabled]=\"i === row.columns.length - 1\"\n matTooltip=\"Mover coluna para a direita\">\n <mat-icon>arrow_forward</mat-icon>\n <span>Mover para direita</span>\n </button>\n\n <button mat-menu-item (click)=\"clearColumn(i)\" [disabled]=\"column.fields.length === 0\"\n matTooltip=\"Remover todos os campos desta coluna\">\n <mat-icon>backspace</mat-icon>\n <span>Limpar conte\u00FAdo</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeColumn(i)\" matTooltip=\"Excluir esta coluna\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </mat-menu>\n <div class=\"column-content\">\n <div class=\"hidden-overlay\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon aria-hidden=\"true\">visibility_off</mat-icon>\n <span>Oculta em {{ previewBreakpoint }}</span>\n </div>\n <ng-container *ngIf=\"column.fields.length > 0; else emptyColumn\">\n <div *ngFor=\"let fieldName of column.fields\" (click)=\"selectField(fieldName, $event)\"\n [class.selected]=\"isFieldSelected(fieldName)\">\n <praxis-field-configurator [field]=\"getFieldByName(fieldName)\"></praxis-field-configurator>\n </div>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou remova.</span>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou remova.</span>\n <div class=\"row-placeholder-actions\">\n <button mat-stroked-button (click)=\"addColumn()\" matTooltip=\"Adicionar coluna\">\n <mat-icon>add</mat-icon> Adicionar coluna\n </button>\n <button mat-stroked-button color=\"warn\" (click)=\"removeRow()\" matTooltip=\"Remover linha\">\n <mat-icon>delete</mat-icon> Remover linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.bp-toggle{display:inline-flex;gap:4px;align-items:center}.bp-toggle__btn{min-width:34px;height:30px;line-height:30px;padding:0 8px;text-transform:uppercase}.bp-toggle__btn.active{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.gap-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.gap-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.chip-title{font:var(--mdc-typography-label-medium, 600 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;letter-spacing:.03em}.span-warning{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-error);background:var(--md-sys-color-error-container);border:1px solid var(--md-sys-color-error);border-radius:6px;padding:4px 8px}.row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:0;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.row-actions-meta{margin-left:auto}.column{position:relative;flex:1;display:flex;flex-direction:column;border:1px dashed var(--md-sys-color-outline-variant);margin:0;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease;border-radius:8px;overflow:hidden}.column-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--md-sys-color-surface-variant);border-bottom:1px solid var(--md-sys-color-outline-variant);min-height:36px}.column-content{flex:1;display:grid;align-content:start;gap:var(--px-row-field-gap, 6px);padding:8px}.column-status-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:12px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none}.column-status-pill:hover,.column-status-pill.active{background:var(--md-sys-color-surface-variant);border-color:var(--md-sys-color-outline)}.status-bp{font-weight:700;text-transform:uppercase;font-size:11px;color:var(--md-sys-color-primary)}.status-divider{color:var(--md-sys-color-outline-variant)}.status-span,.status-offset{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--md-sys-color-on-surface)}.status-span mat-icon{font-size:14px;width:14px;height:14px}.status-hidden{color:var(--md-sys-color-error);display:flex;align-items:center}.status-hidden mat-icon{font-size:14px;width:14px;height:14px}.column-actions{display:flex;align-items:center;opacity:0;transition:opacity .2s ease}.column:hover .column-actions,.column.selected .column-actions,.column-actions:focus-within{opacity:1}.action-btn{width:24px;height:24px;line-height:24px;padding:0}.action-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.popover-content{padding:12px;display:flex;flex-direction:column;gap:12px;min-width:200px}.control-group{display:flex;flex-direction:column;gap:4px}.control-group label{font-size:11px;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;font-weight:600}.control-row{display:flex;align-items:center;justify-content:space-between;background:var(--md-sys-color-surface-container-high);border-radius:8px;padding:2px}.value-display{font-weight:600;font-size:13px}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}.hidden-overlay{position:absolute;inset:0;background:var(--md-sys-color-surface-container-low);border:1px dashed var(--md-sys-color-outline);display:flex;align-items:center;justify-content:center;gap:6px;color:var(--md-sys-color-on-surface-variant);z-index:2;pointer-events:none}\n"] }]
|
|
14182
|
+
], providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], template: "<div class=\"row-meta\" *ngIf=\"row\">\n <div class=\"bp-toggle\" role=\"group\" aria-label=\"Breakpoint de visualiza\u00E7\u00E3o\">\n <button\n *ngFor=\"let bp of breakpoints\"\n type=\"button\"\n mat-stroked-button\n class=\"bp-toggle__btn\"\n [class.active]=\"previewBreakpoint === bp\"\n (click)=\"previewBreakpoint = bp\"\n >\n {{ bp }}\n </button>\n </div>\n <div class=\"gap-controls\">\n <div class=\"gap-chip\" *ngIf=\"hasMultipleColumns()\" matTooltip=\"Gap entre colunas (px)\"\n aria-label=\"Gap entre colunas\">\n <span class=\"chip-title\">Colunas</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', -2)\"\n aria-label=\"Reduzir gap de colunas\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.gap ?? gapGlobal\"\n (ngModelChange)=\"updateRowGap('gap', $event)\" aria-label=\"Valor do gap entre colunas\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', 2)\"\n aria-label=\"Aumentar gap de colunas\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n <div class=\"gap-chip\" matTooltip=\"Gap abaixo da linha (px)\" aria-label=\"Gap abaixo da linha\">\n <span class=\"chip-title\">Linha</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', -2)\"\n aria-label=\"Reduzir espa\u00E7o entre campos da linha\" matTooltip=\"Reduz o espa\u00E7o entre campos desta linha\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.rowGap ?? 0\"\n (ngModelChange)=\"updateRowGap('rowGap', $event)\" aria-label=\"Espa\u00E7o entre campos desta linha\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', 2)\"\n aria-label=\"Aumentar espa\u00E7o entre campos da linha\" matTooltip=\"Aumenta o espa\u00E7o entre campos desta linha\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-icon-button class=\"gap-chip__btn\" [matMenuTriggerFor]=\"rowGapMenu\"\n matTooltip=\"Mais op\u00E7\u00F5es para aplicar este espa\u00E7o\" aria-label=\"Mais op\u00E7\u00F5es de aplica\u00E7\u00E3o\">\n <mat-icon>done_all</mat-icon>\n </button>\n <mat-menu #rowGapMenu=\"matMenu\">\n <button mat-menu-item (click)=\"applyRowGapToAll()\">\n <mat-icon>done_all</mat-icon>\n <span>Aplicar em todas as linhas da se\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item (click)=\"clearRowGap()\">\n <mat-icon>undo</mat-icon>\n <span>Voltar ao padr\u00E3o</span>\n </button>\n </mat-menu>\n </div>\n <div class=\"gap-pill\" aria-label=\"Resumo de espa\u00E7amentos\">\n Campos: {{ (row.rowGap ?? 'padr\u00E3o') }}px \u00B7 Colunas: {{ (row.gap ?? gapGlobal) }}px\n </div>\n <div class=\"row-actions-meta\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" (click)=\"openRowMenu()\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\" (closed)=\"onMenuClosed()\">\n <ng-container *ngIf=\"menuContext?.type === 'column'; else rowMenuContent\">\n <button mat-menu-item (click)=\"toggleHidden(menuContext!.columnIndex!)\">\n <mat-icon>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'visibility' : 'visibility_off'\n }}</mat-icon>\n <span>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'Mostrar neste breakpoint' : 'Ocultar neste\n breakpoint' }}</span>\n </button>\n <button mat-menu-item (click)=\"removeColumn(menuContext!.columnIndex!)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </ng-container>\n <ng-template #rowMenuContent>\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014\n 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014\n 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014\n 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </ng-template>\n </mat-menu>\n </div>\n </div>\n <div class=\"span-warning\" *ngIf=\"getSpanTotal(previewBreakpoint) !== 12\">\n <mat-icon color=\"warn\">warning</mat-icon>\n Soma de spans = {{ getSpanTotal(previewBreakpoint) }} (ideal: 12)\n </div>\n</div>\n\n<div class=\"row-container\" [style.marginBottom.px]=\"!isLastRow ? (row.rowGap || null) : null\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div class=\"row grid-12\" cdkDropListGroup (click)=\"selectRow()\" [class.selected]=\"isRowSelected()\" tabindex=\"0\"\n role=\"button\" [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\" [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\" [style.--px-row-field-gap.px]=\"row.rowGap ?? null\">\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div *ngFor=\"let column of row.columns; let i = index\" class=\"column\" [id]=\"getColumnId(i)\" cdkDropList\n [cdkDropListData]=\"getColumnLayoutItems(column)\" [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\" (cdkDropListEntered)=\"onDropEnter(i)\" (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\" [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\" [ngClass]=\"getColumnClassList(column)\"\n [style.grid-column]=\"'span ' + getSpanFor(column)\" tabindex=\"0\" role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanFor(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\">\n <div class=\"column-header\">\n <div class=\"column-status-pill\" [matMenuTriggerFor]=\"columnSettingsMenu\"\n matTooltip=\"Clique para ajustar largura e offset\" [class.active]=\"isColumnSelected(i)\">\n <span class=\"status-bp\">{{ previewBreakpoint }}</span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-span\">\n <mat-icon>view_column</mat-icon>\n {{ getSpanFor(column) }}/12\n </span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-offset\">\n off {{ getOffsetFor(column) }}\n </span>\n <span class=\"status-hidden\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon>visibility_off</mat-icon>\n </span>\n </div>\n\n <div class=\"column-actions\">\n <button mat-icon-button class=\"action-btn\" [matMenuTriggerFor]=\"columnOverflowMenu\"\n (click)=\"$event.stopPropagation()\" matTooltip=\"Op\u00E7\u00F5es da coluna\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n\n <mat-menu #columnSettingsMenu=\"matMenu\" class=\"column-settings-popover\">\n <div class=\"popover-content\" (click)=\"$event.stopPropagation()\">\n <div class=\"control-group\" *ngIf=\"getSuggestedSpan(i) as suggested\">\n <button mat-flat-button color=\"primary\" (click)=\"setSpan(i, suggested)\"\n matTooltip=\"Ajustar largura para completar 12 colunas\">\n <mat-icon>auto_fix_high</mat-icon>\n Ajustar para {{ suggested }} (Total 12)\n </button>\n </div>\n <div class=\"control-group\">\n <label>Largura ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustSpan(i, -1)\"><mat-icon>remove</mat-icon></button>\n <span class=\"value-display\">{{ getSpanFor(column) }} / 12</span>\n <button mat-icon-button (click)=\"adjustSpan(i, 1)\"><mat-icon>add</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <label>Offset ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustOffset(i, -1)\"><mat-icon>chevron_left</mat-icon></button>\n <span class=\"value-display\">{{ getOffsetFor(column) }}</span>\n <button mat-icon-button (click)=\"adjustOffset(i, 1)\"><mat-icon>chevron_right</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <button mat-stroked-button (click)=\"toggleHidden(i)\" [color]=\"getHiddenFor(column) ? 'warn' : ''\">\n <mat-icon>{{ getHiddenFor(column) ? 'visibility' : 'visibility_off' }}</mat-icon>\n {{ getHiddenFor(column) ? 'Mostrar' : 'Ocultar' }}\n </button>\n </div>\n </div>\n </mat-menu>\n\n <mat-menu #columnOverflowMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openColumnConfig(i)\" matTooltip=\"Abrir painel de configura\u00E7\u00E3o completa\">\n <mat-icon>tune</mat-icon>\n <span>Configurar coluna</span>\n </button>\n <button mat-menu-item [matMenuTriggerFor]=\"apiFieldMenu\" [matTooltip]=\"t('apiFields.addTooltip')\">\n <mat-icon>input</mat-icon>\n <span>{{ t('apiFields.addAction') }}</span>\n </button>\n <mat-menu #apiFieldMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let field of availableFields\"\n (click)=\"addApiFieldToColumn(i, field.name)\"\n >\n <mat-icon>short_text</mat-icon>\n <span>{{ getFieldLabel(field) }}</span>\n </button>\n <button mat-menu-item disabled *ngIf=\"!availableFields.length\">\n <span>{{ t('apiFields.empty') }}</span>\n </button>\n </mat-menu>\n <button mat-menu-item [matMenuTriggerFor]=\"visualBlockPresetMenu\" [matTooltip]=\"t('visualBlock.addTooltip')\">\n <mat-icon>notes</mat-icon>\n <span>{{ t('visualBlock.addAction') }}</span>\n </button>\n <mat-menu #visualBlockPresetMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let preset of visualBlockPresets\"\n (click)=\"addVisualBlockToColumn(i, preset.id)\"\n >\n <mat-icon>{{ preset.icon }}</mat-icon>\n <span>{{ t(preset.labelKey) }}</span>\n </button>\n </mat-menu>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"moveColumn(i, -1)\" [disabled]=\"i === 0\"\n matTooltip=\"Mover coluna para a esquerda\">\n <mat-icon>arrow_back</mat-icon>\n <span>Mover para esquerda</span>\n </button>\n <button mat-menu-item (click)=\"moveColumn(i, 1)\" [disabled]=\"i === row.columns.length - 1\"\n matTooltip=\"Mover coluna para a direita\">\n <mat-icon>arrow_forward</mat-icon>\n <span>Mover para direita</span>\n </button>\n\n <button mat-menu-item (click)=\"clearColumn(i)\" [disabled]=\"!hasColumnContent(column)\"\n matTooltip=\"Remover todo o conte\u00C3\u00BAdo desta coluna\">\n <mat-icon>backspace</mat-icon>\n <span>Limpar conte\u00FAdo</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeColumn(i)\" matTooltip=\"Excluir esta coluna\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </mat-menu>\n <div class=\"column-content\">\n <div class=\"hidden-overlay\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon aria-hidden=\"true\">visibility_off</mat-icon>\n <span>Oculta em {{ previewBreakpoint }}</span>\n </div>\n <ng-container *ngIf=\"hasColumnContent(column); else emptyColumn\">\n <ng-container *ngFor=\"let item of getColumnLayoutItems(column); let itemIndex = index; trackBy: trackLayoutItem\">\n <div *ngIf=\"item.kind === 'field'; else visualBlockItem\" (click)=\"selectField(item.fieldName, $event)\"\n [class.selected]=\"isFieldSelected(item.fieldName)\">\n <praxis-field-configurator [field]=\"getFieldByName(item.fieldName)\"></praxis-field-configurator>\n </div>\n <ng-template #visualBlockItem>\n <div\n class=\"visual-block-preview\"\n *ngIf=\"item.kind === 'richContent'\"\n cdkDrag\n [cdkDragData]=\"item\"\n role=\"button\"\n tabindex=\"0\"\n [class.selected]=\"selected?.type === 'visualBlock' && selected?.itemId === item.id\"\n (click)=\"selectVisualBlock(i, item, $event)\"\n (dblclick)=\"openVisualBlockEditor(i, item, $event)\"\n (keydown.enter)=\"openVisualBlockEditor(i, item, $event)\"\n (keydown.space)=\"selectVisualBlock(i, item, $event); $event.preventDefault()\"\n >\n <button\n class=\"visual-block-preview__drag-handle\"\n type=\"button\"\n cdkDragHandle\n [matTooltip]=\"t('visualBlock.dragHandle')\"\n [attr.aria-label]=\"t('visualBlock.dragHandle')\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </button>\n <mat-icon aria-hidden=\"true\">notes</mat-icon>\n <span class=\"visual-block-preview__text\">\n <span class=\"visual-block-preview__eyebrow\">{{ t('visualBlock.previewEyebrow') }}</span>\n <span class=\"visual-block-preview__label\">{{ getVisualBlockLabel(item) }}</span>\n </span>\n <span class=\"visual-block-preview__actions\">\n <button\n mat-icon-button\n class=\"visual-block-preview__action visual-block-preview__quick-action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveUp')\"\n [attr.aria-label]=\"t('visualBlock.moveUp')\"\n [disabled]=\"itemIndex === 0\"\n (click)=\"moveVisualBlockItem(i, item, -1, $event)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action visual-block-preview__quick-action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveDown')\"\n [attr.aria-label]=\"t('visualBlock.moveDown')\"\n [disabled]=\"itemIndex === getColumnLayoutItems(column).length - 1\"\n (click)=\"moveVisualBlockItem(i, item, 1, $event)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.editAction')\"\n [attr.aria-label]=\"t('visualBlock.editAction')\"\n (click)=\"openVisualBlockEditor(i, item, $event)\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matMenuTriggerFor]=\"visualBlockActionsMenu\"\n [matTooltip]=\"t('visualBlock.moreActions')\"\n [attr.aria-label]=\"t('visualBlock.moreActions')\"\n >\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #visualBlockActionsMenu=\"matMenu\">\n <button\n mat-menu-item\n [disabled]=\"itemIndex === 0\"\n (click)=\"moveVisualBlockItem(i, item, -1, $event)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n <span>{{ t('visualBlock.moveUp') }}</span>\n </button>\n <button\n mat-menu-item\n [disabled]=\"itemIndex === getColumnLayoutItems(column).length - 1\"\n (click)=\"moveVisualBlockItem(i, item, 1, $event)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n <span>{{ t('visualBlock.moveDown') }}</span>\n </button>\n <button\n mat-menu-item\n [disabled]=\"!canMoveVisualBlockToColumn(i, -1)\"\n (click)=\"moveVisualBlockToAdjacentColumn(i, item, -1, $event)\"\n >\n <mat-icon>arrow_back</mat-icon>\n <span>{{ t('visualBlock.movePreviousColumn') }}</span>\n </button>\n <button\n mat-menu-item\n [disabled]=\"!canMoveVisualBlockToColumn(i, 1)\"\n (click)=\"moveVisualBlockToAdjacentColumn(i, item, 1, $event)\"\n >\n <mat-icon>arrow_forward</mat-icon>\n <span>{{ t('visualBlock.moveNextColumn') }}</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeVisualBlockItem(i, item, $event)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>{{ t('visualBlock.removeAction') }}</span>\n </button>\n </mat-menu>\n </span>\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou remova.</span>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou remova.</span>\n <div class=\"row-placeholder-actions\">\n <button mat-stroked-button (click)=\"addColumn()\" matTooltip=\"Adicionar coluna\">\n <mat-icon>add</mat-icon> Adicionar coluna\n </button>\n <button mat-stroked-button color=\"warn\" (click)=\"removeRow()\" matTooltip=\"Remover linha\">\n <mat-icon>delete</mat-icon> Remover linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.bp-toggle{display:inline-flex;gap:4px;align-items:center}.bp-toggle__btn{min-width:34px;height:30px;line-height:30px;padding:0 8px;text-transform:uppercase}.bp-toggle__btn.active{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.gap-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.gap-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.chip-title{font:var(--mdc-typography-label-medium, 600 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;letter-spacing:.03em}.span-warning{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-error);background:var(--md-sys-color-error-container);border:1px solid var(--md-sys-color-error);border-radius:6px;padding:4px 8px}.row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:0;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.row-actions-meta{margin-left:auto}.column{position:relative;flex:1;display:flex;flex-direction:column;border:1px dashed var(--md-sys-color-outline-variant);margin:0;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease;border-radius:8px;overflow:hidden}.column-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--md-sys-color-surface-variant);border-bottom:1px solid var(--md-sys-color-outline-variant);min-height:36px}.column-content{flex:1;display:grid;align-content:start;gap:var(--px-row-field-gap, 6px);padding:8px}.column-status-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:12px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none}.column-status-pill:hover,.column-status-pill.active{background:var(--md-sys-color-surface-variant);border-color:var(--md-sys-color-outline)}.status-bp{font-weight:700;text-transform:uppercase;font-size:11px;color:var(--md-sys-color-primary)}.status-divider{color:var(--md-sys-color-outline-variant)}.status-span,.status-offset{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--md-sys-color-on-surface)}.status-span mat-icon{font-size:14px;width:14px;height:14px}.status-hidden{color:var(--md-sys-color-error);display:flex;align-items:center}.status-hidden mat-icon{font-size:14px;width:14px;height:14px}.column-actions{display:flex;align-items:center;opacity:0;transition:opacity .2s ease}.column:hover .column-actions,.column.selected .column-actions,.column-actions:focus-within{opacity:1}.action-btn{width:24px;height:24px;line-height:24px;padding:0}.action-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.popover-content{padding:12px;display:flex;flex-direction:column;gap:12px;min-width:200px}.control-group{display:flex;flex-direction:column;gap:4px}.control-group label{font-size:11px;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;font-weight:600}.control-row{display:flex;align-items:center;justify-content:space-between;background:var(--md-sys-color-surface-container-high);border-radius:8px;padding:2px}.value-display{font-weight:600;font-size:13px}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.visual-block-preview{display:flex;align-items:center;gap:8px;min-height:44px;min-width:0;padding:8px 10px;border:1px solid var(--md-sys-color-outline-variant);border-left:3px solid color-mix(in srgb,var(--md-sys-color-primary) 54%,var(--md-sys-color-outline-variant) 46%);border-radius:8px;background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface);font-size:13px;cursor:pointer}.visual-block-preview:hover{border-color:color-mix(in srgb,var(--md-sys-color-primary) 38%,var(--md-sys-color-outline-variant) 62%);border-left-color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 10%,var(--md-sys-color-surface-container-low, var(--md-sys-color-surface)) 90%)}.visual-block-preview.selected{border-color:var(--md-sys-color-primary);border-left-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.visual-block-preview.cdk-drag-dragging{cursor:grabbing}.visual-block-preview.cdk-drag-preview{box-sizing:border-box;border-color:var(--md-sys-color-primary);border-left-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-container, var(--md-sys-color-surface));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.visual-block-preview.cdk-drag-placeholder{position:relative;min-height:44px;border-color:transparent;border-left-color:transparent;background:transparent;box-shadow:none;opacity:1}.visual-block-preview.cdk-drag-placeholder>*{visibility:hidden}.visual-block-preview.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.visual-block-preview.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}.visual-block-preview mat-icon{font-size:18px;width:18px;height:18px}.visual-block-preview__drag-handle{border:0;border-radius:50%;padding:0;background:transparent;display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;color:var(--md-sys-color-on-surface-variant);cursor:grab;opacity:.72;flex:0 0 auto}.visual-block-preview__drag-handle:hover,.visual-block-preview__drag-handle:focus-visible{color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 52%,transparent);opacity:1;outline:none}.visual-block-preview__drag-handle:active{cursor:grabbing}.visual-block-preview.selected .visual-block-preview__drag-handle,.visual-block-preview.cdk-drag-dragging .visual-block-preview__drag-handle,.visual-block-preview.cdk-drag-preview .visual-block-preview__drag-handle{color:var(--md-sys-color-primary);opacity:1}.visual-block-preview__text{display:grid;gap:1px;min-width:0}.visual-block-preview__eyebrow{color:var(--md-sys-color-primary);font:var(--mdc-typography-label-small, 700 11px/14px system-ui);text-transform:uppercase}.visual-block-preview__label{overflow:hidden;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 500 13px/18px system-ui);text-overflow:ellipsis;white-space:nowrap}.visual-block-preview__actions{margin-left:auto;display:inline-flex;align-items:center;gap:2px;flex:0 0 auto}.visual-block-preview__action{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;line-height:1;min-width:30px;--mdc-icon-button-size: 30px;--mdc-icon-button-state-layer-size: 30px;--mdc-icon-button-icon-size: 18px;--mat-icon-button-state-layer-size: 30px;--mat-icon-button-icon-size: 18px}.visual-block-preview__action mat-icon{display:inline-flex;align-items:center;justify-content:center;margin:0;line-height:18px}:host ::ng-deep .visual-block-preview__action .mat-mdc-button-touch-target{width:30px;height:30px}:host ::ng-deep .visual-block-preview__action .mat-mdc-button-persistent-ripple,:host ::ng-deep .visual-block-preview__action .mat-mdc-button-persistent-ripple:before,:host ::ng-deep .visual-block-preview__action .mat-ripple{inset:0;border-radius:50%}.visual-block-preview__quick-action{color:var(--md-sys-color-on-surface-variant);opacity:0;visibility:hidden;transition:opacity .12s ease,visibility .12s ease}.visual-block-preview:hover .visual-block-preview__quick-action,.visual-block-preview:focus-within .visual-block-preview__quick-action,.visual-block-preview.selected .visual-block-preview__quick-action{opacity:1;visibility:visible}.visual-block-preview__quick-action[disabled]{opacity:.28}@media(max-width:768px),(pointer:coarse){.visual-block-preview__quick-action{display:none}}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}.hidden-overlay{position:absolute;inset:0;background:var(--md-sys-color-surface-container-low);border:1px dashed var(--md-sys-color-outline);display:flex;align-items:center;justify-content:center;gap:6px;color:var(--md-sys-color-on-surface-variant);z-index:2;pointer-events:none}\n"] }]
|
|
13520
14183
|
}], propDecorators: { row: [{
|
|
13521
14184
|
type: Input
|
|
13522
14185
|
}], fieldMetadata: [{
|
|
13523
14186
|
type: Input
|
|
14187
|
+
}], availableFields: [{
|
|
14188
|
+
type: Input
|
|
13524
14189
|
}], sectionIndex: [{
|
|
13525
14190
|
type: Input
|
|
13526
14191
|
}], rowIndex: [{
|
|
@@ -13543,6 +14208,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
13543
14208
|
type: Output
|
|
13544
14209
|
}], fieldDrop: [{
|
|
13545
14210
|
type: Output
|
|
14211
|
+
}], addVisualBlock: [{
|
|
14212
|
+
type: Output
|
|
14213
|
+
}], addApiField: [{
|
|
14214
|
+
type: Output
|
|
14215
|
+
}], editVisualBlock: [{
|
|
14216
|
+
type: Output
|
|
14217
|
+
}], moveVisualBlock: [{
|
|
14218
|
+
type: Output
|
|
14219
|
+
}], moveVisualBlockToColumn: [{
|
|
14220
|
+
type: Output
|
|
14221
|
+
}], removeVisualBlock: [{
|
|
14222
|
+
type: Output
|
|
13546
14223
|
}], select: [{
|
|
13547
14224
|
type: Output
|
|
13548
14225
|
}] } });
|
|
@@ -13812,6 +14489,7 @@ class SectionConfiguratorComponent {
|
|
|
13812
14489
|
sectionIndex;
|
|
13813
14490
|
allSections = [];
|
|
13814
14491
|
fieldMetadata = [];
|
|
14492
|
+
availableFields = [];
|
|
13815
14493
|
selected = null;
|
|
13816
14494
|
availableFieldsListId = 'available-fields-list';
|
|
13817
14495
|
columnDropListIds = [];
|
|
@@ -13821,6 +14499,12 @@ class SectionConfiguratorComponent {
|
|
|
13821
14499
|
remove = new EventEmitter();
|
|
13822
14500
|
select = new EventEmitter();
|
|
13823
14501
|
fieldDrop = new EventEmitter();
|
|
14502
|
+
addVisualBlock = new EventEmitter();
|
|
14503
|
+
addApiField = new EventEmitter();
|
|
14504
|
+
editVisualBlock = new EventEmitter();
|
|
14505
|
+
moveVisualBlock = new EventEmitter();
|
|
14506
|
+
moveVisualBlockToColumn = new EventEmitter();
|
|
14507
|
+
removeVisualBlock = new EventEmitter();
|
|
13824
14508
|
isHovered = false;
|
|
13825
14509
|
isCollapsed = false;
|
|
13826
14510
|
constructor(dialog, presetRegistry, settingsPanel) {
|
|
@@ -13895,6 +14579,56 @@ class SectionConfiguratorComponent {
|
|
|
13895
14579
|
onFieldDrop(event, rowIndex) {
|
|
13896
14580
|
this.fieldDrop.emit({ event, sectionIndex: this.sectionIndex, rowIndex });
|
|
13897
14581
|
}
|
|
14582
|
+
onAddVisualBlock(event) {
|
|
14583
|
+
this.addVisualBlock.emit({
|
|
14584
|
+
sectionIndex: this.sectionIndex,
|
|
14585
|
+
rowIndex: event.rowIndex,
|
|
14586
|
+
columnIndex: event.columnIndex,
|
|
14587
|
+
presetId: event.presetId,
|
|
14588
|
+
});
|
|
14589
|
+
}
|
|
14590
|
+
onAddApiField(event) {
|
|
14591
|
+
this.addApiField.emit({
|
|
14592
|
+
sectionIndex: this.sectionIndex,
|
|
14593
|
+
rowIndex: event.rowIndex,
|
|
14594
|
+
columnIndex: event.columnIndex,
|
|
14595
|
+
fieldName: event.fieldName,
|
|
14596
|
+
});
|
|
14597
|
+
}
|
|
14598
|
+
onEditVisualBlock(event) {
|
|
14599
|
+
this.editVisualBlock.emit({
|
|
14600
|
+
sectionIndex: this.sectionIndex,
|
|
14601
|
+
rowIndex: event.rowIndex,
|
|
14602
|
+
columnIndex: event.columnIndex,
|
|
14603
|
+
itemId: event.itemId,
|
|
14604
|
+
});
|
|
14605
|
+
}
|
|
14606
|
+
onMoveVisualBlock(event) {
|
|
14607
|
+
this.moveVisualBlock.emit({
|
|
14608
|
+
sectionIndex: this.sectionIndex,
|
|
14609
|
+
rowIndex: event.rowIndex,
|
|
14610
|
+
columnIndex: event.columnIndex,
|
|
14611
|
+
itemId: event.itemId,
|
|
14612
|
+
direction: event.direction,
|
|
14613
|
+
});
|
|
14614
|
+
}
|
|
14615
|
+
onMoveVisualBlockToColumn(event) {
|
|
14616
|
+
this.moveVisualBlockToColumn.emit({
|
|
14617
|
+
sectionIndex: this.sectionIndex,
|
|
14618
|
+
rowIndex: event.rowIndex,
|
|
14619
|
+
columnIndex: event.columnIndex,
|
|
14620
|
+
targetColumnIndex: event.targetColumnIndex,
|
|
14621
|
+
itemId: event.itemId,
|
|
14622
|
+
});
|
|
14623
|
+
}
|
|
14624
|
+
onRemoveVisualBlock(event) {
|
|
14625
|
+
this.removeVisualBlock.emit({
|
|
14626
|
+
sectionIndex: this.sectionIndex,
|
|
14627
|
+
rowIndex: event.rowIndex,
|
|
14628
|
+
columnIndex: event.columnIndex,
|
|
14629
|
+
itemId: event.itemId,
|
|
14630
|
+
});
|
|
14631
|
+
}
|
|
13898
14632
|
onRemoveSection() {
|
|
13899
14633
|
this.remove.emit();
|
|
13900
14634
|
}
|
|
@@ -14050,7 +14784,7 @@ class SectionConfiguratorComponent {
|
|
|
14050
14784
|
this.applyStyleToAll.emit(patch);
|
|
14051
14785
|
}
|
|
14052
14786
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SectionConfiguratorComponent, deps: [{ token: i2$1.MatDialog }, { token: SectionPresetRegistry }, { token: i7.SettingsPanelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
14053
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: SectionConfiguratorComponent, isStandalone: true, selector: "praxis-section-configurator", inputs: { section: "section", sectionIndex: "sectionIndex", allSections: "allSections", fieldMetadata: "fieldMetadata", selected: "selected", availableFieldsListId: "availableFieldsListId", columnDropListIds: "columnDropListIds", gapGlobal: "gapGlobal" }, outputs: { sectionChange: "sectionChange", applyStyleToAll: "applyStyleToAll", remove: "remove", select: "select", fieldDrop: "fieldDrop" }, ngImport: i0, template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n <span class=\"section-desc\" *ngIf=\"section.description\">{{ section.description }}</span>\n </div>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n class=\"section-editor-trigger\"\n (click)=\"openAdvancedEditor($event)\"\n matTooltip=\"Para editar o t\u00EDtulo, use o editor completo da se\u00E7\u00E3o\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n <mat-icon>open_in_new</mat-icon>\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n mat-icon-button\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n <mat-icon>{{ isCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-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-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.section-header-actions .mat-mdc-icon-button{width:36px;height:36px;padding:6px}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\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: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: RowConfiguratorComponent, selector: "praxis-row-configurator", inputs: ["row", "fieldMetadata", "sectionIndex", "rowIndex", "isLastRow", "selected", "availableFieldsListId", "connectedDropListIds", "gapGlobal"], outputs: ["rowChange", "remove", "applyRowGapAll", "fieldDrop", "select"] }, { kind: "ngmodule", type: MatButtonModule }, { 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: 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: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i8.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i8.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { 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: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
|
|
14787
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: SectionConfiguratorComponent, isStandalone: true, selector: "praxis-section-configurator", inputs: { section: "section", sectionIndex: "sectionIndex", allSections: "allSections", fieldMetadata: "fieldMetadata", availableFields: "availableFields", selected: "selected", availableFieldsListId: "availableFieldsListId", columnDropListIds: "columnDropListIds", gapGlobal: "gapGlobal" }, outputs: { sectionChange: "sectionChange", applyStyleToAll: "applyStyleToAll", remove: "remove", select: "select", fieldDrop: "fieldDrop", addVisualBlock: "addVisualBlock", addApiField: "addApiField", editVisualBlock: "editVisualBlock", moveVisualBlock: "moveVisualBlock", moveVisualBlockToColumn: "moveVisualBlockToColumn", removeVisualBlock: "removeVisualBlock" }, ngImport: i0, template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n <span class=\"section-desc\" *ngIf=\"section.description\">{{ section.description }}</span>\n </div>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n class=\"section-editor-trigger\"\n (click)=\"openAdvancedEditor($event)\"\n matTooltip=\"Para editar o t\u00EDtulo, use o editor completo da se\u00E7\u00E3o\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n <mat-icon>open_in_new</mat-icon>\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n mat-icon-button\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n <mat-icon>{{ isCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [availableFields]=\"availableFields\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n (addVisualBlock)=\"onAddVisualBlock($event)\"\n (addApiField)=\"onAddApiField($event)\"\n (editVisualBlock)=\"onEditVisualBlock($event)\"\n (moveVisualBlock)=\"onMoveVisualBlock($event)\"\n (moveVisualBlockToColumn)=\"onMoveVisualBlockToColumn($event)\"\n (removeVisualBlock)=\"onRemoveVisualBlock($event)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card.cdk-drag-dragging{cursor:grabbing}.section-card.cdk-drag-preview{box-sizing:border-box;border-color:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.section-card.cdk-drag-placeholder{position:relative;min-height:64px;border-color:transparent;background:transparent;box-shadow:none;opacity:1}.section-card.cdk-drag-placeholder>*{visibility:hidden}.section-card.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 12px auto 12px;height:2px;border-radius:999px;background:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)) 16%,transparent)}.section-card.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 5px);left:12px;width:10px;height:10px;border-radius:50%;background:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-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-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.section-header-actions .mat-mdc-icon-button{width:36px;height:36px;padding:6px}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}.row-item.cdk-drag-dragging{cursor:grabbing}.row-item.cdk-drag-preview{box-sizing:border-box;border-radius:8px;background:var(--md-sys-color-surface-container, var(--md-sys-color-surface));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.row-item.cdk-drag-placeholder{position:relative;display:block;min-height:56px;opacity:1}.row-item.cdk-drag-placeholder>*{visibility:hidden}.row-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)) 16%,transparent)}.row-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary, var(--sicoob-primary-default))}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\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: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: RowConfiguratorComponent, selector: "praxis-row-configurator", inputs: ["row", "fieldMetadata", "availableFields", "sectionIndex", "rowIndex", "isLastRow", "selected", "availableFieldsListId", "connectedDropListIds", "gapGlobal"], outputs: ["rowChange", "remove", "applyRowGapAll", "fieldDrop", "addVisualBlock", "addApiField", "editVisualBlock", "moveVisualBlock", "moveVisualBlockToColumn", "removeVisualBlock", "select"] }, { kind: "ngmodule", type: MatButtonModule }, { 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: 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: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i8.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i8.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { 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: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
|
|
14054
14788
|
}
|
|
14055
14789
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SectionConfiguratorComponent, decorators: [{
|
|
14056
14790
|
type: Component,
|
|
@@ -14066,7 +14800,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
14066
14800
|
MatDialogModule,
|
|
14067
14801
|
MatMenuModule,
|
|
14068
14802
|
MatDividerModule,
|
|
14069
|
-
], template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n <span class=\"section-desc\" *ngIf=\"section.description\">{{ section.description }}</span>\n </div>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n class=\"section-editor-trigger\"\n (click)=\"openAdvancedEditor($event)\"\n matTooltip=\"Para editar o t\u00EDtulo, use o editor completo da se\u00E7\u00E3o\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n <mat-icon>open_in_new</mat-icon>\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n mat-icon-button\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n <mat-icon>{{ isCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-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-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.section-header-actions .mat-mdc-icon-button{width:36px;height:36px;padding:6px}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"] }]
|
|
14803
|
+
], template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n <span class=\"section-desc\" *ngIf=\"section.description\">{{ section.description }}</span>\n </div>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n class=\"section-editor-trigger\"\n (click)=\"openAdvancedEditor($event)\"\n matTooltip=\"Para editar o t\u00EDtulo, use o editor completo da se\u00E7\u00E3o\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n <mat-icon>open_in_new</mat-icon>\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n mat-icon-button\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n <mat-icon>{{ isCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [availableFields]=\"availableFields\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n (addVisualBlock)=\"onAddVisualBlock($event)\"\n (addApiField)=\"onAddApiField($event)\"\n (editVisualBlock)=\"onEditVisualBlock($event)\"\n (moveVisualBlock)=\"onMoveVisualBlock($event)\"\n (moveVisualBlockToColumn)=\"onMoveVisualBlockToColumn($event)\"\n (removeVisualBlock)=\"onRemoveVisualBlock($event)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card.cdk-drag-dragging{cursor:grabbing}.section-card.cdk-drag-preview{box-sizing:border-box;border-color:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.section-card.cdk-drag-placeholder{position:relative;min-height:64px;border-color:transparent;background:transparent;box-shadow:none;opacity:1}.section-card.cdk-drag-placeholder>*{visibility:hidden}.section-card.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 12px auto 12px;height:2px;border-radius:999px;background:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)) 16%,transparent)}.section-card.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 5px);left:12px;width:10px;height:10px;border-radius:50%;background:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-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-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.section-header-actions .mat-mdc-icon-button{width:36px;height:36px;padding:6px}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}.row-item.cdk-drag-dragging{cursor:grabbing}.row-item.cdk-drag-preview{box-sizing:border-box;border-radius:8px;background:var(--md-sys-color-surface-container, var(--md-sys-color-surface));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.row-item.cdk-drag-placeholder{position:relative;display:block;min-height:56px;opacity:1}.row-item.cdk-drag-placeholder>*{visibility:hidden}.row-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)) 16%,transparent)}.row-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary, var(--sicoob-primary-default))}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"] }]
|
|
14070
14804
|
}], ctorParameters: () => [{ type: i2$1.MatDialog }, { type: SectionPresetRegistry }, { type: i7.SettingsPanelService }], propDecorators: { section: [{
|
|
14071
14805
|
type: Input
|
|
14072
14806
|
}], sectionIndex: [{
|
|
@@ -14075,6 +14809,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
14075
14809
|
type: Input
|
|
14076
14810
|
}], fieldMetadata: [{
|
|
14077
14811
|
type: Input
|
|
14812
|
+
}], availableFields: [{
|
|
14813
|
+
type: Input
|
|
14078
14814
|
}], selected: [{
|
|
14079
14815
|
type: Input
|
|
14080
14816
|
}], availableFieldsListId: [{
|
|
@@ -14093,6 +14829,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
14093
14829
|
type: Output
|
|
14094
14830
|
}], fieldDrop: [{
|
|
14095
14831
|
type: Output
|
|
14832
|
+
}], addVisualBlock: [{
|
|
14833
|
+
type: Output
|
|
14834
|
+
}], addApiField: [{
|
|
14835
|
+
type: Output
|
|
14836
|
+
}], editVisualBlock: [{
|
|
14837
|
+
type: Output
|
|
14838
|
+
}], moveVisualBlock: [{
|
|
14839
|
+
type: Output
|
|
14840
|
+
}], moveVisualBlockToColumn: [{
|
|
14841
|
+
type: Output
|
|
14842
|
+
}], removeVisualBlock: [{
|
|
14843
|
+
type: Output
|
|
14096
14844
|
}] } });
|
|
14097
14845
|
|
|
14098
14846
|
/** Tokens for theme colors used across the layout editor. */
|
|
@@ -14141,6 +14889,10 @@ class LayoutEditorComponent {
|
|
|
14141
14889
|
configChange = new EventEmitter();
|
|
14142
14890
|
paletteCollapsed = false;
|
|
14143
14891
|
prefs = inject(LayoutPrefsService);
|
|
14892
|
+
layoutService = inject(DynamicFormLayoutService);
|
|
14893
|
+
settingsPanel = inject(SettingsPanelService);
|
|
14894
|
+
i18n = inject(PraxisI18nService);
|
|
14895
|
+
visualBlockIdSequence = 0;
|
|
14144
14896
|
colorTokens = LayoutColorToken;
|
|
14145
14897
|
selected = null;
|
|
14146
14898
|
// Global default for section gap (inherited when not customized)
|
|
@@ -14214,12 +14966,15 @@ class LayoutEditorComponent {
|
|
|
14214
14966
|
this.config.sections.forEach((s) => {
|
|
14215
14967
|
s.rows.forEach((r) => {
|
|
14216
14968
|
r.columns.forEach((c) => {
|
|
14217
|
-
c.
|
|
14969
|
+
getFormColumnFieldNames(c).forEach((fieldName) => placedFieldNames.add(fieldName));
|
|
14218
14970
|
});
|
|
14219
14971
|
});
|
|
14220
14972
|
});
|
|
14221
14973
|
return visibleFields.filter((f) => !placedFieldNames.has(f.name));
|
|
14222
14974
|
}
|
|
14975
|
+
t(key, params) {
|
|
14976
|
+
return this.i18n.t(key, params, LAYOUT_EDITOR_DEFAULT_COPY[key] ?? key, LAYOUT_EDITOR_I18N_NAMESPACE);
|
|
14977
|
+
}
|
|
14223
14978
|
get columnDropListIds() {
|
|
14224
14979
|
const ids = [];
|
|
14225
14980
|
this.config.sections.forEach((section, sIdx) => {
|
|
@@ -14264,42 +15019,74 @@ class LayoutEditorComponent {
|
|
|
14264
15019
|
dropField({ event }) {
|
|
14265
15020
|
const prevPos = this.parseColumnId(event.previousContainer.id);
|
|
14266
15021
|
const currentPos = this.parseColumnId(event.container.id);
|
|
14267
|
-
|
|
14268
|
-
|
|
14269
|
-
|
|
14270
|
-
|
|
14271
|
-
|
|
14272
|
-
|
|
14273
|
-
|
|
14274
|
-
|
|
14275
|
-
|
|
14276
|
-
|
|
14277
|
-
|
|
14278
|
-
|
|
14279
|
-
|
|
14280
|
-
|
|
14281
|
-
|
|
14282
|
-
|
|
14283
|
-
|
|
14284
|
-
|
|
14285
|
-
|
|
14286
|
-
|
|
14287
|
-
|
|
14288
|
-
|
|
14289
|
-
|
|
14290
|
-
|
|
14291
|
-
|
|
14292
|
-
|
|
14293
|
-
|
|
14294
|
-
|
|
14295
|
-
|
|
14296
|
-
|
|
14297
|
-
|
|
14298
|
-
}
|
|
14299
|
-
});
|
|
14300
|
-
this.config = newConfig;
|
|
15022
|
+
let nextConfig = this.layoutService.normalizeConfig(this.config);
|
|
15023
|
+
if (event.previousContainer.id === 'available-fields-list') {
|
|
15024
|
+
if (!currentPos)
|
|
15025
|
+
return;
|
|
15026
|
+
const field = (event.item?.data ??
|
|
15027
|
+
event.previousContainer.data?.[event.previousIndex]);
|
|
15028
|
+
if (!field?.name)
|
|
15029
|
+
return;
|
|
15030
|
+
const target = this.getColumnTargetByIndex(nextConfig, currentPos);
|
|
15031
|
+
if (!target)
|
|
15032
|
+
return;
|
|
15033
|
+
nextConfig = this.layoutService.insertLayoutItemById(nextConfig, target, createFieldLayoutItem(field.name, event.currentIndex), event.currentIndex).config;
|
|
15034
|
+
}
|
|
15035
|
+
else if (event.container.id === 'available-fields-list') {
|
|
15036
|
+
if (!prevPos)
|
|
15037
|
+
return;
|
|
15038
|
+
const source = this.getColumnTargetByIndex(nextConfig, prevPos);
|
|
15039
|
+
const sourceItem = this.getColumnLayoutItemByIndex(nextConfig, prevPos, event.previousIndex);
|
|
15040
|
+
if (!source || sourceItem?.kind !== 'field')
|
|
15041
|
+
return;
|
|
15042
|
+
nextConfig = this.layoutService.removeLayoutItemById(nextConfig, source.sectionId, source.rowId, source.columnId, sourceItem.id).config;
|
|
15043
|
+
}
|
|
15044
|
+
else if (prevPos && currentPos) {
|
|
15045
|
+
const source = this.getColumnTargetByIndex(nextConfig, prevPos);
|
|
15046
|
+
const target = this.getColumnTargetByIndex(nextConfig, currentPos);
|
|
15047
|
+
const sourceItem = this.getColumnLayoutItemByIndex(nextConfig, prevPos, event.previousIndex);
|
|
15048
|
+
if (!source || !target || !sourceItem)
|
|
15049
|
+
return;
|
|
15050
|
+
nextConfig = this.layoutService.moveLayoutItemById(nextConfig, { ...source, itemId: sourceItem.id }, { ...target, toIndex: event.currentIndex }).config;
|
|
15051
|
+
}
|
|
15052
|
+
this.config = nextConfig;
|
|
14301
15053
|
this.configChange.emit(this.config);
|
|
14302
15054
|
}
|
|
15055
|
+
getColumnLayoutItemByIndex(config, pos, itemIndex) {
|
|
15056
|
+
const column = config.sections[pos.sectionIndex]?.rows?.[pos.rowIndex]?.columns?.[pos.columnIndex];
|
|
15057
|
+
return normalizeFormLayoutItems(column)[itemIndex] ?? null;
|
|
15058
|
+
}
|
|
15059
|
+
getColumnTargetByIndex(config, pos) {
|
|
15060
|
+
const section = config.sections[pos.sectionIndex];
|
|
15061
|
+
const row = section?.rows?.[pos.rowIndex];
|
|
15062
|
+
const column = row?.columns?.[pos.columnIndex];
|
|
15063
|
+
if (!section?.id || !row?.id || !column?.id)
|
|
15064
|
+
return null;
|
|
15065
|
+
return {
|
|
15066
|
+
sectionId: section.id,
|
|
15067
|
+
rowId: row.id,
|
|
15068
|
+
columnId: column.id,
|
|
15069
|
+
};
|
|
15070
|
+
}
|
|
15071
|
+
getLayoutItemTargetByIndex(config, event) {
|
|
15072
|
+
const section = config.sections[event.sectionIndex];
|
|
15073
|
+
const row = section?.rows?.[event.rowIndex];
|
|
15074
|
+
const column = row?.columns?.[event.columnIndex];
|
|
15075
|
+
if (!section?.id || !row?.id || !column?.id) {
|
|
15076
|
+
return null;
|
|
15077
|
+
}
|
|
15078
|
+
const itemIndex = column.items?.findIndex((item) => item.id === event.itemId) ?? -1;
|
|
15079
|
+
if (itemIndex < 0 || column.items?.[itemIndex]?.kind !== 'richContent') {
|
|
15080
|
+
return null;
|
|
15081
|
+
}
|
|
15082
|
+
return {
|
|
15083
|
+
...event,
|
|
15084
|
+
sectionId: section.id,
|
|
15085
|
+
rowId: row.id,
|
|
15086
|
+
columnId: column.id,
|
|
15087
|
+
itemIndex,
|
|
15088
|
+
};
|
|
15089
|
+
}
|
|
14303
15090
|
dropSection(event) {
|
|
14304
15091
|
const sections = [...this.config.sections];
|
|
14305
15092
|
if (event.previousContainer === event.container) {
|
|
@@ -14341,6 +15128,178 @@ class LayoutEditorComponent {
|
|
|
14341
15128
|
catch { }
|
|
14342
15129
|
this.emitNewConfig({ sections });
|
|
14343
15130
|
}
|
|
15131
|
+
addVisualBlockToColumn(event) {
|
|
15132
|
+
const normalized = this.layoutService.normalizeConfig(this.config);
|
|
15133
|
+
const section = normalized.sections[event.sectionIndex];
|
|
15134
|
+
const row = section?.rows?.[event.rowIndex];
|
|
15135
|
+
const column = row?.columns?.[event.columnIndex];
|
|
15136
|
+
if (!section?.id || !row?.id || !column?.id) {
|
|
15137
|
+
return;
|
|
15138
|
+
}
|
|
15139
|
+
const item = createVisualBlockItemFromPreset(event.presetId, this.createVisualBlockItemId(), {
|
|
15140
|
+
text: this.t('visualBlock.preset.text.default'),
|
|
15141
|
+
notice: this.t('visualBlock.preset.notice.default'),
|
|
15142
|
+
divider: this.t('visualBlock.preset.divider.default'),
|
|
15143
|
+
infoCardTitle: this.t('visualBlock.preset.infoCard.title'),
|
|
15144
|
+
infoCardBody: this.t('visualBlock.preset.infoCard.body'),
|
|
15145
|
+
});
|
|
15146
|
+
const result = this.layoutService.insertLayoutItemById(normalized, {
|
|
15147
|
+
sectionId: section.id,
|
|
15148
|
+
rowId: row.id,
|
|
15149
|
+
columnId: column.id,
|
|
15150
|
+
}, item);
|
|
15151
|
+
this.config = result.config;
|
|
15152
|
+
this.selected = {
|
|
15153
|
+
type: 'visualBlock',
|
|
15154
|
+
sectionIndex: event.sectionIndex,
|
|
15155
|
+
rowIndex: event.rowIndex,
|
|
15156
|
+
columnIndex: event.columnIndex,
|
|
15157
|
+
itemId: item.id,
|
|
15158
|
+
};
|
|
15159
|
+
this.configChange.emit(this.config);
|
|
15160
|
+
}
|
|
15161
|
+
createVisualBlockItemId() {
|
|
15162
|
+
this.visualBlockIdSequence += 1;
|
|
15163
|
+
const entropy = Math.random().toString(36).slice(2, 9);
|
|
15164
|
+
return `rich-content-${Date.now()}-${this.visualBlockIdSequence}-${entropy}`;
|
|
15165
|
+
}
|
|
15166
|
+
addApiFieldToColumn(event) {
|
|
15167
|
+
if (!event.fieldName)
|
|
15168
|
+
return;
|
|
15169
|
+
if (!this.availableFields.some((field) => field.name === event.fieldName)) {
|
|
15170
|
+
return;
|
|
15171
|
+
}
|
|
15172
|
+
const normalized = this.layoutService.normalizeConfig(this.config);
|
|
15173
|
+
const target = this.getColumnTargetByIndex(normalized, event);
|
|
15174
|
+
if (!target) {
|
|
15175
|
+
return;
|
|
15176
|
+
}
|
|
15177
|
+
const result = this.layoutService.insertFieldById(normalized, target, event.fieldName);
|
|
15178
|
+
this.config = result.config;
|
|
15179
|
+
this.selected = {
|
|
15180
|
+
type: 'field',
|
|
15181
|
+
sectionIndex: event.sectionIndex,
|
|
15182
|
+
rowIndex: event.rowIndex,
|
|
15183
|
+
columnIndex: event.columnIndex,
|
|
15184
|
+
fieldName: event.fieldName,
|
|
15185
|
+
};
|
|
15186
|
+
this.configChange.emit(this.config);
|
|
15187
|
+
}
|
|
15188
|
+
openVisualBlockEditor(event) {
|
|
15189
|
+
const normalized = this.layoutService.normalizeConfig(this.config);
|
|
15190
|
+
const section = normalized.sections[event.sectionIndex];
|
|
15191
|
+
const row = section?.rows?.[event.rowIndex];
|
|
15192
|
+
const column = row?.columns?.[event.columnIndex];
|
|
15193
|
+
const item = column?.items?.find((candidate) => candidate.id === event.itemId);
|
|
15194
|
+
if (!section?.id || !row?.id || !column?.id || item?.kind !== 'richContent') {
|
|
15195
|
+
return;
|
|
15196
|
+
}
|
|
15197
|
+
const ref = this.settingsPanel.open({
|
|
15198
|
+
id: `layout.richContent.${section.id}.${row.id}.${column.id}.${item.id}`,
|
|
15199
|
+
title: this.t('visualBlock.editTitle'),
|
|
15200
|
+
titleIcon: 'notes',
|
|
15201
|
+
content: {
|
|
15202
|
+
component: PraxisRichContentConfigEditor,
|
|
15203
|
+
inputs: {
|
|
15204
|
+
inputs: {
|
|
15205
|
+
document: item.document,
|
|
15206
|
+
layout: item.layout ?? 'block',
|
|
15207
|
+
rootClassName: item.rootClassName ?? null,
|
|
15208
|
+
},
|
|
15209
|
+
},
|
|
15210
|
+
},
|
|
15211
|
+
});
|
|
15212
|
+
const applyValue = (value) => {
|
|
15213
|
+
if (!value?.inputs?.document)
|
|
15214
|
+
return;
|
|
15215
|
+
const currentConfig = this.layoutService.normalizeConfig(this.config);
|
|
15216
|
+
const currentColumn = currentConfig.sections
|
|
15217
|
+
.find((candidate) => candidate.id === section.id)
|
|
15218
|
+
?.rows?.find((candidate) => candidate.id === row.id)
|
|
15219
|
+
?.columns?.find((candidate) => candidate.id === column.id);
|
|
15220
|
+
const currentItem = currentColumn?.items?.find((candidate) => candidate.id === item.id);
|
|
15221
|
+
if (currentItem?.kind !== 'richContent')
|
|
15222
|
+
return;
|
|
15223
|
+
const result = this.layoutService.updateLayoutItemById(currentConfig, {
|
|
15224
|
+
sectionId: section.id,
|
|
15225
|
+
rowId: row.id,
|
|
15226
|
+
columnId: column.id,
|
|
15227
|
+
itemId: item.id,
|
|
15228
|
+
}, {
|
|
15229
|
+
...currentItem,
|
|
15230
|
+
document: value.inputs.document,
|
|
15231
|
+
layout: value.inputs.layout ?? 'block',
|
|
15232
|
+
rootClassName: value.inputs.rootClassName ?? null,
|
|
15233
|
+
});
|
|
15234
|
+
this.config = result.config;
|
|
15235
|
+
this.configChange.emit(this.config);
|
|
15236
|
+
};
|
|
15237
|
+
ref.applied$?.subscribe(applyValue);
|
|
15238
|
+
ref.saved$?.subscribe(applyValue);
|
|
15239
|
+
}
|
|
15240
|
+
moveVisualBlock(event) {
|
|
15241
|
+
const normalized = this.layoutService.normalizeConfig(this.config);
|
|
15242
|
+
const target = this.getLayoutItemTargetByIndex(normalized, event);
|
|
15243
|
+
if (!target) {
|
|
15244
|
+
return;
|
|
15245
|
+
}
|
|
15246
|
+
const toIndex = target.itemIndex + event.direction;
|
|
15247
|
+
const itemCount = normalized.sections[event.sectionIndex].rows[event.rowIndex]
|
|
15248
|
+
.columns[event.columnIndex].items?.length ?? 0;
|
|
15249
|
+
if (toIndex < 0 || toIndex >= itemCount) {
|
|
15250
|
+
return;
|
|
15251
|
+
}
|
|
15252
|
+
const result = this.layoutService.moveLayoutItemById(normalized, {
|
|
15253
|
+
sectionId: target.sectionId,
|
|
15254
|
+
rowId: target.rowId,
|
|
15255
|
+
columnId: target.columnId,
|
|
15256
|
+
itemId: event.itemId,
|
|
15257
|
+
}, {
|
|
15258
|
+
sectionId: target.sectionId,
|
|
15259
|
+
rowId: target.rowId,
|
|
15260
|
+
columnId: target.columnId,
|
|
15261
|
+
toIndex,
|
|
15262
|
+
}, { policy: 'keepEmptyContainers' });
|
|
15263
|
+
this.config = result.config;
|
|
15264
|
+
this.configChange.emit(this.config);
|
|
15265
|
+
}
|
|
15266
|
+
moveVisualBlockToColumn(event) {
|
|
15267
|
+
const normalized = this.layoutService.normalizeConfig(this.config);
|
|
15268
|
+
const source = this.getLayoutItemTargetByIndex(normalized, event);
|
|
15269
|
+
const target = this.getColumnTargetByIndex(normalized, {
|
|
15270
|
+
sectionIndex: event.sectionIndex,
|
|
15271
|
+
rowIndex: event.rowIndex,
|
|
15272
|
+
columnIndex: event.targetColumnIndex,
|
|
15273
|
+
});
|
|
15274
|
+
const targetColumn = normalized.sections[event.sectionIndex]?.rows?.[event.rowIndex]
|
|
15275
|
+
?.columns?.[event.targetColumnIndex];
|
|
15276
|
+
if (!source || !target || !targetColumn) {
|
|
15277
|
+
return;
|
|
15278
|
+
}
|
|
15279
|
+
const result = this.layoutService.moveLayoutItemById(normalized, {
|
|
15280
|
+
sectionId: source.sectionId,
|
|
15281
|
+
rowId: source.rowId,
|
|
15282
|
+
columnId: source.columnId,
|
|
15283
|
+
itemId: event.itemId,
|
|
15284
|
+
}, {
|
|
15285
|
+
sectionId: target.sectionId,
|
|
15286
|
+
rowId: target.rowId,
|
|
15287
|
+
columnId: target.columnId,
|
|
15288
|
+
toIndex: targetColumn.items?.length ?? 0,
|
|
15289
|
+
}, { policy: 'keepEmptyContainers' });
|
|
15290
|
+
this.config = result.config;
|
|
15291
|
+
this.configChange.emit(this.config);
|
|
15292
|
+
}
|
|
15293
|
+
removeVisualBlock(event) {
|
|
15294
|
+
const normalized = this.layoutService.normalizeConfig(this.config);
|
|
15295
|
+
const target = this.getLayoutItemTargetByIndex(normalized, event);
|
|
15296
|
+
if (!target) {
|
|
15297
|
+
return;
|
|
15298
|
+
}
|
|
15299
|
+
const result = this.layoutService.removeLayoutItemById(normalized, target.sectionId, target.rowId, target.columnId, event.itemId, { policy: 'keepEmptyContainers' });
|
|
15300
|
+
this.config = result.config;
|
|
15301
|
+
this.configChange.emit(this.config);
|
|
15302
|
+
}
|
|
14344
15303
|
emitNewConfig(configChanges) {
|
|
14345
15304
|
const newConfig = {
|
|
14346
15305
|
...this.config,
|
|
@@ -14357,7 +15316,7 @@ class LayoutEditorComponent {
|
|
|
14357
15316
|
return s.id ?? index;
|
|
14358
15317
|
}
|
|
14359
15318
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: LayoutEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14360
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: LayoutEditorComponent, isStandalone: true, selector: "praxis-layout-editor", inputs: { config: "config" }, outputs: { configChange: "configChange", select: "select" }, host: { listeners: { "document:keydown": "handleKeydown($event)" } }, ngImport: i0, template: `
|
|
15319
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: LayoutEditorComponent, isStandalone: true, selector: "praxis-layout-editor", inputs: { config: "config" }, outputs: { configChange: "configChange", select: "select" }, host: { listeners: { "document:keydown": "handleKeydown($event)" } }, providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], ngImport: i0, template: `
|
|
14361
15320
|
<div class="layout-editor-wrapper"
|
|
14362
15321
|
cdkDropListGroup
|
|
14363
15322
|
[class.no-available-fields]="!availableFields.length"
|
|
@@ -14446,8 +15405,8 @@ class LayoutEditorComponent {
|
|
|
14446
15405
|
>
|
|
14447
15406
|
<mat-icon>chevron_right</mat-icon>
|
|
14448
15407
|
</button>
|
|
14449
|
-
<h4>
|
|
14450
|
-
<small class="available-fields__hint">
|
|
15408
|
+
<h4>{{ t('apiFields.heading') }}</h4>
|
|
15409
|
+
<small class="available-fields__hint">{{ t('apiFields.hint') }}</small>
|
|
14451
15410
|
<div
|
|
14452
15411
|
cdkDropList
|
|
14453
15412
|
id="available-fields-list"
|
|
@@ -14472,8 +15431,12 @@ class LayoutEditorComponent {
|
|
|
14472
15431
|
<mat-icon>chevron_left</mat-icon>
|
|
14473
15432
|
</button>
|
|
14474
15433
|
<div class="layout-canvas">
|
|
14475
|
-
<div
|
|
14476
|
-
|
|
15434
|
+
<div
|
|
15435
|
+
class="no-fields-chip"
|
|
15436
|
+
data-testid="layout-editor-api-fields-empty"
|
|
15437
|
+
*ngIf="!availableFields.length"
|
|
15438
|
+
>
|
|
15439
|
+
{{ t('apiFields.empty') }}
|
|
14477
15440
|
</div>
|
|
14478
15441
|
<div
|
|
14479
15442
|
cdkDropList
|
|
@@ -14487,6 +15450,7 @@ class LayoutEditorComponent {
|
|
|
14487
15450
|
[sectionIndex]="i"
|
|
14488
15451
|
[allSections]="config.sections"
|
|
14489
15452
|
[fieldMetadata]="config.fieldMetadata || []"
|
|
15453
|
+
[availableFields]="availableFields"
|
|
14490
15454
|
[selected]="selected"
|
|
14491
15455
|
[gapGlobal]="gapGlobal || 16"
|
|
14492
15456
|
[availableFieldsListId]="
|
|
@@ -14498,6 +15462,12 @@ class LayoutEditorComponent {
|
|
|
14498
15462
|
(sectionChange)="onSectionUpdated(i, $event)"
|
|
14499
15463
|
(applyStyleToAll)="onApplyStyleToAll($event)"
|
|
14500
15464
|
(fieldDrop)="dropField($event)"
|
|
15465
|
+
(addVisualBlock)="addVisualBlockToColumn($event)"
|
|
15466
|
+
(addApiField)="addApiFieldToColumn($event)"
|
|
15467
|
+
(editVisualBlock)="openVisualBlockEditor($event)"
|
|
15468
|
+
(moveVisualBlock)="moveVisualBlock($event)"
|
|
15469
|
+
(moveVisualBlockToColumn)="moveVisualBlockToColumn($event)"
|
|
15470
|
+
(removeVisualBlock)="removeVisualBlock($event)"
|
|
14501
15471
|
cdkDrag
|
|
14502
15472
|
></praxis-section-configurator>
|
|
14503
15473
|
</div>
|
|
@@ -14515,7 +15485,7 @@ class LayoutEditorComponent {
|
|
|
14515
15485
|
</div>
|
|
14516
15486
|
</div>
|
|
14517
15487
|
</div>
|
|
14518
|
-
`, isInline: true, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\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: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: SectionConfiguratorComponent, selector: "praxis-section-configurator", inputs: ["section", "sectionIndex", "allSections", "fieldMetadata", "selected", "availableFieldsListId", "columnDropListIds", "gapGlobal"], outputs: ["sectionChange", "applyStyleToAll", "remove", "select", "fieldDrop"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { 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: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: MatToolbarModule }, { kind: "component", type: i6$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i7$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i7$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { 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.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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
15488
|
+
`, isInline: true, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\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: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: SectionConfiguratorComponent, selector: "praxis-section-configurator", inputs: ["section", "sectionIndex", "allSections", "fieldMetadata", "availableFields", "selected", "availableFieldsListId", "columnDropListIds", "gapGlobal"], outputs: ["sectionChange", "applyStyleToAll", "remove", "select", "fieldDrop", "addVisualBlock", "addApiField", "editVisualBlock", "moveVisualBlock", "moveVisualBlockToColumn", "removeVisualBlock"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { 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: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: MatToolbarModule }, { kind: "component", type: i6$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i7$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i7$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { 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.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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
14519
15489
|
}
|
|
14520
15490
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: LayoutEditorComponent, decorators: [{
|
|
14521
15491
|
type: Component,
|
|
@@ -14620,8 +15590,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
14620
15590
|
>
|
|
14621
15591
|
<mat-icon>chevron_right</mat-icon>
|
|
14622
15592
|
</button>
|
|
14623
|
-
<h4>
|
|
14624
|
-
<small class="available-fields__hint">
|
|
15593
|
+
<h4>{{ t('apiFields.heading') }}</h4>
|
|
15594
|
+
<small class="available-fields__hint">{{ t('apiFields.hint') }}</small>
|
|
14625
15595
|
<div
|
|
14626
15596
|
cdkDropList
|
|
14627
15597
|
id="available-fields-list"
|
|
@@ -14646,8 +15616,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
14646
15616
|
<mat-icon>chevron_left</mat-icon>
|
|
14647
15617
|
</button>
|
|
14648
15618
|
<div class="layout-canvas">
|
|
14649
|
-
<div
|
|
14650
|
-
|
|
15619
|
+
<div
|
|
15620
|
+
class="no-fields-chip"
|
|
15621
|
+
data-testid="layout-editor-api-fields-empty"
|
|
15622
|
+
*ngIf="!availableFields.length"
|
|
15623
|
+
>
|
|
15624
|
+
{{ t('apiFields.empty') }}
|
|
14651
15625
|
</div>
|
|
14652
15626
|
<div
|
|
14653
15627
|
cdkDropList
|
|
@@ -14661,6 +15635,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
14661
15635
|
[sectionIndex]="i"
|
|
14662
15636
|
[allSections]="config.sections"
|
|
14663
15637
|
[fieldMetadata]="config.fieldMetadata || []"
|
|
15638
|
+
[availableFields]="availableFields"
|
|
14664
15639
|
[selected]="selected"
|
|
14665
15640
|
[gapGlobal]="gapGlobal || 16"
|
|
14666
15641
|
[availableFieldsListId]="
|
|
@@ -14672,6 +15647,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
14672
15647
|
(sectionChange)="onSectionUpdated(i, $event)"
|
|
14673
15648
|
(applyStyleToAll)="onApplyStyleToAll($event)"
|
|
14674
15649
|
(fieldDrop)="dropField($event)"
|
|
15650
|
+
(addVisualBlock)="addVisualBlockToColumn($event)"
|
|
15651
|
+
(addApiField)="addApiFieldToColumn($event)"
|
|
15652
|
+
(editVisualBlock)="openVisualBlockEditor($event)"
|
|
15653
|
+
(moveVisualBlock)="moveVisualBlock($event)"
|
|
15654
|
+
(moveVisualBlockToColumn)="moveVisualBlockToColumn($event)"
|
|
15655
|
+
(removeVisualBlock)="removeVisualBlock($event)"
|
|
14675
15656
|
cdkDrag
|
|
14676
15657
|
></praxis-section-configurator>
|
|
14677
15658
|
</div>
|
|
@@ -14689,7 +15670,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
14689
15670
|
</div>
|
|
14690
15671
|
</div>
|
|
14691
15672
|
</div>
|
|
14692
|
-
`, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\n"] }]
|
|
15673
|
+
`, providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\n"] }]
|
|
14693
15674
|
}], propDecorators: { config: [{
|
|
14694
15675
|
type: Input
|
|
14695
15676
|
}], configChange: [{
|
|
@@ -18687,6 +19668,9 @@ function detectTarget(value) {
|
|
|
18687
19668
|
if (value?.startsWith('column:')) {
|
|
18688
19669
|
return { type: 'column', value: value.substring('column:'.length) };
|
|
18689
19670
|
}
|
|
19671
|
+
if (value?.startsWith('visualBlock:')) {
|
|
19672
|
+
return { type: 'visualBlock', value: value.substring('visualBlock:'.length) };
|
|
19673
|
+
}
|
|
18690
19674
|
return { type: 'field', value };
|
|
18691
19675
|
}
|
|
18692
19676
|
function prefixTarget(targetType, value) {
|
|
@@ -18702,6 +19686,8 @@ function prefixTarget(targetType, value) {
|
|
|
18702
19686
|
return `row:${value}`;
|
|
18703
19687
|
if (targetType === 'column')
|
|
18704
19688
|
return `column:${value}`;
|
|
19689
|
+
if (targetType === 'visualBlock')
|
|
19690
|
+
return `visualBlock:${value}`;
|
|
18705
19691
|
return value;
|
|
18706
19692
|
}
|
|
18707
19693
|
function isScopedSectionHeaderActionTarget(value) {
|
|
@@ -19320,6 +20306,7 @@ class PraxisDynamicFormConfigEditor {
|
|
|
19320
20306
|
actions: mapped.byType.actions,
|
|
19321
20307
|
rows: mapped.byType.rows,
|
|
19322
20308
|
columns: mapped.byType.columns,
|
|
20309
|
+
visualBlocks: mapped.byType.visualBlocks,
|
|
19323
20310
|
},
|
|
19324
20311
|
targetPropertySchemas: RULE_PROPERTY_SCHEMA,
|
|
19325
20312
|
propertySchema: RULE_PROPERTY_SCHEMA,
|
|
@@ -19333,6 +20320,7 @@ class PraxisDynamicFormConfigEditor {
|
|
|
19333
20320
|
actions: {},
|
|
19334
20321
|
rows: {},
|
|
19335
20322
|
columns: {},
|
|
20323
|
+
visualBlocks: {},
|
|
19336
20324
|
};
|
|
19337
20325
|
const visibleFields = (metadata || []).filter((f) => !f?.formHidden);
|
|
19338
20326
|
for (const field of visibleFields) {
|
|
@@ -19396,6 +20384,20 @@ class PraxisDynamicFormConfigEditor {
|
|
|
19396
20384
|
};
|
|
19397
20385
|
combined[colKey] = colSchema;
|
|
19398
20386
|
byType.columns[colId] = colSchema;
|
|
20387
|
+
(column.items || [])
|
|
20388
|
+
.filter((item) => item?.kind === 'richContent' && item?.id)
|
|
20389
|
+
.forEach((item) => {
|
|
20390
|
+
const blockLabel = this.getVisualBlockTargetLabel(item);
|
|
20391
|
+
const blockSchema = {
|
|
20392
|
+
name: `visualBlock:${item.id}`,
|
|
20393
|
+
label: `[Bloco visual] ${blockLabel}`,
|
|
20394
|
+
origin: 'visualBlock',
|
|
20395
|
+
type: FieldType.STRING,
|
|
20396
|
+
description: `${sectionLabel} • ${rowLabel} • ${columnLabel}`,
|
|
20397
|
+
};
|
|
20398
|
+
combined[blockSchema.name] = blockSchema;
|
|
20399
|
+
byType.visualBlocks[item.id] = blockSchema;
|
|
20400
|
+
});
|
|
19399
20401
|
});
|
|
19400
20402
|
});
|
|
19401
20403
|
});
|
|
@@ -19439,6 +20441,31 @@ class PraxisDynamicFormConfigEditor {
|
|
|
19439
20441
|
});
|
|
19440
20442
|
return { combined, byType };
|
|
19441
20443
|
}
|
|
20444
|
+
getVisualBlockTargetLabel(item) {
|
|
20445
|
+
const found = this.findRichContentNodeText(item?.document?.nodes);
|
|
20446
|
+
return found || item?.id || 'Bloco visual';
|
|
20447
|
+
}
|
|
20448
|
+
findRichContentNodeText(nodes) {
|
|
20449
|
+
if (!Array.isArray(nodes))
|
|
20450
|
+
return null;
|
|
20451
|
+
for (const node of nodes) {
|
|
20452
|
+
if (!node || typeof node !== 'object')
|
|
20453
|
+
continue;
|
|
20454
|
+
for (const key of ['text', 'label', 'title', 'subtitle']) {
|
|
20455
|
+
const value = node[key];
|
|
20456
|
+
if (typeof value === 'string' && value.trim()) {
|
|
20457
|
+
return value.trim();
|
|
20458
|
+
}
|
|
20459
|
+
}
|
|
20460
|
+
const nested = this.findRichContentNodeText(node.items) ||
|
|
20461
|
+
this.findRichContentNodeText(node.content) ||
|
|
20462
|
+
this.findRichContentNodeText(node.titleNodes) ||
|
|
20463
|
+
this.findRichContentNodeText(node.subtitleNodes);
|
|
20464
|
+
if (nested)
|
|
20465
|
+
return nested;
|
|
20466
|
+
}
|
|
20467
|
+
return null;
|
|
20468
|
+
}
|
|
19442
20469
|
mapDataTypeToFieldType(dataType) {
|
|
19443
20470
|
const mapping = {
|
|
19444
20471
|
text: FieldType.STRING,
|
|
@@ -19919,7 +20946,8 @@ class PraxisFilterForm {
|
|
|
19919
20946
|
}
|
|
19920
20947
|
getColumnFields(column) {
|
|
19921
20948
|
const metas = this.fieldMetadata;
|
|
19922
|
-
|
|
20949
|
+
const fieldNames = new Set(getFormColumnFieldNames(column));
|
|
20950
|
+
return metas.filter((m) => fieldNames.has(m.name));
|
|
19923
20951
|
}
|
|
19924
20952
|
get fieldMetadata() {
|
|
19925
20953
|
return this.config?.fieldMetadata || [];
|
|
@@ -24045,7 +25073,7 @@ const FORM_COMPONENT_AI_CAPABILITIES = {
|
|
|
24045
25073
|
* Manifesto de authoring canônico para o componente praxis-dynamic-form.
|
|
24046
25074
|
* Este arquivo define as operações permitidas pela IA para editar formulários.
|
|
24047
25075
|
*
|
|
24048
|
-
* @version 1.
|
|
25076
|
+
* @version 1.5.0
|
|
24049
25077
|
* @status COMPLIANT - Alinhado com contrato v2, gate de aceitação e semântica local/schema-backed.
|
|
24050
25078
|
*/
|
|
24051
25079
|
const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
@@ -24053,7 +25081,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24053
25081
|
componentId: 'praxis-dynamic-form',
|
|
24054
25082
|
ownerPackage: '@praxisui/dynamic-form',
|
|
24055
25083
|
configSchemaId: 'FormConfig',
|
|
24056
|
-
manifestVersion: '1.
|
|
25084
|
+
manifestVersion: '1.5.0',
|
|
24057
25085
|
runtimeInputs: [
|
|
24058
25086
|
{ name: 'config', type: 'FormConfig', description: 'Configuração completa do formulário' },
|
|
24059
25087
|
{ name: 'resourcePath', type: 'string', description: 'Caminho do recurso (API)' },
|
|
@@ -24076,6 +25104,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24076
25104
|
* Usado conceitualmente por layout.field.move; declarado como target para futuras ops
|
|
24077
25105
|
* de reposicionamento granular (ex: layout.placement.swap).
|
|
24078
25106
|
*/
|
|
25107
|
+
{ kind: 'visualBlock', resolver: 'layout-item-by-id', description: 'Blocos visuais richContent em sections[].rows[].columns[].items[]; não participam do payload de submissão' },
|
|
24079
25108
|
{ kind: 'layoutPlacement', resolver: 'layout-placement-by-field', description: 'Posicionamento de campo no layout; target para ops de reposicionamento' },
|
|
24080
25109
|
{ kind: 'formAction', resolver: 'action-by-id-or-label', description: 'Ações da toolbar (submit, cancel, reset)' },
|
|
24081
25110
|
{ kind: 'formRule', resolver: 'rule-by-id-or-name', description: 'Regras de visibilidade e validação' },
|
|
@@ -24102,7 +25131,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24102
25131
|
effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
|
|
24103
25132
|
validators: ['field-exists'],
|
|
24104
25133
|
affectedPaths: ['fieldMetadata[].label'],
|
|
24105
|
-
submissionImpact:
|
|
25134
|
+
submissionImpact: 'visual-only',
|
|
24106
25135
|
preconditions: ['config-initialized', 'target-exists']
|
|
24107
25136
|
},
|
|
24108
25137
|
{
|
|
@@ -24119,7 +25148,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24119
25148
|
effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
|
|
24120
25149
|
validators: ['field-exists'],
|
|
24121
25150
|
affectedPaths: ['fieldMetadata[].placeholder'],
|
|
24122
|
-
submissionImpact:
|
|
25151
|
+
submissionImpact: 'visual-only',
|
|
24123
25152
|
preconditions: ['config-initialized', 'target-exists']
|
|
24124
25153
|
},
|
|
24125
25154
|
{
|
|
@@ -24136,7 +25165,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24136
25165
|
effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
|
|
24137
25166
|
validators: ['field-exists'],
|
|
24138
25167
|
affectedPaths: ['fieldMetadata[].required'],
|
|
24139
|
-
submissionImpact:
|
|
25168
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
24140
25169
|
preconditions: ['config-initialized', 'target-exists']
|
|
24141
25170
|
},
|
|
24142
25171
|
{
|
|
@@ -24153,7 +25182,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24153
25182
|
effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
|
|
24154
25183
|
validators: ['field-exists'],
|
|
24155
25184
|
affectedPaths: ['fieldMetadata[].readOnly'],
|
|
24156
|
-
submissionImpact:
|
|
25185
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
24157
25186
|
preconditions: ['config-initialized', 'target-exists']
|
|
24158
25187
|
},
|
|
24159
25188
|
{
|
|
@@ -24170,7 +25199,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24170
25199
|
effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
|
|
24171
25200
|
validators: ['field-exists'],
|
|
24172
25201
|
affectedPaths: ['fieldMetadata[].disabled'],
|
|
24173
|
-
submissionImpact:
|
|
25202
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
24174
25203
|
preconditions: ['config-initialized', 'target-exists']
|
|
24175
25204
|
},
|
|
24176
25205
|
{
|
|
@@ -24187,7 +25216,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24187
25216
|
effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
|
|
24188
25217
|
validators: ['field-exists'],
|
|
24189
25218
|
affectedPaths: ['fieldMetadata[].hidden'],
|
|
24190
|
-
submissionImpact:
|
|
25219
|
+
submissionImpact: 'visual-only',
|
|
24191
25220
|
preconditions: ['config-initialized', 'target-exists']
|
|
24192
25221
|
},
|
|
24193
25222
|
{
|
|
@@ -24206,7 +25235,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24206
25235
|
requiresConfirmation: true,
|
|
24207
25236
|
validators: ['field-exists', 'control-type-compatible'],
|
|
24208
25237
|
affectedPaths: ['fieldMetadata[].controlType'],
|
|
24209
|
-
submissionImpact:
|
|
25238
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
24210
25239
|
preconditions: ['config-initialized', 'target-exists']
|
|
24211
25240
|
},
|
|
24212
25241
|
{
|
|
@@ -24241,7 +25270,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24241
25270
|
effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
|
|
24242
25271
|
validators: ['field-exists', 'option-source-valid'],
|
|
24243
25272
|
affectedPaths: ['fieldMetadata[].optionSource'],
|
|
24244
|
-
submissionImpact:
|
|
25273
|
+
submissionImpact: 'affects-remote-binding',
|
|
24245
25274
|
preconditions: ['config-initialized', 'target-exists']
|
|
24246
25275
|
},
|
|
24247
25276
|
// ─── LOCAL FIELD OPERATIONS ───────────────────────────────────────────────
|
|
@@ -24279,7 +25308,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24279
25308
|
effects: [{ kind: 'append-unique', path: 'fieldMetadata[]', key: 'name' }],
|
|
24280
25309
|
validators: ['field-name-unique', 'local-schema-name-no-collision'],
|
|
24281
25310
|
affectedPaths: ['fieldMetadata[]'],
|
|
24282
|
-
submissionImpact:
|
|
25311
|
+
submissionImpact: 'affects-submission',
|
|
24283
25312
|
preconditions: ['config-initialized']
|
|
24284
25313
|
},
|
|
24285
25314
|
{
|
|
@@ -24299,8 +25328,8 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24299
25328
|
kind: 'compile-domain-patch',
|
|
24300
25329
|
handler: 'form-layout-field-cleanup',
|
|
24301
25330
|
handlerContract: {
|
|
24302
|
-
reads: ['fieldMetadata[].name', 'sections[].rows[].columns[].fields'],
|
|
24303
|
-
writes: ['sections[].rows[].columns[].fields'],
|
|
25331
|
+
reads: ['fieldMetadata[].name', 'sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
|
|
25332
|
+
writes: ['sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
|
|
24304
25333
|
identityKeys: ['fieldMetadata[].name', 'sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id'],
|
|
24305
25334
|
inputSchema: { type: 'object', required: ['target.name'], properties: { 'target.name': { type: 'string' } } },
|
|
24306
25335
|
failureModes: ['target-field-not-found', 'target-field-not-local', 'layout-reference-conflict'],
|
|
@@ -24311,8 +25340,8 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24311
25340
|
destructive: true,
|
|
24312
25341
|
requiresConfirmation: true,
|
|
24313
25342
|
validators: ['field-exists', 'field-is-local'],
|
|
24314
|
-
affectedPaths: ['fieldMetadata[]', 'sections[].rows[].columns[].fields'],
|
|
24315
|
-
submissionImpact:
|
|
25343
|
+
affectedPaths: ['fieldMetadata[]', 'sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
|
|
25344
|
+
submissionImpact: 'affects-submission',
|
|
24316
25345
|
preconditions: ['config-initialized', 'target-exists']
|
|
24317
25346
|
},
|
|
24318
25347
|
{
|
|
@@ -24331,7 +25360,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24331
25360
|
effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
|
|
24332
25361
|
validators: ['field-exists', 'field-is-local', 'editor-round-trip-preserve'],
|
|
24333
25362
|
affectedPaths: ['fieldMetadata[].submitPolicy'],
|
|
24334
|
-
submissionImpact:
|
|
25363
|
+
submissionImpact: 'affects-submission',
|
|
24335
25364
|
preconditions: ['config-initialized', 'target-exists']
|
|
24336
25365
|
},
|
|
24337
25366
|
// ─── LAYOUT OPERATIONS ────────────────────────────────────────────────────
|
|
@@ -24354,7 +25383,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24354
25383
|
effects: [{ kind: 'append-unique', path: 'sections[]', key: 'id' }],
|
|
24355
25384
|
validators: ['section-id-unique'],
|
|
24356
25385
|
affectedPaths: ['sections[]'],
|
|
24357
|
-
submissionImpact:
|
|
25386
|
+
submissionImpact: 'visual-only',
|
|
24358
25387
|
preconditions: ['config-initialized']
|
|
24359
25388
|
},
|
|
24360
25389
|
{
|
|
@@ -24375,7 +25404,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24375
25404
|
kind: 'compile-domain-patch',
|
|
24376
25405
|
handler: 'form-layout-section-cleanup',
|
|
24377
25406
|
handlerContract: {
|
|
24378
|
-
reads: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].fields'],
|
|
25407
|
+
reads: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
|
|
24379
25408
|
writes: ['sections[]'],
|
|
24380
25409
|
identityKeys: ['sections[].id'],
|
|
24381
25410
|
inputSchema: { type: 'object', required: ['target.id'], properties: { 'target.id': { type: 'string' } } },
|
|
@@ -24387,8 +25416,8 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24387
25416
|
destructive: true,
|
|
24388
25417
|
requiresConfirmation: true,
|
|
24389
25418
|
validators: ['section-exists'],
|
|
24390
|
-
affectedPaths: ['sections[]', 'sections[].rows[]', 'sections[].rows[].columns[]', 'sections[].rows[].columns[].fields'],
|
|
24391
|
-
submissionImpact:
|
|
25419
|
+
affectedPaths: ['sections[]', 'sections[].rows[]', 'sections[].rows[].columns[]', 'sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
|
|
25420
|
+
submissionImpact: 'visual-only',
|
|
24392
25421
|
preconditions: ['config-initialized', 'target-exists']
|
|
24393
25422
|
},
|
|
24394
25423
|
{
|
|
@@ -24408,7 +25437,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24408
25437
|
effects: [{ kind: 'append-unique', path: 'sections[].rows[]', key: 'id' }],
|
|
24409
25438
|
validators: ['section-exists', 'row-id-unique-in-section'],
|
|
24410
25439
|
affectedPaths: ['sections[].rows[]'],
|
|
24411
|
-
submissionImpact:
|
|
25440
|
+
submissionImpact: 'visual-only',
|
|
24412
25441
|
preconditions: ['config-initialized', 'target-exists']
|
|
24413
25442
|
},
|
|
24414
25443
|
{
|
|
@@ -24428,7 +25457,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24428
25457
|
effects: [{ kind: 'append-unique', path: 'sections[].rows[].columns[]', key: 'id' }],
|
|
24429
25458
|
validators: ['row-exists', 'column-id-unique-in-row'],
|
|
24430
25459
|
affectedPaths: ['sections[].rows[].columns[]'],
|
|
24431
|
-
submissionImpact:
|
|
25460
|
+
submissionImpact: 'visual-only',
|
|
24432
25461
|
preconditions: ['config-initialized', 'target-exists']
|
|
24433
25462
|
},
|
|
24434
25463
|
{
|
|
@@ -24456,9 +25485,10 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24456
25485
|
'sections[].id',
|
|
24457
25486
|
'sections[].rows[].id',
|
|
24458
25487
|
'sections[].rows[].columns[].id',
|
|
25488
|
+
'sections[].rows[].columns[].items',
|
|
24459
25489
|
'sections[].rows[].columns[].fields'
|
|
24460
25490
|
],
|
|
24461
|
-
writes: ['sections[].rows[].columns[].fields'],
|
|
25491
|
+
writes: ['sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
|
|
24462
25492
|
identityKeys: ['fieldMetadata[].name', 'sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id'],
|
|
24463
25493
|
inputSchema: {
|
|
24464
25494
|
type: 'object',
|
|
@@ -24476,11 +25506,184 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24476
25506
|
}
|
|
24477
25507
|
}],
|
|
24478
25508
|
validators: ['field-exists', 'layout-target-exists', 'no-index-as-identity', 'field-exists-in-layout'],
|
|
24479
|
-
affectedPaths: ['sections[].rows[].columns[].fields'],
|
|
24480
|
-
submissionImpact:
|
|
25509
|
+
affectedPaths: ['sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
|
|
25510
|
+
submissionImpact: 'visual-only',
|
|
24481
25511
|
preconditions: ['config-initialized', 'target-exists']
|
|
24482
25512
|
},
|
|
24483
25513
|
// ─── RULE OPERATIONS ──────────────────────────────────────────────────────
|
|
25514
|
+
{
|
|
25515
|
+
operationId: 'layout.visualBlock.add',
|
|
25516
|
+
title: 'Adicionar bloco visual',
|
|
25517
|
+
scope: 'column',
|
|
25518
|
+
targetKind: 'column',
|
|
25519
|
+
target: { kind: 'column', resolver: 'column-by-id-in-row', ambiguityPolicy: 'fail', required: true },
|
|
25520
|
+
inputSchema: {
|
|
25521
|
+
type: 'object',
|
|
25522
|
+
required: ['id', 'document'],
|
|
25523
|
+
properties: {
|
|
25524
|
+
id: { type: 'string' },
|
|
25525
|
+
document: {
|
|
25526
|
+
type: 'object',
|
|
25527
|
+
required: ['kind', 'version', 'nodes'],
|
|
25528
|
+
properties: {
|
|
25529
|
+
kind: { const: 'praxis.rich-content' },
|
|
25530
|
+
version: { type: 'string' },
|
|
25531
|
+
nodes: { type: 'array' }
|
|
25532
|
+
}
|
|
25533
|
+
},
|
|
25534
|
+
layout: { enum: ['block', 'inline'], default: 'block' },
|
|
25535
|
+
rootClassName: { type: ['string', 'null'] },
|
|
25536
|
+
index: { type: 'number' }
|
|
25537
|
+
}
|
|
25538
|
+
},
|
|
25539
|
+
effects: [{
|
|
25540
|
+
kind: 'compile-domain-patch',
|
|
25541
|
+
handler: 'form-layout-visual-block-add',
|
|
25542
|
+
handlerContract: {
|
|
25543
|
+
reads: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items'],
|
|
25544
|
+
writes: ['sections[].rows[].columns[].items'],
|
|
25545
|
+
identityKeys: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
|
|
25546
|
+
inputSchema: {
|
|
25547
|
+
type: 'object',
|
|
25548
|
+
required: ['target.sectionId', 'target.rowId', 'target.columnId', 'id', 'document'],
|
|
25549
|
+
properties: {
|
|
25550
|
+
'target.sectionId': { type: 'string' },
|
|
25551
|
+
'target.rowId': { type: 'string' },
|
|
25552
|
+
'target.columnId': { type: 'string' },
|
|
25553
|
+
id: { type: 'string' },
|
|
25554
|
+
document: { type: 'object' },
|
|
25555
|
+
layout: { enum: ['block', 'inline'] },
|
|
25556
|
+
rootClassName: { type: ['string', 'null'] },
|
|
25557
|
+
index: { type: 'number' }
|
|
25558
|
+
}
|
|
25559
|
+
},
|
|
25560
|
+
failureModes: ['target-layout-location-not-found', 'duplicate-visual-block-id', 'invalid-rich-content-document'],
|
|
25561
|
+
description: 'Adds a richContent layout item into sections[].rows[].columns[].items[] by stable section, row, and column ids.'
|
|
25562
|
+
}
|
|
25563
|
+
}],
|
|
25564
|
+
validators: ['layout-target-exists', 'visual-block-id-unique', 'rich-content-document-valid'],
|
|
25565
|
+
affectedPaths: ['sections[].rows[].columns[].items'],
|
|
25566
|
+
submissionImpact: 'visual-only',
|
|
25567
|
+
preconditions: ['config-initialized', 'target-exists']
|
|
25568
|
+
},
|
|
25569
|
+
{
|
|
25570
|
+
operationId: 'layout.visualBlock.update',
|
|
25571
|
+
title: 'Atualizar bloco visual',
|
|
25572
|
+
scope: 'layout',
|
|
25573
|
+
targetKind: 'visualBlock',
|
|
25574
|
+
target: { kind: 'visualBlock', resolver: 'layout-item-by-id', ambiguityPolicy: 'fail', required: true },
|
|
25575
|
+
inputSchema: {
|
|
25576
|
+
type: 'object',
|
|
25577
|
+
minProperties: 1,
|
|
25578
|
+
properties: {
|
|
25579
|
+
document: {
|
|
25580
|
+
type: 'object',
|
|
25581
|
+
required: ['kind', 'version', 'nodes'],
|
|
25582
|
+
properties: {
|
|
25583
|
+
kind: { const: 'praxis.rich-content' },
|
|
25584
|
+
version: { type: 'string' },
|
|
25585
|
+
nodes: { type: 'array' }
|
|
25586
|
+
}
|
|
25587
|
+
},
|
|
25588
|
+
layout: { enum: ['block', 'inline'] },
|
|
25589
|
+
rootClassName: { type: ['string', 'null'] }
|
|
25590
|
+
}
|
|
25591
|
+
},
|
|
25592
|
+
effects: [{
|
|
25593
|
+
kind: 'compile-domain-patch',
|
|
25594
|
+
handler: 'form-layout-visual-block-update',
|
|
25595
|
+
handlerContract: {
|
|
25596
|
+
reads: ['sections[].rows[].columns[].items[].id'],
|
|
25597
|
+
writes: ['sections[].rows[].columns[].items'],
|
|
25598
|
+
identityKeys: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
|
|
25599
|
+
inputSchema: {
|
|
25600
|
+
type: 'object',
|
|
25601
|
+
required: ['target.itemId'],
|
|
25602
|
+
properties: {
|
|
25603
|
+
'target.itemId': { type: 'string' },
|
|
25604
|
+
document: { type: 'object' },
|
|
25605
|
+
layout: { enum: ['block', 'inline'] },
|
|
25606
|
+
rootClassName: { type: ['string', 'null'] }
|
|
25607
|
+
}
|
|
25608
|
+
},
|
|
25609
|
+
failureModes: ['target-visual-block-not-found', 'invalid-rich-content-document'],
|
|
25610
|
+
description: 'Updates a richContent layout item by stable layout item id without touching fieldMetadata or form submit payload.'
|
|
25611
|
+
}
|
|
25612
|
+
}],
|
|
25613
|
+
validators: ['visual-block-exists', 'rich-content-document-valid', 'editor-round-trip-preserve'],
|
|
25614
|
+
affectedPaths: ['sections[].rows[].columns[].items'],
|
|
25615
|
+
submissionImpact: 'visual-only',
|
|
25616
|
+
preconditions: ['config-initialized', 'target-exists']
|
|
25617
|
+
},
|
|
25618
|
+
{
|
|
25619
|
+
operationId: 'layout.visualBlock.move',
|
|
25620
|
+
title: 'Mover bloco visual',
|
|
25621
|
+
scope: 'layout',
|
|
25622
|
+
targetKind: 'visualBlock',
|
|
25623
|
+
target: { kind: 'visualBlock', resolver: 'layout-item-by-id', ambiguityPolicy: 'fail', required: true },
|
|
25624
|
+
inputSchema: {
|
|
25625
|
+
type: 'object',
|
|
25626
|
+
required: ['targetSectionId', 'targetRowId', 'targetColumnId'],
|
|
25627
|
+
properties: {
|
|
25628
|
+
targetSectionId: { type: 'string' },
|
|
25629
|
+
targetRowId: { type: 'string' },
|
|
25630
|
+
targetColumnId: { type: 'string' },
|
|
25631
|
+
index: { type: 'number' }
|
|
25632
|
+
}
|
|
25633
|
+
},
|
|
25634
|
+
effects: [{
|
|
25635
|
+
kind: 'compile-domain-patch',
|
|
25636
|
+
handler: 'form-layout-visual-block-move',
|
|
25637
|
+
handlerContract: {
|
|
25638
|
+
reads: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
|
|
25639
|
+
writes: ['sections[].rows[].columns[].items'],
|
|
25640
|
+
identityKeys: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
|
|
25641
|
+
inputSchema: {
|
|
25642
|
+
type: 'object',
|
|
25643
|
+
required: ['target.itemId', 'targetSectionId', 'targetRowId', 'targetColumnId'],
|
|
25644
|
+
properties: {
|
|
25645
|
+
'target.itemId': { type: 'string' },
|
|
25646
|
+
targetSectionId: { type: 'string' },
|
|
25647
|
+
targetRowId: { type: 'string' },
|
|
25648
|
+
targetColumnId: { type: 'string' },
|
|
25649
|
+
index: { type: 'number' }
|
|
25650
|
+
}
|
|
25651
|
+
},
|
|
25652
|
+
failureModes: ['target-visual-block-not-found', 'target-layout-location-not-found', 'ambiguous-visual-block-target'],
|
|
25653
|
+
description: 'Moves a richContent layout item by stable item, section, row, and column ids; index is insertion position only.'
|
|
25654
|
+
}
|
|
25655
|
+
}],
|
|
25656
|
+
validators: ['visual-block-exists', 'layout-target-exists', 'no-index-as-identity'],
|
|
25657
|
+
affectedPaths: ['sections[].rows[].columns[].items'],
|
|
25658
|
+
submissionImpact: 'visual-only',
|
|
25659
|
+
preconditions: ['config-initialized', 'target-exists']
|
|
25660
|
+
},
|
|
25661
|
+
{
|
|
25662
|
+
operationId: 'layout.visualBlock.remove',
|
|
25663
|
+
title: 'Remover bloco visual',
|
|
25664
|
+
scope: 'layout',
|
|
25665
|
+
targetKind: 'visualBlock',
|
|
25666
|
+
target: { kind: 'visualBlock', resolver: 'layout-item-by-id', ambiguityPolicy: 'fail', required: true },
|
|
25667
|
+
inputSchema: { type: 'object', properties: {} },
|
|
25668
|
+
effects: [{
|
|
25669
|
+
kind: 'compile-domain-patch',
|
|
25670
|
+
handler: 'form-layout-visual-block-remove',
|
|
25671
|
+
handlerContract: {
|
|
25672
|
+
reads: ['sections[].rows[].columns[].items[].id'],
|
|
25673
|
+
writes: ['sections[].rows[].columns[].items'],
|
|
25674
|
+
identityKeys: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
|
|
25675
|
+
inputSchema: { type: 'object', required: ['target.itemId'], properties: { 'target.itemId': { type: 'string' } } },
|
|
25676
|
+
failureModes: ['target-visual-block-not-found', 'ambiguous-visual-block-target'],
|
|
25677
|
+
description: 'Removes a richContent layout item from sections[].rows[].columns[].items[] without touching fieldMetadata or form submit payload.'
|
|
25678
|
+
}
|
|
25679
|
+
}],
|
|
25680
|
+
destructive: true,
|
|
25681
|
+
requiresConfirmation: true,
|
|
25682
|
+
validators: ['visual-block-exists'],
|
|
25683
|
+
affectedPaths: ['sections[].rows[].columns[].items'],
|
|
25684
|
+
submissionImpact: 'visual-only',
|
|
25685
|
+
preconditions: ['config-initialized', 'target-exists']
|
|
25686
|
+
},
|
|
24484
25687
|
{
|
|
24485
25688
|
operationId: 'rule.visibility.add',
|
|
24486
25689
|
title: 'Adicionar regra de visibilidade',
|
|
@@ -24495,7 +25698,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24495
25698
|
name: { type: 'string' },
|
|
24496
25699
|
/** Discriminador de tipo armazenado no item formRules[]; distingue regras de visibilidade das de validação. */
|
|
24497
25700
|
type: { const: 'visibility', description: 'Discriminador de tipo da regra; obrigatório para distinção em formRules[]' },
|
|
24498
|
-
targetType: { enum: ['field', 'section', 'row', 'column', 'action'], default: 'field' },
|
|
25701
|
+
targetType: { enum: ['field', 'section', 'row', 'column', 'action', 'visualBlock'], default: 'field' },
|
|
24499
25702
|
targets: { type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
24500
25703
|
condition: { type: 'object', description: 'JsonLogic AST' }
|
|
24501
25704
|
}
|
|
@@ -24503,7 +25706,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24503
25706
|
effects: [{ kind: 'append-unique', path: 'formRules[]', key: 'id' }],
|
|
24504
25707
|
validators: ['rule-id-unique', 'rule-target-refs-exist', 'json-logic-valid'],
|
|
24505
25708
|
affectedPaths: ['formRules[]'],
|
|
24506
|
-
submissionImpact:
|
|
25709
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
24507
25710
|
preconditions: ['config-initialized']
|
|
24508
25711
|
},
|
|
24509
25712
|
{
|
|
@@ -24524,7 +25727,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24524
25727
|
* targetType espelha o campo equivalente de rule.visibility.add.
|
|
24525
25728
|
* Regras de validação podem se aplicar a campos, seções ou ações da toolbar.
|
|
24526
25729
|
*/
|
|
24527
|
-
targetType: { enum: ['field', 'section', 'row', 'column', 'action'], default: 'field' },
|
|
25730
|
+
targetType: { enum: ['field', 'section', 'row', 'column', 'action', 'visualBlock'], default: 'field' },
|
|
24528
25731
|
targets: { type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
24529
25732
|
condition: { type: 'object', description: 'JsonLogic AST; quando true, exibe mensagem de erro' },
|
|
24530
25733
|
message: { type: 'string', description: 'Mensagem de erro a exibir ao usuário' },
|
|
@@ -24534,7 +25737,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24534
25737
|
effects: [{ kind: 'append-unique', path: 'formRules[]', key: 'id' }],
|
|
24535
25738
|
validators: ['rule-id-unique', 'rule-target-refs-exist', 'json-logic-valid'],
|
|
24536
25739
|
affectedPaths: ['formRules[]'],
|
|
24537
|
-
submissionImpact:
|
|
25740
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
24538
25741
|
preconditions: ['config-initialized']
|
|
24539
25742
|
},
|
|
24540
25743
|
{
|
|
@@ -24549,7 +25752,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24549
25752
|
requiresConfirmation: true,
|
|
24550
25753
|
validators: ['rule-exists'],
|
|
24551
25754
|
affectedPaths: ['formRules[]'],
|
|
24552
|
-
submissionImpact:
|
|
25755
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
24553
25756
|
preconditions: ['config-initialized', 'target-exists']
|
|
24554
25757
|
},
|
|
24555
25758
|
// ─── ACTION OPERATIONS ────────────────────────────────────────────────────
|
|
@@ -24572,7 +25775,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24572
25775
|
effects: [{ kind: 'merge-object', path: 'actions.submit' }],
|
|
24573
25776
|
validators: ['editor-round-trip-preserve'],
|
|
24574
25777
|
affectedPaths: ['actions.submit'],
|
|
24575
|
-
submissionImpact:
|
|
25778
|
+
submissionImpact: 'affects-submission',
|
|
24576
25779
|
preconditions: ['config-initialized']
|
|
24577
25780
|
},
|
|
24578
25781
|
{
|
|
@@ -24595,7 +25798,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24595
25798
|
effects: [{ kind: 'merge-object', path: 'actions.cancel' }],
|
|
24596
25799
|
validators: ['editor-round-trip-preserve'],
|
|
24597
25800
|
affectedPaths: ['actions.cancel'],
|
|
24598
|
-
submissionImpact:
|
|
25801
|
+
submissionImpact: 'config-only',
|
|
24599
25802
|
preconditions: ['config-initialized']
|
|
24600
25803
|
},
|
|
24601
25804
|
{
|
|
@@ -24618,9 +25821,9 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24618
25821
|
effects: [{ kind: 'merge-object', path: 'actions.reset' }],
|
|
24619
25822
|
validators: ['editor-round-trip-preserve'],
|
|
24620
25823
|
affectedPaths: ['actions.reset'],
|
|
24621
|
-
submissionImpact:
|
|
25824
|
+
submissionImpact: 'config-only',
|
|
24622
25825
|
preconditions: ['config-initialized']
|
|
24623
|
-
}
|
|
25826
|
+
},
|
|
24624
25827
|
],
|
|
24625
25828
|
validators: [
|
|
24626
25829
|
{
|
|
@@ -24736,12 +25939,31 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24736
25939
|
level: 'error',
|
|
24737
25940
|
code: 'DF019',
|
|
24738
25941
|
description: 'Edição não deve corromper propriedades críticas para o round-trip do editor. Aplicado após operações que afetam submitPolicy ou source de campos locais.'
|
|
25942
|
+
},
|
|
25943
|
+
{
|
|
25944
|
+
validatorId: 'visual-block-exists',
|
|
25945
|
+
level: 'error',
|
|
25946
|
+
code: 'DF020',
|
|
25947
|
+
description: 'O bloco visual alvo deve existir como item kind:"richContent" em sections[].rows[].columns[].items[].'
|
|
25948
|
+
},
|
|
25949
|
+
{
|
|
25950
|
+
validatorId: 'visual-block-id-unique',
|
|
25951
|
+
level: 'error',
|
|
25952
|
+
code: 'DF021',
|
|
25953
|
+
description: 'IDs de blocos visuais devem ser unicos entre os itens de layout do formulario.'
|
|
25954
|
+
},
|
|
25955
|
+
{
|
|
25956
|
+
validatorId: 'rich-content-document-valid',
|
|
25957
|
+
level: 'error',
|
|
25958
|
+
code: 'DF022',
|
|
25959
|
+
description: 'O document do bloco visual deve seguir o contrato RichContentDocument canonico.'
|
|
24739
25960
|
}
|
|
24740
25961
|
],
|
|
24741
25962
|
roundTripRequirements: [
|
|
24742
25963
|
'strip-undefined',
|
|
24743
25964
|
'normalize-json-logic',
|
|
24744
25965
|
'stable-field-order',
|
|
25966
|
+
'preserve-column-layout-items',
|
|
24745
25967
|
'preserve-local-field-source',
|
|
24746
25968
|
'preserve-section-row-column-ids'
|
|
24747
25969
|
],
|
|
@@ -24776,6 +25998,30 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
|
|
|
24776
25998
|
params: { targetSectionId: 'secao-contato', targetRowId: 'row-1', targetColumnId: 'col-1' },
|
|
24777
25999
|
isPositive: true
|
|
24778
26000
|
},
|
|
26001
|
+
{
|
|
26002
|
+
id: 'add-visual-block',
|
|
26003
|
+
request: 'Adicionar um aviso visual antes dos campos de contato',
|
|
26004
|
+
operationId: 'layout.visualBlock.add',
|
|
26005
|
+
target: 'col-contato',
|
|
26006
|
+
params: {
|
|
26007
|
+
id: 'aviso-contato',
|
|
26008
|
+
document: {
|
|
26009
|
+
kind: 'praxis.rich-content',
|
|
26010
|
+
version: '1.0.0',
|
|
26011
|
+
nodes: [{ type: 'text', text: 'Confira os dados antes de salvar.' }]
|
|
26012
|
+
},
|
|
26013
|
+
layout: 'block'
|
|
26014
|
+
},
|
|
26015
|
+
isPositive: true
|
|
26016
|
+
},
|
|
26017
|
+
{
|
|
26018
|
+
id: 'move-visual-block',
|
|
26019
|
+
request: 'Mover o aviso visual para a segunda coluna da secao de contato',
|
|
26020
|
+
operationId: 'layout.visualBlock.move',
|
|
26021
|
+
target: 'aviso-contato',
|
|
26022
|
+
params: { targetSectionId: 'secao-contato', targetRowId: 'row-1', targetColumnId: 'col-2' },
|
|
26023
|
+
isPositive: true
|
|
26024
|
+
},
|
|
24779
26025
|
{
|
|
24780
26026
|
id: 'add-visibility-rule',
|
|
24781
26027
|
request: 'Ocultar o campo cpf quando o tipo de pessoa for jurídica',
|