@praxisui/visual-builder 9.0.0-beta.4 → 9.0.0-beta.40

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Inject, ChangeDetectionStrategy, Component, EventEmitter, ViewChild, Output, Input, Optional, inject } from '@angular/core';
2
+ import { Injectable, Inject, ChangeDetectionStrategy, Component, EventEmitter, ViewChild, Output, Input, Optional, inject, ENVIRONMENT_INITIALIZER } from '@angular/core';
3
3
  import * as i12$1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1$1 from '@angular/forms';
@@ -28,7 +28,7 @@ import * as i9 from '@angular/material/tooltip';
28
28
  import { MatTooltipModule } from '@angular/material/tooltip';
29
29
  import { BehaviorSubject, Subject, from, takeUntil as takeUntil$1, interval, Observable, of, throwError, combineLatest } from 'rxjs';
30
30
  import * as i1$2 from '@praxisui/core';
31
- import { RULE_PROPERTY_SCHEMA, providePraxisI18n, PraxisI18nService, PraxisIconDirective } from '@praxisui/core';
31
+ import { RULE_PROPERTY_SCHEMA, providePraxisI18n, PraxisI18nService, ComponentMetadataRegistry, PraxisIconDirective } from '@praxisui/core';
32
32
  import * as i3$1 from '@praxisui/ai';
33
33
  import { AiRuleWizardDialogComponent } from '@praxisui/ai';
34
34
  import { map, takeUntil, debounceTime, distinctUntilChanged, switchMap, catchError, startWith } from 'rxjs/operators';
@@ -1003,7 +1003,7 @@ class RuleBuilderService {
1003
1003
  ...this.getInitialState(),
1004
1004
  isDirty: false,
1005
1005
  });
1006
- // Salva estado inicial para habilitar undo/redo desde a primeira ação
1006
+ // Salva estado inicial para habilitar undo/redo desde a primeira ação
1007
1007
  this.saveSnapshot('Estado inicial');
1008
1008
  }
1009
1009
  /**
@@ -1279,7 +1279,7 @@ class RuleBuilderService {
1279
1279
  parsed = typeof content === 'string' ? JSON.parse(content) : content;
1280
1280
  }
1281
1281
  catch (e) {
1282
- throw new Error(`Importação falhou: JSON inválido (${e?.message || e})`);
1282
+ throw new Error(`Importação falhou: JSON inválido (${e?.message || e})`);
1283
1283
  }
1284
1284
  if (!parsed || (typeof parsed === 'object' && !Object.keys(parsed).length)) {
1285
1285
  return;
@@ -1309,7 +1309,7 @@ class RuleBuilderService {
1309
1309
  }
1310
1310
  }
1311
1311
  }
1312
- throw new Error(`Formato de importação não suportado ou inválido: ${format}`);
1312
+ throw new Error(`Formato de importação não suportado ou inválido: ${format}`);
1313
1313
  }
1314
1314
  /**
1315
1315
  * Export rules to JSON payload
@@ -1328,11 +1328,11 @@ class RuleBuilderService {
1328
1328
  };
1329
1329
  if (this.containsPropertyRule()) {
1330
1330
  payload.warning =
1331
- 'Exportação de propertyRule é experimental e pode exigir revisão manual.';
1331
+ 'Exportação de propertyRule é experimental e pode exigir revisão manual.';
1332
1332
  }
1333
1333
  return JSON.stringify(payload, null, options?.prettyPrint ? 2 : undefined);
1334
1334
  }
1335
- throw new Error(`Formato de exportação não suportado: ${format}`);
1335
+ throw new Error(`Formato de exportação não suportado: ${format}`);
1336
1336
  }
1337
1337
  toSpecification() {
1338
1338
  return null;
@@ -1417,31 +1417,31 @@ class RuleBuilderService {
1417
1417
  }
1418
1418
  generateNodeLabel(type) {
1419
1419
  const labels = {
1420
- [RuleNodeType.FIELD_CONDITION]: 'Condição de campo',
1420
+ [RuleNodeType.FIELD_CONDITION]: 'Condição de campo',
1421
1421
  [RuleNodeType.PROPERTY_RULE]: 'Propriedade',
1422
1422
  [RuleNodeType.AND_GROUP]: 'Grupo E',
1423
1423
  [RuleNodeType.OR_GROUP]: 'Grupo OU',
1424
- [RuleNodeType.NOT_GROUP]: 'Grupo NÃO',
1424
+ [RuleNodeType.NOT_GROUP]: 'Grupo NÃO',
1425
1425
  [RuleNodeType.XOR_GROUP]: 'Grupo XOR',
1426
1426
  [RuleNodeType.IMPLIES_GROUP]: 'Implica',
1427
- [RuleNodeType.REQUIRED_IF]: 'Obrigatório se',
1428
- [RuleNodeType.VISIBLE_IF]: 'Visível se',
1427
+ [RuleNodeType.REQUIRED_IF]: 'Obrigatório se',
1428
+ [RuleNodeType.VISIBLE_IF]: 'Visível se',
1429
1429
  [RuleNodeType.DISABLED_IF]: 'Desabilitado se',
1430
1430
  [RuleNodeType.READONLY_IF]: 'Somente leitura se',
1431
1431
  [RuleNodeType.FOR_EACH]: 'Para cada item',
1432
- [RuleNodeType.UNIQUE_BY]: 'Único por campo',
1433
- [RuleNodeType.MIN_LENGTH]: 'Mínimo de itens',
1434
- [RuleNodeType.MAX_LENGTH]: 'Máximo de itens',
1432
+ [RuleNodeType.UNIQUE_BY]: 'Único por campo',
1433
+ [RuleNodeType.MIN_LENGTH]: 'Mínimo de itens',
1434
+ [RuleNodeType.MAX_LENGTH]: 'Máximo de itens',
1435
1435
  [RuleNodeType.IF_DEFINED]: 'Se definido',
1436
- [RuleNodeType.IF_NOT_NULL]: 'Se não for nulo',
1436
+ [RuleNodeType.IF_NOT_NULL]: 'Se não for nulo',
1437
1437
  [RuleNodeType.IF_EXISTS]: 'Se existir',
1438
- [RuleNodeType.WITH_DEFAULT]: 'Com valor padrão',
1439
- [RuleNodeType.FUNCTION_CALL]: 'Chamada de função',
1438
+ [RuleNodeType.WITH_DEFAULT]: 'Com valor padrão',
1439
+ [RuleNodeType.FUNCTION_CALL]: 'Chamada de função',
1440
1440
  [RuleNodeType.FIELD_TO_FIELD]: 'Campo para campo',
1441
1441
  [RuleNodeType.CONTEXTUAL]: 'Contextual',
1442
1442
  [RuleNodeType.AT_LEAST]: 'Pelo menos',
1443
1443
  [RuleNodeType.EXACTLY]: 'Exatamente',
1444
- [RuleNodeType.EXPRESSION]: 'Expressão',
1444
+ [RuleNodeType.EXPRESSION]: 'Expressão',
1445
1445
  [RuleNodeType.CONTEXTUAL_TEMPLATE]: 'Template contextual',
1446
1446
  [RuleNodeType.CUSTOM]: 'Personalizado',
1447
1447
  };
@@ -1471,8 +1471,8 @@ class RuleBuilderService {
1471
1471
  });
1472
1472
  }
1473
1473
  /**
1474
- * Constrói um array de FormLayoutRule a partir do estado atual do builder,
1475
- * focando em nós propertyRule ou nós com propriedades/targets definidos.
1474
+ * Constrói um array de FormLayoutRule a partir do estado atual do builder,
1475
+ * focando em nós propertyRule ou nós com propriedades/targets definidos.
1476
1476
  */
1477
1477
  exportFormRulesFromState(state) {
1478
1478
  const rules = [];
@@ -1486,7 +1486,7 @@ class RuleBuilderService {
1486
1486
  }
1487
1487
  }
1488
1488
  if (warnings.length) {
1489
- console.warn('[RuleBuilderService] Algumas propriedades foram removidas ou ajustadas durante a exportação de formRules:', warnings);
1489
+ console.warn('[RuleBuilderService] Algumas propriedades foram removidas ou ajustadas durante a exportação de formRules:', warnings);
1490
1490
  }
1491
1491
  return rules;
1492
1492
  }
@@ -1545,7 +1545,7 @@ class RuleBuilderService {
1545
1545
  return null;
1546
1546
  }
1547
1547
  return {
1548
- [operator]: [{ var: cfg.fieldName }, this.normalizeConditionValue(cfg.value)],
1548
+ [operator]: [{ var: cfg.fieldName }, this.buildConditionRightOperand(cfg)],
1549
1549
  };
1550
1550
  }
