@praxisui/metadata-editor 8.0.0-beta.19 → 8.0.0-beta.20

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.
@@ -2103,8 +2103,46 @@ function cloneProperty$7(prop) {
2103
2103
  : prop.options,
2104
2104
  };
2105
2105
  }
2106
+ function cloneEntityLookupBaseProperty(prop) {
2107
+ const cloned = cloneProperty$7(prop);
2108
+ if (cloned.name === 'multiple') {
2109
+ return {
2110
+ ...cloned,
2111
+ group: 'Selecao em colecao',
2112
+ hint: 'Ativa selecao governada de varias entidades no mesmo campo.',
2113
+ };
2114
+ }
2115
+ if (cloned.name === 'maxSelections') {
2116
+ return {
2117
+ ...cloned,
2118
+ group: 'Selecao em colecao',
2119
+ hint: 'Limite maximo de entidades selecionadas quando multiple=true.',
2120
+ };
2121
+ }
2122
+ return cloned;
2123
+ }
2106
2124
  const entityLookupProperties = [
2107
- ...selectProperties.map((prop) => cloneProperty$7(prop)),
2125
+ ...selectProperties.map((prop) => cloneEntityLookupBaseProperty(prop)),
2126
+ {
2127
+ name: 'payloadMode',
2128
+ label: 'Modo do payload',
2129
+ editorType: 'select',
2130
+ group: 'Selecao em colecao',
2131
+ options: [
2132
+ { value: 'id', text: 'id' },
2133
+ { value: 'entityRef', text: 'entityRef' },
2134
+ { value: 'ids', text: 'ids' },
2135
+ { value: 'entityRefs', text: 'entityRefs' },
2136
+ ],
2137
+ hint: 'Define o shape salvo no payload. O runtime resolve combinacoes invalidas conforme multiple.',
2138
+ },
2139
+ {
2140
+ name: 'allowDuplicates',
2141
+ label: 'Permitir duplicados',
2142
+ editorType: 'checkbox',
2143
+ group: 'Selecao em colecao',
2144
+ hint: 'Permite repetir a mesma entidade na colecao quando o runtime suportar esse comportamento.',
2145
+ },
2108
2146
  {
2109
2147
  name: 'optionSource.key',
2110
2148
  label: 'Option source key',
@@ -2204,6 +2242,95 @@ const entityLookupProperties = [
2204
2242
  group: 'Exibicao de entidade',
2205
2243
  hint: 'Campo opcional com mensagem de bloqueio quando selectable=false.',
2206
2244
  },
2245
+ {
2246
+ name: 'selectedLayout',
2247
+ label: 'Layout selecionado',
2248
+ editorType: 'select',
2249
+ group: 'Exibicao de entidade',
2250
+ options: [
2251
+ { value: 'card', text: 'card' },
2252
+ { value: 'inline', text: 'inline' },
2253
+ { value: 'compact', text: 'compact' },
2254
+ { value: 'token', text: 'token' },
2255
+ ],
2256
+ hint: 'Layout do item selecionado no trigger ou card principal.',
2257
+ },
2258
+ {
2259
+ name: 'resultLayout',
2260
+ label: 'Layout dos resultados',
2261
+ editorType: 'select',
2262
+ group: 'Exibicao de entidade',
2263
+ options: [
2264
+ { value: 'list', text: 'list' },
2265
+ { value: 'denseList', text: 'denseList' },
2266
+ { value: 'table', text: 'table' },
2267
+ { value: 'card', text: 'card' },
2268
+ ],
2269
+ hint: 'Layout principal usado na lista inline e no dialog.',
2270
+ },
2271
+ {
2272
+ name: 'showCode',
2273
+ label: 'Mostrar codigo',
2274
+ editorType: 'checkbox',
2275
+ group: 'Exibicao de entidade',
2276
+ },
2277
+ {
2278
+ name: 'showDescription',
2279
+ label: 'Mostrar descricao',
2280
+ editorType: 'checkbox',
2281
+ group: 'Exibicao de entidade',
2282
+ },
2283
+ {
2284
+ name: 'showStatus',
2285
+ label: 'Mostrar status',
2286
+ editorType: 'checkbox',
2287
+ group: 'Exibicao de entidade',
2288
+ },
2289
+ {
2290
+ name: 'showAvatar',
2291
+ label: 'Mostrar avatar',
2292
+ editorType: 'checkbox',
2293
+ group: 'Exibicao de entidade',
2294
+ },
2295
+ {
2296
+ name: 'showBadges',
2297
+ label: 'Mostrar badges',
2298
+ editorType: 'checkbox',
2299
+ group: 'Exibicao de entidade',
2300
+ },
2301
+ {
2302
+ name: 'showDisabledReason',
2303
+ label: 'Mostrar motivo bloqueado',
2304
+ editorType: 'checkbox',
2305
+ group: 'Exibicao de entidade',
2306
+ },
2307
+ {
2308
+ name: 'showResultCount',
2309
+ label: 'Mostrar contador de resultados',
2310
+ editorType: 'checkbox',
2311
+ group: 'Exibicao de entidade',
2312
+ },
2313
+ {
2314
+ name: 'statusToneMap',
2315
+ label: 'Mapa de tons de status',
2316
+ editorType: 'textarea',
2317
+ group: 'Exibicao de entidade',
2318
+ hint: 'JSON object. Ex.: { \"ACTIVE\": \"success\", \"BLOCKED\": \"danger\" }.',
2319
+ },
2320
+ {
2321
+ name: 'badgeKeys',
2322
+ label: 'Chaves de badges',
2323
+ editorType: 'textarea',
2324
+ group: 'Exibicao de entidade',
2325
+ hint: 'JSON array ou uma linha por chave complementar de badge.',
2326
+ },
2327
+ {
2328
+ name: 'maxVisibleBadges',
2329
+ label: 'Maximo de badges visiveis',
2330
+ editorType: 'number',
2331
+ group: 'Exibicao de entidade',
2332
+ hint: 'Limita a quantidade de badges visiveis antes do overflow.',
2333
+ },
2207
2334
  {
2208
2335
  name: 'optionSource.searchPropertyPaths',
2209
2336
  label: 'Campos de busca',
@@ -2238,6 +2365,48 @@ const entityLookupProperties = [
2238
2365
  defaultValue: true,
2239
2366
  hint: 'Mantem entidades ja selecionadas visiveis durante busca paginada.',
2240
2367
  },
2368
+ {
2369
+ name: 'optionSource.filtering.availableFilters',
2370
+ label: 'Filtros disponiveis',
2371
+ editorType: 'textarea',
2372
+ group: 'Busca',
2373
+ hint: 'JSON array de filtros estruturados. Ex.: [{ \"field\": \"status\", \"type\": \"enum\", \"operators\": [\"in\"] }].',
2374
+ },
2375
+ {
2376
+ name: 'optionSource.filtering.defaultFilters',
2377
+ label: 'Filtros padrao',
2378
+ editorType: 'textarea',
2379
+ group: 'Busca',
2380
+ hint: 'JSON object. Ex.: { \"status\": [\"ACTIVE\"] }.',
2381
+ },
2382
+ {
2383
+ name: 'optionSource.filtering.sortOptions',
2384
+ label: 'Ordenacoes disponiveis',
2385
+ editorType: 'textarea',
2386
+ group: 'Busca',
2387
+ hint: 'JSON array. Ex.: [{ \"key\": \"code:asc\", \"field\": \"code\", \"direction\": \"asc\", \"label\": \"Codigo\" }].',
2388
+ },
2389
+ {
2390
+ name: 'optionSource.filtering.defaultSort',
2391
+ label: 'Ordenacao padrao',
2392
+ editorType: 'text',
2393
+ group: 'Busca',
2394
+ hint: 'Chave default do sort declarada em sortOptions.',
2395
+ },
2396
+ {
2397
+ name: 'optionSource.filtering.quickFilterFields',
2398
+ label: 'Campos de filtro rapido',
2399
+ editorType: 'textarea',
2400
+ group: 'Busca',
2401
+ hint: 'JSON array ou uma linha por campo rapido no toolbar do lookup.',
2402
+ },
2403
+ {
2404
+ name: 'optionSource.filtering.searchPlaceholder',
2405
+ label: 'Placeholder canonico de busca',
2406
+ editorType: 'text',
2407
+ group: 'Busca',
2408
+ hint: 'Fallback do optionSource.filtering quando o campo nao sobrescreve searchPlaceholder.',
2409
+ },
2241
2410
  {
2242
2411
  name: 'optionSource.dependsOn',
2243
2412
  label: 'Dependencias',
@@ -2383,12 +2552,178 @@ const entityLookupProperties = [
2383
2552
  editorType: 'select',
2384
2553
  group: 'Navegacao',
2385
2554
  options: [
2386
- { value: 'route', text: 'Rota' },
2555
+ { value: 'samePage', text: 'samePage' },
2556
+ { value: 'newTab', text: 'newTab' },
2557
+ { value: 'drawer', text: 'Drawer' },
2558
+ { value: 'modal', text: 'Modal' },
2559
+ ],
2560
+ },
2561
+ {
2562
+ name: 'optionSource.create.hrefTemplate',
2563
+ label: 'Template create href',
2564
+ editorType: 'text',
2565
+ group: 'Navegacao',
2566
+ hint: 'Template opcional de criacao publicado pelo optionSource.',
2567
+ },
2568
+ {
2569
+ name: 'optionSource.create.routeTemplate',
2570
+ label: 'Template create route',
2571
+ editorType: 'text',
2572
+ group: 'Navegacao',
2573
+ hint: 'Rota opcional de criacao, por exemplo /suppliers/new.',
2574
+ },
2575
+ {
2576
+ name: 'optionSource.create.openMode',
2577
+ label: 'Modo de create',
2578
+ editorType: 'select',
2579
+ group: 'Navegacao',
2580
+ options: [
2581
+ { value: 'samePage', text: 'samePage' },
2582
+ { value: 'newTab', text: 'newTab' },
2387
2583
  { value: 'drawer', text: 'Drawer' },
2388
- { value: 'dialog', text: 'Dialog' },
2389
- { value: 'external', text: 'Externo' },
2584
+ { value: 'modal', text: 'Modal' },
2390
2585
  ],
2391
2586
  },
2587
+ {
2588
+ name: 'dialog.enabled',
2589
+ label: 'Dialog habilitado',
2590
+ editorType: 'checkbox',
2591
+ group: 'Dialogo avancado',
2592
+ },
2593
+ {
2594
+ name: 'dialog.title',
2595
+ label: 'Titulo do dialog',
2596
+ editorType: 'text',
2597
+ group: 'Dialogo avancado',
2598
+ },
2599
+ {
2600
+ name: 'dialog.size',
2601
+ label: 'Tamanho do dialog',
2602
+ editorType: 'select',
2603
+ group: 'Dialogo avancado',
2604
+ options: [
2605
+ { value: 'sm', text: 'sm' },
2606
+ { value: 'md', text: 'md' },
2607
+ { value: 'lg', text: 'lg' },
2608
+ { value: 'xl', text: 'xl' },
2609
+ { value: 'full', text: 'full' },
2610
+ ],
2611
+ },
2612
+ {
2613
+ name: 'dialog.previewPanel',
2614
+ label: 'Preview panel',
2615
+ editorType: 'checkbox',
2616
+ group: 'Dialogo avancado',
2617
+ },
2618
+ {
2619
+ name: 'dialog.allowColumnChooser',
2620
+ label: 'Permitir seletor de colunas',
2621
+ editorType: 'checkbox',
2622
+ group: 'Dialogo avancado',
2623
+ },
2624
+ {
2625
+ name: 'dialog.allowSavedViews',
2626
+ label: 'Permitir views salvas',
2627
+ editorType: 'checkbox',
2628
+ group: 'Dialogo avancado',
2629
+ },
2630
+ {
2631
+ name: 'dialog.resultColumns',
2632
+ label: 'Colunas do resultado',
2633
+ editorType: 'textarea',
2634
+ group: 'Dialogo avancado',
2635
+ hint: 'JSON array. Ex.: [{ \"field\": \"code\", \"label\": \"Codigo\", \"kind\": \"code\", \"width\": \"140px\" }].',
2636
+ },
2637
+ {
2638
+ name: 'dialog.openActionLabel',
2639
+ label: 'Label abrir dialog',
2640
+ editorType: 'text',
2641
+ group: 'Dialogo avancado',
2642
+ },
2643
+ {
2644
+ name: 'dialog.applyActionLabel',
2645
+ label: 'Label aplicar dialog',
2646
+ editorType: 'text',
2647
+ group: 'Dialogo avancado',
2648
+ },
2649
+ {
2650
+ name: 'dialog.cancelActionLabel',
2651
+ label: 'Label cancelar dialog',
2652
+ editorType: 'text',
2653
+ group: 'Dialogo avancado',
2654
+ },
2655
+ {
2656
+ name: 'detailActionLabel',
2657
+ label: 'Label detalhe',
2658
+ editorType: 'text',
2659
+ group: 'Acoes do lookup',
2660
+ },
2661
+ {
2662
+ name: 'changeActionLabel',
2663
+ label: 'Label trocar',
2664
+ editorType: 'text',
2665
+ group: 'Acoes do lookup',
2666
+ },
2667
+ {
2668
+ name: 'copyCodeActionLabel',
2669
+ label: 'Label copiar codigo',
2670
+ editorType: 'text',
2671
+ group: 'Acoes do lookup',
2672
+ },
2673
+ {
2674
+ name: 'copyIdActionLabel',
2675
+ label: 'Label copiar ID',
2676
+ editorType: 'text',
2677
+ group: 'Acoes do lookup',
2678
+ },
2679
+ {
2680
+ name: 'createActionLabel',
2681
+ label: 'Label criar',
2682
+ editorType: 'text',
2683
+ group: 'Acoes do lookup',
2684
+ },
2685
+ {
2686
+ name: 'clearActionLabel',
2687
+ label: 'Label limpar',
2688
+ editorType: 'text',
2689
+ group: 'Acoes do lookup',
2690
+ },
2691
+ {
2692
+ name: 'actions.showDetail',
2693
+ label: 'Acao: detalhe',
2694
+ editorType: 'checkbox',
2695
+ group: 'Acoes do lookup',
2696
+ },
2697
+ {
2698
+ name: 'actions.showChange',
2699
+ label: 'Acao: trocar',
2700
+ editorType: 'checkbox',
2701
+ group: 'Acoes do lookup',
2702
+ },
2703
+ {
2704
+ name: 'actions.showCopyCode',
2705
+ label: 'Acao: copiar codigo',
2706
+ editorType: 'checkbox',
2707
+ group: 'Acoes do lookup',
2708
+ },
2709
+ {
2710
+ name: 'actions.showCopyId',
2711
+ label: 'Acao: copiar ID',
2712
+ editorType: 'checkbox',
2713
+ group: 'Acoes do lookup',
2714
+ },
2715
+ {
2716
+ name: 'actions.showCreate',
2717
+ label: 'Acao: criar',
2718
+ editorType: 'checkbox',
2719
+ group: 'Acoes do lookup',
2720
+ },
2721
+ {
2722
+ name: 'actions.showClear',
2723
+ label: 'Acao: limpar',
2724
+ editorType: 'checkbox',
2725
+ group: 'Acoes do lookup',
2726
+ },
2392
2727
  ];
2393
2728
 
2394
2729
  const transferListProperties = [
@@ -4310,6 +4645,18 @@ const sliderProperties = [
4310
4645
  // Formato/Comportamento
4311
4646
  { name: 'step', label: 'Step', editorType: 'number', group: 'Formato/Comportamento', hint: 'Incremento entre valores (ex.: 1, 0.5). Combine com min/max.' },
4312
4647
  { name: 'thumbLabel', label: 'Thumb label', editorType: 'checkbox', group: 'Formato/Comportamento', hint: 'Exibe valor sobre o thumb ao arrastar.' },
4648
+ { name: 'valueLabelDisplay', label: 'Value label', editorType: 'select', group: 'Formato/Comportamento', options: [
4649
+ { value: 'off', text: 'Desligado' },
4650
+ { value: 'auto', text: 'Ao interagir' },
4651
+ { value: 'on', text: 'Sempre visivel' },
4652
+ ], hint: 'Controla quando o valor aparece no thumb.' },
4653
+ { name: 'valueLabelFormat', label: 'Formato do valor', editorType: 'select', group: 'Formato/Comportamento', options: [
4654
+ { value: 'number', text: 'Numero' },
4655
+ { value: 'percent', text: 'Percentual' },
4656
+ { value: 'currency', text: 'Moeda' },
4657
+ { value: 'compact', text: 'Compacto' },
4658
+ { value: 'storage', text: 'Armazenamento' },
4659
+ ], hint: 'Formatter declarativo para labels e aria-valuetext.' },
4313
4660
  { name: 'vertical', label: 'Vertical', editorType: 'checkbox', group: 'Formato/Comportamento', row: 'fmt.flags', inline: true, hint: 'Altera para eixo Y.' },
4314
4661
  { name: 'invert', label: 'Inverter', editorType: 'checkbox', group: 'Formato/Comportamento', row: 'fmt.flags', inline: true, hint: 'Inverte direção (direita→esquerda).' },
4315
4662
  { name: 'showTicks', label: 'Ticks', editorType: 'select', group: 'Formato/Comportamento', options: [
@@ -4317,6 +4664,26 @@ const sliderProperties = [
4317
4664
  { value: true, text: 'Com ticks' },
4318
4665
  { value: 'auto', text: 'Auto' },
4319
4666
  ], hint: 'Marcas na trilha; auto calcula com base no step.' },
4667
+ { name: 'marks', label: 'Marcadores (JSON)', editorType: 'textarea', group: 'Formato/Comportamento', hint: 'Array JSON. Ex.: [{"value":0,"label":"Baixo"},{"value":100,"label":"Alto","tone":"danger"}].' },
4668
+ { name: 'semanticBands', label: 'Bandas semanticas (JSON)', editorType: 'textarea', group: 'Formato/Comportamento', hint: 'Array JSON. Ex.: [{"start":0,"end":40,"label":"Saudavel","tone":"success"}].' },
4669
+ { name: 'distribution', label: 'Distribuicao (JSON)', editorType: 'textarea', group: 'Formato/Comportamento', hint: 'Array JSON ou config de histograma compacto. Ex.: {"colorMode":"gradient","bins":[4,8,16,12,6]}.' },
4670
+ { name: 'track', label: 'Track', editorType: 'select', group: 'Formato/Comportamento', options: [
4671
+ { value: 'normal', text: 'Normal' },
4672
+ { value: 'inverted', text: 'Invertido' },
4673
+ { value: 'none', text: 'Sem track ativo' },
4674
+ ], hint: 'Apresentacao visual do track.' },
4675
+ { name: 'size', label: 'Tamanho', editorType: 'select', group: 'Formato/Comportamento', options: [
4676
+ { value: 'small', text: 'Pequeno' },
4677
+ { value: 'medium', text: 'Medio' },
4678
+ { value: 'large', text: 'Grande' },
4679
+ ], hint: 'Densidade visual do slider.' },
4680
+ { name: 'scale', label: 'Escala', editorType: 'select', group: 'Formato/Comportamento', options: [
4681
+ { value: 'linear', text: 'Linear' },
4682
+ { value: 'percent', text: 'Percentual' },
4683
+ { value: 'log', text: 'Logaritmica' },
4684
+ { value: 'pow2', text: 'Potencia 2' },
4685
+ ], hint: 'Escala declarativa para dominios nao lineares.' },
4686
+ { name: 'shiftStep', label: 'Shift step', editorType: 'number', group: 'Formato/Comportamento', hint: 'Incremento acelerado para teclado.' },
4320
4687
  { name: 'discrete', label: 'Discreto', editorType: 'checkbox', group: 'Formato/Comportamento', hint: 'Exibe ticks/labels fixos para valores discretos.' },
4321
4688
  // Validação
4322
4689
  { name: 'min', label: 'Mínimo', editorType: 'number', group: 'Validação', row: 'val.minmax', inline: true },
@@ -4356,11 +4723,44 @@ const rangeSliderProperties = [
4356
4723
  ], hint: 'Escolha faixa para dois marcadores.' },
4357
4724
  { name: 'step', label: 'Step', editorType: 'number', group: 'Formato/Comportamento', hint: 'Incremento entre valores (ex.: 1, 0.5). Combine com min/max.' },
4358
4725
  { name: 'thumbLabel', label: 'Thumb label', editorType: 'checkbox', group: 'Formato/Comportamento', hint: 'Exibe o valor sobre o thumb ao arrastar.' },
4726
+ { name: 'valueLabelDisplay', label: 'Value label', editorType: 'select', group: 'Formato/Comportamento', options: [
4727
+ { value: 'off', text: 'Desligado' },
4728
+ { value: 'auto', text: 'Ao interagir' },
4729
+ { value: 'on', text: 'Sempre visivel' },
4730
+ ], hint: 'Controla quando o valor aparece no thumb.' },
4731
+ { name: 'valueLabelFormat', label: 'Formato do valor', editorType: 'select', group: 'Formato/Comportamento', options: [
4732
+ { value: 'number', text: 'Numero' },
4733
+ { value: 'percent', text: 'Percentual' },
4734
+ { value: 'currency', text: 'Moeda' },
4735
+ { value: 'compact', text: 'Compacto' },
4736
+ { value: 'storage', text: 'Armazenamento' },
4737
+ ], hint: 'Formatter declarativo para labels e aria-valuetext.' },
4359
4738
  { name: 'showTicks', label: 'Ticks', editorType: 'select', group: 'Formato/Comportamento', options: [
4360
4739
  { value: false, text: 'Sem ticks' },
4361
4740
  { value: true, text: 'Com ticks' },
4362
4741
  { value: 'auto', text: 'Auto' },
4363
4742
  ], hint: 'Marcas na trilha; auto calcula com base no step.' },
4743
+ { name: 'marks', label: 'Marcadores (JSON)', editorType: 'textarea', group: 'Formato/Comportamento', hint: 'Array JSON. Ex.: [{"value":0,"label":"Min"},{"value":100,"label":"Max","tone":"danger"}].' },
4744
+ { name: 'semanticBands', label: 'Bandas semanticas (JSON)', editorType: 'textarea', group: 'Formato/Comportamento', hint: 'Array JSON. Ex.: [{"start":0,"end":40,"label":"Baixo","tone":"success"}].' },
4745
+ { name: 'distribution', label: 'Distribuicao (JSON)', editorType: 'textarea', group: 'Formato/Comportamento', hint: 'Array JSON ou config de histograma compacto. Ex.: {"colorMode":"gradient","bins":[4,8,16,12,6]}.' },
4746
+ { name: 'track', label: 'Track', editorType: 'select', group: 'Formato/Comportamento', options: [
4747
+ { value: 'normal', text: 'Normal' },
4748
+ { value: 'inverted', text: 'Invertido' },
4749
+ { value: 'none', text: 'Sem track ativo' },
4750
+ ], hint: 'Apresentacao visual do track.' },
4751
+ { name: 'size', label: 'Tamanho', editorType: 'select', group: 'Formato/Comportamento', options: [
4752
+ { value: 'small', text: 'Pequeno' },
4753
+ { value: 'medium', text: 'Medio' },
4754
+ { value: 'large', text: 'Grande' },
4755
+ ], hint: 'Densidade visual do slider.' },
4756
+ { name: 'scale', label: 'Escala', editorType: 'select', group: 'Formato/Comportamento', options: [
4757
+ { value: 'linear', text: 'Linear' },
4758
+ { value: 'percent', text: 'Percentual' },
4759
+ { value: 'log', text: 'Logaritmica' },
4760
+ { value: 'pow2', text: 'Potencia 2' },
4761
+ ], hint: 'Escala declarativa para dominios nao lineares.' },
4762
+ { name: 'shiftStep', label: 'Shift step', editorType: 'number', group: 'Formato/Comportamento', hint: 'Incremento acelerado para teclado.' },
4763
+ { name: 'disableThumbSwap', label: 'Bloquear troca dos thumbs', editorType: 'checkbox', group: 'Formato/Comportamento', hint: 'Mantem start/end sem permitir inversao visual no modo range.' },
4364
4764
  { name: 'discrete', label: 'Discreto', editorType: 'checkbox', group: 'Formato/Comportamento', hint: 'Mostra valor fixo por tick; use com showTicks.' },
4365
4765
  { name: 'readonly', label: 'Somente leitura', editorType: 'checkbox', group: 'Formato/Comportamento', row: 'comp.state', inline: true, hint: 'Mantém o valor renderizado sem permitir ajuste do slider.' },
4366
4766
  { name: 'disabled', label: 'Desabilitado', editorType: 'checkbox', group: 'Formato/Comportamento', row: 'comp.state', inline: true, hint: 'Desativa arraste, foco e presets rápidos.' },
@@ -7357,17 +7757,30 @@ class FieldMetadataEditorComponent {
7357
7757
  }
7358
7758
  normalizeEntityLookupPatchValues(patch) {
7359
7759
  const optionSource = patch?.optionSource;
7360
- if (!optionSource || typeof optionSource !== 'object') {
7361
- return;
7760
+ if (optionSource && typeof optionSource === 'object') {
7761
+ this.normalizeStringListProperty(optionSource, 'descriptionPropertyPaths');
7762
+ this.normalizeStringListProperty(optionSource, 'searchPropertyPaths');
7763
+ this.normalizeStringListProperty(optionSource, 'dependsOn');
7764
+ this.normalizeJsonObjectProperty(optionSource, 'dependencyFilterMap');
7765
+ this.normalizeJsonObjectProperty(optionSource, 'create');
7766
+ const selectionPolicy = optionSource.selectionPolicy;
7767
+ if (selectionPolicy && typeof selectionPolicy === 'object') {
7768
+ this.normalizeStringListProperty(selectionPolicy, 'allowedStatuses');
7769
+ this.normalizeStringListProperty(selectionPolicy, 'blockedStatuses');
7770
+ }
7771
+ const filtering = optionSource.filtering;
7772
+ if (filtering && typeof filtering === 'object') {
7773
+ this.normalizeJsonArrayProperty(filtering, 'availableFilters');
7774
+ this.normalizeJsonObjectProperty(filtering, 'defaultFilters');
7775
+ this.normalizeJsonArrayProperty(filtering, 'sortOptions');
7776
+ this.normalizeStringListProperty(filtering, 'quickFilterFields');
7777
+ }
7362
7778
  }
7363
- this.normalizeStringListProperty(optionSource, 'descriptionPropertyPaths');
7364
- this.normalizeStringListProperty(optionSource, 'searchPropertyPaths');
7365
- this.normalizeStringListProperty(optionSource, 'dependsOn');
7366
- this.normalizeJsonObjectProperty(optionSource, 'dependencyFilterMap');
7367
- const selectionPolicy = optionSource.selectionPolicy;
7368
- if (selectionPolicy && typeof selectionPolicy === 'object') {
7369
- this.normalizeStringListProperty(selectionPolicy, 'allowedStatuses');
7370
- this.normalizeStringListProperty(selectionPolicy, 'blockedStatuses');
7779
+ this.normalizeStringListProperty(patch, 'badgeKeys');
7780
+ this.normalizeJsonObjectProperty(patch, 'statusToneMap');
7781
+ const dialog = patch?.dialog;
7782
+ if (dialog && typeof dialog === 'object') {
7783
+ this.normalizeJsonArrayProperty(dialog, 'resultColumns');
7371
7784
  }
7372
7785
  }
7373
7786
  normalizeStringListProperty(target, key) {
@@ -7388,6 +7801,15 @@ class FieldMetadataEditorComponent {
7388
7801
  target[key] = parsed;
7389
7802
  }
7390
7803
  }
7804
+ normalizeJsonArrayProperty(target, key) {
7805
+ if (!target || typeof target !== 'object' || typeof target[key] !== 'string') {
7806
+ return;
7807
+ }
7808
+ const parsed = this.parseArrayTextarea(target[key]);
7809
+ if (parsed) {
7810
+ target[key] = parsed;
7811
+ }
7812
+ }
7391
7813
  normalizeArrayPatchValues(patch) {
7392
7814
  const arrayPatch = patch?.array;
7393
7815
  if (!arrayPatch || typeof arrayPatch !== 'object') {
@@ -8786,6 +9208,16 @@ const cascadeSchema = {
8786
9208
  debounceMs: { type: 'number' },
8787
9209
  loadMode: { enum: ['immediate', 'manual', 'respectLoadOn'] },
8788
9210
  dependencyFilterMap: { type: 'object' },
9211
+ optionSource: {
9212
+ type: 'object',
9213
+ properties: {
9214
+ kind: { enum: ['static', 'remote', 'resource', 'lookup'] },
9215
+ resource: { type: 'string' },
9216
+ endpoint: { type: 'string' },
9217
+ dependsOn: { type: 'string' },
9218
+ dependencyFilterMap: { type: 'object' },
9219
+ },
9220
+ },
8789
9221
  },
8790
9222
  };
8791
9223
  const PRAXIS_METADATA_EDITOR_AUTHORING_MANIFEST = {
@@ -8894,7 +9326,7 @@ const PRAXIS_METADATA_EDITOR_AUTHORING_MANIFEST = {
8894
9326
  inputSchema: cascadeSchema,
8895
9327
  effects: [{ kind: 'compile-domain-patch', handler: 'metadata-cascade-configure', handlerContract: {
8896
9328
  reads: ['CascadeManagerTabComponent', 'CascadeRulesService', 'fields', 'fieldMetadata.optionSource', 'fieldMetadata.dependencyFields', 'fieldMetadata.dependencyFilterMap'],
8897
- writes: ['fieldMetadata.dependencyFields', 'fieldMetadata.enableDependencyCascade', 'fieldMetadata.resetOnDependentChange', 'fieldMetadata.dependencyFilterMap', 'fieldMetadata.dependencyValuePath', 'fieldMetadata.dependencyMergeStrategy', 'fieldMetadata.dependencyDebounceMs', 'fieldMetadata.dependencyLoadOnChange'],
9329
+ writes: ['fieldMetadata.dependencyFields', 'fieldMetadata.enableDependencyCascade', 'fieldMetadata.resetOnDependentChange', 'fieldMetadata.dependencyFilterMap', 'fieldMetadata.dependencyValuePath', 'fieldMetadata.dependencyMergeStrategy', 'fieldMetadata.dependencyDebounceMs', 'fieldMetadata.dependencyLoadOnChange', 'fieldMetadata.optionSource.dependsOn', 'fieldMetadata.optionSource.dependencyFilterMap'],
8898
9330
  identityKeys: ['dependentField', 'sourceField'],
8899
9331
  inputSchema: cascadeSchema,
8900
9332
  failureModes: ['dependent-field-not-found', 'source-field-not-found', 'cascade-cycle-detected', 'dependency-filter-map-invalid'],
@@ -8902,9 +9334,9 @@ const PRAXIS_METADATA_EDITOR_AUTHORING_MANIFEST = {
8902
9334
  } }],
8903
9335
  destructive: false,
8904
9336
  requiresConfirmation: false,
8905
- validators: ['cascade-fields-exist', 'cascade-cycle-free', 'cascade-backend-shape-preserved', 'metadata-round-trip'],
8906
- affectedPaths: ['fieldMetadata.dependencyFields', 'fieldMetadata.enableDependencyCascade', 'fieldMetadata.resetOnDependentChange', 'fieldMetadata.dependencyFilterMap', 'fieldMetadata.dependencyValuePath', 'fieldMetadata.dependencyMergeStrategy', 'fieldMetadata.dependencyDebounceMs', 'fieldMetadata.dependencyLoadOnChange'],
8907
- submissionImpact: 'config-only',
9337
+ validators: ['cascade-fields-exist', 'cascade-cycle-free', 'cascade-backend-shape-preserved', 'option-source-shape-canonical', 'remote-option-source-governed', 'metadata-round-trip'],
9338
+ affectedPaths: ['fieldMetadata.dependencyFields', 'fieldMetadata.enableDependencyCascade', 'fieldMetadata.resetOnDependentChange', 'fieldMetadata.dependencyFilterMap', 'fieldMetadata.dependencyValuePath', 'fieldMetadata.dependencyMergeStrategy', 'fieldMetadata.dependencyDebounceMs', 'fieldMetadata.dependencyLoadOnChange', 'fieldMetadata.optionSource.dependsOn', 'fieldMetadata.optionSource.dependencyFilterMap'],
9339
+ submissionImpact: 'affects-remote-binding',
8908
9340
  preconditions: ['field-list-loaded'],
8909
9341
  },
8910
9342
  {
package/index.d.ts CHANGED
@@ -157,6 +157,7 @@ declare class FieldMetadataEditorComponent implements OnInit {
157
157
  private normalizeEntityLookupPatchValues;
158
158
  private normalizeStringListProperty;
159
159
  private normalizeJsonObjectProperty;
160
+ private normalizeJsonArrayProperty;
160
161
  private normalizeArrayPatchValues;
161
162
  private normalizeArrayCountRuleValue;
162
163
  private toEditorControlValue;
package/package.json CHANGED
@@ -1,10 +1,18 @@
1
1
  {
2
2
  "name": "@praxisui/metadata-editor",
3
- "version": "8.0.0-beta.19",
3
+ "version": "8.0.0-beta.20",
4
4
  "description": "Metadata editor for Praxis UI fields and components with runtime integration.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^20.0.0",
7
- "@angular/core": "^20.0.0"
7
+ "@angular/core": "^20.0.0",
8
+ "@angular/cdk": "^20.0.0",
9
+ "@angular/forms": "^20.0.0",
10
+ "@angular/material": "^20.0.0",
11
+ "@praxisui/ai": "^8.0.0-beta.20",
12
+ "@praxisui/core": "^8.0.0-beta.20",
13
+ "@praxisui/dynamic-fields": "^8.0.0-beta.20",
14
+ "@praxisui/settings-panel": "^8.0.0-beta.20",
15
+ "rxjs": "~7.8.0"
8
16
  },
9
17
  "dependencies": {
10
18
  "tslib": "^2.3.0"