1551
1551
  if (node.type === RuleNodeType.AND_GROUP || node.type === RuleNodeType.OR_GROUP) {
@@ -1624,7 +1624,7 @@ class RuleBuilderService {
1624
1624
  const id = (rawRule && (rawRule.id || rawRule.name)) || `#${index + 1}`;
1625
1625
  const ruleErrorsStart = errors.length;
1626
1626
  if (!rawRule || typeof rawRule !== 'object') {
1627
- errors.push(`Regra ${id}: valor inválido (esperado objeto)`);
1627
+ errors.push(`Regra ${id}: valor inválido (esperado objeto)`);
1628
1628
  return;
1629
1629
  }
1630
1630
  const rawTargets = Array.isArray(rawRule.targets) && rawRule.targets.length
@@ -1634,16 +1634,16 @@ class RuleBuilderService {
1634
1634
  : [];
1635
1635
  const { targets, targetType } = this.normalizeTargets(rawTargets, rawRule.targetType);
1636
1636
  if (!targets.length) {
1637
- errors.push(`Regra ${id}: targets obrigatórios ausentes`);
1637
+ errors.push(`Regra ${id}: targets obrigatórios ausentes`);
1638
1638
  return;
1639
1639
  }
1640
1640
  if (!allowedTargets.has(targetType)) {
1641
- errors.push(`Regra ${id}: targetType inválido "${rawRule.targetType || targetType}"`);
1641
+ errors.push(`Regra ${id}: targetType inválido "${rawRule.targetType || targetType}"`);
1642
1642
  return;
1643
1643
  }
1644
1644
  const effect = rawRule.effect;
1645
1645
  if (!effect || typeof effect !== 'object') {
1646
- errors.push(`Regra ${id}: effect ausente ou inválido`);
1646
+ errors.push(`Regra ${id}: effect ausente ou inválido`);
1647
1647
  return;
1648
1648
  }
1649
1649
  const condition = this.normalizeJsonLogicCondition(effect.condition);
@@ -1654,7 +1654,7 @@ class RuleBuilderService {
1654
1654
  const propertiesWhenFalse = this.sanitizeRuleProperties(targetType, effect.propertiesWhenFalse, errors, `regra ${id} (propertiesWhenFalse)`, true);
1655
1655
  if (Object.keys(properties).length === 0 &&
1656
1656
  Object.keys(propertiesWhenFalse).length === 0) {
1657
- errors.push(`Regra ${id}: nenhuma propriedade válida encontrada`);
1657
+ errors.push(`Regra ${id}: nenhuma propriedade válida encontrada`);
1658
1658
  }
1659
1659
  if (errors.length === ruleErrorsStart) {
1660
1660
  normalized.push({
@@ -1672,7 +1672,7 @@ class RuleBuilderService {
1672
1672
  }
1673
1673
  });
1674
1674
  if (errors.length) {
1675
- throw new Error(`FormRules inválidos: ${errors.join('; ')}`);
1675
+ throw new Error(`FormRules inválidos: ${errors.join('; ')}`);
1676
1676
  }
1677
1677
  return normalized;
1678
1678
  }
@@ -1687,7 +1687,7 @@ class RuleBuilderService {
1687
1687
  const def = defMap.get(name);
1688
1688
  if (!def) {
1689
1689
  if (strict || collector) {
1690
- collector?.push(`${context}: propriedade "${name}" não é permitida para ${targetType}`);
1690
+ collector?.push(`${context}: propriedade "${name}" não é permitida para ${targetType}`);
1691
1691
  }
1692
1692
  return acc;
1693
1693
  }
@@ -1696,14 +1696,14 @@ class RuleBuilderService {
1696
1696
  acc[name] = coerced.value;
1697
1697
  }
1698
1698
  else if (strict || collector) {
1699
- collector?.push(`${context}: valor inválido para "${name}" (esperado ${def.type}, recebido ${typeof value})`);
1699
+ collector?.push(`${context}: valor inválido para "${name}" (esperado ${def.type}, recebido ${typeof value})`);
1700
1700
  }
1701
1701
  return acc;
1702
1702
  }, {});
1703
1703
  }
1704
1704
  coerceRulePropertyValue(def, value) {
1705
1705
  if (value === null) {
1706
- // null mantém semântica de remover override
1706
+ // null mantém semântica de remover override
1707
1707
  return { ok: true, value: null };
1708
1708
  }
1709
1709
  switch (def.type) {
@@ -1735,10 +1735,19 @@ class RuleBuilderService {
1735
1735
  return { ok: true, value: this.sanitizeStructuredValue(def.name, value) };
1736
1736
  }
1737
1737
  return { ok: false };
1738
+ case 'array':
1739
+ return Array.isArray(value)
1740
+ ? { ok: true, value: this.sanitizeStructuredArray(def.name, value) }
1741
+ : { ok: false };
1738
1742
  default:
1739
1743
  return { ok: false };
1740
1744
  }
1741
1745
  }
1746
+ sanitizeStructuredArray(name, value) {
1747
+ return value.map((item) => item && typeof item === 'object' && !Array.isArray(item)
1748
+ ? this.sanitizeStructuredValue(name, item)
1749
+ : item);
1750
+ }
1742
1751
  sanitizeStructuredValue(name, value) {
1743
1752
  if (name === 'options') {
1744
1753
  const normalizeItems = (items) => items
@@ -1951,15 +1960,20 @@ class RuleBuilderService {
1951
1960
  if (!this.isVarExpression(left)) {
1952
1961
  return undefined;
1953
1962
  }
1963
+ const config = {
1964
+ type: 'fieldCondition',
1965
+ fieldName: this.extractVarPath(left.var),
1966
+ operator: builderOperator,
1967
+ value: right,
1968
+ };
1969
+ if (this.isVarExpression(right)) {
1970
+ config['valueType'] = 'field';
1971
+ config['compareToField'] = this.extractVarPath(right.var);
1972
+ }
1954
1973
  return {
1955
1974
  id: v4(),
1956
1975
  type: RuleNodeType.FIELD_CONDITION,
1957
- config: {
1958
- type: 'fieldCondition',
1959
- fieldName: this.extractVarPath(left.var),
1960
- operator: builderOperator,
1961
- value: right,
1962
- },
1976
+ config: config,
1963
1977
  };
1964
1978
  }
1965
1979
  parseJsonLogicChild(child) {
@@ -2073,6 +2087,14 @@ class RuleBuilderService {
2073
2087
  }
2074
2088
  return value;
2075
2089
  }
2090
+ buildConditionRightOperand(cfg) {
2091
+ if (cfg['valueType'] === 'field' &&
2092
+ typeof cfg['compareToField'] === 'string' &&
2093
+ cfg['compareToField'].trim()) {
2094
+ return { var: cfg['compareToField'].trim() };
2095
+ }
2096
+ return this.normalizeConditionValue(cfg['value']);
2097
+ }
2076
2098
  isJsonLogicExpressionCandidate(value) {
2077
2099
  return !!value && typeof value === 'object' && !Array.isArray(value);
2078
2100
  }
@@ -2228,13 +2250,17 @@ class RuleBuilderService {
2228
2250
  this.addValidationError(errors, `field-condition:compare-field:${node.id}`, 'Escolha o campo usado na comparacao.', 'error', node.id);
2229
2251
  return;
2230
2252
  }
2231
- if (cfg.valueType === 'context' &&
2232
- (!cfg.contextVariable || typeof cfg.contextVariable !== 'string')) {
2233
- this.addValidationError(errors, `field-condition:context:${node.id}`, 'Escolha a variavel de contexto usada na comparacao.', 'error', node.id);
2253
+ if (cfg.valueType === 'context') {
2254
+ this.addValidationError(errors, `field-condition:context:${node.id}`, 'Comparação com variável de contexto ainda não possui serialização JSON Logic canônica.', 'error', node.id);
2255
+ return;
2256
+ }
2257
+ if (cfg.valueType === 'function') {
2258
+ this.addValidationError(errors, `field-condition:function:${node.id}`, 'Comparação com chamada de função ainda não possui serialização JSON Logic canônica.', 'error', node.id);
2234
2259
  return;
2235
2260
  }
2236
2261
  if (cfg.valueType !== 'field' &&
2237
2262
  cfg.valueType !== 'context' &&
2263
+ cfg.valueType !== 'function' &&
2238
2264
  !Object.prototype.hasOwnProperty.call(cfg, 'value')) {
2239
2265
  this.addValidationError(errors, `field-condition:value:${node.id}`, 'Informe o valor da condicao.', 'error', node.id);
2240
2266
  }
@@ -2310,7 +2336,7 @@ class RuleBuilderService {
2310
2336
  return null;
2311
2337
  if (input.type)
2312
2338
  return input;
2313
- // Inferência básica de tipos de especificação comuns
2339
+ // Inferência básica de tipos de especificação comuns
2314
2340
  // Campo simples: { field, operator, value }
2315
2341
  if (input.field && input.operator !== undefined) {
2316
2342
  return { type: 'field', ...input };
@@ -4434,12 +4460,12 @@ class PropertyEffectEditorComponent {
4434
4460
  clearValue(entry, branch) {
4435
4461
  if (branch === 'true') {
4436
4462
  entry.value = null;
4437
- entry.jsonValue = entry.type === 'object' ? '' : entry.value;
4463
+ entry.jsonValue = this.isStructuredJsonType(entry.type) ? '' : entry.value;
4438
4464
  entry.error = undefined;
4439
4465
  }
4440
4466
  else {
4441
4467
  entry.valueWhenFalse = null;
4442
- entry.jsonValueWhenFalse = entry.type === 'object' ? '' : entry.valueWhenFalse;
4468
+ entry.jsonValueWhenFalse = this.isStructuredJsonType(entry.type) ? '' : entry.valueWhenFalse;
4443
4469
  entry.errorWhenFalse = undefined;
4444
4470
  }
4445
4471
  this.emitChange();
@@ -4457,8 +4483,8 @@ class PropertyEffectEditorComponent {
4457
4483
  entry.type = def.type;
4458
4484
  entry.value = def.type === 'boolean' ? true : undefined;
4459
4485
  entry.valueWhenFalse = undefined;
4460
- entry.jsonValue = def.type === 'object' ? '' : undefined;
4461
- entry.jsonValueWhenFalse = def.type === 'object' ? '' : undefined;
4486
+ entry.jsonValue = this.isStructuredJsonType(def.type) ? '' : undefined;
4487
+ entry.jsonValueWhenFalse = this.isStructuredJsonType(def.type) ? '' : undefined;
4462
4488
  }
4463
4489
  entry.error = undefined;
4464
4490
  entry.errorWhenFalse = undefined;
@@ -4509,11 +4535,11 @@ class PropertyEffectEditorComponent {
4509
4535
  return;
4510
4536
  const entry = this.createEntry(def);
4511
4537
  entry.property = name;
4512
- entry.value = def.type === 'object' ? undefined : props[name];
4513
- entry.valueWhenFalse = def.type === 'object' ? undefined : propsFalse[name];
4514
- entry.jsonValue = def.type === 'object' ? this.stringifyValue(props[name]) : undefined;
4538
+ entry.value = this.isStructuredJsonType(def.type) ? undefined : props[name];
4539
+ entry.valueWhenFalse = this.isStructuredJsonType(def.type) ? undefined : propsFalse[name];
4540
+ entry.jsonValue = this.isStructuredJsonType(def.type) ? this.stringifyValue(props[name]) : undefined;
4515
4541
  entry.jsonValueWhenFalse =
4516
- def.type === 'object' ? this.stringifyValue(propsFalse[name]) : undefined;
4542
+ this.isStructuredJsonType(def.type) ? this.stringifyValue(propsFalse[name]) : undefined;
4517
4543
  entries.push(entry);
4518
4544
  });
4519
4545
  if (!entries.length && this.properties.length) {
@@ -4532,8 +4558,8 @@ class PropertyEffectEditorComponent {
4532
4558
  type: def.type,
4533
4559
  value: def.type === 'boolean' ? true : undefined,
4534
4560
  valueWhenFalse: undefined,
4535
- jsonValue: def.type === 'object' ? '' : undefined,
4536
- jsonValueWhenFalse: def.type === 'object' ? '' : undefined,
4561
+ jsonValue: this.isStructuredJsonType(def.type) ? '' : undefined,
4562
+ jsonValueWhenFalse: this.isStructuredJsonType(def.type) ? '' : undefined,
4537
4563
  };
4538
4564
  }
4539
4565
  buildConfigFromEntries() {
@@ -4561,7 +4587,7 @@ class PropertyEffectEditorComponent {
4561
4587
  }
4562
4588
  normalizeValue(entry, branch) {
4563
4589
  const type = entry.type;
4564
- const raw = type === 'object'
4590
+ const raw = this.isStructuredJsonType(type)
4565
4591
  ? branch === 'true'
4566
4592
  ? entry.jsonValue
4567
4593
  : entry.jsonValueWhenFalse
@@ -4593,8 +4619,9 @@ class PropertyEffectEditorComponent {
4593
4619
  }
4594
4620
  case 'string':
4595
4621
  return { ok: true, value: String(raw) };
4622
+ case 'array':
4596
4623
  default: {
4597
- const parsedResult = this.parseObject(raw, entry.property);
4624
+ const parsedResult = this.parseObject(raw, entry.property, type === 'array' ? 'array' : 'object');
4598
4625
  if (!parsedResult.ok) {
4599
4626
  return { ok: false, error: parsedResult.error || 'JSON inválido' };
4600
4627
  }
@@ -4602,7 +4629,7 @@ class PropertyEffectEditorComponent {
4602
4629
  }
4603
4630
  }
4604
4631
  }
4605
- parseObject(raw, propertyName) {
4632
+ parseObject(raw, propertyName, expectedType = 'object') {
4606
4633
  let value = raw;
4607
4634
  if (typeof raw === 'string') {
4608
4635
  try {
@@ -4612,6 +4639,11 @@ class PropertyEffectEditorComponent {
4612
4639
  return { ok: false, error: 'JSON inválido' };
4613
4640
  }
4614
4641
  }
4642
+ if (expectedType === 'array') {
4643
+ return Array.isArray(value)
4644
+ ? { ok: true, value }
4645
+ : { ok: false, error: 'Informe uma lista' };
4646
+ }
4615
4647
  if (propertyName === 'options') {
4616
4648
  if (Array.isArray(value)) {
4617
4649
  return { ok: true, value: { items: value } };
@@ -4635,6 +4667,9 @@ class PropertyEffectEditorComponent {
4635
4667
  return '';
4636
4668
  }
4637
4669
  }
4670
+ isStructuredJsonType(type) {
4671
+ return type === 'object' || type === 'array';
4672
+ }
4638
4673
  signature(config) {
4639
4674
  try {
4640
4675
  return JSON.stringify(config || {});
@@ -5279,6 +5314,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5279
5314
  args: ['searchInput']
5280
5315
  }] } });
5281
5316
 
5317
+ const VISUAL_SAFE_OPERATORS = new Set([
5318
+ 'equals',
5319
+ 'notEquals',
5320
+ 'greaterThan',
5321
+ 'greaterThanOrEqual',
5322
+ 'lessThan',
5323
+ 'lessThanOrEqual',
5324
+ 'contains',
5325
+ 'startsWith',
5326
+ 'endsWith',
5327
+ 'in',
5328
+ ]);
5282
5329
  class FieldConditionEditorComponent {
5283
5330
  fb;
5284
5331
  config = null;
@@ -5384,34 +5431,40 @@ class FieldConditionEditorComponent {
5384
5431
  const normalizedFieldName = this.normalizeFieldName(this.config.fieldName);
5385
5432
  const resolvedField = this.resolveFieldSchema(normalizedFieldName) || null;
5386
5433
  const formFieldName = resolvedField?.name || normalizedFieldName;
5434
+ const valueType = this.normalizeValueTypeForVisualEditor(this.config.valueType);
5387
5435
  this.conditionForm.patchValue({
5388
5436
  fieldName: formFieldName || '',
5389
5437
  operator: normalizedOperator || '',
5390
- value: this.config.value !== undefined ? this.config.value : '',
5391
- valueType: this.config.valueType || 'literal',
5392
- compareToField: this.config.compareToField || '',
5393
- contextVariable: this.config.contextVariable || '',
5438
+ value: valueType === 'literal' && this.config.value !== undefined
5439
+ ? this.config.value
5440
+ : '',
5441
+ valueType,
5442
+ compareToField: valueType === 'field' ? this.config.compareToField || '' : '',
5443
+ contextVariable: '',
5444
+ functionName: '',
5394
5445
  });
5446
+ this.valueType = valueType;
5395
5447
  if (formFieldName) {
5396
5448
  this.onFieldChanged(formFieldName);
5397
5449
  }
5398
5450
  const opCtrl = this.conditionForm.get('operator');
5399
5451
  if (opCtrl) {
5400
- this.selectedOperator = opCtrl.value;
5452
+ this.selectedOperator = opCtrl.value || null;
5401
5453
  }
5402
5454
  }
5403
5455
  emitConfigChange() {
5404
5456
  if (!this.conditionForm.valid)
5405
5457
  return;
5406
5458
  const formValue = this.conditionForm.value;
5459
+ const valueType = this.normalizeValueTypeForVisualEditor(formValue.valueType);
5407
5460
  const config = {
5408
5461
  type: 'fieldCondition',
5409
5462
  fieldName: formValue.fieldName,
5410
5463
  operator: formValue.operator,
5411
- value: this.processValue(formValue.value),
5412
- valueType: formValue.valueType,
5413
- compareToField: formValue.compareToField,
5414
- contextVariable: formValue.contextVariable,
5464
+ value: valueType === 'literal' ? this.processValue(formValue.value) : null,
5465
+ valueType,
5466
+ compareToField: valueType === 'field' ? formValue.compareToField : '',
5467
+ contextVariable: '',
5415
5468
  };
5416
5469
  this.configChanged.emit(config);
5417
5470
  }
@@ -5487,6 +5540,9 @@ class FieldConditionEditorComponent {
5487
5540
  return operator;
5488
5541
  }
5489
5542
  }
5543
+ normalizeValueTypeForVisualEditor(valueType) {
5544
+ return valueType === 'field' ? 'field' : 'literal';
5545
+ }
5490
5546
  // Template methods
5491
5547
  getFieldIcon(type) {
5492
5548
  const icons = {
@@ -5644,8 +5700,7 @@ class FieldConditionEditorComponent {
5644
5700
  }
5645
5701
  this.selectedField = resolvedField;
5646
5702
  if (this.selectedField) {
5647
- this.availableOperators =
5648
- FIELD_TYPE_OPERATORS[this.selectedField.type] || [];
5703
+ this.availableOperators = (FIELD_TYPE_OPERATORS[this.selectedField.type] || []).filter((operator) => VISUAL_SAFE_OPERATORS.has(operator));
5649
5704
  // Reset operator if not compatible
5650
5705
  const currentOperator = this.conditionForm.get('operator')?.value;
5651
5706
  if (currentOperator &&
@@ -5664,9 +5719,10 @@ class FieldConditionEditorComponent {
5664
5719
  this.conditionForm.patchValue({ value: '' });
5665
5720
  }
5666
5721
  onValueTypeChanged(event) {
5667
- this.valueType = event.value;
5722
+ this.valueType = this.normalizeValueTypeForVisualEditor(event.value);
5668
5723
  // Reset related fields
5669
5724
  this.conditionForm.patchValue({
5725
+ valueType: this.valueType,
5670
5726
  value: '',
5671
5727
  compareToField: '',
5672
5728
  contextVariable: '',
@@ -5689,6 +5745,11 @@ class FieldConditionEditorComponent {
5689
5745
  const valueType = this.conditionForm.get('valueType')?.value;
5690
5746
  const valueControl = this.conditionForm.get('value');
5691
5747
  const valueProvided = valueControl && valueControl.value !== undefined && valueControl.value !== '';
5748
+ const normalizedValueType = this.normalizeValueTypeForVisualEditor(valueType);
5749
+ if (valueType !== normalizedValueType) {
5750
+ errors.push('Tipo de valor disponivel apenas por JSON avancado');
5751
+ return errors;
5752
+ }
5692
5753
  switch (valueType) {
5693
5754
  case 'literal':
5694
5755
  if (!valueProvided) {
@@ -5825,8 +5886,8 @@ class FieldConditionEditorComponent {
5825
5886
  >
5826
5887
  <mat-option value="literal">Valor digitado</mat-option>
5827
5888
  <mat-option value="field">Outro campo</mat-option>
5828
- <mat-option value="context">Variável de contexto</mat-option>
5829
- <mat-option value="function">Chamada de função</mat-option>
5889
+ <mat-option value="context" disabled>Contexto (JSON-only)</mat-option>
5890
+ <mat-option value="function" disabled>Função (JSON-only)</mat-option>
5830
5891
  </mat-select>
5831
5892
  </mat-form-field>
5832
5893
  @switch (valueType) {
@@ -5978,15 +6039,6 @@ class FieldConditionEditorComponent {
5978
6039
  </div>
5979
6040
  }
5980
6041
 
5981
- <!-- Ações -->
5982
- <div class="actions-col">
5983
- <button mat-icon-button type="button" aria-label="Duplicar" matTooltip="Duplicar (placeholder)">
5984
- <mat-icon>content_copy</mat-icon>
5985
- </button>
5986
- <button mat-icon-button type="button" aria-label="Excluir" matTooltip="Excluir (placeholder)">
5987
- <mat-icon>delete</mat-icon>
5988
- </button>
5989
- </div>
5990
6042
  </div>
5991
6043
 
5992
6044
  @if (!hasFieldOptions()) {
@@ -6012,7 +6064,7 @@ class FieldConditionEditorComponent {
6012
6064
  </div>
6013
6065
  }
6014
6066
  </form>
6015
- `, isInline: true, styles: [".field-condition-form{display:flex;flex-direction:column;gap:8px;min-width:300px;background:var(--md-sys-color-surface-container-low);border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;padding:8px 10px;overflow:visible}.condition-row-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:4px}.condition-title{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:var(--md-sys-color-on-surface)}.compact-grid{gap:12px}.condition-row{display:grid;grid-template-columns:minmax(180px,2fr) minmax(140px,1.5fr) minmax(220px,3fr) auto;gap:12px 4px;align-items:center}.compact-field{width:100%}.value-inline{display:grid;grid-template-columns:1.2fr 2fr;gap:8px;align-items:center}.value-field{width:100%}.actions-col{display:flex;flex-direction:column;gap:4px;align-items:center;justify-content:center}.field-option,.context-option,.function-option{display:flex;align-items:center;gap:8px;width:100%}.field-icon{font-size:16px;width:16px;height:16px;color:var(--md-sys-color-primary)}.field-label{flex:1;font-weight:500}.field-type{font-size:11px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);padding:2px 6px;border-radius:4px}.select-search-container{position:sticky;top:0;z-index:1;background:var(--md-sys-color-surface-container-lowest, #fff);padding:8px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant, rgba(0,0,0,.12))}.search-input-field{width:100%}.search-input-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.no-results{font-style:italic;font-size:13px;text-align:center}.field-info{flex:1;display:flex;flex-direction:column;line-height:1.2;overflow:hidden}.field-name{font-size:10px;opacity:.6}.variable-name{font-family:monospace;font-weight:500;color:var(--md-sys-color-secondary)}.variable-type{font-size:11px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);padding:2px 6px;border-radius:4px}.function-name{font-weight:500;color:var(--md-sys-color-tertiary)}.function-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);font-style:italic}.boolean-inline{display:flex;align-items:center;padding:4px 0}.condition-preview{background:var(--md-sys-color-surface-container);border-radius:8px;padding:8px 12px;border-left:4px solid var(--md-sys-color-primary);margin-top:2px}.preview-label{font-size:12px;font-weight:500;color:var(--md-sys-color-on-surface-variant);margin-bottom:2px}.preview-text{font-family:monospace;font-size:14px;color:var(--md-sys-color-on-surface);background:var(--md-sys-color-surface);padding:6px 8px;border-radius:4px;border:1px solid var(--md-sys-color-outline-variant)}.error-row{display:inline-flex;align-items:center;gap:6px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border:1px solid var(--md-sys-color-error);border-radius:8px;padding:4px 10px;font-size:12px;min-height:32px}@media(max-width:1024px){.condition-row{grid-template-columns:repeat(2,minmax(180px,1fr))}.value-inline{grid-template-columns:1fr}}@media(max-width:768px){.condition-row{grid-template-columns:1fr}}.no-fields-hint{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--md-sys-color-on-surface-variant);padding:8px 0}:host ::ng-deep .mat-mdc-select-panel{scrollbar-width:thin;scrollbar-color:var(--md-sys-color-on-surface-variant) transparent}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar{width:8px}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar-thumb{background-color:var(--md-sys-color-on-surface-variant);border-radius:8px}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar-track{background-color:transparent}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i3.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i3.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i7$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i8$2.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i8$2.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i8$2.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6067
+ `, isInline: true, styles: [".field-condition-form{display:flex;flex-direction:column;gap:8px;min-width:300px;background:var(--md-sys-color-surface-container-low);border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;padding:8px 10px;overflow:visible}.condition-row-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:4px}.condition-title{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:var(--md-sys-color-on-surface)}.compact-grid{gap:12px}.condition-row{display:grid;grid-template-columns:minmax(180px,2fr) minmax(140px,1.5fr) minmax(220px,3fr) auto;gap:12px 4px;align-items:center}.compact-field{width:100%}.value-inline{display:grid;grid-template-columns:1.2fr 2fr;gap:8px;align-items:center}.value-field{width:100%}.field-option,.context-option,.function-option{display:flex;align-items:center;gap:8px;width:100%}.field-icon{font-size:16px;width:16px;height:16px;color:var(--md-sys-color-primary)}.field-label{flex:1;font-weight:500}.field-type{font-size:11px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);padding:2px 6px;border-radius:4px}.select-search-container{position:sticky;top:0;z-index:1;background:var(--md-sys-color-surface-container-lowest, #fff);padding:8px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant, rgba(0,0,0,.12))}.search-input-field{width:100%}.search-input-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.no-results{font-style:italic;font-size:13px;text-align:center}.field-info{flex:1;display:flex;flex-direction:column;line-height:1.2;overflow:hidden}.field-name{font-size:10px;opacity:.6}.variable-name{font-family:monospace;font-weight:500;color:var(--md-sys-color-secondary)}.variable-type{font-size:11px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);padding:2px 6px;border-radius:4px}.function-name{font-weight:500;color:var(--md-sys-color-tertiary)}.function-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);font-style:italic}.boolean-inline{display:flex;align-items:center;padding:4px 0}.condition-preview{background:var(--md-sys-color-surface-container);border-radius:8px;padding:8px 12px;border-left:4px solid var(--md-sys-color-primary);margin-top:2px}.preview-label{font-size:12px;font-weight:500;color:var(--md-sys-color-on-surface-variant);margin-bottom:2px}.preview-text{font-family:monospace;font-size:14px;color:var(--md-sys-color-on-surface);background:var(--md-sys-color-surface);padding:6px 8px;border-radius:4px;border:1px solid var(--md-sys-color-outline-variant)}.error-row{display:inline-flex;align-items:center;gap:6px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border:1px solid var(--md-sys-color-error);border-radius:8px;padding:4px 10px;font-size:12px;min-height:32px}@media(max-width:1024px){.condition-row{grid-template-columns:repeat(2,minmax(180px,1fr))}.value-inline{grid-template-columns:1fr}}@media(max-width:768px){.condition-row{grid-template-columns:1fr}}.no-fields-hint{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--md-sys-color-on-surface-variant);padding:8px 0}:host ::ng-deep .mat-mdc-select-panel{scrollbar-width:thin;scrollbar-color:var(--md-sys-color-on-surface-variant) transparent}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar{width:8px}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar-thumb{background-color:var(--md-sys-color-on-surface-variant);border-radius:8px}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar-track{background-color:transparent}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i3.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i3.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i7$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i8$2.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i8$2.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i8$2.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6016
6068
  }
6017
6069
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FieldConditionEditorComponent, decorators: [{
6018
6070
  type: Component,
@@ -6133,8 +6185,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6133
6185
  >
6134
6186
  <mat-option value="literal">Valor digitado</mat-option>
6135
6187
  <mat-option value="field">Outro campo</mat-option>
6136
- <mat-option value="context">Variável de contexto</mat-option>
6137
- <mat-option value="function">Chamada de função</mat-option>
6188
+ <mat-option value="context" disabled>Contexto (JSON-only)</mat-option>
6189
+ <mat-option value="function" disabled>Função (JSON-only)</mat-option>
6138
6190
  </mat-select>
6139
6191
  </mat-form-field>
6140
6192
  @switch (valueType) {
@@ -6286,15 +6338,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6286
6338
  </div>
6287
6339
  }
6288
6340
 
6289
- <!-- Ações -->
6290
- <div class="actions-col">
6291
- <button mat-icon-button type="button" aria-label="Duplicar" matTooltip="Duplicar (placeholder)">
6292
- <mat-icon>content_copy</mat-icon>
6293
- </button>
6294
- <button mat-icon-button type="button" aria-label="Excluir" matTooltip="Excluir (placeholder)">
6295
- <mat-icon>delete</mat-icon>
6296
- </button>
6297
- </div>
6298
6341
  </div>
6299
6342
 
6300
6343
  @if (!hasFieldOptions()) {
@@ -6320,7 +6363,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6320
6363
  </div>
6321
6364
  }
6322
6365
  </form>
6323
- `, styles: [".field-condition-form{display:flex;flex-direction:column;gap:8px;min-width:300px;background:var(--md-sys-color-surface-container-low);border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;padding:8px 10px;overflow:visible}.condition-row-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:4px}.condition-title{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:var(--md-sys-color-on-surface)}.compact-grid{gap:12px}.condition-row{display:grid;grid-template-columns:minmax(180px,2fr) minmax(140px,1.5fr) minmax(220px,3fr) auto;gap:12px 4px;align-items:center}.compact-field{width:100%}.value-inline{display:grid;grid-template-columns:1.2fr 2fr;gap:8px;align-items:center}.value-field{width:100%}.actions-col{display:flex;flex-direction:column;gap:4px;align-items:center;justify-content:center}.field-option,.context-option,.function-option{display:flex;align-items:center;gap:8px;width:100%}.field-icon{font-size:16px;width:16px;height:16px;color:var(--md-sys-color-primary)}.field-label{flex:1;font-weight:500}.field-type{font-size:11px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);padding:2px 6px;border-radius:4px}.select-search-container{position:sticky;top:0;z-index:1;background:var(--md-sys-color-surface-container-lowest, #fff);padding:8px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant, rgba(0,0,0,.12))}.search-input-field{width:100%}.search-input-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.no-results{font-style:italic;font-size:13px;text-align:center}.field-info{flex:1;display:flex;flex-direction:column;line-height:1.2;overflow:hidden}.field-name{font-size:10px;opacity:.6}.variable-name{font-family:monospace;font-weight:500;color:var(--md-sys-color-secondary)}.variable-type{font-size:11px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);padding:2px 6px;border-radius:4px}.function-name{font-weight:500;color:var(--md-sys-color-tertiary)}.function-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);font-style:italic}.boolean-inline{display:flex;align-items:center;padding:4px 0}.condition-preview{background:var(--md-sys-color-surface-container);border-radius:8px;padding:8px 12px;border-left:4px solid var(--md-sys-color-primary);margin-top:2px}.preview-label{font-size:12px;font-weight:500;color:var(--md-sys-color-on-surface-variant);margin-bottom:2px}.preview-text{font-family:monospace;font-size:14px;color:var(--md-sys-color-on-surface);background:var(--md-sys-color-surface);padding:6px 8px;border-radius:4px;border:1px solid var(--md-sys-color-outline-variant)}.error-row{display:inline-flex;align-items:center;gap:6px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border:1px solid var(--md-sys-color-error);border-radius:8px;padding:4px 10px;font-size:12px;min-height:32px}@media(max-width:1024px){.condition-row{grid-template-columns:repeat(2,minmax(180px,1fr))}.value-inline{grid-template-columns:1fr}}@media(max-width:768px){.condition-row{grid-template-columns:1fr}}.no-fields-hint{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--md-sys-color-on-surface-variant);padding:8px 0}:host ::ng-deep .mat-mdc-select-panel{scrollbar-width:thin;scrollbar-color:var(--md-sys-color-on-surface-variant) transparent}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar{width:8px}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar-thumb{background-color:var(--md-sys-color-on-surface-variant);border-radius:8px}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar-track{background-color:transparent}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}\n"] }]
6366
+ `, styles: [".field-condition-form{display:flex;flex-direction:column;gap:8px;min-width:300px;background:var(--md-sys-color-surface-container-low);border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;padding:8px 10px;overflow:visible}.condition-row-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:4px}.condition-title{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:var(--md-sys-color-on-surface)}.compact-grid{gap:12px}.condition-row{display:grid;grid-template-columns:minmax(180px,2fr) minmax(140px,1.5fr) minmax(220px,3fr) auto;gap:12px 4px;align-items:center}.compact-field{width:100%}.value-inline{display:grid;grid-template-columns:1.2fr 2fr;gap:8px;align-items:center}.value-field{width:100%}.field-option,.context-option,.function-option{display:flex;align-items:center;gap:8px;width:100%}.field-icon{font-size:16px;width:16px;height:16px;color:var(--md-sys-color-primary)}.field-label{flex:1;font-weight:500}.field-type{font-size:11px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);padding:2px 6px;border-radius:4px}.select-search-container{position:sticky;top:0;z-index:1;background:var(--md-sys-color-surface-container-lowest, #fff);padding:8px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant, rgba(0,0,0,.12))}.search-input-field{width:100%}.search-input-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.no-results{font-style:italic;font-size:13px;text-align:center}.field-info{flex:1;display:flex;flex-direction:column;line-height:1.2;overflow:hidden}.field-name{font-size:10px;opacity:.6}.variable-name{font-family:monospace;font-weight:500;color:var(--md-sys-color-secondary)}.variable-type{font-size:11px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);padding:2px 6px;border-radius:4px}.function-name{font-weight:500;color:var(--md-sys-color-tertiary)}.function-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);font-style:italic}.boolean-inline{display:flex;align-items:center;padding:4px 0}.condition-preview{background:var(--md-sys-color-surface-container);border-radius:8px;padding:8px 12px;border-left:4px solid var(--md-sys-color-primary);margin-top:2px}.preview-label{font-size:12px;font-weight:500;color:var(--md-sys-color-on-surface-variant);margin-bottom:2px}.preview-text{font-family:monospace;font-size:14px;color:var(--md-sys-color-on-surface);background:var(--md-sys-color-surface);padding:6px 8px;border-radius:4px;border:1px solid var(--md-sys-color-outline-variant)}.error-row{display:inline-flex;align-items:center;gap:6px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border:1px solid var(--md-sys-color-error);border-radius:8px;padding:4px 10px;font-size:12px;min-height:32px}@media(max-width:1024px){.condition-row{grid-template-columns:repeat(2,minmax(180px,1fr))}.value-inline{grid-template-columns:1fr}}@media(max-width:768px){.condition-row{grid-template-columns:1fr}}.no-fields-hint{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--md-sys-color-on-surface-variant);padding:8px 0}:host ::ng-deep .mat-mdc-select-panel{scrollbar-width:thin;scrollbar-color:var(--md-sys-color-on-surface-variant) transparent}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar{width:8px}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar-thumb{background-color:var(--md-sys-color-on-surface-variant);border-radius:8px}:host ::ng-deep .mat-mdc-select-panel::-webkit-scrollbar-track{background-color:transparent}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}\n"] }]
6324
6367
  }], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { config: [{
6325
6368
  type: Input
6326
6369
  }], fieldSchemas: [{
@@ -6699,132 +6742,132 @@ const PRAXIS_VISUAL_BUILDER_EN_US = {
6699
6742
 
6700
6743
  const PRAXIS_VISUAL_BUILDER_PT_BR = {
6701
6744
  'praxis.visualBuilder.expression.title': 'Editor de expressoes legadas',
6702
- 'praxis.visualBuilder.expression.tooltip.format': 'Formatar expressão',
6703
- 'praxis.visualBuilder.expression.tooltip.validate': 'Validar expressão',
6745
+ 'praxis.visualBuilder.expression.tooltip.format': 'Formatar expressão',
6746
+ 'praxis.visualBuilder.expression.tooltip.validate': 'Validar expressão',
6704
6747
  'praxis.visualBuilder.expression.tooltip.help': 'Ajuda e exemplos',
6705
6748
  'praxis.visualBuilder.expression.label.rules': 'Texto legado da regra',
6706
- 'praxis.visualBuilder.expression.validationTitle': 'Resultados da validação',
6749
+ 'praxis.visualBuilder.expression.validationTitle': 'Resultados da validação',
6707
6750
  'praxis.visualBuilder.expression.validationIssues': 'Pontos a corrigir:',
6708
6751
  'praxis.visualBuilder.expression.lineColumn': 'Linha {{line}}, Coluna {{column}}',
6709
- 'praxis.visualBuilder.expression.suggestion': 'Sugestão:',
6752
+ 'praxis.visualBuilder.expression.suggestion': 'Sugestão:',
6710
6753
  'praxis.visualBuilder.expression.performance': 'Desempenho:',
6711
- 'praxis.visualBuilder.expression.parseTime': 'Tempo de análise:',
6754
+ 'praxis.visualBuilder.expression.parseTime': 'Tempo de análise:',
6712
6755
  'praxis.visualBuilder.expression.complexity': 'Complexidade:',
6713
- 'praxis.visualBuilder.expression.generatedSpec': 'Especificação gerada:',
6714
- 'praxis.visualBuilder.expression.quickReference': 'Referência rápida',
6756
+ 'praxis.visualBuilder.expression.generatedSpec': 'Especificação gerada:',
6757
+ 'praxis.visualBuilder.expression.quickReference': 'Referência rápida',
6715
6758
  'praxis.visualBuilder.expression.tab.operators': 'Operadores',
6716
- 'praxis.visualBuilder.expression.tab.functions': 'Funções',
6717
- 'praxis.visualBuilder.expression.tab.variables': 'Variáveis',
6718
- 'praxis.visualBuilder.expression.variablesScope': 'Variáveis ({{scope}})',
6719
- 'praxis.visualBuilder.expression.menu.toggleReference': 'Mostrar/ocultar referência rápida',
6759
+ 'praxis.visualBuilder.expression.tab.functions': 'Funções',
6760
+ 'praxis.visualBuilder.expression.tab.variables': 'Variáveis',
6761
+ 'praxis.visualBuilder.expression.variablesScope': 'Variáveis ({{scope}})',
6762
+ 'praxis.visualBuilder.expression.menu.toggleReference': 'Mostrar/ocultar referência rápida',
6720
6763
  'praxis.visualBuilder.expression.menu.examples': 'Ver exemplos',
6721
- 'praxis.visualBuilder.expression.menu.docs': 'Documentação',
6764
+ 'praxis.visualBuilder.expression.menu.docs': 'Documentação',
6722
6765
  'praxis.visualBuilder.expression.placeholder': 'Digite o texto das regras (ex.: ${idade} > 18 && status == "ativo")',
6723
- 'praxis.visualBuilder.expression.group.logical': 'Operadores lógicos',
6724
- 'praxis.visualBuilder.expression.group.comparison': 'Operadores de comparação',
6725
- 'praxis.visualBuilder.expression.op.and': 'E (AND) lógico',
6726
- 'praxis.visualBuilder.expression.op.or': 'OU (OR) lógico',
6727
- 'praxis.visualBuilder.expression.op.not': 'NÃO (NOT) lógico',
6766
+ 'praxis.visualBuilder.expression.group.logical': 'Operadores lógicos',
6767
+ 'praxis.visualBuilder.expression.group.comparison': 'Operadores de comparação',
6768
+ 'praxis.visualBuilder.expression.op.and': 'E (AND) lógico',
6769
+ 'praxis.visualBuilder.expression.op.or': 'OU (OR) lógico',
6770
+ 'praxis.visualBuilder.expression.op.not': 'NÃO (NOT) lógico',
6728
6771
  'praxis.visualBuilder.expression.op.xor': 'OU exclusivo (XOR)',
6729
- 'praxis.visualBuilder.expression.op.implies': 'Implica (se... então...)',
6772
+ 'praxis.visualBuilder.expression.op.implies': 'Implica (se... então...)',
6730
6773
  'praxis.visualBuilder.expression.op.eq': 'Igual a',
6731
6774
  'praxis.visualBuilder.expression.op.neq': 'Diferente de',
6732
6775
  'praxis.visualBuilder.expression.op.lt': 'Menor que',
6733
6776
  'praxis.visualBuilder.expression.op.lte': 'Menor ou igual',
6734
6777
  'praxis.visualBuilder.expression.op.gt': 'Maior que',
6735
6778
  'praxis.visualBuilder.expression.op.gte': 'Maior ou igual',
6736
- 'praxis.visualBuilder.expression.op.in': 'Contém o valor',
6737
- 'praxis.visualBuilder.expression.group.textFunctions': 'Funções de texto',
6738
- 'praxis.visualBuilder.expression.group.listFunctions': 'Funções para listas',
6739
- 'praxis.visualBuilder.expression.group.conditionalFunctions': 'Funções condicionais',
6740
- 'praxis.visualBuilder.expression.fn.contains': 'Verifica se o campo contém o valor',
6741
- 'praxis.visualBuilder.expression.fn.startsWith': 'Verifica se o campo começa com o prefixo',
6779
+ 'praxis.visualBuilder.expression.op.in': 'Contém o valor',
6780
+ 'praxis.visualBuilder.expression.group.textFunctions': 'Funções de texto',
6781
+ 'praxis.visualBuilder.expression.group.listFunctions': 'Funções para listas',
6782
+ 'praxis.visualBuilder.expression.group.conditionalFunctions': 'Funções condicionais',
6783
+ 'praxis.visualBuilder.expression.fn.contains': 'Verifica se o campo contém o valor',
6784
+ 'praxis.visualBuilder.expression.fn.startsWith': 'Verifica se o campo começa com o prefixo',
6742
6785
  'praxis.visualBuilder.expression.fn.endsWith': 'Verifica se o campo termina com o sufixo',
6743
6786
  'praxis.visualBuilder.expression.fn.forEach': 'Todos os itens devem seguir a regra',
6744
- 'praxis.visualBuilder.expression.fn.uniqueBy': 'Os itens devem ser únicos pelo campo',
6745
- 'praxis.visualBuilder.expression.fn.minLength': 'Tamanho mínimo da lista',
6746
- 'praxis.visualBuilder.expression.fn.maxLength': 'Tamanho máximo da lista',
6747
- 'praxis.visualBuilder.expression.fn.requiredIf': 'Campo obrigatório quando a condição é verdadeira',
6748
- 'praxis.visualBuilder.expression.fn.visibleIf': 'Campo visível quando a condição é verdadeira',
6749
- 'praxis.visualBuilder.expression.fn.disabledIf': 'Campo desabilitado quando a condição é verdadeira',
6750
- 'praxis.visualBuilder.expression.fn.readonlyIf': 'Campo somente leitura quando a condição é verdadeira',
6751
- 'praxis.visualBuilder.expression.error.parse': 'Erro ao interpretar a expressão',
6752
- 'praxis.visualBuilder.expression.error.validation': 'Erro de validação',
6753
- 'praxis.visualBuilder.expression.hint.startTyping': 'Comece a digitar para ver sugestões...',
6754
- 'praxis.visualBuilder.expression.hint.valid': 'Expressão válida (complexidade {{complexity}})',
6787
+ 'praxis.visualBuilder.expression.fn.uniqueBy': 'Os itens devem ser únicos pelo campo',
6788
+ 'praxis.visualBuilder.expression.fn.minLength': 'Tamanho mínimo da lista',
6789
+ 'praxis.visualBuilder.expression.fn.maxLength': 'Tamanho máximo da lista',
6790
+ 'praxis.visualBuilder.expression.fn.requiredIf': 'Campo obrigatório quando a condição é verdadeira',
6791
+ 'praxis.visualBuilder.expression.fn.visibleIf': 'Campo visível quando a condição é verdadeira',
6792
+ 'praxis.visualBuilder.expression.fn.disabledIf': 'Campo desabilitado quando a condição é verdadeira',
6793
+ 'praxis.visualBuilder.expression.fn.readonlyIf': 'Campo somente leitura quando a condição é verdadeira',
6794
+ 'praxis.visualBuilder.expression.error.parse': 'Erro ao interpretar a expressão',
6795
+ 'praxis.visualBuilder.expression.error.validation': 'Erro de validação',
6796
+ 'praxis.visualBuilder.expression.hint.startTyping': 'Comece a digitar para ver sugestões...',
6797
+ 'praxis.visualBuilder.expression.hint.valid': 'Expressão válida (complexidade {{complexity}})',
6755
6798
  'praxis.visualBuilder.expression.hint.fixItems': '{{count}} ponto(s) para corrigir',
6756
6799
  'praxis.visualBuilder.expression.hint.validating': 'Validando...',
6757
- 'praxis.visualBuilder.expression.summary.valid': 'Expressão válida e pronta para uso',
6800
+ 'praxis.visualBuilder.expression.summary.valid': 'Expressão válida e pronta para uso',
6758
6801
  'praxis.visualBuilder.expression.summary.issues': '{{errors}} erro(s), {{warnings}} aviso(s)',
6759
6802
  'praxis.visualBuilder.expression.operatorSuggestion': 'Operador {{value}}',
6760
6803
  'praxis.visualBuilder.expression.keywordSuggestion': 'Palavra-chave {{value}}',
6761
6804
  'praxis.visualBuilder.conditionalValidator.label.validatorType': 'Tipo de validador',
6762
6805
  'praxis.visualBuilder.conditionalValidator.label.targetField': 'Campo alvo',
6763
- 'praxis.visualBuilder.conditionalValidator.label.logicOperator': 'Operador lógico',
6806
+ 'praxis.visualBuilder.conditionalValidator.label.logicOperator': 'Operador lógico',
6764
6807
  'praxis.visualBuilder.conditionalValidator.label.errorMessage': 'Mensagem de erro personalizada',
6765
- 'praxis.visualBuilder.conditionalValidator.label.animation': 'Animação ao ocultar/exibir',
6766
- 'praxis.visualBuilder.conditionalValidator.label.disabledStyle': 'Aparência quando desabilitado',
6808
+ 'praxis.visualBuilder.conditionalValidator.label.animation': 'Animação ao ocultar/exibir',
6809
+ 'praxis.visualBuilder.conditionalValidator.label.disabledStyle': 'Aparência quando desabilitado',
6767
6810
  'praxis.visualBuilder.conditionalValidator.label.disabledMessage': 'Mensagem ao desabilitar',
6768
- 'praxis.visualBuilder.conditionalValidator.label.readonlyStyle': 'Aparência em modo somente leitura',
6769
- 'praxis.visualBuilder.conditionalValidator.label.logic': 'Lógica:',
6770
- 'praxis.visualBuilder.conditionalValidator.type.requiredIf.label': 'Obrigatório se',
6771
- 'praxis.visualBuilder.conditionalValidator.type.requiredIf.description': 'Campo obrigatório quando a condição for atendida',
6772
- 'praxis.visualBuilder.conditionalValidator.type.visibleIf.label': 'Visível se',
6773
- 'praxis.visualBuilder.conditionalValidator.type.visibleIf.description': 'Campo aparece quando a condição for atendida',
6811
+ 'praxis.visualBuilder.conditionalValidator.label.readonlyStyle': 'Aparência em modo somente leitura',
6812
+ 'praxis.visualBuilder.conditionalValidator.label.logic': 'Lógica:',
6813
+ 'praxis.visualBuilder.conditionalValidator.type.requiredIf.label': 'Obrigatório se',
6814
+ 'praxis.visualBuilder.conditionalValidator.type.requiredIf.description': 'Campo obrigatório quando a condição for atendida',
6815
+ 'praxis.visualBuilder.conditionalValidator.type.visibleIf.label': 'Visível se',
6816
+ 'praxis.visualBuilder.conditionalValidator.type.visibleIf.description': 'Campo aparece quando a condição for atendida',
6774
6817
  'praxis.visualBuilder.conditionalValidator.type.disabledIf.label': 'Desabilitado se',
6775
- 'praxis.visualBuilder.conditionalValidator.type.disabledIf.description': 'Campo fica desabilitado quando a condição for atendida',
6818
+ 'praxis.visualBuilder.conditionalValidator.type.disabledIf.description': 'Campo fica desabilitado quando a condição for atendida',
6776
6819
  'praxis.visualBuilder.conditionalValidator.type.readonlyIf.label': 'Somente leitura se',
6777
- 'praxis.visualBuilder.conditionalValidator.type.readonlyIf.description': 'Campo fica somente leitura quando a condição for atendida',
6778
- 'praxis.visualBuilder.conditionalValidator.help.targetField': 'Escolha o campo que será afetado por esta regra',
6779
- 'praxis.visualBuilder.conditionalValidator.help.errorMessage': 'Substitui a mensagem padrão exibida ao usuário',
6780
- 'praxis.visualBuilder.conditionalValidator.section.condition': 'Configuração da condição',
6781
- 'praxis.visualBuilder.conditionalValidator.section.validation': 'Configurações de validação',
6782
- 'praxis.visualBuilder.conditionalValidator.section.uiBehavior': 'Configurações de comportamento da interface',
6783
- 'praxis.visualBuilder.conditionalValidator.section.preview': 'Pré-visualização',
6784
- 'praxis.visualBuilder.conditionalValidator.mode.simple': 'Condição simples',
6785
- 'praxis.visualBuilder.conditionalValidator.mode.advanced': 'Lógica avançada',
6786
- 'praxis.visualBuilder.conditionalValidator.logic.and': 'E (AND) - todas as condições precisam ser verdadeiras',
6787
- 'praxis.visualBuilder.conditionalValidator.logic.or': 'OU (OR) - qualquer condição pode ser verdadeira',
6788
- 'praxis.visualBuilder.conditionalValidator.logic.not': 'NÃO (NOT) - a condição precisa ser falsa',
6789
- 'praxis.visualBuilder.conditionalValidator.logic.xor': 'XOR - apenas uma condição pode ser verdadeira',
6790
- 'praxis.visualBuilder.conditionalValidator.action.addCondition': 'Adicionar condição',
6791
- 'praxis.visualBuilder.conditionalValidator.placeholder.errorMessage': 'Este campo é obrigatório',
6792
- 'praxis.visualBuilder.conditionalValidator.placeholder.disabledMessage': 'Este campo está desabilitado no momento',
6820
+ 'praxis.visualBuilder.conditionalValidator.type.readonlyIf.description': 'Campo fica somente leitura quando a condição for atendida',
6821
+ 'praxis.visualBuilder.conditionalValidator.help.targetField': 'Escolha o campo que será afetado por esta regra',
6822
+ 'praxis.visualBuilder.conditionalValidator.help.errorMessage': 'Substitui a mensagem padrão exibida ao usuário',
6823
+ 'praxis.visualBuilder.conditionalValidator.section.condition': 'Configuração da condição',
6824
+ 'praxis.visualBuilder.conditionalValidator.section.validation': 'Configurações de validação',
6825
+ 'praxis.visualBuilder.conditionalValidator.section.uiBehavior': 'Configurações de comportamento da interface',
6826
+ 'praxis.visualBuilder.conditionalValidator.section.preview': 'Pré-visualização',
6827
+ 'praxis.visualBuilder.conditionalValidator.mode.simple': 'Condição simples',
6828
+ 'praxis.visualBuilder.conditionalValidator.mode.advanced': 'Lógica avançada',
6829
+ 'praxis.visualBuilder.conditionalValidator.logic.and': 'E (AND) - todas as condições precisam ser verdadeiras',
6830
+ 'praxis.visualBuilder.conditionalValidator.logic.or': 'OU (OR) - qualquer condição pode ser verdadeira',
6831
+ 'praxis.visualBuilder.conditionalValidator.logic.not': 'NÃO (NOT) - a condição precisa ser falsa',
6832
+ 'praxis.visualBuilder.conditionalValidator.logic.xor': 'XOR - apenas uma condição pode ser verdadeira',
6833
+ 'praxis.visualBuilder.conditionalValidator.action.addCondition': 'Adicionar condição',
6834
+ 'praxis.visualBuilder.conditionalValidator.placeholder.errorMessage': 'Este campo é obrigatório',
6835
+ 'praxis.visualBuilder.conditionalValidator.placeholder.disabledMessage': 'Este campo está desabilitado no momento',
6793
6836
  'praxis.visualBuilder.conditionalValidator.option.validateOnChange': 'Validar ao alterar o campo',
6794
6837
  'praxis.visualBuilder.conditionalValidator.option.validateOnBlur': 'Validar ao sair do campo',
6795
- 'praxis.visualBuilder.conditionalValidator.option.showErrorImmediately': 'Exibir erro assim que a condição for atendida',
6796
- 'praxis.visualBuilder.conditionalValidator.option.hideLabel': 'Ocultar rótulo do campo quando escondido',
6797
- 'praxis.visualBuilder.conditionalValidator.option.preserveSpace': 'Preservar espaço ao esconder',
6838
+ 'praxis.visualBuilder.conditionalValidator.option.showErrorImmediately': 'Exibir erro assim que a condição for atendida',
6839
+ 'praxis.visualBuilder.conditionalValidator.option.hideLabel': 'Ocultar rótulo do campo quando escondido',
6840
+ 'praxis.visualBuilder.conditionalValidator.option.preserveSpace': 'Preservar espaço ao esconder',
6798
6841
  'praxis.visualBuilder.conditionalValidator.option.clearOnDisable': 'Limpar valor ao desabilitar',
6799
6842
  'praxis.visualBuilder.conditionalValidator.option.showDisabledMessage': 'Mostrar mensagem quando desabilitado',
6800
- 'praxis.visualBuilder.conditionalValidator.option.showReadonlyIndicator': 'Mostrar ícone indicando somente leitura',
6801
- 'praxis.visualBuilder.conditionalValidator.animation.none': 'Sem animação',
6802
- 'praxis.visualBuilder.conditionalValidator.animation.fade': 'Transição suave (fade)',
6843
+ 'praxis.visualBuilder.conditionalValidator.option.showReadonlyIndicator': 'Mostrar ícone indicando somente leitura',
6844
+ 'praxis.visualBuilder.conditionalValidator.animation.none': 'Sem animação',
6845
+ 'praxis.visualBuilder.conditionalValidator.animation.fade': 'Transição suave (fade)',
6803
6846
  'praxis.visualBuilder.conditionalValidator.animation.slide': 'Deslizante (vertical)',
6804
6847
  'praxis.visualBuilder.conditionalValidator.animation.scale': 'Crescer/encolher',
6805
- 'praxis.visualBuilder.conditionalValidator.disabledStyle.default': 'Padrão (cinza)',
6848
+ 'praxis.visualBuilder.conditionalValidator.disabledStyle.default': 'Padrão (cinza)',
6806
6849
  'praxis.visualBuilder.conditionalValidator.disabledStyle.faded': 'Esmaecido',
6807
6850
  'praxis.visualBuilder.conditionalValidator.disabledStyle.hidden': 'Ocultar totalmente',
6808
- 'praxis.visualBuilder.conditionalValidator.readonlyStyle.default': 'Padrão (não editável)',
6851
+ 'praxis.visualBuilder.conditionalValidator.readonlyStyle.default': 'Padrão (não editável)',
6809
6852
  'praxis.visualBuilder.conditionalValidator.readonlyStyle.display': 'Mostrar apenas o valor',
6810
6853
  'praxis.visualBuilder.conditionalValidator.readonlyStyle.bordered': 'Valor com borda',
6811
6854
  'praxis.visualBuilder.conditionalValidator.category.other': 'Outros',
6812
6855
  'praxis.visualBuilder.conditionalValidator.selectField': 'Selecione um campo',
6813
- 'praxis.visualBuilder.conditionalValidator.summary.incomplete': 'Complete as informações da regra para ver o resumo',
6814
- 'praxis.visualBuilder.conditionalValidator.summary.action.required': 'ficará obrigatório',
6815
- 'praxis.visualBuilder.conditionalValidator.summary.action.visible': 'ficará visível',
6816
- 'praxis.visualBuilder.conditionalValidator.summary.action.disabled': 'ficará desabilitado',
6817
- 'praxis.visualBuilder.conditionalValidator.summary.action.readonly': 'ficará somente leitura',
6818
- 'praxis.visualBuilder.conditionalValidator.summary.simpleCondition': 'quando a condição for atendida',
6819
- 'praxis.visualBuilder.conditionalValidator.summary.advancedCondition': 'quando as condições ({{operator}}) forem atendidas',
6820
- 'praxis.visualBuilder.conditionalValidator.summary.logicPreview.one': '{{operator}} com 1 condição',
6821
- 'praxis.visualBuilder.conditionalValidator.summary.logicPreview.other': '{{operator}} com {{count}} condições',
6856
+ 'praxis.visualBuilder.conditionalValidator.summary.incomplete': 'Complete as informações da regra para ver o resumo',
6857
+ 'praxis.visualBuilder.conditionalValidator.summary.action.required': 'ficará obrigatório',
6858
+ 'praxis.visualBuilder.conditionalValidator.summary.action.visible': 'ficará visível',
6859
+ 'praxis.visualBuilder.conditionalValidator.summary.action.disabled': 'ficará desabilitado',
6860
+ 'praxis.visualBuilder.conditionalValidator.summary.action.readonly': 'ficará somente leitura',
6861
+ 'praxis.visualBuilder.conditionalValidator.summary.simpleCondition': 'quando a condição for atendida',
6862
+ 'praxis.visualBuilder.conditionalValidator.summary.advancedCondition': 'quando as condições ({{operator}}) forem atendidas',
6863
+ 'praxis.visualBuilder.conditionalValidator.summary.logicPreview.one': '{{operator}} com 1 condição',
6864
+ 'praxis.visualBuilder.conditionalValidator.summary.logicPreview.other': '{{operator}} com {{count}} condições',
6822
6865
  'praxis.visualBuilder.conditionalValidator.error.validatorTypeRequired': 'Escolha o tipo de validador',
6823
- 'praxis.visualBuilder.conditionalValidator.error.targetFieldRequired': 'Informe o campo que será avaliado',
6824
- 'praxis.visualBuilder.conditionalValidator.error.conditionRequired': 'Adicione pelo menos uma condição',
6866
+ 'praxis.visualBuilder.conditionalValidator.error.targetFieldRequired': 'Informe o campo que será avaliado',
6867
+ 'praxis.visualBuilder.conditionalValidator.error.conditionRequired': 'Adicione pelo menos uma condição',
6825
6868
  'praxis.visualBuilder.ruleList.eyebrow': 'Regras',
6826
6869
  'praxis.visualBuilder.ruleList.title': 'Regras',
6827
- 'praxis.visualBuilder.ruleList.subtitle': 'Visibilidade, estilo e comportamento em um fluxo único.',
6870
+ 'praxis.visualBuilder.ruleList.subtitle': 'Visibilidade, estilo e comportamento em um fluxo único.',
6828
6871
  'praxis.visualBuilder.ruleList.headerCaption': 'ativas',
6829
6872
  'praxis.visualBuilder.ruleList.searchPlaceholder': 'Buscar regras...',
6830
6873
  'praxis.visualBuilder.ruleList.clearSearch': 'Limpar busca',
@@ -6833,11 +6876,11 @@ const PRAXIS_VISUAL_BUILDER_PT_BR = {
6833
6876
  'praxis.visualBuilder.ruleList.aiButton': 'IA',
6834
6877
  'praxis.visualBuilder.ruleList.listAria': 'Lista de regras',
6835
6878
  'praxis.visualBuilder.ruleList.status.ready': 'Pronta',
6836
- 'praxis.visualBuilder.ruleList.status.valid': 'Válida',
6879
+ 'praxis.visualBuilder.ruleList.status.valid': 'Válida',
6837
6880
  'praxis.visualBuilder.ruleList.status.incomplete': 'Incompleta',
6838
6881
  'praxis.visualBuilder.ruleList.status.draft': 'Rascunho',
6839
6882
  'praxis.visualBuilder.ruleList.status.error': 'Com erro',
6840
- 'praxis.visualBuilder.ruleList.summary.validLabel': 'Válidas',
6883
+ 'praxis.visualBuilder.ruleList.summary.validLabel': 'Válidas',
6841
6884
  'praxis.visualBuilder.ruleList.summary.incompleteLabel': 'Pendentes',
6842
6885
  'praxis.visualBuilder.ruleList.summary.errorLabel': 'Com erro',
6843
6886
  'praxis.visualBuilder.ruleList.filter.all': 'Todas',
@@ -6848,12 +6891,12 @@ const PRAXIS_VISUAL_BUILDER_PT_BR = {
6848
6891
  'praxis.visualBuilder.ruleList.noResults': 'Nenhuma regra encontrada.',
6849
6892
  'praxis.visualBuilder.ruleList.condition.with': 'Condicional',
6850
6893
  'praxis.visualBuilder.ruleList.condition.without': 'Sempre',
6851
- 'praxis.visualBuilder.ruleList.condition.configured': 'Expressão configurada',
6894
+ 'praxis.visualBuilder.ruleList.condition.configured': 'Expressão configurada',
6852
6895
  'praxis.visualBuilder.ruleList.targetType.fieldPlural': 'campos',
6853
- 'praxis.visualBuilder.ruleList.targetType.sectionPlural': 'seções',
6896
+ 'praxis.visualBuilder.ruleList.targetType.sectionPlural': 'seções',
6854
6897
  'praxis.visualBuilder.ruleList.targetType.rowPlural': 'linhas',
6855
6898
  'praxis.visualBuilder.ruleList.targetType.columnPlural': 'colunas',
6856
- 'praxis.visualBuilder.ruleList.targetType.actionPlural': 'ações',
6899
+ 'praxis.visualBuilder.ruleList.targetType.actionPlural': 'ações',
6857
6900
  'praxis.visualBuilder.ruleList.targetType.visualBlockPlural': 'blocos visuais',
6858
6901
  'praxis.visualBuilder.ruleList.target.none': 'Nenhum alvo',
6859
6902
  'praxis.visualBuilder.ruleList.summary.when': 'Quando',
@@ -6873,98 +6916,98 @@ const PRAXIS_VISUAL_BUILDER_PT_BR = {
6873
6916
  'praxis.visualBuilder.ruleList.summary.draft': 'Comece escolhendo um alvo e definindo o efeito principal.',
6874
6917
  'praxis.visualBuilder.ruleList.summary.error': 'A regra precisa de ajuste antes de ser publicada.',
6875
6918
  'praxis.visualBuilder.ruleList.insight.target': 'Alvo principal',
6876
- 'praxis.visualBuilder.ruleList.insight.condition': 'Condição',
6919
+ 'praxis.visualBuilder.ruleList.insight.condition': 'Condição',
6877
6920
  'praxis.visualBuilder.ruleList.insight.effect': 'Efeito',
6878
6921
  'praxis.visualBuilder.ruleList.effect.pending': 'Sem efeito',
6879
6922
  'praxis.visualBuilder.ruleList.effect.whenFalse': 'quando falso',
6880
6923
  'praxis.visualBuilder.ruleList.effect.visibleOn': 'mostrar',
6881
6924
  'praxis.visualBuilder.ruleList.effect.visibleOff': 'ocultar',
6882
- 'praxis.visualBuilder.ruleList.effect.requiredOn': 'tornar obrigatório',
6925
+ 'praxis.visualBuilder.ruleList.effect.requiredOn': 'tornar obrigatório',
6883
6926
  'praxis.visualBuilder.ruleList.effect.requiredOff': 'tornar opcional',
6884
6927
  'praxis.visualBuilder.ruleList.effect.disabledOn': 'desabilitar',
6885
6928
  'praxis.visualBuilder.ruleList.effect.disabledOff': 'habilitar',
6886
6929
  'praxis.visualBuilder.ruleList.effect.set': 'definir',
6887
6930
  'praxis.visualBuilder.ruleList.time.now': 'Agora',
6888
- 'praxis.visualBuilder.ruleList.time.minute': 'min atrás',
6889
- 'praxis.visualBuilder.ruleList.time.minutes': 'min atrás',
6890
- 'praxis.visualBuilder.ruleList.time.hour': 'h atrás',
6891
- 'praxis.visualBuilder.ruleList.time.hours': 'h atrás',
6892
- 'praxis.visualBuilder.ruleList.time.day': 'dia atrás',
6893
- 'praxis.visualBuilder.ruleList.time.days': 'dias atrás',
6931
+ 'praxis.visualBuilder.ruleList.time.minute': 'min atrás',
6932
+ 'praxis.visualBuilder.ruleList.time.minutes': 'min atrás',
6933
+ 'praxis.visualBuilder.ruleList.time.hour': 'h atrás',
6934
+ 'praxis.visualBuilder.ruleList.time.hours': 'h atrás',
6935
+ 'praxis.visualBuilder.ruleList.time.day': 'dia atrás',
6936
+ 'praxis.visualBuilder.ruleList.time.days': 'dias atrás',
6894
6937
  'praxis.visualBuilder.target.title': 'Alvos',
6895
6938
  'praxis.visualBuilder.target.subtitle': 'Onde aplicar a regra',
6896
6939
  'praxis.visualBuilder.target.description': 'Escolha um tipo de alvo e selecione os itens que a regra vai afetar.',
6897
6940
  'praxis.visualBuilder.target.heroTitle': 'Selecione os alvos da regra',
6898
- 'praxis.visualBuilder.target.heroDescription': 'Defina onde esta regra será aplicada: campos, seções, linhas, colunas ou ações do formulário.',
6899
- 'praxis.visualBuilder.target.heroHint': 'Escolha um tipo de alvo e selecione os elementos específicos do formulário.',
6941
+ 'praxis.visualBuilder.target.heroDescription': 'Defina onde esta regra será aplicada: campos, seções, linhas, colunas ou ações do formulário.',
6942
+ 'praxis.visualBuilder.target.heroHint': 'Escolha um tipo de alvo e selecione os elementos específicos do formulário.',
6900
6943
  'praxis.visualBuilder.target.selectTitle': 'Selecionar alvos',
6901
- 'praxis.visualBuilder.target.searchPlaceholder': 'Filtrar por rótulo ou ID interno...',
6944
+ 'praxis.visualBuilder.target.searchPlaceholder': 'Filtrar por rótulo ou ID interno...',
6902
6945
  'praxis.visualBuilder.target.searchClear': 'Limpar busca',
6903
6946
  'praxis.visualBuilder.target.noResults': 'Nenhum alvo encontrado.',
6904
6947
  'praxis.visualBuilder.target.selectedLabel': 'Alvos selecionados',
6905
6948
  'praxis.visualBuilder.target.selectedSummary': 'selecionados',
6906
- 'praxis.visualBuilder.target.stats.available': 'disponíveis',
6949
+ 'praxis.visualBuilder.target.stats.available': 'disponíveis',
6907
6950
  'praxis.visualBuilder.target.stats.selected': 'selecionados',
6908
- 'praxis.visualBuilder.target.group.availableSingular': 'disponível',
6909
- 'praxis.visualBuilder.target.group.availablePlural': 'disponíveis',
6951
+ 'praxis.visualBuilder.target.group.availableSingular': 'disponível',
6952
+ 'praxis.visualBuilder.target.group.availablePlural': 'disponíveis',
6910
6953
  'praxis.visualBuilder.target.group.fields': 'Campos',
6911
6954
  'praxis.visualBuilder.target.meta.internalId': 'ID interno',
6912
- 'praxis.visualBuilder.target.meta.scope': 'do formulário',
6955
+ 'praxis.visualBuilder.target.meta.scope': 'do formulário',
6913
6956
  'praxis.visualBuilder.target.type.field.label': 'Campo',
6914
6957
  'praxis.visualBuilder.target.type.field.labelPlural': 'Campos',
6915
- 'praxis.visualBuilder.target.type.field.description': 'Campos específicos.',
6916
- 'praxis.visualBuilder.target.type.section.label': 'Seção',
6917
- 'praxis.visualBuilder.target.type.section.labelPlural': 'Seções',
6918
- 'praxis.visualBuilder.target.type.section.description': 'Seção inteira.',
6958
+ 'praxis.visualBuilder.target.type.field.description': 'Campos específicos.',
6959
+ 'praxis.visualBuilder.target.type.section.label': 'Seção',
6960
+ 'praxis.visualBuilder.target.type.section.labelPlural': 'Seções',
6961
+ 'praxis.visualBuilder.target.type.section.description': 'Seção inteira.',
6919
6962
  'praxis.visualBuilder.target.type.row.label': 'Linha',
6920
6963
  'praxis.visualBuilder.target.type.row.labelPlural': 'Linhas',
6921
6964
  'praxis.visualBuilder.target.type.row.description': 'Linha do layout.',
6922
6965
  'praxis.visualBuilder.target.type.column.label': 'Coluna',
6923
6966
  'praxis.visualBuilder.target.type.column.labelPlural': 'Colunas',
6924
6967
  'praxis.visualBuilder.target.type.column.description': 'Coluna do layout.',
6925
- 'praxis.visualBuilder.target.type.action.label': 'Ação',
6926
- 'praxis.visualBuilder.target.type.action.labelPlural': 'Ações',
6927
- 'praxis.visualBuilder.target.type.action.description': 'Botões de ação.',
6968
+ 'praxis.visualBuilder.target.type.action.label': 'Ação',
6969
+ 'praxis.visualBuilder.target.type.action.labelPlural': 'Ações',
6970
+ 'praxis.visualBuilder.target.type.action.description': 'Botões de ação.',
6928
6971
  'praxis.visualBuilder.target.type.visualBlock.label': 'Bloco visual',
6929
6972
  'praxis.visualBuilder.target.type.visualBlock.labelPlural': 'Blocos visuais',
6930
6973
  'praxis.visualBuilder.target.type.visualBlock.description': 'Bloco editorial no layout.',
6931
6974
  'praxis.visualBuilder.target.type.allPlural': 'Alvos',
6932
6975
  'praxis.visualBuilder.ruleDefinition.step1.title': 'Alvos',
6933
6976
  'praxis.visualBuilder.ruleDefinition.step1.subtitle': 'Onde aplicar',
6934
- 'praxis.visualBuilder.ruleDefinition.step1.question': 'Escolha onde essa regra entra em ação.',
6935
- 'praxis.visualBuilder.ruleDefinition.step2.title': 'Condição',
6977
+ 'praxis.visualBuilder.ruleDefinition.step1.question': 'Escolha onde essa regra entra em ação.',
6978
+ 'praxis.visualBuilder.ruleDefinition.step2.title': 'Condição',
6936
6979
  'praxis.visualBuilder.ruleDefinition.step2.subtitle': 'Quando executar',
6937
6980
  'praxis.visualBuilder.ruleDefinition.step2.question': 'Quando a regra deve ser aplicada?',
6938
6981
  'praxis.visualBuilder.ruleDefinition.step3.title': 'Efeitos',
6939
6982
  'praxis.visualBuilder.ruleDefinition.step3.subtitle': 'O que fazer',
6940
- 'praxis.visualBuilder.ruleDefinition.step3.question': 'O que deve acontecer quando a condição for satisfeita?',
6941
- 'praxis.visualBuilder.ruleDefinition.step4.title': 'Revisão',
6983
+ 'praxis.visualBuilder.ruleDefinition.step3.question': 'O que deve acontecer quando a condição for satisfeita?',
6984
+ 'praxis.visualBuilder.ruleDefinition.step4.title': 'Revisão',
6942
6985
  'praxis.visualBuilder.ruleDefinition.step4.subtitle': 'Confirmar regra',
6943
6986
  'praxis.visualBuilder.ruleDefinition.step4.question': 'Revise e confirme a regra',
6944
- 'praxis.visualBuilder.ruleDefinition.action.next': 'Próximo',
6987
+ 'praxis.visualBuilder.ruleDefinition.action.next': 'Próximo',
6945
6988
  'praxis.visualBuilder.ruleDefinition.action.previous': 'Anterior',
6946
6989
  'praxis.visualBuilder.ruleDefinition.action.cancel': 'Cancelar',
6947
6990
  'praxis.visualBuilder.ruleDefinition.action.reset': 'Resetar',
6948
6991
  'praxis.visualBuilder.ruleDefinition.action.save': 'Salvar regra',
6949
6992
  'praxis.visualBuilder.ruleDefinition.conditionMode.always': 'Sempre',
6950
6993
  'praxis.visualBuilder.ruleDefinition.conditionMode.visual': 'Visual',
6951
- 'praxis.visualBuilder.ruleDefinition.conditionWarning.tooltip': 'Altere o alvo ou ajuste os campos da condição para este contexto.',
6994
+ 'praxis.visualBuilder.ruleDefinition.conditionWarning.tooltip': 'Altere o alvo ou ajuste os campos da condição para este contexto.',
6952
6995
  'praxis.visualBuilder.ruleDefinition.conditionWarning.prefix': 'Campos fora do contexto atual',
6953
- 'praxis.visualBuilder.ruleDefinition.conditionWarning.suffix': 'Eles serão ignorados até você escolher campos compatíveis.',
6954
- 'praxis.visualBuilder.ruleDefinition.condition.alwaysHint': 'A regra será aplicada sempre.',
6996
+ 'praxis.visualBuilder.ruleDefinition.conditionWarning.suffix': 'Eles serão ignorados até você escolher campos compatíveis.',
6997
+ 'praxis.visualBuilder.ruleDefinition.condition.alwaysHint': 'A regra será aplicada sempre.',
6955
6998
  'praxis.visualBuilder.ruleDefinition.review.targets': 'Alvos selecionados',
6956
6999
  'praxis.visualBuilder.ruleDefinition.review.heroTitle': 'Resumo da regra',
6957
7000
  'praxis.visualBuilder.ruleDefinition.review.noTargets': 'Nenhum alvo selecionado.',
6958
- 'praxis.visualBuilder.ruleDefinition.review.condition': 'Condição',
7001
+ 'praxis.visualBuilder.ruleDefinition.review.condition': 'Condição',
6959
7002
  'praxis.visualBuilder.ruleDefinition.review.mode': 'Modo',
6960
- 'praxis.visualBuilder.ruleDefinition.review.alwaysMode': 'Sempre (sem condição)',
7003
+ 'praxis.visualBuilder.ruleDefinition.review.alwaysMode': 'Sempre (sem condição)',
6961
7004
  'praxis.visualBuilder.ruleDefinition.review.effects': 'Efeitos',
6962
7005
  'praxis.visualBuilder.ruleDefinition.review.whenFalse': 'Quando falso',
6963
- 'praxis.visualBuilder.ruleDefinition.review.whenFalseNone': 'Sem ação adicional',
6964
- 'praxis.visualBuilder.ruleDefinition.review.technical': 'Detalhes técnicos',
6965
- 'praxis.visualBuilder.ruleDefinition.review.conditionJson': 'JSON da condição',
6966
- 'praxis.visualBuilder.ruleDefinition.review.summary.always': 'sempre que o formulário estiver neste contexto',
6967
- 'praxis.visualBuilder.ruleDefinition.review.summary.conditional': 'quando a condição configurada for satisfeita',
7006
+ 'praxis.visualBuilder.ruleDefinition.review.whenFalseNone': 'Sem ação adicional',
7007
+ 'praxis.visualBuilder.ruleDefinition.review.technical': 'Detalhes técnicos',
7008
+ 'praxis.visualBuilder.ruleDefinition.review.conditionJson': 'JSON da condição',
7009
+ 'praxis.visualBuilder.ruleDefinition.review.summary.always': 'sempre que o formulário estiver neste contexto',
7010
+ 'praxis.visualBuilder.ruleDefinition.review.summary.conditional': 'quando a condição configurada for satisfeita',
6968
7011
  'praxis.visualBuilder.ruleDefinition.review.json': 'JSON da regra',
6969
7012
  'praxis.visualBuilder.ruleDefinition.review.effects.noneEditorial': 'Nenhum efeito principal definido',
6970
7013
  'praxis.visualBuilder.ruleDefinition.conditionDescription.always': 'Sempre',
@@ -6974,14 +7017,14 @@ const PRAXIS_VISUAL_BUILDER_PT_BR = {
6974
7017
  'praxis.visualBuilder.ruleDefinition.effects.trueCount': 'efeito(s) verdadeiro(s)',
6975
7018
  'praxis.visualBuilder.ruleDefinition.effects.falseCount': 'efeito(s) falso(s)',
6976
7019
  'praxis.visualBuilder.ruleDefinition.targetType.fieldPlural': 'Campos',
6977
- 'praxis.visualBuilder.ruleDefinition.targetType.sectionPlural': 'Seções',
7020
+ 'praxis.visualBuilder.ruleDefinition.targetType.sectionPlural': 'Seções',
6978
7021
  'praxis.visualBuilder.ruleDefinition.targetType.rowPlural': 'Linhas',
6979
7022
  'praxis.visualBuilder.ruleDefinition.targetType.columnPlural': 'Colunas',
6980
- 'praxis.visualBuilder.ruleDefinition.targetType.actionPlural': 'Ações',
7023
+ 'praxis.visualBuilder.ruleDefinition.targetType.actionPlural': 'Ações',
6981
7024
  'praxis.visualBuilder.ruleDefinition.targetType.visualBlockPlural': 'Blocos visuais',
6982
7025
  'praxis.visualBuilder.ruleDefinition.effect.visibleOn': 'Mostrar os elementos selecionados',
6983
7026
  'praxis.visualBuilder.ruleDefinition.effect.visibleOff': 'Ocultar os elementos selecionados',
6984
- 'praxis.visualBuilder.ruleDefinition.effect.requiredOn': 'Tornar os campos obrigatórios',
7027
+ 'praxis.visualBuilder.ruleDefinition.effect.requiredOn': 'Tornar os campos obrigatórios',
6985
7028
  'praxis.visualBuilder.ruleDefinition.effect.requiredOff': 'Tornar os campos opcionais',
6986
7029
  'praxis.visualBuilder.ruleDefinition.effect.disabledOn': 'Desabilitar os elementos selecionados',
6987
7030
  'praxis.visualBuilder.ruleDefinition.effect.disabledOff': 'Habilitar os elementos selecionados',
@@ -6991,11 +7034,11 @@ const PRAXIS_VISUAL_BUILDER_PT_BR = {
6991
7034
  'praxis.visualBuilder.ruleEditor.shell.breadcrumb': 'Editor de regras',
6992
7035
  'praxis.visualBuilder.ruleEditor.shell.nav.layout': 'Layout',
6993
7036
  'praxis.visualBuilder.ruleEditor.shell.nav.rules': 'Regras',
6994
- 'praxis.visualBuilder.ruleEditor.shell.nav.docs': 'Documentação',
6995
- 'praxis.visualBuilder.ruleEditor.shell.unsaved': 'Alterações não salvas',
7037
+ 'praxis.visualBuilder.ruleEditor.shell.nav.docs': 'Documentação',
7038
+ 'praxis.visualBuilder.ruleEditor.shell.unsaved': 'Alterações não salvas',
6996
7039
  'praxis.visualBuilder.ruleEditor.toolbar.collapseList': 'Recolher painel lateral',
6997
7040
  'praxis.visualBuilder.ruleEditor.toolbar.expandList': 'Expandir painel lateral',
6998
- 'praxis.visualBuilder.ruleEditor.toolbar.aiTooltip': 'Descreva sua regra e a IA monta o rascunho para você',
7041
+ 'praxis.visualBuilder.ruleEditor.toolbar.aiTooltip': 'Descreva sua regra e a IA monta o rascunho para você',
6999
7042
  'praxis.visualBuilder.ruleEditor.toolbar.newRule': 'Nova regra',
7000
7043
  'praxis.visualBuilder.ruleEditor.toolbar.aiButton': 'Criar com IA',
7001
7044
  'praxis.visualBuilder.ruleEditor.toolbar.undo': 'Desfazer',
@@ -7004,11 +7047,11 @@ const PRAXIS_VISUAL_BUILDER_PT_BR = {
7004
7047
  'praxis.visualBuilder.ruleEditor.toolbar.export': 'Exportar',
7005
7048
  'praxis.visualBuilder.ruleEditor.toolbar.importTooltip': 'Importar regras',
7006
7049
  'praxis.visualBuilder.ruleEditor.toolbar.import': 'Importar',
7007
- 'praxis.visualBuilder.ruleEditor.toolbar.advanced': 'Mais opções',
7008
- 'praxis.visualBuilder.ruleEditor.toolbar.devOptions': 'Opções de desenvolvedor',
7050
+ 'praxis.visualBuilder.ruleEditor.toolbar.advanced': 'Mais opções',
7051
+ 'praxis.visualBuilder.ruleEditor.toolbar.devOptions': 'Opções de desenvolvedor',
7009
7052
  'praxis.visualBuilder.ruleEditor.hero.eyebrow': 'Builder visual',
7010
7053
  'praxis.visualBuilder.ruleEditor.hero.title': 'Construa regras com clareza visual',
7011
- 'praxis.visualBuilder.ruleEditor.hero.subtitle': 'Combine alvos, condições e efeitos em uma experiência guiada para usuários de negócio e usuários técnicos.',
7054
+ 'praxis.visualBuilder.ruleEditor.hero.subtitle': 'Combine alvos, condições e efeitos em uma experiência guiada para usuários de negócio e usuários técnicos.',
7012
7055
  'praxis.visualBuilder.ruleEditor.hero.progress': 'Progresso',
7013
7056
  'praxis.visualBuilder.ruleEditor.hero.progressOf': 'de',
7014
7057
  'praxis.visualBuilder.ruleEditor.hero.progressEmpty': '0 de 0',
@@ -7017,30 +7060,30 @@ const PRAXIS_VISUAL_BUILDER_PT_BR = {
7017
7060
  'praxis.visualBuilder.ruleEditor.hero.healthError': 'Revisar',
7018
7061
  'praxis.visualBuilder.ruleEditor.hero.healthProgress': 'Em progresso',
7019
7062
  'praxis.visualBuilder.ruleEditor.hero.healthIdle': 'Em branco',
7020
- 'praxis.visualBuilder.ruleEditor.hero.selectedFallback': 'Regra em edição',
7063
+ 'praxis.visualBuilder.ruleEditor.hero.selectedFallback': 'Regra em edição',
7021
7064
  'praxis.visualBuilder.ruleEditor.hero.targetCount': 'alvo(s)',
7022
7065
  'praxis.visualBuilder.ruleEditor.hero.conditional': 'condicional',
7023
7066
  'praxis.visualBuilder.ruleEditor.hero.always': 'sempre ativa',
7024
7067
  'praxis.visualBuilder.ruleEditor.hero.effectCount': 'efeito(s)',
7025
- 'praxis.visualBuilder.ruleEditor.debug.show': 'Mostrar painel de depuração (debug)',
7026
- 'praxis.visualBuilder.ruleEditor.debug.hide': 'Ocultar painel de depuração (debug)',
7068
+ 'praxis.visualBuilder.ruleEditor.debug.show': 'Mostrar painel de depuração (debug)',
7069
+ 'praxis.visualBuilder.ruleEditor.debug.hide': 'Ocultar painel de depuração (debug)',
7027
7070
  'praxis.visualBuilder.ruleEditor.debug.clearAll': 'Limpar tudo',
7028
- 'praxis.visualBuilder.ruleEditor.debug.title': 'Estado de depuração (debug)',
7029
- 'praxis.visualBuilder.ruleEditor.unsupported.title': 'Tipo de regra não suportado',
7030
- 'praxis.visualBuilder.ruleEditor.unsupported.body': 'Este nó usa um formato legado. Remova e recrie como regra de propriedade.',
7071
+ 'praxis.visualBuilder.ruleEditor.debug.title': 'Estado de depuração (debug)',
7072
+ 'praxis.visualBuilder.ruleEditor.unsupported.title': 'Tipo de regra não suportado',
7073
+ 'praxis.visualBuilder.ruleEditor.unsupported.body': 'Este usa um formato legado. Remova e recrie como regra de propriedade.',
7031
7074
  'praxis.visualBuilder.ruleEditor.empty.title': 'Selecione uma regra ou crie uma nova',
7032
- 'praxis.visualBuilder.ruleEditor.empty.body': 'Monte regras visuais com alvo, condição e efeito em uma trilha guiada.',
7075
+ 'praxis.visualBuilder.ruleEditor.empty.body': 'Monte regras visuais com alvo, condição e efeito em uma trilha guiada.',
7033
7076
  'praxis.visualBuilder.ruleEditor.empty.cta': 'Criar regra',
7034
7077
  'praxis.visualBuilder.ruleEditor.status.rules': 'Regras',
7035
- 'praxis.visualBuilder.ruleEditor.status.unsaved': 'Não salvo',
7078
+ 'praxis.visualBuilder.ruleEditor.status.unsaved': 'Não salvo',
7036
7079
  'praxis.visualBuilder.ruleEditor.status.errors': 'erro(s)',
7037
- 'praxis.visualBuilder.ruleEditor.status.valid': 'Válido',
7080
+ 'praxis.visualBuilder.ruleEditor.status.valid': 'Válido',
7038
7081
  'praxis.visualBuilder.ruleEditor.confirm.clearAll': 'Tem certeza que deseja apagar todas as regras?',
7039
7082
  'praxis.visualBuilder.ruleEditor.confirm.removeRule': 'Remover esta regra?',
7040
7083
  'praxis.visualBuilder.ruleEditor.action.close': 'Fechar',
7041
7084
  'praxis.visualBuilder.ruleEditor.actionLabel.show': 'Mostrar',
7042
7085
  'praxis.visualBuilder.ruleEditor.actionLabel.hide': 'Ocultar',
7043
- 'praxis.visualBuilder.ruleEditor.actionLabel.require': 'Tornar obrigatório',
7086
+ 'praxis.visualBuilder.ruleEditor.actionLabel.require': 'Tornar obrigatório',
7044
7087
  'praxis.visualBuilder.ruleEditor.actionLabel.optional': 'Tornar opcional',
7045
7088
  'praxis.visualBuilder.ruleEditor.actionLabel.disable': 'Desabilitar',
7046
7089
  'praxis.visualBuilder.ruleEditor.actionLabel.enable': 'Habilitar',
@@ -7048,12 +7091,12 @@ const PRAXIS_VISUAL_BUILDER_PT_BR = {
7048
7091
  'praxis.visualBuilder.ruleEditor.label.ruleFor': 'Regra para',
7049
7092
  'praxis.visualBuilder.ruleEditor.label.targets': 'alvo(s)',
7050
7093
  'praxis.visualBuilder.ruleEditor.label.newWithoutTargets': 'Nova regra sem alvos',
7051
- 'praxis.visualBuilder.ruleEditor.label.withCondition': 'com condição',
7052
- 'praxis.visualBuilder.ruleEditor.validation.found': 'erro(s) de validação encontrado(s)',
7094
+ 'praxis.visualBuilder.ruleEditor.label.withCondition': 'com condição',
7095
+ 'praxis.visualBuilder.ruleEditor.validation.found': 'erro(s) de validação encontrado(s)',
7053
7096
  'praxis.visualBuilder.ruleEditor.validation.view': 'Ver',
7054
7097
  'praxis.visualBuilder.ruleEditor.newRule': 'Nova regra',
7055
- 'praxis.visualBuilder.ruleEditor.duplicateCopy': 'cópia',
7056
- 'praxis.visualBuilder.ruleEditor.import.success': 'Importação concluída',
7098
+ 'praxis.visualBuilder.ruleEditor.duplicateCopy': 'cópia',
7099
+ 'praxis.visualBuilder.ruleEditor.import.success': 'Importação concluída',
7057
7100
  'praxis.visualBuilder.ruleEditor.import.failure': 'Falha ao importar regras',
7058
7101
  'praxis.visualBuilder.ruleEditor.ai.applyError': 'Erro ao aplicar regra',
7059
7102
  'praxis.visualBuilder.ruleEditor.ai.draftPrefix': 'IA',
@@ -12126,6 +12169,7 @@ class RuleDefinitionComponent {
12126
12169
  <button
12127
12170
  mat-stroked-button
12128
12171
  type="button"
12172
+ data-testid="rule-definition-previous"
12129
12173
  (click)="goPrevious()"
12130
12174
  [disabled]="selectedStepIndex === 0"
12131
12175
  >
@@ -12135,6 +12179,7 @@ class RuleDefinitionComponent {
12135
12179
  mat-flat-button
12136
12180
  color="primary"
12137
12181
  type="button"
12182
+ [attr.data-testid]="selectedStepIndex === 3 ? 'rule-definition-save' : 'rule-definition-next'"
12138
12183
  (click)="goNext()"
12139
12184
  [disabled]="!canAdvance()"
12140
12185
  >
@@ -12428,6 +12473,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
12428
12473
  <button
12429
12474
  mat-stroked-button
12430
12475
  type="button"
12476
+ data-testid="rule-definition-previous"
12431
12477
  (click)="goPrevious()"
12432
12478
  [disabled]="selectedStepIndex === 0"
12433
12479
  >
@@ -12437,6 +12483,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
12437
12483
  mat-flat-button
12438
12484
  color="primary"
12439
12485
  type="button"
12486
+ [attr.data-testid]="selectedStepIndex === 3 ? 'rule-definition-save' : 'rule-definition-next'"
12440
12487
  (click)="goNext()"
12441
12488
  [disabled]="!canAdvance()"
12442
12489
  >
@@ -13744,7 +13791,7 @@ class RuleEditorComponent {
13744
13791
  (change)="onFileSelected($event)"
13745
13792
  />
13746
13793
  </div>
13747
- `, isInline: true, styles: [".rule-editor-container{--_pvb-editor-accent: var(--md-sys-color-primary, var(--sicoob-primary-default));--_pvb-editor-accent-soft: color-mix(in srgb, var(--_pvb-editor-accent) 16%, transparent);--_pvb-editor-surface: var(--md-sys-color-surface, var(--sicoob-background-primary));--_pvb-editor-surface-low: var(--md-sys-color-surface-container-low, var(--sicoob-background-secondary));--_pvb-editor-surface-strong: var(--md-sys-color-surface-container, var(--sicoob-background-tertiary));--_pvb-editor-border: var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));--_pvb-editor-text: var(--md-sys-color-on-surface, var(--sicoob-text-default));--_pvb-editor-text-soft: var(--md-sys-color-on-surface-variant, var(--sicoob-text-subtle));display:flex;flex-direction:column;height:100%;background:radial-gradient(circle at top center,color-mix(in srgb,var(--_pvb-editor-accent) 12%,transparent) 0%,transparent 32%),linear-gradient(180deg,color-mix(in srgb,var(--_pvb-editor-surface-low) 96%,black 4%),color-mix(in srgb,var(--_pvb-editor-surface) 98%,black 2%));overflow:hidden;position:relative;color:var(--_pvb-editor-text)}.rule-editor-container.embedded{height:100%}.condition-only-editor{display:flex;flex-direction:column;height:100%;min-height:360px;overflow:hidden}.condition-only-header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 16px;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 68%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 94%,black 6%)}.condition-only-header h3{margin:0;font-size:16px;font-weight:600}.condition-only-header p{margin:4px 0 0;font-size:12px;color:var(--_pvb-editor-text-soft)}.condition-only-canvas{flex:1;min-height:0}.builder-shell-header{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:54px;padding:0 18px;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 68%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 94%,black 6%);flex-shrink:0}.shell-brand{display:flex;align-items:center;gap:10px;min-width:0}.shell-menu{margin-right:2px}.brand-mark{width:32px;height:32px;border-radius:10px;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--_pvb-editor-accent) 16%,transparent);border:1px solid color-mix(in srgb,var(--_pvb-editor-accent) 24%,transparent)}.brand-mark mat-icon{display:flex;align-items:center;justify-content:center;font-size:18px;width:18px;height:18px;color:var(--_pvb-editor-accent)}.brand-copy{display:flex;flex-direction:column;gap:2px;min-width:0}.brand-title{font-size:14px;font-weight:700}.brand-breadcrumb{font-size:12px;color:var(--_pvb-editor-text-soft)}.shell-nav{display:inline-flex;align-items:center;gap:10px;padding:4px;border-radius:14px;background:color-mix(in srgb,var(--_pvb-editor-surface-low) 94%,black 6%);border:1px solid color-mix(in srgb,var(--_pvb-editor-border) 56%,transparent)}.nav-pill{min-width:96px;height:34px;border:0;border-radius:10px;background:transparent;color:var(--_pvb-editor-text-soft);font:inherit;font-size:13px;cursor:default}.nav-pill.active{color:var(--_pvb-editor-text);background:color-mix(in srgb,var(--_pvb-editor-accent) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_pvb-editor-accent) 34%,transparent)}.shell-status{display:flex;align-items:center;gap:6px}.unsaved-indicator{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--_pvb-editor-text);margin-right:6px}.unsaved-dot{width:8px;height:8px;border-radius:999px;background:#f0b429;box-shadow:0 0 12px #f0b42973}.builder-shell-header button[mat-icon-button]{width:36px;height:36px;line-height:36px;padding:8px}.builder-shell-header button[mat-icon-button] mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-content-grid{display:grid;grid-template-columns:360px 1fr;flex:1;overflow:hidden;min-height:0;transition:grid-template-columns .2s ease}.editor-content-grid.list-closed{grid-template-columns:0 1fr}.rule-list-panel{border-right:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-low) 94%,black 6%);display:flex;flex-direction:column;overflow:hidden}.rule-definition-panel{background:radial-gradient(circle at 50% 0%,color-mix(in srgb,var(--_pvb-editor-accent) 8%,transparent) 0%,transparent 26%),transparent;overflow:hidden;display:flex;flex-direction:column;position:relative;min-height:0;flex:1}.empty-state,.unsupported-node{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--_pvb-editor-text-soft);gap:16px;text-align:center;padding:32px}.empty-state mat-icon,.unsupported-node mat-icon{font-size:64px;width:64px;height:64px;opacity:.9;color:var(--_pvb-editor-accent)}.status-bar{height:32px;background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 92%,black 8%);border-top:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent);display:flex;align-items:center;justify-content:space-between;padding:0 16px;font-size:12px;color:var(--_pvb-editor-text-soft);flex-shrink:0}.status-left,.status-center{display:flex;align-items:center;gap:8px}.validation-status{display:flex;align-items:center;gap:4px}.validation-status.error{color:var(--md-sys-color-error)}.validation-status.success{color:var(--md-sys-color-tertiary)}.validation-status mat-icon{font-size:16px;width:16px;height:16px}.debug-panel{position:absolute;top:0;right:0;bottom:0;width:400px;background:var(--_pvb-editor-surface);border-left:1px solid var(--_pvb-editor-border);box-shadow:-2px 0 8px #0000001a;z-index:var(--praxis-layer-authoring-toolbar, 340);display:flex;flex-direction:column}.debug-header{padding:8px 16px;border-bottom:1px solid var(--_pvb-editor-border);display:flex;align-items:center;justify-content:space-between;background:var(--_pvb-editor-surface-strong)}.debug-content{flex:1;overflow:auto;padding:16px;font-family:monospace;font-size:12px}@media(max-width:1180px){.builder-shell-header{flex-wrap:wrap;justify-content:flex-start;padding:10px 14px}.shell-nav{order:3;width:100%;justify-content:center}.shell-status{margin-left:auto}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5.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: i5.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatSnackBarModule }, { 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: MatBadgeModule }, { kind: "directive", type: i10$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i7$2.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: i7$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: RuleListComponent, selector: "praxis-rule-list", inputs: ["rules", "selectedRuleId", "nodeMap", "validationErrors"], outputs: ["ruleSelected", "ruleDeleted", "ruleDuplicated", "ruleAdded", "aiRequested"] }, { kind: "component", type: RuleDefinitionComponent, selector: "praxis-rule-definition", inputs: ["ruleNode", "fieldSchemas", "targetSchemas", "propertySchema"], outputs: ["ruleChanged"] }, { kind: "component", type: RuleCanvasComponent, selector: "praxis-rule-canvas", inputs: ["conditionOnly", "state", "fieldSchemas", "validationErrors"], outputs: ["nodeSelected", "nodeAdded", "nodeUpdated", "nodeRemoved"] }, { kind: "pipe", type: i12$1.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13794
+ `, isInline: true, styles: [".rule-editor-container{--_pvb-editor-accent: var(--md-sys-color-primary, var(--sicoob-primary-default));--_pvb-editor-accent-soft: color-mix(in srgb, var(--_pvb-editor-accent) 16%, transparent);--_pvb-editor-surface: var(--md-sys-color-surface, var(--sicoob-background-primary));--_pvb-editor-surface-low: var(--md-sys-color-surface-container-low, var(--sicoob-background-secondary));--_pvb-editor-surface-strong: var(--md-sys-color-surface-container, var(--sicoob-background-tertiary));--_pvb-editor-border: var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));--_pvb-editor-text: var(--md-sys-color-on-surface, var(--sicoob-text-default));--_pvb-editor-text-soft: var(--md-sys-color-on-surface-variant, var(--sicoob-text-subtle));display:flex;flex-direction:column;height:100%;background:radial-gradient(circle at top center,color-mix(in srgb,var(--_pvb-editor-accent) 12%,transparent) 0%,transparent 32%),linear-gradient(180deg,color-mix(in srgb,var(--_pvb-editor-surface-low) 96%,black 4%),color-mix(in srgb,var(--_pvb-editor-surface) 98%,black 2%));overflow:hidden;position:relative;color:var(--_pvb-editor-text)}.rule-editor-container.embedded{height:100%}.condition-only-editor{display:flex;flex-direction:column;height:100%;min-height:360px;overflow:hidden}.condition-only-header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 16px;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 68%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 94%,black 6%)}.condition-only-header h3{margin:0;font-size:16px;font-weight:600}.condition-only-header p{margin:4px 0 0;font-size:12px;color:var(--_pvb-editor-text-soft)}.condition-only-canvas{flex:1;min-height:0}.builder-shell-header{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:54px;padding:0 18px;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 68%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 94%,black 6%);flex-shrink:0}.shell-brand{display:flex;align-items:center;gap:10px;min-width:0}.shell-menu{margin-right:2px}.brand-mark{width:32px;height:32px;border-radius:10px;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--_pvb-editor-accent) 16%,transparent);border:1px solid color-mix(in srgb,var(--_pvb-editor-accent) 24%,transparent)}.brand-mark mat-icon{display:flex;align-items:center;justify-content:center;font-size:18px;width:18px;height:18px;color:var(--_pvb-editor-accent)}.brand-copy{display:flex;flex-direction:column;gap:2px;min-width:0}.brand-title{font-size:14px;font-weight:700}.brand-breadcrumb{font-size:12px;color:var(--_pvb-editor-text-soft)}.shell-nav{display:inline-flex;align-items:center;gap:10px;padding:4px;border-radius:14px;background:color-mix(in srgb,var(--_pvb-editor-surface-low) 94%,black 6%);border:1px solid color-mix(in srgb,var(--_pvb-editor-border) 56%,transparent)}.nav-pill{min-width:96px;height:34px;border:0;border-radius:10px;background:transparent;color:var(--_pvb-editor-text-soft);font:inherit;font-size:13px;cursor:default}.nav-pill.active{color:var(--_pvb-editor-text);background:color-mix(in srgb,var(--_pvb-editor-accent) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_pvb-editor-accent) 34%,transparent)}.shell-status{display:flex;align-items:center;gap:6px}.unsaved-indicator{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--_pvb-editor-text);margin-right:6px}.unsaved-dot{width:8px;height:8px;border-radius:999px;background:#f0b429;box-shadow:0 0 12px #f0b42973}.builder-shell-header button[mat-icon-button]{width:36px;height:36px;line-height:36px;padding:8px}.builder-shell-header button[mat-icon-button] mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-content-grid{display:grid;grid-template-columns:360px 1fr;flex:1;overflow:hidden;min-height:0;min-width:0;transition:grid-template-columns .2s ease}.editor-content-grid.list-closed{grid-template-columns:0 1fr}.rule-list-panel{border-right:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-low) 94%,black 6%);display:flex;flex-direction:column;overflow:hidden;min-width:0}.rule-definition-panel{background:radial-gradient(circle at 50% 0%,color-mix(in srgb,var(--_pvb-editor-accent) 8%,transparent) 0%,transparent 26%),transparent;overflow:hidden;display:flex;flex-direction:column;position:relative;min-height:0;min-width:0;flex:1}.empty-state,.unsupported-node{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--_pvb-editor-text-soft);gap:16px;text-align:center;padding:32px}.empty-state mat-icon,.unsupported-node mat-icon{font-size:64px;width:64px;height:64px;opacity:.9;color:var(--_pvb-editor-accent)}.status-bar{height:32px;background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 92%,black 8%);border-top:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent);display:flex;align-items:center;justify-content:space-between;padding:0 16px;font-size:12px;color:var(--_pvb-editor-text-soft);flex-shrink:0}.status-left,.status-center{display:flex;align-items:center;gap:8px}.validation-status{display:flex;align-items:center;gap:4px}.validation-status.error{color:var(--md-sys-color-error)}.validation-status.success{color:var(--md-sys-color-tertiary)}.validation-status mat-icon{font-size:16px;width:16px;height:16px}.debug-panel{position:absolute;top:0;right:0;bottom:0;width:400px;background:var(--_pvb-editor-surface);border-left:1px solid var(--_pvb-editor-border);box-shadow:-2px 0 8px #0000001a;z-index:var(--praxis-layer-authoring-toolbar, 340);display:flex;flex-direction:column}.debug-header{padding:8px 16px;border-bottom:1px solid var(--_pvb-editor-border);display:flex;align-items:center;justify-content:space-between;background:var(--_pvb-editor-surface-strong)}.debug-content{flex:1;overflow:auto;padding:16px;font-family:monospace;font-size:12px}@media(max-width:1180px){.builder-shell-header{flex-wrap:wrap;justify-content:flex-start;padding:10px 14px}.shell-nav{order:3;width:100%;justify-content:center}.shell-status{margin-left:auto}}@media(max-width:720px){.editor-content-grid,.editor-content-grid.list-closed{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(360px,1fr);overflow-y:auto}.rule-list-panel{max-height:min(360px,48vh);border-right:0;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent)}.rule-definition-panel{min-height:360px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5.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: i5.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatSnackBarModule }, { 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: MatBadgeModule }, { kind: "directive", type: i10$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i7$2.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: i7$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: RuleListComponent, selector: "praxis-rule-list", inputs: ["rules", "selectedRuleId", "nodeMap", "validationErrors"], outputs: ["ruleSelected", "ruleDeleted", "ruleDuplicated", "ruleAdded", "aiRequested"] }, { kind: "component", type: RuleDefinitionComponent, selector: "praxis-rule-definition", inputs: ["ruleNode", "fieldSchemas", "targetSchemas", "propertySchema"], outputs: ["ruleChanged"] }, { kind: "component", type: RuleCanvasComponent, selector: "praxis-rule-canvas", inputs: ["conditionOnly", "state", "fieldSchemas", "validationErrors"], outputs: ["nodeSelected", "nodeAdded", "nodeUpdated", "nodeRemoved"] }, { kind: "pipe", type: i12$1.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13748
13795
  }
13749
13796
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: RuleEditorComponent, decorators: [{
13750
13797
  type: Component,
@@ -13972,7 +14019,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
13972
14019
  (change)="onFileSelected($event)"
13973
14020
  />
13974
14021
  </div>
13975
- `, styles: [".rule-editor-container{--_pvb-editor-accent: var(--md-sys-color-primary, var(--sicoob-primary-default));--_pvb-editor-accent-soft: color-mix(in srgb, var(--_pvb-editor-accent) 16%, transparent);--_pvb-editor-surface: var(--md-sys-color-surface, var(--sicoob-background-primary));--_pvb-editor-surface-low: var(--md-sys-color-surface-container-low, var(--sicoob-background-secondary));--_pvb-editor-surface-strong: var(--md-sys-color-surface-container, var(--sicoob-background-tertiary));--_pvb-editor-border: var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));--_pvb-editor-text: var(--md-sys-color-on-surface, var(--sicoob-text-default));--_pvb-editor-text-soft: var(--md-sys-color-on-surface-variant, var(--sicoob-text-subtle));display:flex;flex-direction:column;height:100%;background:radial-gradient(circle at top center,color-mix(in srgb,var(--_pvb-editor-accent) 12%,transparent) 0%,transparent 32%),linear-gradient(180deg,color-mix(in srgb,var(--_pvb-editor-surface-low) 96%,black 4%),color-mix(in srgb,var(--_pvb-editor-surface) 98%,black 2%));overflow:hidden;position:relative;color:var(--_pvb-editor-text)}.rule-editor-container.embedded{height:100%}.condition-only-editor{display:flex;flex-direction:column;height:100%;min-height:360px;overflow:hidden}.condition-only-header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 16px;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 68%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 94%,black 6%)}.condition-only-header h3{margin:0;font-size:16px;font-weight:600}.condition-only-header p{margin:4px 0 0;font-size:12px;color:var(--_pvb-editor-text-soft)}.condition-only-canvas{flex:1;min-height:0}.builder-shell-header{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:54px;padding:0 18px;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 68%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 94%,black 6%);flex-shrink:0}.shell-brand{display:flex;align-items:center;gap:10px;min-width:0}.shell-menu{margin-right:2px}.brand-mark{width:32px;height:32px;border-radius:10px;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--_pvb-editor-accent) 16%,transparent);border:1px solid color-mix(in srgb,var(--_pvb-editor-accent) 24%,transparent)}.brand-mark mat-icon{display:flex;align-items:center;justify-content:center;font-size:18px;width:18px;height:18px;color:var(--_pvb-editor-accent)}.brand-copy{display:flex;flex-direction:column;gap:2px;min-width:0}.brand-title{font-size:14px;font-weight:700}.brand-breadcrumb{font-size:12px;color:var(--_pvb-editor-text-soft)}.shell-nav{display:inline-flex;align-items:center;gap:10px;padding:4px;border-radius:14px;background:color-mix(in srgb,var(--_pvb-editor-surface-low) 94%,black 6%);border:1px solid color-mix(in srgb,var(--_pvb-editor-border) 56%,transparent)}.nav-pill{min-width:96px;height:34px;border:0;border-radius:10px;background:transparent;color:var(--_pvb-editor-text-soft);font:inherit;font-size:13px;cursor:default}.nav-pill.active{color:var(--_pvb-editor-text);background:color-mix(in srgb,var(--_pvb-editor-accent) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_pvb-editor-accent) 34%,transparent)}.shell-status{display:flex;align-items:center;gap:6px}.unsaved-indicator{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--_pvb-editor-text);margin-right:6px}.unsaved-dot{width:8px;height:8px;border-radius:999px;background:#f0b429;box-shadow:0 0 12px #f0b42973}.builder-shell-header button[mat-icon-button]{width:36px;height:36px;line-height:36px;padding:8px}.builder-shell-header button[mat-icon-button] mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-content-grid{display:grid;grid-template-columns:360px 1fr;flex:1;overflow:hidden;min-height:0;transition:grid-template-columns .2s ease}.editor-content-grid.list-closed{grid-template-columns:0 1fr}.rule-list-panel{border-right:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-low) 94%,black 6%);display:flex;flex-direction:column;overflow:hidden}.rule-definition-panel{background:radial-gradient(circle at 50% 0%,color-mix(in srgb,var(--_pvb-editor-accent) 8%,transparent) 0%,transparent 26%),transparent;overflow:hidden;display:flex;flex-direction:column;position:relative;min-height:0;flex:1}.empty-state,.unsupported-node{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--_pvb-editor-text-soft);gap:16px;text-align:center;padding:32px}.empty-state mat-icon,.unsupported-node mat-icon{font-size:64px;width:64px;height:64px;opacity:.9;color:var(--_pvb-editor-accent)}.status-bar{height:32px;background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 92%,black 8%);border-top:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent);display:flex;align-items:center;justify-content:space-between;padding:0 16px;font-size:12px;color:var(--_pvb-editor-text-soft);flex-shrink:0}.status-left,.status-center{display:flex;align-items:center;gap:8px}.validation-status{display:flex;align-items:center;gap:4px}.validation-status.error{color:var(--md-sys-color-error)}.validation-status.success{color:var(--md-sys-color-tertiary)}.validation-status mat-icon{font-size:16px;width:16px;height:16px}.debug-panel{position:absolute;top:0;right:0;bottom:0;width:400px;background:var(--_pvb-editor-surface);border-left:1px solid var(--_pvb-editor-border);box-shadow:-2px 0 8px #0000001a;z-index:var(--praxis-layer-authoring-toolbar, 340);display:flex;flex-direction:column}.debug-header{padding:8px 16px;border-bottom:1px solid var(--_pvb-editor-border);display:flex;align-items:center;justify-content:space-between;background:var(--_pvb-editor-surface-strong)}.debug-content{flex:1;overflow:auto;padding:16px;font-family:monospace;font-size:12px}@media(max-width:1180px){.builder-shell-header{flex-wrap:wrap;justify-content:flex-start;padding:10px 14px}.shell-nav{order:3;width:100%;justify-content:center}.shell-status{margin-left:auto}}\n"] }]
14022
+ `, styles: [".rule-editor-container{--_pvb-editor-accent: var(--md-sys-color-primary, var(--sicoob-primary-default));--_pvb-editor-accent-soft: color-mix(in srgb, var(--_pvb-editor-accent) 16%, transparent);--_pvb-editor-surface: var(--md-sys-color-surface, var(--sicoob-background-primary));--_pvb-editor-surface-low: var(--md-sys-color-surface-container-low, var(--sicoob-background-secondary));--_pvb-editor-surface-strong: var(--md-sys-color-surface-container, var(--sicoob-background-tertiary));--_pvb-editor-border: var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium));--_pvb-editor-text: var(--md-sys-color-on-surface, var(--sicoob-text-default));--_pvb-editor-text-soft: var(--md-sys-color-on-surface-variant, var(--sicoob-text-subtle));display:flex;flex-direction:column;height:100%;background:radial-gradient(circle at top center,color-mix(in srgb,var(--_pvb-editor-accent) 12%,transparent) 0%,transparent 32%),linear-gradient(180deg,color-mix(in srgb,var(--_pvb-editor-surface-low) 96%,black 4%),color-mix(in srgb,var(--_pvb-editor-surface) 98%,black 2%));overflow:hidden;position:relative;color:var(--_pvb-editor-text)}.rule-editor-container.embedded{height:100%}.condition-only-editor{display:flex;flex-direction:column;height:100%;min-height:360px;overflow:hidden}.condition-only-header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 16px;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 68%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 94%,black 6%)}.condition-only-header h3{margin:0;font-size:16px;font-weight:600}.condition-only-header p{margin:4px 0 0;font-size:12px;color:var(--_pvb-editor-text-soft)}.condition-only-canvas{flex:1;min-height:0}.builder-shell-header{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:54px;padding:0 18px;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 68%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 94%,black 6%);flex-shrink:0}.shell-brand{display:flex;align-items:center;gap:10px;min-width:0}.shell-menu{margin-right:2px}.brand-mark{width:32px;height:32px;border-radius:10px;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--_pvb-editor-accent) 16%,transparent);border:1px solid color-mix(in srgb,var(--_pvb-editor-accent) 24%,transparent)}.brand-mark mat-icon{display:flex;align-items:center;justify-content:center;font-size:18px;width:18px;height:18px;color:var(--_pvb-editor-accent)}.brand-copy{display:flex;flex-direction:column;gap:2px;min-width:0}.brand-title{font-size:14px;font-weight:700}.brand-breadcrumb{font-size:12px;color:var(--_pvb-editor-text-soft)}.shell-nav{display:inline-flex;align-items:center;gap:10px;padding:4px;border-radius:14px;background:color-mix(in srgb,var(--_pvb-editor-surface-low) 94%,black 6%);border:1px solid color-mix(in srgb,var(--_pvb-editor-border) 56%,transparent)}.nav-pill{min-width:96px;height:34px;border:0;border-radius:10px;background:transparent;color:var(--_pvb-editor-text-soft);font:inherit;font-size:13px;cursor:default}.nav-pill.active{color:var(--_pvb-editor-text);background:color-mix(in srgb,var(--_pvb-editor-accent) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_pvb-editor-accent) 34%,transparent)}.shell-status{display:flex;align-items:center;gap:6px}.unsaved-indicator{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--_pvb-editor-text);margin-right:6px}.unsaved-dot{width:8px;height:8px;border-radius:999px;background:#f0b429;box-shadow:0 0 12px #f0b42973}.builder-shell-header button[mat-icon-button]{width:36px;height:36px;line-height:36px;padding:8px}.builder-shell-header button[mat-icon-button] mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-content-grid{display:grid;grid-template-columns:360px 1fr;flex:1;overflow:hidden;min-height:0;min-width:0;transition:grid-template-columns .2s ease}.editor-content-grid.list-closed{grid-template-columns:0 1fr}.rule-list-panel{border-right:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent);background:color-mix(in srgb,var(--_pvb-editor-surface-low) 94%,black 6%);display:flex;flex-direction:column;overflow:hidden;min-width:0}.rule-definition-panel{background:radial-gradient(circle at 50% 0%,color-mix(in srgb,var(--_pvb-editor-accent) 8%,transparent) 0%,transparent 26%),transparent;overflow:hidden;display:flex;flex-direction:column;position:relative;min-height:0;min-width:0;flex:1}.empty-state,.unsupported-node{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--_pvb-editor-text-soft);gap:16px;text-align:center;padding:32px}.empty-state mat-icon,.unsupported-node mat-icon{font-size:64px;width:64px;height:64px;opacity:.9;color:var(--_pvb-editor-accent)}.status-bar{height:32px;background:color-mix(in srgb,var(--_pvb-editor-surface-strong) 92%,black 8%);border-top:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent);display:flex;align-items:center;justify-content:space-between;padding:0 16px;font-size:12px;color:var(--_pvb-editor-text-soft);flex-shrink:0}.status-left,.status-center{display:flex;align-items:center;gap:8px}.validation-status{display:flex;align-items:center;gap:4px}.validation-status.error{color:var(--md-sys-color-error)}.validation-status.success{color:var(--md-sys-color-tertiary)}.validation-status mat-icon{font-size:16px;width:16px;height:16px}.debug-panel{position:absolute;top:0;right:0;bottom:0;width:400px;background:var(--_pvb-editor-surface);border-left:1px solid var(--_pvb-editor-border);box-shadow:-2px 0 8px #0000001a;z-index:var(--praxis-layer-authoring-toolbar, 340);display:flex;flex-direction:column}.debug-header{padding:8px 16px;border-bottom:1px solid var(--_pvb-editor-border);display:flex;align-items:center;justify-content:space-between;background:var(--_pvb-editor-surface-strong)}.debug-content{flex:1;overflow:auto;padding:16px;font-family:monospace;font-size:12px}@media(max-width:1180px){.builder-shell-header{flex-wrap:wrap;justify-content:flex-start;padding:10px 14px}.shell-nav{order:3;width:100%;justify-content:center}.shell-status{margin-left:auto}}@media(max-width:720px){.editor-content-grid,.editor-content-grid.list-closed{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(360px,1fr);overflow-y:auto}.rule-list-panel{max-height:min(360px,48vh);border-right:0;border-bottom:1px solid color-mix(in srgb,var(--_pvb-editor-border) 74%,transparent)}.rule-definition-panel{min-height:360px}}\n"] }]
13976
14023
  }], ctorParameters: () => [{ type: RuleBuilderService }, { type: FieldSchemaService }, { type: i3$1.AiResponseValidatorService }, { type: i4.MatSnackBar }, { type: i1.MatDialog }, { type: i0.ChangeDetectorRef }, { type: i1$2.PraxisI18nService, decorators: [{
13977
14024
  type: Optional
13978
14025
  }] }], propDecorators: { embedded: [{
@@ -14075,6 +14122,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
14075
14122
  type: Output
14076
14123
  }] } });
14077
14124
 
14125
+ /** Metadata for Praxis Visual Builder component */
14126
+ const PRAXIS_VISUAL_BUILDER_COMPONENT_METADATA = {
14127
+ id: 'praxis-visual-builder',
14128
+ selector: 'praxis-visual-builder',
14129
+ component: PraxisVisualBuilder,
14130
+ friendlyName: 'Praxis Visual Builder',
14131
+ description: 'Visual rule builder with JSON Logic authoring and governed compatibility for legacy payloads.',
14132
+ inputs: [
14133
+ {
14134
+ name: 'config',
14135
+ type: 'RuleBuilderConfig | null',
14136
+ label: 'Configuracao',
14137
+ description: 'Configuracao do builder (schemas, templates, UI e validacoes).',
14138
+ },
14139
+ {
14140
+ name: 'initialRules',
14141
+ type: 'any',
14142
+ label: 'Regras iniciais',
14143
+ description: 'Estado inicial de regras para carregar no editor.',
14144
+ },
14145
+ ],
14146
+ outputs: [
14147
+ {
14148
+ name: 'rulesChanged',
14149
+ type: 'RuleBuilderState',
14150
+ label: 'Regras alteradas',
14151
+ description: 'Disparado quando o grafo/estado de regras e alterado.',
14152
+ },
14153
+ {
14154
+ name: 'exportRequested',
14155
+ type: 'ExportOptions',
14156
+ label: 'Exportacao solicitada',
14157
+ description: 'Disparado quando o usuario solicita exportacao.',
14158
+ },
14159
+ {
14160
+ name: 'importRequested',
14161
+ type: 'ImportOptions',
14162
+ label: 'Importacao solicitada',
14163
+ description: 'Disparado quando o usuario solicita importacao.',
14164
+ },
14165
+ ],
14166
+ tags: ['widget', 'rules', 'configurable'],
14167
+ lib: '@praxisui/visual-builder',
14168
+ };
14169
+ /** Provider para auto-registrar metadados do componente Visual Builder. */
14170
+ function providePraxisVisualBuilderMetadata() {
14171
+ return {
14172
+ provide: ENVIRONMENT_INITIALIZER,
14173
+ multi: true,
14174
+ useFactory: (registry) => () => {
14175
+ registry.register(PRAXIS_VISUAL_BUILDER_COMPONENT_METADATA);
14176
+ },
14177
+ deps: [ComponentMetadataRegistry],
14178
+ };
14179
+ }
14180
+
14078
14181
  const nodeAddSchema = {
14079
14182
  type: 'object',
14080
14183
  required: ['nodeId', 'nodeType'],
@@ -14164,7 +14267,6 @@ const variableAddSchema = {
14164
14267
  name: { type: 'string' },
14165
14268
  scope: { type: 'string' },
14166
14269
  type: { enum: ['string', 'number', 'boolean', 'object', 'array'] },
14167
- valueType: { enum: ['literal', 'field', 'context', 'function'] },
14168
14270
  defaultValue: {},
14169
14271
  description: { type: 'string' },
14170
14272
  },
@@ -14221,7 +14323,7 @@ const PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST = {
14221
14323
  editableTargets: [
14222
14324
  { kind: 'node', resolver: 'rule-node-by-id', description: 'Visual rule graph node keyed by stable RuleNode.id.' },
14223
14325
  { kind: 'edge', resolver: 'rule-node-edge-by-source-target', description: 'Parent-child or semantic graph edge between existing rule nodes.' },
14224
- { kind: 'variable', resolver: 'context-variable-by-name-scope', description: 'Context variable available to rule conditions and contextual nodes.' },
14326
+ { kind: 'variable', resolver: 'context-variable-by-name-scope', description: 'Context variable governed by ContextManagementService for contextual/template flows; visual field-condition references are not authorable until a canonical JSON Logic shape exists.' },
14225
14327
  { kind: 'condition', resolver: 'json-logic-condition-by-node', description: 'JSON Logic condition attached to a node or represented by condition nodes.' },
14226
14328
  { kind: 'effect', resolver: 'property-effect-by-node', description: 'Targeted property effect persisted as propertyRule/FormLayoutRule semantics.' },
14227
14329
  { kind: 'dslDocument', resolver: 'rule-builder-json-logic-document', description: 'Serialized JSON Logic/form-config document produced from the visual model.' },
@@ -14350,7 +14452,7 @@ const PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST = {
14350
14452
  identityKeys: ['scope', 'name'],
14351
14453
  inputSchema: variableAddSchema,
14352
14454
  failureModes: ['duplicate-variable', 'scope-not-found', 'variable-type-invalid', 'context-token-conflict'],
14353
- description: 'Adds a governed context variable that can be referenced by contextual and field condition nodes.',
14455
+ description: 'Adds a governed context variable to ContextManagementService for contextual/template flows. Field-condition references stay unsupported until a canonical JSON Logic shape exists.',
14354
14456
  } }],
14355
14457
  validators: ['variable-id-unique', 'variable-scope-exists', 'context-variable-reference-valid', 'dsl-round-trip-stable'],
14356
14458
  affectedPaths: ['RuleBuilderConfig.contextVariables', 'ContextManagementService'],
@@ -14372,7 +14474,7 @@ const PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST = {
14372
14474
  identityKeys: ['nodeId'],
14373
14475
  inputSchema: conditionSetSchema,
14374
14476
  failureModes: ['node-not-found', 'json-logic-invalid', 'unsupported-operator', 'visual-parse-failed', 'dsl-round-trip-failed'],
14375
- description: 'Sets a canonical JSON Logic condition and proves it can parse back into the visual graph.',
14477
+ description: 'Sets a canonical JSON Logic condition within the runtime-supported visual subset and proves it can parse back into the visual graph.',
14376
14478
  } }],
14377
14479
  validators: ['json-logic-valid', 'condition-operators-supported', 'condition-fields-known', 'dsl-round-trip-stable'],
14378
14480
  affectedPaths: ['RuleBuilderState.nodes[].config.condition', 'RuleBuilderState.currentJSON'],
@@ -14439,10 +14541,10 @@ const PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST = {
14439
14541
  { validatorId: 'destructive-removal-confirmed', level: 'error', code: 'VISUAL_BUILDER_DESTRUCTIVE_REMOVAL_CONFIRMED', description: 'Destructive node or edge removal requires explicit confirmation.' },
14440
14542
  { validatorId: 'variable-id-unique', level: 'error', code: 'VISUAL_BUILDER_VARIABLE_ID_UNIQUE', description: 'Context variable name and scope must be unique.' },
14441
14543
  { validatorId: 'variable-scope-exists', level: 'error', code: 'VISUAL_BUILDER_VARIABLE_SCOPE_EXISTS', description: 'Context variable scope must exist in ContextManagementService before variables are added.' },
14442
- { validatorId: 'context-variable-reference-valid', level: 'error', code: 'VISUAL_BUILDER_CONTEXT_VARIABLE_VALID', description: 'Context variable references must resolve to declared variables.' },
14544
+ { validatorId: 'context-variable-reference-valid', level: 'error', code: 'VISUAL_BUILDER_CONTEXT_VARIABLE_VALID', description: 'Contextual/template variable references must resolve to declared variables.' },
14443
14545
  { validatorId: 'json-logic-valid', level: 'error', code: 'VISUAL_BUILDER_JSON_LOGIC_VALID', description: 'Conditions must be valid JSON Logic objects, not JavaScript or legacy textual DSL.' },
14444
14546
  { validatorId: 'condition-operators-supported', level: 'error', code: 'VISUAL_BUILDER_CONDITION_OPERATORS_SUPPORTED', description: 'Condition operators must be supported by visual parsing and export.' },
14445
- { validatorId: 'condition-fields-known', level: 'error', code: 'VISUAL_BUILDER_CONDITION_FIELDS_KNOWN', description: 'Condition field references must resolve to configured field schemas or context variables.' },
14547
+ { validatorId: 'condition-fields-known', level: 'error', code: 'VISUAL_BUILDER_CONDITION_FIELDS_KNOWN', description: 'Condition field references must resolve to configured field schemas; field-to-field comparisons use JSON Logic var operands.' },
14446
14548
  { validatorId: 'effect-targets-exist', level: 'error', code: 'VISUAL_BUILDER_EFFECT_TARGETS_EXIST', description: 'Effect targets must exist in configured target schemas.' },
14447
14549
  { validatorId: 'effect-properties-governed', level: 'error', code: 'VISUAL_BUILDER_EFFECT_PROPERTIES_GOVERNED', description: 'Effect properties must be allowed for the target type.' },
14448
14550
  { validatorId: 'effect-values-valid', level: 'error', code: 'VISUAL_BUILDER_EFFECT_VALUES_VALID', description: 'Effect property values must satisfy target property schema types.' },
@@ -14451,11 +14553,11 @@ const PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST = {
14451
14553
  ],
14452
14554
  roundTripRequirements: [
14453
14555
  'RuleBuilderState is the visual source of truth; JSON export must import back without semantic drift.',
14454
- 'RuleNode.id and context variable scope/name are canonical identities; array indexes are not canonical identities.',
14556
+ 'RuleNode.id and context variable scope/name are canonical identities for their own surfaces; array indexes are not canonical identities.',
14455
14557
  'Edges must reference existing nodes and must not create cycles in hierarchical rule graphs.',
14456
14558
  'Conditions are canonical JSON Logic objects. JavaScript expressions and legacy textual DSL must not be introduced as persisted authoring payloads.',
14457
14559
  'Effects must be constrained by target property schemas and RULE_PROPERTY_SCHEMA so exported FormLayoutRule payloads stay deterministic.',
14458
- 'Component-specific configuration belongs to child component manifests; visual-builder owns graph, JSON Logic, variables and property-effect orchestration.',
14560
+ 'Component-specific configuration belongs to child component manifests; visual-builder owns graph, supported JSON Logic, context-variable registry and property-effect orchestration.',
14459
14561
  ],
14460
14562
  examples: [
14461
14563
  { id: 'add-field-condition', request: 'Add a condition that age is greater than 18.', operationId: 'node.add', params: { nodeId: 'age-gt-18', nodeType: 'fieldCondition', label: 'Age over 18', config: { type: 'fieldCondition', fieldName: 'age', operator: 'gt', value: 18 } }, isPositive: true },
@@ -14463,7 +14565,7 @@ const PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST = {
14463
14565
  { id: 'configure-node', request: 'Rename the eligibility rule and mark it expanded.', operationId: 'node.configure', params: { nodeId: 'eligibility', label: 'Eligibility rule', expanded: true }, isPositive: true },
14464
14566
  { id: 'connect-edge', request: 'Make the age condition a child of the AND group.', operationId: 'edge.connect', params: { sourceNodeId: 'eligibility-and', targetNodeId: 'age-gt-18', edgeKind: 'child' }, isPositive: true },
14465
14567
  { id: 'remove-edge', request: 'Disconnect the age condition from the AND group.', operationId: 'edge.remove', params: { sourceNodeId: 'eligibility-and', targetNodeId: 'age-gt-18', edgeKind: 'child' }, isPositive: true },
14466
- { id: 'add-variable', request: 'Add a global variable for current tenant.', operationId: 'variable.add', params: { name: 'tenantId', scope: 'global', type: 'string', valueType: 'context', description: 'Current tenant id' }, isPositive: true },
14568
+ { id: 'add-variable', request: 'Add a global variable for current tenant.', operationId: 'variable.add', params: { name: 'tenantId', scope: 'global', type: 'string', description: 'Current tenant id' }, isPositive: true },
14467
14569
  { id: 'set-condition', request: 'Set this condition to require country equal Brazil.', operationId: 'condition.set', params: { nodeId: 'country-br', condition: { '===': [{ var: 'country' }, 'BR'] }, source: 'jsonLogic' }, isPositive: true },
14468
14570
  { id: 'set-effect', request: 'Make the salary field readonly when the condition is true.', operationId: 'effect.set', params: { nodeId: 'salary-readonly', targetType: 'field', targets: ['salary'], properties: { readonly: true } }, isPositive: true },
14469
14571
  { id: 'validate-round-trip', request: 'Validate that this graph exports and imports without drift.', operationId: 'dsl.roundTrip.validate', params: { format: 'json', requireStableIds: true, compareMode: 'semantic' }, isPositive: true },
@@ -21674,4 +21776,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21674
21776
  * Generated bundle index. Do not edit.
21675
21777
  */
21676
21778
 
21677
- export { ArrayFieldAnalyzer, CollectionValidatorEditorComponent, ConditionalValidatorEditorComponent, ConditionalValidatorType, ConfigurationError, ContextError, ContextManagementService, ConversionError, ErrorCategory, ErrorHandler, ErrorSeverity, ExportDialogComponent, ExportIntegrationService, ExpressionError, FIELD_TYPE_OPERATORS, FieldConditionEditorComponent, FieldSchemaService, FieldType, InternalError, JsonViewerComponent, MetadataEditorComponent, OPERATOR_LABELS, PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST, PraxisVisualBuilder, RegistryError, RuleBuilderService, RuleCanvasComponent, RuleEditorComponent, RuleListComponent, RuleNodeComponent, RuleNodeRegistryService, RuleNodeType, RuleTemplateService, RuleValidationService, TemplateEditorDialogComponent, TemplateGalleryComponent, TemplatePreviewDialogComponent, ValidationError as VBValidationError, ValidationCategory, ValidationSeverity, VisualBuilderError, VisualRuleBuilderComponent, WebhookIntegrationService, createError, getArrayItemFieldPaths, globalErrorHandler, isArrayFieldSchema };
21779
+ export { ArrayFieldAnalyzer, CollectionValidatorEditorComponent, ConditionalValidatorEditorComponent, ConditionalValidatorType, ConfigurationError, ContextError, ContextManagementService, ConversionError, ErrorCategory, ErrorHandler, ErrorSeverity, ExportDialogComponent, ExportIntegrationService, ExpressionError, FIELD_TYPE_OPERATORS, FieldConditionEditorComponent, FieldSchemaService, FieldType, InternalError, JsonViewerComponent, MetadataEditorComponent, OPERATOR_LABELS, PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST, PRAXIS_VISUAL_BUILDER_COMPONENT_METADATA, PraxisVisualBuilder, RegistryError, RuleBuilderService, RuleCanvasComponent, RuleEditorComponent, RuleListComponent, RuleNodeComponent, RuleNodeRegistryService, RuleNodeType, RuleTemplateService, RuleValidationService, TemplateEditorDialogComponent, TemplateGalleryComponent, TemplatePreviewDialogComponent, ValidationError as VBValidationError, ValidationCategory, ValidationSeverity, VisualBuilderError, VisualRuleBuilderComponent, WebhookIntegrationService, createError, getArrayItemFieldPaths, globalErrorHandler, isArrayFieldSchema, providePraxisVisualBuilderMetadata };