@praxisui/crud 9.0.4-rc.2 → 9.0.4-rc.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.
- package/README.md +20 -1
- package/ai/component-registry.json +44 -8
- package/fesm2022/praxisui-crud.mjs +220 -83
- package/package.json +7 -7
- package/types/praxisui-crud.d.ts +11 -2
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Use this package to combine `@praxisui/table`, `@praxisui/dynamic-form`, governe
|
|
|
20
20
|
## Install
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npm i @praxisui/crud@
|
|
23
|
+
npm i @praxisui/crud@rc
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
Peer dependencies:
|
|
@@ -123,6 +123,21 @@ Child component semantics stay with their owners:
|
|
|
123
123
|
- dialog presentation belongs to `@praxisui/dialog` and host adapters
|
|
124
124
|
- page composition belongs to `@praxisui/page-builder`
|
|
125
125
|
|
|
126
|
+
Item surfaces published by capabilities are not limited to the conventional
|
|
127
|
+
`create`, `view`, and `edit` ids. A row may expose domain surfaces such as
|
|
128
|
+
`payroll-history`, `address`, or `equipment-custody`. The runtime trusts the
|
|
129
|
+
canonical `ResourceSurfaceCatalogItem` carried by the row action; if that object
|
|
130
|
+
is not forwarded, it resolves the exact `surface.id` through the row HATEOAS
|
|
131
|
+
links. A surface is distinguished from a business action by its `kind` and is
|
|
132
|
+
materialized with the corresponding widget. Related collection surfaces open a
|
|
133
|
+
governed `praxis-table` filtered by the selected parent id, while unavailable
|
|
134
|
+
surfaces remain disabled according to their published availability decision.
|
|
135
|
+
|
|
136
|
+
Consumers should not translate these domain surfaces into local CRUD aliases or
|
|
137
|
+
duplicate their filters in the host. The backend owns relationship metadata and
|
|
138
|
+
availability; `@praxisui/core`, `@praxisui/table`, and `@praxisui/crud` own the
|
|
139
|
+
materialization and immediate interaction feedback.
|
|
140
|
+
|
|
126
141
|
## Open Modes
|
|
127
142
|
|
|
128
143
|
CRUD actions can open by route, modal, or drawer. `CrudLauncherService` resolves the final mode from persisted overrides, action metadata, and global/default configuration.
|
|
@@ -165,6 +180,10 @@ maximizing or restoring. The default edge is right/top; a configured left edge
|
|
|
165
180
|
is preserved by the same lifecycle. `defaults.modal.edgeGap` controls the
|
|
166
181
|
viewport inset while maximized. Provide `CRUD_DRAWER_ADAPTER` only when a
|
|
167
182
|
host must replace that standard shell with a real corporate drawer implementation.
|
|
183
|
+
Upstream surface materializers should publish the semantic `openMode` and leave
|
|
184
|
+
geometry absent unless the host intentionally overrides it with a valid
|
|
185
|
+
`DialogPosition` object. Values such as `position: "end"` are not drawer
|
|
186
|
+
positions and must not be used to imitate a side panel.
|
|
168
187
|
|
|
169
188
|
For edit drawers and modals, the runtime presents the selected record identity
|
|
170
189
|
above the command form when the table has materialized it. An explicit valid
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-
|
|
3
|
+
"generatedAt": "2026-08-04T11:45:12.207Z",
|
|
4
4
|
"packageName": "@praxisui/crud",
|
|
5
|
-
"packageVersion": "9.0.4-rc.
|
|
5
|
+
"packageVersion": "9.0.4-rc.20",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 2,
|
|
@@ -11403,6 +11403,24 @@
|
|
|
11403
11403
|
],
|
|
11404
11404
|
"description": "Metodo HTTP canonico para o submit quando o backend publica operacao explicita."
|
|
11405
11405
|
},
|
|
11406
|
+
{
|
|
11407
|
+
"path": "inputs.submitIdempotencyKey",
|
|
11408
|
+
"category": "inputs",
|
|
11409
|
+
"valueKind": "string",
|
|
11410
|
+
"description": "Identidade estavel da tentativa de comando, materializada a partir da politica execution da action."
|
|
11411
|
+
},
|
|
11412
|
+
{
|
|
11413
|
+
"path": "inputs.submitCorrelationId",
|
|
11414
|
+
"category": "inputs",
|
|
11415
|
+
"valueKind": "string",
|
|
11416
|
+
"description": "Identificador de correlacao governado para rastreabilidade ponta a ponta do comando."
|
|
11417
|
+
},
|
|
11418
|
+
{
|
|
11419
|
+
"path": "inputs.submitResourceVersion",
|
|
11420
|
+
"category": "inputs",
|
|
11421
|
+
"valueKind": "string",
|
|
11422
|
+
"description": "Versao persistida esperada, transportada como If-Match quando exigida pela action."
|
|
11423
|
+
},
|
|
11406
11424
|
{
|
|
11407
11425
|
"path": "inputs.responseSchemaUrl",
|
|
11408
11426
|
"category": "inputs",
|
|
@@ -11452,6 +11470,17 @@
|
|
|
11452
11470
|
"description": "Preset usado somente na criacao inicial de FormConfig a partir de schema/metadata.",
|
|
11453
11471
|
"safetyNotes": "Nao reprocessa layouts ja persistidos ou authorados."
|
|
11454
11472
|
},
|
|
11473
|
+
{
|
|
11474
|
+
"path": "inputs.configPersistenceStrategy",
|
|
11475
|
+
"category": "inputs",
|
|
11476
|
+
"valueKind": "enum",
|
|
11477
|
+
"allowedValues": [
|
|
11478
|
+
"local-first",
|
|
11479
|
+
"input-first"
|
|
11480
|
+
],
|
|
11481
|
+
"description": "Define se preferências locais persistidas ou o contrato explícito do host governam a materialização corrente.",
|
|
11482
|
+
"safetyNotes": "Use input-first em commands e surfaces transitórias; isso impede que mode e estados operacionais antigos sobrescrevam o schema atual."
|
|
11483
|
+
},
|
|
11455
11484
|
{
|
|
11456
11485
|
"path": "inputs.layoutPolicy",
|
|
11457
11486
|
"category": "inputs",
|
|
@@ -11522,6 +11551,13 @@
|
|
|
11522
11551
|
"description": "Define como uma linha groupedCommand com um unico campo usa o espaco restante. O default medium-and-wide expande spans 6 ou 8 e preserva campos compactos.",
|
|
11523
11552
|
"safetyNotes": "Use preserve quando o espaco vazio for intencional; use all apenas quando ate campos xs/sm devam ocupar a linha completa."
|
|
11524
11553
|
},
|
|
11554
|
+
{
|
|
11555
|
+
"path": "inputs.layoutPolicy.groupedCommand.contextFields",
|
|
11556
|
+
"category": "inputs",
|
|
11557
|
+
"valueKind": "array",
|
|
11558
|
+
"description": "Campos canônicos do request cujo valor vem do contexto da surface. Eles permanecem no FormGroup e no payload, sem renderizar controles redundantes.",
|
|
11559
|
+
"safetyNotes": "Use somente para campos realmente hidratados por initialValue ou leitura da entidade; nunca use para esconder dados que a pessoa ainda precisa informar."
|
|
11560
|
+
},
|
|
11525
11561
|
{
|
|
11526
11562
|
"path": "inputs.layoutPolicy.detailSummary",
|
|
11527
11563
|
"category": "inputs",
|
|
@@ -12183,9 +12219,9 @@
|
|
|
12183
12219
|
{
|
|
12184
12220
|
"chunkIndex": 10,
|
|
12185
12221
|
"chunkKind": "capabilities",
|
|
12186
|
-
"content": "Schema Capability:\n - Path: fieldMetadata[].transformDisplayValue\n Category: transform\n Kind: expression\n Description: Transforma valor para exibição.\n\nSchema Capability:\n - Path: fieldMetadata[].transformSaveValue\n Category: transform\n Kind: expression\n Description: Transforma valor para salvar.\n\nSchema Capability:\n - Path: fieldMetadata[].textTransformApply\n Category: transform\n Kind: enum\n Description: Quando aplicar transformação de texto.\n\nSchema Capability:\n - Path: fieldMetadata[].inlineEditing\n Category: behavior\n Kind: boolean\n Description: Permite edição inline (tabelas).\n\nSchema Capability:\n - Path: fieldMetadata[].unique\n Category: validation\n Kind: boolean\n Description: Valida unicidade no backend.\n\nSchema Capability:\n - Path: fieldMetadata[].readOnly\n Category: behavior\n Kind: boolean\n Description: Campo somente leitura.\n\nSchema Capability:\n - Path: fieldMetadata[].disabled\n Category: behavior\n Kind: boolean\n Description: Campo desabilitado.\n\nSchema Capability:\n - Path: fieldMetadata[].defaultValue\n Category: data\n Kind: object\n Description: Valor inicial do campo.\n\nSchema Capability:\n - Path: fieldMetadata[].ariaLabel\n Category: accessibility\n Kind: string\n Description: Label para leitores de tela.\n\nSchema Capability:\n - Path: fieldMetadata[].ariaDescribedBy\n Category: accessibility\n Kind: string\n Description: IDs de descrição acessível.\n\nSchema Capability:\n - Path: fieldMetadata[].tabIndex\n Category: accessibility\n Kind: number\n Description: Ordem de tabulacao para teclado.\n\nSchema Capability:\n - Path: fieldMetadata[].accessKey\n Category: accessibility\n Kind: string\n Description: Atalho de teclado (accessKey).\n\nComponent Capability:\n - Path: inputs.resourcePath\n Category: inputs\n Kind: string\n Description: Caminho do recurso para carregar/salvar dados via CRUD.\n\nComponent Capability:\n - Path: inputs.resourceId\n Category: inputs\n Kind: string\n Description: ID do registro atual (string ou number).\n\nComponent Capability:\n - Path: inputs.initialValue\n Category: inputs\n Kind: object\n Description: Valores iniciais locais para campos host-authored ou complementares.\n\nComponent Capability:\n - Path: inputs.mode\n Category: inputs\n Kind: enum\n Description: Modo do formulario (create/edit/view).\n\nComponent Capability:\n - Path: inputs.config\n Category: inputs\n Kind: object\n Description: Configuracao completa do formulario (FormConfig).\n\nComponent Capability:\n - Path: inputs.schemaSource\n Category: inputs\n Kind: enum\n Description: Fonte de schema para construcao automatica (resource/filter).\n\nComponent Capability:\n - Path: inputs.schemaUrl\n Category: inputs\n Kind: string\n Description: Schema canonico explicito publicado pelo backend para hosts que seguem surfaces/actions/capabilities.\n\nComponent Capability:\n - Path: inputs.readUrl\n Category: inputs\n Kind: string\n Description: Endpoint canonico de leitura publicado por surface VIEW/READ_PROJECTION para hidratar a entidade exibida.\n\nComponent Capability:\n - Path: inputs.apiEndpointKey\n Category: inputs\n Kind: string\n Description: Endpoint canonico usado para resolver schemaUrl, readUrl e submitUrl relativos em hosts destacados.\n\nComponent Capability:\n - Path: inputs.submitUrl\n Category: inputs\n Kind: string\n Description: Endpoint canonico de submit publicado por surface/action.\n\nComponent Capability:\n - Path: inputs.submitMethod\n Category: inputs\n Kind: enum\n Description: Metodo HTTP canonico para o submit quando o backend publica operacao explicita.\n\nComponent Capability:\n - Path: inputs.responseSchemaUrl\n Category: inputs\n Kind: string\n Description: Schema de resposta publicado pelo backend para inspeção diagnostica/read-only do host.\n\nComponent Capability:\n - Path: inputs.enableCustomization\n Category: inputs\n Kind: boolean\n Description: Habilita a edicao de layout/configuracao no editor.\n\nComponent Capability:\n - Path: inputs.showAiAssistant\n Category: inputs\n Kind: boolean\n Description: Mostra os gatilhos do copiloto semantico Praxis para a instancia do formulario.\n\nComponent Capability:\n - Path: inputs.formId\n Category: inputs\n Kind: string\n Description: ID persistente para salvar configuracoes e preferencias.\n\nComponent Capability:\n - Path: inputs.editorialContext\n Category: inputs\n Kind: object\n Description: Override de contexto editorial fornecido pelo host para os blocos hospedados antes/depois do formulario.\n\nComponent Capability:\n - Path: inputs.layout\n Category: inputs\n Kind: object\n Description: Layout legado (FormLayout). Preferir inputs.config + sections.\n\nComponent Capability:\n - Path: inputs.generatedLayoutPreset\n Category: inputs\n Kind: enum\n Description: Preset usado somente na criacao inicial de FormConfig a partir de schema/metadata.\n\nComponent Capability:\n - Path: inputs.layoutPolicy\n Category: inputs\n Kind: object\n Description: Politica opt-in para materializar layout diretamente do schema atual sem depender de FormConfig.sections authoradas.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.source\n Category: inputs\n Kind: enum\n Description: Define se o layout vem de configuracao authorada ou do schema.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.preset\n Category: inputs\n Kind: enum\n Description: Preset de layout schema-driven. compactPresentation cobre detalhe read-only; groupedCommand cobre create/edit.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.intent\n Category: inputs\n Kind: enum\n Description: Intencao da surface: detalhe/apresentacao ou comando/editavel.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.lifecycle\n Category: inputs\n Kind: enum\n Description: Ciclo de materializacao do layout schema-driven.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.persistence\n Category: inputs\n Kind: enum\n Description: Define se sections geradas sao transient ou podem virar layout authorado apos detach explicito.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.groupedCommand.orphanFieldExpansion\n Category: inputs\n Kind: enum\n Description: Define como uma linha groupedCommand com um unico campo usa o espaco restante. O default medium-and-wide expande spans 6 ou 8 e preserva campos compactos.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.
|
|
12222
|
+
"content": "Schema Capability:\n - Path: fieldMetadata[].transformDisplayValue\n Category: transform\n Kind: expression\n Description: Transforma valor para exibição.\n\nSchema Capability:\n - Path: fieldMetadata[].transformSaveValue\n Category: transform\n Kind: expression\n Description: Transforma valor para salvar.\n\nSchema Capability:\n - Path: fieldMetadata[].textTransformApply\n Category: transform\n Kind: enum\n Description: Quando aplicar transformação de texto.\n\nSchema Capability:\n - Path: fieldMetadata[].inlineEditing\n Category: behavior\n Kind: boolean\n Description: Permite edição inline (tabelas).\n\nSchema Capability:\n - Path: fieldMetadata[].unique\n Category: validation\n Kind: boolean\n Description: Valida unicidade no backend.\n\nSchema Capability:\n - Path: fieldMetadata[].readOnly\n Category: behavior\n Kind: boolean\n Description: Campo somente leitura.\n\nSchema Capability:\n - Path: fieldMetadata[].disabled\n Category: behavior\n Kind: boolean\n Description: Campo desabilitado.\n\nSchema Capability:\n - Path: fieldMetadata[].defaultValue\n Category: data\n Kind: object\n Description: Valor inicial do campo.\n\nSchema Capability:\n - Path: fieldMetadata[].ariaLabel\n Category: accessibility\n Kind: string\n Description: Label para leitores de tela.\n\nSchema Capability:\n - Path: fieldMetadata[].ariaDescribedBy\n Category: accessibility\n Kind: string\n Description: IDs de descrição acessível.\n\nSchema Capability:\n - Path: fieldMetadata[].tabIndex\n Category: accessibility\n Kind: number\n Description: Ordem de tabulacao para teclado.\n\nSchema Capability:\n - Path: fieldMetadata[].accessKey\n Category: accessibility\n Kind: string\n Description: Atalho de teclado (accessKey).\n\nComponent Capability:\n - Path: inputs.resourcePath\n Category: inputs\n Kind: string\n Description: Caminho do recurso para carregar/salvar dados via CRUD.\n\nComponent Capability:\n - Path: inputs.resourceId\n Category: inputs\n Kind: string\n Description: ID do registro atual (string ou number).\n\nComponent Capability:\n - Path: inputs.initialValue\n Category: inputs\n Kind: object\n Description: Valores iniciais locais para campos host-authored ou complementares.\n\nComponent Capability:\n - Path: inputs.mode\n Category: inputs\n Kind: enum\n Description: Modo do formulario (create/edit/view).\n\nComponent Capability:\n - Path: inputs.config\n Category: inputs\n Kind: object\n Description: Configuracao completa do formulario (FormConfig).\n\nComponent Capability:\n - Path: inputs.schemaSource\n Category: inputs\n Kind: enum\n Description: Fonte de schema para construcao automatica (resource/filter).\n\nComponent Capability:\n - Path: inputs.schemaUrl\n Category: inputs\n Kind: string\n Description: Schema canonico explicito publicado pelo backend para hosts que seguem surfaces/actions/capabilities.\n\nComponent Capability:\n - Path: inputs.readUrl\n Category: inputs\n Kind: string\n Description: Endpoint canonico de leitura publicado por surface VIEW/READ_PROJECTION para hidratar a entidade exibida.\n\nComponent Capability:\n - Path: inputs.apiEndpointKey\n Category: inputs\n Kind: string\n Description: Endpoint canonico usado para resolver schemaUrl, readUrl e submitUrl relativos em hosts destacados.\n\nComponent Capability:\n - Path: inputs.submitUrl\n Category: inputs\n Kind: string\n Description: Endpoint canonico de submit publicado por surface/action.\n\nComponent Capability:\n - Path: inputs.submitMethod\n Category: inputs\n Kind: enum\n Description: Metodo HTTP canonico para o submit quando o backend publica operacao explicita.\n\nComponent Capability:\n - Path: inputs.submitIdempotencyKey\n Category: inputs\n Kind: string\n Description: Identidade estavel da tentativa de comando, materializada a partir da politica execution da action.\n\nComponent Capability:\n - Path: inputs.submitCorrelationId\n Category: inputs\n Kind: string\n Description: Identificador de correlacao governado para rastreabilidade ponta a ponta do comando.\n\nComponent Capability:\n - Path: inputs.submitResourceVersion\n Category: inputs\n Kind: string\n Description: Versao persistida esperada, transportada como If-Match quando exigida pela action.\n\nComponent Capability:\n - Path: inputs.responseSchemaUrl\n Category: inputs\n Kind: string\n Description: Schema de resposta publicado pelo backend para inspeção diagnostica/read-only do host.\n\nComponent Capability:\n - Path: inputs.enableCustomization\n Category: inputs\n Kind: boolean\n Description: Habilita a edicao de layout/configuracao no editor.\n\nComponent Capability:\n - Path: inputs.showAiAssistant\n Category: inputs\n Kind: boolean\n Description: Mostra os gatilhos do copiloto semantico Praxis para a instancia do formulario.\n\nComponent Capability:\n - Path: inputs.formId\n Category: inputs\n Kind: string\n Description: ID persistente para salvar configuracoes e preferencias.\n\nComponent Capability:\n - Path: inputs.editorialContext\n Category: inputs\n Kind: object\n Description: Override de contexto editorial fornecido pelo host para os blocos hospedados antes/depois do formulario.\n\nComponent Capability:\n - Path: inputs.layout\n Category: inputs\n Kind: object\n Description: Layout legado (FormLayout). Preferir inputs.config + sections.\n\nComponent Capability:\n - Path: inputs.generatedLayoutPreset\n Category: inputs\n Kind: enum\n Description: Preset usado somente na criacao inicial de FormConfig a partir de schema/metadata.\n\nComponent Capability:\n - Path: inputs.configPersistenceStrategy\n Category: inputs\n Kind: enum\n Description: Define se preferências locais persistidas ou o contrato explícito do host governam a materialização corrente.\n\nComponent Capability:\n - Path: inputs.layoutPolicy\n Category: inputs\n Kind: object\n Description: Politica opt-in para materializar layout diretamente do schema atual sem depender de FormConfig.sections authoradas.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.source\n Category: inputs\n Kind: enum\n Description: Define se o layout vem de configuracao authorada ou do schema.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.preset\n Category: inputs\n Kind: enum\n Description: Preset de layout schema-driven. compactPresentation cobre detalhe read-only; groupedCommand cobre create/edit.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.intent\n Category: inputs\n Kind: enum\n Description: Intencao da surface: detalhe/apresentacao ou comando/editavel.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.lifecycle\n Category: inputs\n Kind: enum\n Description: Ciclo de materializacao do layout schema-driven.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.persistence\n Category: inputs\n Kind: enum\n Description: Define se sections geradas sao transient ou podem virar layout authorado apos detach explicito.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.groupedCommand.orphanFieldExpansion\n Category: inputs\n Kind: enum\n Description: Define como uma linha groupedCommand com um unico campo usa o espaco restante. O default medium-and-wide expande spans 6 ou 8 e preserva campos compactos.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.groupedCommand.contextFields\n Category: inputs\n Kind: array\n Description: Campos canônicos do request cujo valor vem do contexto da surface. Eles permanecem no FormGroup e no payload, sem renderizar controles redundantes.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary\n Category: inputs\n Kind: object\n Description: Politica declarativa para resumo read-only compacto em compactPresentation, sem FormConfig.sections locais.",
|
|
12187
12223
|
"sourcePointer": "projects/praxis-dynamic-form/src/lib/ai/form-ai-capabilities.ts",
|
|
12188
|
-
"contentHash": "
|
|
12224
|
+
"contentHash": "c0a08ef89a122e2e5ec62606017281c689a4e7e35662112e4ea5c00dbd4e3055",
|
|
12189
12225
|
"sourceKind": "component_definition",
|
|
12190
12226
|
"sourceId": "praxis-dynamic-form-dialog-host",
|
|
12191
12227
|
"corpusVersion": "1.0.0"
|
|
@@ -12193,9 +12229,9 @@
|
|
|
12193
12229
|
{
|
|
12194
12230
|
"chunkIndex": 11,
|
|
12195
12231
|
"chunkKind": "capabilities",
|
|
12196
|
-
"content": "Component Capability:\n - Path: inputs.layoutPolicy.detailSummary.excludeRoles\n Category: inputs\n Kind: array\n Description: Lista de papeis semanticos de campo que devem ficar fora do resumo read-only compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.maxFields\n Category: inputs\n Kind: number\n Description: Limite maximo de campos materializados no primeiro painel compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.fieldPriority\n Category: inputs\n Kind: object\n Description: Mapa campo -> prioridade para ordenar campos do resumo quando o schema publica candidatos suficientes.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.groupPriority\n Category: inputs\n Kind: object\n Description: Mapa grupo -> prioridade para ordenar grupos do resumo quando o schema publica agrupamento semantico.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.columns\n Category: inputs\n Kind: number\n Description: Quantidade base de colunas para distribuir campos de resumo schema-driven sem criar FormConfig.sections locais.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.responsiveColumns\n Category: inputs\n Kind: object\n Description: Mapa de colunas por breakpoint xs/sm/md/lg/xl para detalhes read-only compactos em drawers, side sheets e desktop largo.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.widthPrecedence\n Category: inputs\n Kind: enum\n Description: Define se larguras explicitas do schema ou a densidade do resumo controlam os spans no compactPresentation read-only.\n\nComponent Capability:\n - Path: inputs.fieldIconPolicy\n Category: inputs\n Kind: enum\n Description: Controla se icones prefix/suffix dos metadados aparecem em todos os modos, apenas apresentacao, ou nunca.\n\nComponent Capability:\n - Path: inputs.backConfig\n Category: inputs\n Kind: object\n Description: Configuracao de navegacao/retorno (BackConfig).\n\nComponent Capability:\n - Path: inputs.backConfig.strategy\n Category: inputs\n Kind: enum\n Description: Estrategia de retorno (auto/close/navigate).\n\nComponent Capability:\n - Path: inputs.backConfig.returnTo\n Category: inputs\n Kind: string\n Description: Rota para retornar quando strategy=navigate.\n\nComponent Capability:\n - Path: inputs.backConfig.confirmOnDirty\n Category: inputs\n Kind: boolean\n Description: Solicita confirmacao ao sair com mudancas nao salvas.\n\nComponent Capability:\n - Path: inputs.hooks\n Category: inputs\n Kind: object\n Description: Declaracoes de hooks fornecidas diretamente ao componente.\n\nComponent Capability:\n - Path: inputs.hooks.beforeInit[]\n Category: hooks\n Kind: array\n Description: Hooks executados antes da inicializacao.\n\nComponent Capability:\n - Path: inputs.hooks.afterInit[]\n Category: hooks\n Kind: array\n Description: Hooks executados apos a inicializacao.\n\nComponent Capability:\n - Path: inputs.hooks.beforeValidate[]\n Category: hooks\n Kind: array\n Description: Hooks executados antes da validacao.\n\nComponent Capability:\n - Path: inputs.hooks.afterValidate[]\n Category: hooks\n Kind: array\n Description: Hooks executados apos a validacao.\n\nComponent Capability:\n - Path: inputs.hooks.beforeSubmit[]\n Category: hooks\n Kind: array\n Description: Hooks executados antes do submit.\n\nComponent Capability:\n - Path: inputs.hooks.afterSubmit[]\n Category: hooks\n Kind: array\n Description: Hooks executados apos o submit.\n\nComponent Capability:\n - Path: inputs.hooks.onError[]\n Category: hooks\n Kind: array\n Description: Hooks executados em erros de submit/validacao.\n\nComponent Capability:\n - Path: inputs.removeEmptyContainersOnSave\n Category: inputs\n Kind: boolean\n Description: Remove containers vazios ao salvar configuracao.\n\nComponent Capability:\n - Path: inputs.reactiveValidation\n Category: inputs\n Kind: boolean\n Description: Ativa validacao reativa (afterValidate em valueChanges).\n\nComponent Capability:\n - Path: inputs.reactiveValidationDebounceMs\n Category: inputs\n Kind: number\n Description: Debounce em ms para validacao reativa.\n\nComponent Capability:\n - Path: inputs.notifyIfOutdated\n Category: inputs\n Kind: enum\n Description: Canal de notificacao para schema desatualizado.\n\nComponent Capability:\n - Path: inputs.snoozeMs\n Category: inputs\n Kind: number\n Description: Duracao do snooze para alertas de schema.\n\nComponent Capability:\n - Path: inputs.autoOpenSettingsOnOutdated\n Category: inputs\n Kind: boolean\n Description: Abre automaticamente o editor ao detectar schema desatualizado.\n\nComponent Capability:\n - Path: inputs.readonlyModeGlobal\n Category: inputs\n Kind: boolean\n Description: Forca modo somente leitura global.\n\nComponent Capability:\n - Path: inputs.disabledModeGlobal\n Category: inputs\n Kind: boolean\n Description: Forca modo desabilitado global.\n\nComponent Capability:\n - Path: inputs.presentationModeGlobal\n Category: inputs\n Kind: boolean\n Description: Ativa modo de apresentacao global (somente view).\n\nComponent Capability:\n - Path: inputs.visibleGlobal\n Category: inputs\n Kind: boolean\n Description: Forca visibilidade global dos campos.\n\nComponent Capability:\n - Path: inputs.customEndpoints\n Category: inputs\n Kind: object\n Description: Override de endpoints CRUD (EndpointConfig).\n\nComponent Capability:\n - Path: inputs.customEndpoints.getAll\n Category: inputs\n Kind: string\n Description: Endpoint customizado para listar registros.\n\nComponent Capability:\n - Path: inputs.customEndpoints.getById\n Category: inputs\n Kind: string\n Description: Endpoint customizado para obter registro por ID.\n\nComponent Capability:\n - Path: inputs.customEndpoints.create\n Category: inputs\n Kind: string\n Description: Endpoint customizado para criar registro.\n\nComponent Capability:\n - Path: inputs.customEndpoints.update\n Category: inputs\n Kind: string\n Description: Endpoint customizado para atualizar registro.\n\nComponent Capability:\n - Path: inputs.customEndpoints.delete\n Category: inputs\n Kind: string\n Description: Endpoint customizado para deletar registro.\n\nComponent Capability:\n - Path: inputs.customEndpoints.filter\n Category: inputs\n Kind: string\n Description: Endpoint customizado para filtro.\n\nComponent Capability:\n - Path: inputs.customEndpoints.schema\n Category: inputs\n Kind: string\n Description: Endpoint customizado para schemas.\n\nComponent Capability:\n - Path: inputs.config.presentation\n Category: appearance\n Kind: object\n Description: Preferencias visuais persistidas no config
|
|
12232
|
+
"content": "Component Capability:\n - Path: inputs.layoutPolicy.detailSummary.includeFields\n Category: inputs\n Kind: array\n Description: Lista de campos canônicos do schema que devem entrar no resumo read-only compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.excludeFields\n Category: inputs\n Kind: array\n Description: Lista de campos canônicos do schema que devem ficar fora do resumo read-only compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.includeGroups\n Category: inputs\n Kind: array\n Description: Lista de grupos do schema que devem entrar no resumo read-only compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.excludeGroups\n Category: inputs\n Kind: array\n Description: Lista de grupos do schema que devem ficar fora do resumo read-only compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.includeRoles\n Category: inputs\n Kind: array\n Description: Lista de papeis semanticos de campo que devem entrar no resumo read-only compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.excludeRoles\n Category: inputs\n Kind: array\n Description: Lista de papeis semanticos de campo que devem ficar fora do resumo read-only compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.maxFields\n Category: inputs\n Kind: number\n Description: Limite maximo de campos materializados no primeiro painel compacto.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.fieldPriority\n Category: inputs\n Kind: object\n Description: Mapa campo -> prioridade para ordenar campos do resumo quando o schema publica candidatos suficientes.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.groupPriority\n Category: inputs\n Kind: object\n Description: Mapa grupo -> prioridade para ordenar grupos do resumo quando o schema publica agrupamento semantico.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.columns\n Category: inputs\n Kind: number\n Description: Quantidade base de colunas para distribuir campos de resumo schema-driven sem criar FormConfig.sections locais.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.responsiveColumns\n Category: inputs\n Kind: object\n Description: Mapa de colunas por breakpoint xs/sm/md/lg/xl para detalhes read-only compactos em drawers, side sheets e desktop largo.\n\nComponent Capability:\n - Path: inputs.layoutPolicy.detailSummary.widthPrecedence\n Category: inputs\n Kind: enum\n Description: Define se larguras explicitas do schema ou a densidade do resumo controlam os spans no compactPresentation read-only.\n\nComponent Capability:\n - Path: inputs.fieldIconPolicy\n Category: inputs\n Kind: enum\n Description: Controla se icones prefix/suffix dos metadados aparecem em todos os modos, apenas apresentacao, ou nunca.\n\nComponent Capability:\n - Path: inputs.backConfig\n Category: inputs\n Kind: object\n Description: Configuracao de navegacao/retorno (BackConfig).\n\nComponent Capability:\n - Path: inputs.backConfig.strategy\n Category: inputs\n Kind: enum\n Description: Estrategia de retorno (auto/close/navigate).\n\nComponent Capability:\n - Path: inputs.backConfig.returnTo\n Category: inputs\n Kind: string\n Description: Rota para retornar quando strategy=navigate.\n\nComponent Capability:\n - Path: inputs.backConfig.confirmOnDirty\n Category: inputs\n Kind: boolean\n Description: Solicita confirmacao ao sair com mudancas nao salvas.\n\nComponent Capability:\n - Path: inputs.hooks\n Category: inputs\n Kind: object\n Description: Declaracoes de hooks fornecidas diretamente ao componente.\n\nComponent Capability:\n - Path: inputs.hooks.beforeInit[]\n Category: hooks\n Kind: array\n Description: Hooks executados antes da inicializacao.\n\nComponent Capability:\n - Path: inputs.hooks.afterInit[]\n Category: hooks\n Kind: array\n Description: Hooks executados apos a inicializacao.\n\nComponent Capability:\n - Path: inputs.hooks.beforeValidate[]\n Category: hooks\n Kind: array\n Description: Hooks executados antes da validacao.\n\nComponent Capability:\n - Path: inputs.hooks.afterValidate[]\n Category: hooks\n Kind: array\n Description: Hooks executados apos a validacao.\n\nComponent Capability:\n - Path: inputs.hooks.beforeSubmit[]\n Category: hooks\n Kind: array\n Description: Hooks executados antes do submit.\n\nComponent Capability:\n - Path: inputs.hooks.afterSubmit[]\n Category: hooks\n Kind: array\n Description: Hooks executados apos o submit.\n\nComponent Capability:\n - Path: inputs.hooks.onError[]\n Category: hooks\n Kind: array\n Description: Hooks executados em erros de submit/validacao.\n\nComponent Capability:\n - Path: inputs.removeEmptyContainersOnSave\n Category: inputs\n Kind: boolean\n Description: Remove containers vazios ao salvar configuracao.\n\nComponent Capability:\n - Path: inputs.reactiveValidation\n Category: inputs\n Kind: boolean\n Description: Ativa validacao reativa (afterValidate em valueChanges).\n\nComponent Capability:\n - Path: inputs.reactiveValidationDebounceMs\n Category: inputs\n Kind: number\n Description: Debounce em ms para validacao reativa.\n\nComponent Capability:\n - Path: inputs.notifyIfOutdated\n Category: inputs\n Kind: enum\n Description: Canal de notificacao para schema desatualizado.\n\nComponent Capability:\n - Path: inputs.snoozeMs\n Category: inputs\n Kind: number\n Description: Duracao do snooze para alertas de schema.\n\nComponent Capability:\n - Path: inputs.autoOpenSettingsOnOutdated\n Category: inputs\n Kind: boolean\n Description: Abre automaticamente o editor ao detectar schema desatualizado.\n\nComponent Capability:\n - Path: inputs.readonlyModeGlobal\n Category: inputs\n Kind: boolean\n Description: Forca modo somente leitura global.\n\nComponent Capability:\n - Path: inputs.disabledModeGlobal\n Category: inputs\n Kind: boolean\n Description: Forca modo desabilitado global.\n\nComponent Capability:\n - Path: inputs.presentationModeGlobal\n Category: inputs\n Kind: boolean\n Description: Ativa modo de apresentacao global (somente view).\n\nComponent Capability:\n - Path: inputs.visibleGlobal\n Category: inputs\n Kind: boolean\n Description: Forca visibilidade global dos campos.\n\nComponent Capability:\n - Path: inputs.customEndpoints\n Category: inputs\n Kind: object\n Description: Override de endpoints CRUD (EndpointConfig).\n\nComponent Capability:\n - Path: inputs.customEndpoints.getAll\n Category: inputs\n Kind: string\n Description: Endpoint customizado para listar registros.\n\nComponent Capability:\n - Path: inputs.customEndpoints.getById\n Category: inputs\n Kind: string\n Description: Endpoint customizado para obter registro por ID.\n\nComponent Capability:\n - Path: inputs.customEndpoints.create\n Category: inputs\n Kind: string\n Description: Endpoint customizado para criar registro.\n\nComponent Capability:\n - Path: inputs.customEndpoints.update\n Category: inputs\n Kind: string\n Description: Endpoint customizado para atualizar registro.\n\nComponent Capability:\n - Path: inputs.customEndpoints.delete\n Category: inputs\n Kind: string\n Description: Endpoint customizado para deletar registro.\n\nComponent Capability:\n - Path: inputs.customEndpoints.filter\n Category: inputs\n Kind: string\n Description: Endpoint customizado para filtro.\n\nComponent Capability:\n - Path: inputs.customEndpoints.schema\n Category: inputs\n Kind: string\n Description: Endpoint customizado para schemas.\n\nComponent Capability:\n - Path: inputs.config.presentation\n Category: appearance\n Kind: object\n Description: Preferencias visuais persistidas no config.",
|
|
12197
12233
|
"sourcePointer": "projects/praxis-dynamic-form/src/lib/ai/form-ai-capabilities.ts",
|
|
12198
|
-
"contentHash": "
|
|
12234
|
+
"contentHash": "e04d360e46c5cf6d9856c9b55a6f140cc7a2fa07a670575bfe1319fd5079b158",
|
|
12199
12235
|
"sourceKind": "component_definition",
|
|
12200
12236
|
"sourceId": "praxis-dynamic-form-dialog-host",
|
|
12201
12237
|
"corpusVersion": "1.0.0"
|
|
@@ -12203,9 +12239,9 @@
|
|
|
12203
12239
|
{
|
|
12204
12240
|
"chunkIndex": 12,
|
|
12205
12241
|
"chunkKind": "capabilities",
|
|
12206
|
-
"content": "Component Capability:\n - Path: inputs.config.presentation.valueAlign\n Category: appearance\n Kind: enum\n Description: Alinhamento do valor.\n\nComponent Capability:\n - Path: outputs.formSubmit\n Category: outputs\n Kind: object\n Description: Evento emitido no submit do formulario.\n\nComponent Capability:\n - Path: outputs.formCancel\n Category: outputs\n Kind: object\n Description: Evento emitido ao cancelar.\n\nComponent Capability:\n - Path: outputs.formReset\n Category: outputs\n Kind: object\n Description: Evento emitido ao resetar o formulario.\n\nComponent Capability:\n - Path: outputs.configChange\n Category: outputs\n Kind: object\n Description: Evento emitido quando a configuracao muda.\n\nComponent Capability:\n - Path: outputs.formReady\n Category: outputs\n Kind: object\n Description: Evento emitido quando o formulario esta pronto.\n\nComponent Capability:\n - Path: outputs.valueChange\n Category: outputs\n Kind: object\n Description: Evento emitido quando o valor do formulario muda.\n\nComponent Capability:\n - Path: outputs.syncCompleted\n Category: outputs\n Kind: object\n Description: Evento emitido ao completar sincronizacao com schema.\n\nComponent Capability:\n - Path: outputs.initializationError\n Category: outputs\n Kind: object\n Description: Evento emitido quando ocorre erro na inicializacao.\n\nComponent Capability:\n - Path: outputs.enableCustomizationChange\n Category: outputs\n Kind: object\n Description: Evento emitido quando o modo de customizacao muda.\n\nComponent Capability:\n - Path: outputs.customAction\n Category: outputs\n Kind: object\n Description: Evento emitido ao disparar acao customizada.\n\nComponent Capability:\n - Path: outputs.actionConfirmation\n Category: outputs\n Kind: object\n Description: Evento emitido quando acao requer confirmacao.\n\nComponent Capability:\n - Path: outputs.schemaStatusChange\n Category: outputs\n Kind: object\n Description: Evento emitido quando o status do schema muda.\n\nCapability Note:\n - Este catalogo descreve inputs e outputs do componente.\n\nCapability Note:\n - O objeto inputs.config segue o schema de FormConfig (veja form-ai-capabilities).\n\nCapability Note:\n - inputs.config.presentation e uma extensao de runtime aplicada pelo componente.\n\nCapability Note:\n - Preferir FormConfig (sections/fieldMetadata) em vez do layout legado (fieldsets).\n\nCapability Note:\n - Use inputs.editorialContext apenas para override de contexto editorial do host; a precedencia final e runtime < config.editorialContext < host.\n\nCapability Note:\n - rich content editorial hospedado pelo form pode ser renderizado em tres slots semanticos: before, beforeActions e after.",
|
|
12242
|
+
"content": "Component Capability:\n - Path: inputs.config.presentation.labelFontSize\n Category: appearance\n Kind: number\n Description: Tamanho da fonte do label (px).\n\nComponent Capability:\n - Path: inputs.config.presentation.valueFontSize\n Category: appearance\n Kind: number\n Description: Tamanho da fonte do valor (px).\n\nComponent Capability:\n - Path: inputs.config.presentation.labelPosition\n Category: appearance\n Kind: enum\n Description: Posicionamento do label (above/left).\n\nComponent Capability:\n - Path: inputs.config.presentation.compact\n Category: appearance\n Kind: boolean\n Description: Modo compacto de apresentacao.\n\nComponent Capability:\n - Path: inputs.config.presentation.density\n Category: appearance\n Kind: enum\n Description: Densidade visual global.\n\nComponent Capability:\n - Path: inputs.config.presentation.labelWidth\n Category: appearance\n Kind: number\n Description: Largura do label (px).\n\nComponent Capability:\n - Path: inputs.config.presentation.labelAlign\n Category: appearance\n Kind: enum\n Description: Alinhamento do label.\n\nComponent Capability:\n - Path: inputs.config.presentation.valueAlign\n Category: appearance\n Kind: enum\n Description: Alinhamento do valor.\n\nComponent Capability:\n - Path: outputs.formSubmit\n Category: outputs\n Kind: object\n Description: Evento emitido no submit do formulario.\n\nComponent Capability:\n - Path: outputs.formCancel\n Category: outputs\n Kind: object\n Description: Evento emitido ao cancelar.\n\nComponent Capability:\n - Path: outputs.formReset\n Category: outputs\n Kind: object\n Description: Evento emitido ao resetar o formulario.\n\nComponent Capability:\n - Path: outputs.configChange\n Category: outputs\n Kind: object\n Description: Evento emitido quando a configuracao muda.\n\nComponent Capability:\n - Path: outputs.formReady\n Category: outputs\n Kind: object\n Description: Evento emitido quando o formulario esta pronto.\n\nComponent Capability:\n - Path: outputs.valueChange\n Category: outputs\n Kind: object\n Description: Evento emitido quando o valor do formulario muda.\n\nComponent Capability:\n - Path: outputs.syncCompleted\n Category: outputs\n Kind: object\n Description: Evento emitido ao completar sincronizacao com schema.\n\nComponent Capability:\n - Path: outputs.initializationError\n Category: outputs\n Kind: object\n Description: Evento emitido quando ocorre erro na inicializacao.\n\nComponent Capability:\n - Path: outputs.enableCustomizationChange\n Category: outputs\n Kind: object\n Description: Evento emitido quando o modo de customizacao muda.\n\nComponent Capability:\n - Path: outputs.customAction\n Category: outputs\n Kind: object\n Description: Evento emitido ao disparar acao customizada.\n\nComponent Capability:\n - Path: outputs.actionConfirmation\n Category: outputs\n Kind: object\n Description: Evento emitido quando acao requer confirmacao.\n\nComponent Capability:\n - Path: outputs.schemaStatusChange\n Category: outputs\n Kind: object\n Description: Evento emitido quando o status do schema muda.\n\nCapability Note:\n - Este catalogo descreve inputs e outputs do componente.\n\nCapability Note:\n - O objeto inputs.config segue o schema de FormConfig (veja form-ai-capabilities).\n\nCapability Note:\n - inputs.config.presentation e uma extensao de runtime aplicada pelo componente.\n\nCapability Note:\n - Preferir FormConfig (sections/fieldMetadata) em vez do layout legado (fieldsets).\n\nCapability Note:\n - Use inputs.editorialContext apenas para override de contexto editorial do host; a precedencia final e runtime < config.editorialContext < host.\n\nCapability Note:\n - rich content editorial hospedado pelo form pode ser renderizado em tres slots semanticos: before, beforeActions e after.",
|
|
12207
12243
|
"sourcePointer": "projects/praxis-dynamic-form/src/lib/ai/form-ai-capabilities.ts",
|
|
12208
|
-
"contentHash": "
|
|
12244
|
+
"contentHash": "beda7b0e56767eb05d2104f64b078e5d582354da389421f4cc5db0853bf87a2a",
|
|
12209
12245
|
"sourceKind": "component_definition",
|
|
12210
12246
|
"sourceId": "praxis-dynamic-form-dialog-host",
|
|
12211
12247
|
"corpusVersion": "1.0.0"
|
|
@@ -103,6 +103,7 @@ class CrudLauncherService {
|
|
|
103
103
|
storage = inject(ASYNC_CONFIG_STORAGE);
|
|
104
104
|
global = inject(GlobalConfigService);
|
|
105
105
|
operationResolver = inject(CrudOperationResolutionService);
|
|
106
|
+
dialogHostPromise;
|
|
106
107
|
drawerAdapter = (() => {
|
|
107
108
|
try {
|
|
108
109
|
return inject(CRUD_DRAWER_ADAPTER);
|
|
@@ -112,6 +113,9 @@ class CrudLauncherService {
|
|
|
112
113
|
}
|
|
113
114
|
})();
|
|
114
115
|
async launch(action, row, metadata, componentKeyId, drawerCallbacks, runtime) {
|
|
116
|
+
const prefetchedDialogHost = this.isLikelyOverlayAction(action, metadata)
|
|
117
|
+
? this.loadDialogHost()
|
|
118
|
+
: undefined;
|
|
115
119
|
// Carregar overrides de CRUD (se houver) e mesclar em uma cópia local
|
|
116
120
|
const merged = await this.mergeCrudOverrides(metadata, action, componentKeyId || undefined);
|
|
117
121
|
merged.action = this.normalizeActionForLaunch(merged.action);
|
|
@@ -177,7 +181,7 @@ class CrudLauncherService {
|
|
|
177
181
|
backdropClasses.push('pfx-transparent-backdrop');
|
|
178
182
|
}
|
|
179
183
|
const mergedBackdropClasses = mergeClassList(backdropClasses, modalCfg.backdropClass);
|
|
180
|
-
const ref = await this.dialog.openAsync(() =>
|
|
184
|
+
const ref = await this.dialog.openAsync(() => prefetchedDialogHost ?? this.loadDialogHost(), {
|
|
181
185
|
...modalCfg,
|
|
182
186
|
panelClass: panelClasses,
|
|
183
187
|
backdropClass: mergedBackdropClasses,
|
|
@@ -256,6 +260,13 @@ class CrudLauncherService {
|
|
|
256
260
|
return 'route';
|
|
257
261
|
}
|
|
258
262
|
}
|
|
263
|
+
isLikelyOverlayAction(action, metadata) {
|
|
264
|
+
const configuredMode = action.openMode ?? metadata.defaults?.openMode;
|
|
265
|
+
return configuredMode === 'drawer' || configuredMode === 'modal';
|
|
266
|
+
}
|
|
267
|
+
loadDialogHost() {
|
|
268
|
+
return this.dialogHostPromise ??= Promise.resolve().then(function () { return dynamicFormDialogHost_component; }).then((module) => module.DynamicFormDialogHostComponent);
|
|
269
|
+
}
|
|
259
270
|
buildRoute(action, row, metadata) {
|
|
260
271
|
let route = action.route;
|
|
261
272
|
const query = {};
|
|
@@ -896,6 +907,9 @@ const PRAXIS_CRUD_RUNTIME_I18N_CONFIG = {
|
|
|
896
907
|
'crud.actions.view': 'Ver',
|
|
897
908
|
'crud.actions.edit': 'Editar',
|
|
898
909
|
'crud.actions.delete': 'Excluir',
|
|
910
|
+
'crud.actions.default': 'ação',
|
|
911
|
+
'crud.actions.opening': 'Abrindo {action}…',
|
|
912
|
+
'crud.surface.openFailed': 'Não foi possível abrir {title}. Tente novamente ou confirme se esse recurso continua disponível.',
|
|
899
913
|
'crud.dialog.recordContextLabel': 'Registro em edição',
|
|
900
914
|
'crud.delete.confirmMessage': 'Esta ação não pode ser desfeita. Deseja continuar?',
|
|
901
915
|
'crud.delete.cancel': 'Cancelar',
|
|
@@ -914,6 +928,9 @@ const PRAXIS_CRUD_RUNTIME_I18N_CONFIG = {
|
|
|
914
928
|
'crud.actions.view': 'View',
|
|
915
929
|
'crud.actions.edit': 'Edit',
|
|
916
930
|
'crud.actions.delete': 'Delete',
|
|
931
|
+
'crud.actions.default': 'action',
|
|
932
|
+
'crud.actions.opening': 'Opening {action}…',
|
|
933
|
+
'crud.surface.openFailed': 'Could not open {title}. Try again or confirm that this resource is still available.',
|
|
917
934
|
'crud.dialog.recordContextLabel': 'Record being edited',
|
|
918
935
|
'crud.delete.confirmMessage': 'This action cannot be undone. Do you want to continue?',
|
|
919
936
|
'crud.delete.cancel': 'Cancel',
|
|
@@ -3664,6 +3681,7 @@ class PraxisCrudComponent {
|
|
|
3664
3681
|
tableQueryContext = null;
|
|
3665
3682
|
tableFilterCriteria = {};
|
|
3666
3683
|
tableCrudContext;
|
|
3684
|
+
openingActionLabel = signal(null, ...(ngDevMode ? [{ debugName: "openingActionLabel" }] : /* istanbul ignore next */ []));
|
|
3667
3685
|
launcher = inject(CrudLauncherService);
|
|
3668
3686
|
http = inject(HttpClient);
|
|
3669
3687
|
destroyRef = inject(DestroyRef);
|
|
@@ -3815,8 +3833,11 @@ class PraxisCrudComponent {
|
|
|
3815
3833
|
}
|
|
3816
3834
|
}
|
|
3817
3835
|
async onAction(action, row, runtimeEvent) {
|
|
3836
|
+
if (this.openingActionLabel()) {
|
|
3837
|
+
return;
|
|
3838
|
+
}
|
|
3839
|
+
this.openingActionLabel.set(this.resolveOpeningActionLabel(action, runtimeEvent));
|
|
3818
3840
|
try {
|
|
3819
|
-
document.activeElement?.blur();
|
|
3820
3841
|
const normalizedAction = this.normalizeCrudActionName(action);
|
|
3821
3842
|
const contextualRow = row ?? this.resolveSelectedRowForAction(normalizedAction);
|
|
3822
3843
|
let actionMeta = this.resolvedMetadata.actions?.find((candidate) => this.normalizeCrudActionName(candidate.action) === normalizedAction);
|
|
@@ -3921,6 +3942,26 @@ class PraxisCrudComponent {
|
|
|
3921
3942
|
catch (err) {
|
|
3922
3943
|
this.error.emit(err);
|
|
3923
3944
|
}
|
|
3945
|
+
finally {
|
|
3946
|
+
this.openingActionLabel.set(null);
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
getOpeningActionStatus(actionLabel) {
|
|
3950
|
+
return this.txWithParams('crud.actions.opening', 'Abrindo {action}…', { action: actionLabel });
|
|
3951
|
+
}
|
|
3952
|
+
resolveOpeningActionLabel(action, runtimeEvent) {
|
|
3953
|
+
const configuredLabel = String(runtimeEvent?.actionConfig?.label || '').trim();
|
|
3954
|
+
if (configuredLabel) {
|
|
3955
|
+
return configuredLabel;
|
|
3956
|
+
}
|
|
3957
|
+
const normalized = this.normalizeCrudActionName(action);
|
|
3958
|
+
if (normalized === 'create'
|
|
3959
|
+
|| normalized === 'view'
|
|
3960
|
+
|| normalized === 'edit'
|
|
3961
|
+
|| normalized === 'delete') {
|
|
3962
|
+
return this.getCrudActionLabel(normalized);
|
|
3963
|
+
}
|
|
3964
|
+
return String(action || '').trim() || this.tx('crud.actions.default', 'ação');
|
|
3924
3965
|
}
|
|
3925
3966
|
hasExplicitOpenBinding(action) {
|
|
3926
3967
|
const mode = action.openMode;
|
|
@@ -4335,9 +4376,6 @@ class PraxisCrudComponent {
|
|
|
4335
4376
|
return false;
|
|
4336
4377
|
}
|
|
4337
4378
|
const providedSurface = this.resolveProvidedSurface(normalizedAction, this.extractDiscoveryActionConfig(runtimeEvent));
|
|
4338
|
-
if (!providedSurface && !this.isDiscoveryManagedCrudAction(normalizedAction)) {
|
|
4339
|
-
return false;
|
|
4340
|
-
}
|
|
4341
4379
|
const catalog = providedSurface
|
|
4342
4380
|
? null
|
|
4343
4381
|
: await this.resolveDiscoveredSurfaceCatalog(normalizedAction, row);
|
|
@@ -4358,10 +4396,15 @@ class PraxisCrudComponent {
|
|
|
4358
4396
|
endpointKey: this.resolvedMetadata?.resource?.endpointKey,
|
|
4359
4397
|
apiUrlEntry: this.resolveDiscoveryApiEntry(),
|
|
4360
4398
|
group: catalog?.group ?? null,
|
|
4399
|
+
presentation: 'drawer',
|
|
4400
|
+
title: surface.title,
|
|
4401
|
+
subtitle: surface.description ?? undefined,
|
|
4361
4402
|
});
|
|
4362
4403
|
}
|
|
4363
|
-
catch {
|
|
4364
|
-
|
|
4404
|
+
catch (error) {
|
|
4405
|
+
this.error.emit(error);
|
|
4406
|
+
this.snack.open(this.txWithParams('crud.surface.openFailed', 'Não foi possível abrir {title}. Tente novamente ou confirme se esse recurso continua disponível.', { title: surface.title || surface.id }), undefined, { duration: 4500 });
|
|
4407
|
+
return true;
|
|
4365
4408
|
}
|
|
4366
4409
|
let openPromise;
|
|
4367
4410
|
try {
|
|
@@ -4393,9 +4436,12 @@ class PraxisCrudComponent {
|
|
|
4393
4436
|
mode: this.mapSurfacePresentationToCrudMode(payload?.presentation),
|
|
4394
4437
|
action,
|
|
4395
4438
|
});
|
|
4396
|
-
|
|
4397
|
-
.
|
|
4398
|
-
|
|
4439
|
+
try {
|
|
4440
|
+
this.bindDiscoveredSurfaceLifecycle(await openPromise);
|
|
4441
|
+
}
|
|
4442
|
+
catch (err) {
|
|
4443
|
+
this.error.emit(err);
|
|
4444
|
+
}
|
|
4399
4445
|
return true;
|
|
4400
4446
|
}
|
|
4401
4447
|
async resolveDiscoveredSurfaceCatalog(action, row) {
|
|
@@ -4518,13 +4564,13 @@ class PraxisCrudComponent {
|
|
|
4518
4564
|
}
|
|
4519
4565
|
return catalogCandidate;
|
|
4520
4566
|
}
|
|
4521
|
-
resolveProvidedSurface(
|
|
4567
|
+
resolveProvidedSurface(_action, candidate) {
|
|
4522
4568
|
if (!candidate || typeof candidate !== 'object') {
|
|
4523
4569
|
return null;
|
|
4524
4570
|
}
|
|
4525
4571
|
const catalogCandidate = candidate;
|
|
4526
4572
|
const normalizedId = String(catalogCandidate.id || '').trim().toLowerCase();
|
|
4527
|
-
if (!normalizedId
|
|
4573
|
+
if (!normalizedId) {
|
|
4528
4574
|
return null;
|
|
4529
4575
|
}
|
|
4530
4576
|
const surface = catalogCandidate;
|
|
@@ -4540,6 +4586,10 @@ class PraxisCrudComponent {
|
|
|
4540
4586
|
const candidates = surfaces
|
|
4541
4587
|
.filter((surface) => surface.availability?.allowed !== false)
|
|
4542
4588
|
.sort((left, right) => (left.order ?? 0) - (right.order ?? 0));
|
|
4589
|
+
const exact = candidates.find((surface) => String(surface.id || '').trim().toLowerCase() === action);
|
|
4590
|
+
if (exact) {
|
|
4591
|
+
return exact;
|
|
4592
|
+
}
|
|
4543
4593
|
const preferredIds = this.getPreferredSurfaceIdsForCrudAction(action);
|
|
4544
4594
|
const preferred = candidates.find((surface) => preferredIds.includes(String(surface.id || '').trim().toLowerCase()));
|
|
4545
4595
|
if (preferred) {
|
|
@@ -4600,7 +4650,6 @@ class PraxisCrudComponent {
|
|
|
4600
4650
|
return presentation === 'modal' ? 'modal' : 'drawer';
|
|
4601
4651
|
}
|
|
4602
4652
|
handleDiscoveredSurfaceResult(result) {
|
|
4603
|
-
this.afterClose.emit();
|
|
4604
4653
|
const data = (result?.data || {});
|
|
4605
4654
|
const idField = this.getIdField();
|
|
4606
4655
|
if (result?.type === 'save') {
|
|
@@ -4614,6 +4663,34 @@ class PraxisCrudComponent {
|
|
|
4614
4663
|
this.refreshTable();
|
|
4615
4664
|
}
|
|
4616
4665
|
}
|
|
4666
|
+
bindDiscoveredSurfaceLifecycle(ref) {
|
|
4667
|
+
const surfaceRef = ref;
|
|
4668
|
+
if (!surfaceRef)
|
|
4669
|
+
return;
|
|
4670
|
+
let terminalResultHandled = false;
|
|
4671
|
+
let closeHandled = false;
|
|
4672
|
+
const handleResult = (result) => {
|
|
4673
|
+
const type = String(result?.type || '');
|
|
4674
|
+
if (terminalResultHandled || (type !== 'save' && type !== 'delete'))
|
|
4675
|
+
return;
|
|
4676
|
+
terminalResultHandled = true;
|
|
4677
|
+
this.handleDiscoveredSurfaceResult(result);
|
|
4678
|
+
};
|
|
4679
|
+
surfaceRef.result$?.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(handleResult);
|
|
4680
|
+
const handleClose = (result) => {
|
|
4681
|
+
handleResult(result);
|
|
4682
|
+
if (closeHandled)
|
|
4683
|
+
return;
|
|
4684
|
+
closeHandled = true;
|
|
4685
|
+
this.afterClose.emit();
|
|
4686
|
+
};
|
|
4687
|
+
if (surfaceRef.closed$) {
|
|
4688
|
+
surfaceRef.closed$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(handleClose);
|
|
4689
|
+
}
|
|
4690
|
+
else {
|
|
4691
|
+
surfaceRef.afterClosed?.().pipe(takeUntilDestroyed(this.destroyRef)).subscribe(handleClose);
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4617
4694
|
buildEffectiveTableConfig(meta, capabilities) {
|
|
4618
4695
|
const base = meta.table;
|
|
4619
4696
|
const current = this.getCurrentTableConfigSnapshot();
|
|
@@ -5161,38 +5238,46 @@ class PraxisCrudComponent {
|
|
|
5161
5238
|
providePraxisI18nConfig(RESOURCE_DISCOVERY_I18N_CONFIG),
|
|
5162
5239
|
providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
|
|
5163
5240
|
], viewQueries: [{ propertyName: "table", first: true, predicate: PraxisTable, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
[filterCriteria]="tableFilterCriteria"
|
|
5171
|
-
[tableId]="crudId || 'default'"
|
|
5172
|
-
[crudContext]="tableCrudContext"
|
|
5173
|
-
[enableCustomization]="enableCustomization"
|
|
5174
|
-
[authoringCapability]="authoringCapability"
|
|
5175
|
-
(rowClick)="onTableRowClick($event)"
|
|
5176
|
-
(selectionChange)="onTableSelectionChange($event)"
|
|
5177
|
-
(rowAction)="onAction($event.action, $event.row, $event)"
|
|
5178
|
-
(toolbarAction)="onToolbarAction($event)"
|
|
5179
|
-
(bulkAction)="onBulkAction($event)"
|
|
5180
|
-
(collectionLinksChange)="onCollectionLinksChange($event)"
|
|
5181
|
-
(reset)="onResetPreferences()"
|
|
5182
|
-
(metadataChange)="onTableMetadataChange()"
|
|
5183
|
-
(loadingStateChange)="onTableLoadingStateChange($event)"
|
|
5184
|
-
></praxis-table>
|
|
5185
|
-
} @else {
|
|
5186
|
-
@if (isCustomizationAvailable()) {
|
|
5187
|
-
<praxis-empty-state-card
|
|
5188
|
-
icon="table_rows"
|
|
5189
|
-
[title]="getEmptyStateTitle()"
|
|
5190
|
-
[description]="getEmptyStateDescription()"
|
|
5191
|
-
[primaryAction]="{ label: getEmptyStatePrimaryAction(), icon: 'bolt', action: onConfigureRequested.bind(this) }"
|
|
5192
|
-
/>
|
|
5241
|
+
<div class="praxis-crud-runtime" [attr.aria-busy]="openingActionLabel() ? 'true' : null">
|
|
5242
|
+
@if (openingActionLabel(); as actionLabel) {
|
|
5243
|
+
<div class="praxis-crud-opening-status" role="status" aria-live="polite" data-testid="praxis-crud-opening-status">
|
|
5244
|
+
<span class="praxis-crud-opening-status__spinner" aria-hidden="true"></span>
|
|
5245
|
+
<span>{{ getOpeningActionStatus(actionLabel) }}</span>
|
|
5246
|
+
</div>
|
|
5193
5247
|
}
|
|
5194
|
-
|
|
5195
|
-
|
|
5248
|
+
@if (shouldRenderTable(resolvedMetadata)) {
|
|
5249
|
+
<praxis-table
|
|
5250
|
+
[config]="tableConfigForBinding"
|
|
5251
|
+
[resourcePath]="resolveResourcePath(resolvedMetadata)"
|
|
5252
|
+
[data]="resolveTableData(resolvedMetadata)"
|
|
5253
|
+
[queryContext]="tableQueryContext"
|
|
5254
|
+
[filterCriteria]="tableFilterCriteria"
|
|
5255
|
+
[tableId]="crudId || 'default'"
|
|
5256
|
+
[crudContext]="tableCrudContext"
|
|
5257
|
+
[enableCustomization]="enableCustomization"
|
|
5258
|
+
[authoringCapability]="authoringCapability"
|
|
5259
|
+
(rowClick)="onTableRowClick($event)"
|
|
5260
|
+
(selectionChange)="onTableSelectionChange($event)"
|
|
5261
|
+
(rowAction)="onAction($event.action, $event.row, $event)"
|
|
5262
|
+
(toolbarAction)="onToolbarAction($event)"
|
|
5263
|
+
(bulkAction)="onBulkAction($event)"
|
|
5264
|
+
(collectionLinksChange)="onCollectionLinksChange($event)"
|
|
5265
|
+
(reset)="onResetPreferences()"
|
|
5266
|
+
(metadataChange)="onTableMetadataChange()"
|
|
5267
|
+
(loadingStateChange)="onTableLoadingStateChange($event)"
|
|
5268
|
+
></praxis-table>
|
|
5269
|
+
} @else {
|
|
5270
|
+
@if (isCustomizationAvailable()) {
|
|
5271
|
+
<praxis-empty-state-card
|
|
5272
|
+
icon="table_rows"
|
|
5273
|
+
[title]="getEmptyStateTitle()"
|
|
5274
|
+
[description]="getEmptyStateDescription()"
|
|
5275
|
+
[primaryAction]="{ label: getEmptyStatePrimaryAction(), icon: 'bolt', action: onConfigureRequested.bind(this) }"
|
|
5276
|
+
/>
|
|
5277
|
+
}
|
|
5278
|
+
}
|
|
5279
|
+
</div>
|
|
5280
|
+
`, isInline: true, styles: [":host{display:block;width:100%;min-width:0;max-width:100%}.praxis-crud-runtime{position:relative;min-width:0}.praxis-crud-opening-status{position:absolute;z-index:6;top:.7rem;right:.7rem;display:inline-flex;align-items:center;gap:.55rem;min-height:2.25rem;max-width:min(24rem,calc(100% - 1.4rem));padding:.48rem .72rem;border:1px solid color-mix(in srgb,var(--md-sys-color-primary, #3f51b5) 32%,transparent);border-radius:999px;color:var(--md-sys-color-on-surface, currentColor);background:color-mix(in srgb,var(--md-sys-color-surface-container-high, #fff) 94%,transparent);box-shadow:0 10px 28px #0f172a29;font-size:.82rem;font-weight:650;line-height:1.25;pointer-events:none}.praxis-crud-opening-status__spinner{width:.95rem;height:.95rem;flex:0 0 auto;border:2px solid color-mix(in srgb,var(--md-sys-color-primary, #3f51b5) 26%,transparent);border-top-color:var(--md-sys-color-primary, #3f51b5);border-radius:50%;animation:praxis-crud-opening-spin .72s linear infinite}@keyframes praxis-crud-opening-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.praxis-crud-opening-status__spinner{animation:none;border-top-color:currentColor}}\n"], dependencies: [{ kind: "component", type: PraxisTable, selector: "praxis-table", inputs: ["config", "resourcePath", "data", "tableId", "componentInstanceId", "configPersistenceStrategy", "title", "subtitle", "icon", "autoDelete", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "crudContext", "filterCriteria", "queryContext", "aiContext", "aiAssistantVoiceInputMode", "aiAssistantVoiceLanguage", "horizontalScroll", "enableCustomization", "authoringCapability", "dense"], outputs: ["rowClick", "widgetEvent", "resourceEvent", "rowDoubleClick", "rowExpansionChange", "rowAction", "toolbarAction", "bulkAction", "exportAction", "columnReorder", "columnReorderAttempt", "columnResize", "beforeDelete", "afterDelete", "deleteError", "beforeBulkDelete", "afterBulkDelete", "bulkDeleteError", "schemaStatusChange", "configChange", "metadataChange", "loadingStateChange", "collectionLinksChange", "selectionChange"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone", "variant", "alignment", "density", "iconContainer"] }] });
|
|
5196
5281
|
}
|
|
5197
5282
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisCrudComponent, decorators: [{
|
|
5198
5283
|
type: Component,
|
|
@@ -5200,38 +5285,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5200
5285
|
providePraxisI18nConfig(RESOURCE_DISCOVERY_I18N_CONFIG),
|
|
5201
5286
|
providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
|
|
5202
5287
|
], template: `
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
[filterCriteria]="tableFilterCriteria"
|
|
5210
|
-
[tableId]="crudId || 'default'"
|
|
5211
|
-
[crudContext]="tableCrudContext"
|
|
5212
|
-
[enableCustomization]="enableCustomization"
|
|
5213
|
-
[authoringCapability]="authoringCapability"
|
|
5214
|
-
(rowClick)="onTableRowClick($event)"
|
|
5215
|
-
(selectionChange)="onTableSelectionChange($event)"
|
|
5216
|
-
(rowAction)="onAction($event.action, $event.row, $event)"
|
|
5217
|
-
(toolbarAction)="onToolbarAction($event)"
|
|
5218
|
-
(bulkAction)="onBulkAction($event)"
|
|
5219
|
-
(collectionLinksChange)="onCollectionLinksChange($event)"
|
|
5220
|
-
(reset)="onResetPreferences()"
|
|
5221
|
-
(metadataChange)="onTableMetadataChange()"
|
|
5222
|
-
(loadingStateChange)="onTableLoadingStateChange($event)"
|
|
5223
|
-
></praxis-table>
|
|
5224
|
-
} @else {
|
|
5225
|
-
@if (isCustomizationAvailable()) {
|
|
5226
|
-
<praxis-empty-state-card
|
|
5227
|
-
icon="table_rows"
|
|
5228
|
-
[title]="getEmptyStateTitle()"
|
|
5229
|
-
[description]="getEmptyStateDescription()"
|
|
5230
|
-
[primaryAction]="{ label: getEmptyStatePrimaryAction(), icon: 'bolt', action: onConfigureRequested.bind(this) }"
|
|
5231
|
-
/>
|
|
5288
|
+
<div class="praxis-crud-runtime" [attr.aria-busy]="openingActionLabel() ? 'true' : null">
|
|
5289
|
+
@if (openingActionLabel(); as actionLabel) {
|
|
5290
|
+
<div class="praxis-crud-opening-status" role="status" aria-live="polite" data-testid="praxis-crud-opening-status">
|
|
5291
|
+
<span class="praxis-crud-opening-status__spinner" aria-hidden="true"></span>
|
|
5292
|
+
<span>{{ getOpeningActionStatus(actionLabel) }}</span>
|
|
5293
|
+
</div>
|
|
5232
5294
|
}
|
|
5233
|
-
|
|
5234
|
-
|
|
5295
|
+
@if (shouldRenderTable(resolvedMetadata)) {
|
|
5296
|
+
<praxis-table
|
|
5297
|
+
[config]="tableConfigForBinding"
|
|
5298
|
+
[resourcePath]="resolveResourcePath(resolvedMetadata)"
|
|
5299
|
+
[data]="resolveTableData(resolvedMetadata)"
|
|
5300
|
+
[queryContext]="tableQueryContext"
|
|
5301
|
+
[filterCriteria]="tableFilterCriteria"
|
|
5302
|
+
[tableId]="crudId || 'default'"
|
|
5303
|
+
[crudContext]="tableCrudContext"
|
|
5304
|
+
[enableCustomization]="enableCustomization"
|
|
5305
|
+
[authoringCapability]="authoringCapability"
|
|
5306
|
+
(rowClick)="onTableRowClick($event)"
|
|
5307
|
+
(selectionChange)="onTableSelectionChange($event)"
|
|
5308
|
+
(rowAction)="onAction($event.action, $event.row, $event)"
|
|
5309
|
+
(toolbarAction)="onToolbarAction($event)"
|
|
5310
|
+
(bulkAction)="onBulkAction($event)"
|
|
5311
|
+
(collectionLinksChange)="onCollectionLinksChange($event)"
|
|
5312
|
+
(reset)="onResetPreferences()"
|
|
5313
|
+
(metadataChange)="onTableMetadataChange()"
|
|
5314
|
+
(loadingStateChange)="onTableLoadingStateChange($event)"
|
|
5315
|
+
></praxis-table>
|
|
5316
|
+
} @else {
|
|
5317
|
+
@if (isCustomizationAvailable()) {
|
|
5318
|
+
<praxis-empty-state-card
|
|
5319
|
+
icon="table_rows"
|
|
5320
|
+
[title]="getEmptyStateTitle()"
|
|
5321
|
+
[description]="getEmptyStateDescription()"
|
|
5322
|
+
[primaryAction]="{ label: getEmptyStatePrimaryAction(), icon: 'bolt', action: onConfigureRequested.bind(this) }"
|
|
5323
|
+
/>
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
</div>
|
|
5327
|
+
`, styles: [":host{display:block;width:100%;min-width:0;max-width:100%}.praxis-crud-runtime{position:relative;min-width:0}.praxis-crud-opening-status{position:absolute;z-index:6;top:.7rem;right:.7rem;display:inline-flex;align-items:center;gap:.55rem;min-height:2.25rem;max-width:min(24rem,calc(100% - 1.4rem));padding:.48rem .72rem;border:1px solid color-mix(in srgb,var(--md-sys-color-primary, #3f51b5) 32%,transparent);border-radius:999px;color:var(--md-sys-color-on-surface, currentColor);background:color-mix(in srgb,var(--md-sys-color-surface-container-high, #fff) 94%,transparent);box-shadow:0 10px 28px #0f172a29;font-size:.82rem;font-weight:650;line-height:1.25;pointer-events:none}.praxis-crud-opening-status__spinner{width:.95rem;height:.95rem;flex:0 0 auto;border:2px solid color-mix(in srgb,var(--md-sys-color-primary, #3f51b5) 26%,transparent);border-top-color:var(--md-sys-color-primary, #3f51b5);border-radius:50%;animation:praxis-crud-opening-spin .72s linear infinite}@keyframes praxis-crud-opening-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.praxis-crud-opening-status__spinner{animation:none;border-top-color:currentColor}}\n"] }]
|
|
5235
5328
|
}], ctorParameters: () => [], propDecorators: { metadata: [{
|
|
5236
5329
|
type: Input,
|
|
5237
5330
|
args: [{ required: true }]
|
|
@@ -5458,6 +5551,22 @@ class DynamicFormDialogHostComponent {
|
|
|
5458
5551
|
deriveModeTitle(this.mode, this.resolveResourceTitle()) ||
|
|
5459
5552
|
this.texts.title;
|
|
5460
5553
|
}
|
|
5554
|
+
get dialogSubtitle() {
|
|
5555
|
+
const action = this.data.action ?? {};
|
|
5556
|
+
const form = this.formConfig;
|
|
5557
|
+
const resource = this.data.metadata?.resource ?? {};
|
|
5558
|
+
const table = this.data.metadata?.table ?? {};
|
|
5559
|
+
return stringOrUndefined(action.description ??
|
|
5560
|
+
action.tooltip ??
|
|
5561
|
+
form['description'] ??
|
|
5562
|
+
resource.description ??
|
|
5563
|
+
table.subtitle ??
|
|
5564
|
+
table.description);
|
|
5565
|
+
}
|
|
5566
|
+
get dialogIcon() {
|
|
5567
|
+
const action = this.data.action ?? {};
|
|
5568
|
+
return stringOrUndefined(action.icon ?? this.modal.titleIcon ?? this.modal.icon);
|
|
5569
|
+
}
|
|
5461
5570
|
resolveActionDialogTitle() {
|
|
5462
5571
|
const actionLabel = stringOrUndefined(this.data.action?.label);
|
|
5463
5572
|
if (!actionLabel) {
|
|
@@ -5709,9 +5818,21 @@ class DynamicFormDialogHostComponent {
|
|
|
5709
5818
|
providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
|
|
5710
5819
|
], viewQueries: [{ propertyName: "formComp", first: true, predicate: PraxisDynamicForm, descendants: true }], ngImport: i0, template: `
|
|
5711
5820
|
<div mat-dialog-title class="dialog-header">
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5821
|
+
@if (dialogIcon; as icon) {
|
|
5822
|
+
<span class="dialog-title-icon" aria-hidden="true">
|
|
5823
|
+
<mat-icon [praxisIcon]="icon"></mat-icon>
|
|
5824
|
+
</span>
|
|
5825
|
+
}
|
|
5826
|
+
<span class="dialog-heading">
|
|
5827
|
+
<h2 id="crudDialogTitle" class="dialog-title">
|
|
5828
|
+
{{ dialogTitle }}
|
|
5829
|
+
</h2>
|
|
5830
|
+
@if (dialogSubtitle; as subtitle) {
|
|
5831
|
+
<span id="crudDialogDescription" class="dialog-subtitle">
|
|
5832
|
+
{{ subtitle }}
|
|
5833
|
+
</span>
|
|
5834
|
+
}
|
|
5835
|
+
</span>
|
|
5715
5836
|
<span class="spacer"></span>
|
|
5716
5837
|
@if (modal.canMaximize) {
|
|
5717
5838
|
<button
|
|
@@ -5735,6 +5856,7 @@ class DynamicFormDialogHostComponent {
|
|
|
5735
5856
|
<mat-dialog-content
|
|
5736
5857
|
class="dialog-content"
|
|
5737
5858
|
aria-labelledby="crudDialogTitle"
|
|
5859
|
+
[attr.aria-describedby]="dialogSubtitle ? 'crudDialogDescription' : null"
|
|
5738
5860
|
>
|
|
5739
5861
|
@if (resourceIdentity) {
|
|
5740
5862
|
<div class="crud-resource-identity" data-testid="crud-resource-identity">
|
|
@@ -5770,13 +5892,15 @@ class DynamicFormDialogHostComponent {
|
|
|
5770
5892
|
(formCancel)="onCancel()"
|
|
5771
5893
|
></praxis-dynamic-form>
|
|
5772
5894
|
</mat-dialog-content>
|
|
5773
|
-
`, isInline: true, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);
|
|
5895
|
+
`, isInline: true, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-resource-identity{position:sticky;top:0;z-index:1;display:grid;gap:.25rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisResourceIdentityComponent, selector: "praxis-resource-identity", inputs: ["identity", "emptyTitle", "density", "showMetadataLabels", "showKeyLabel", "ariaLabel"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
5774
5896
|
}
|
|
5775
5897
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, decorators: [{
|
|
5776
5898
|
type: Component,
|
|
5777
5899
|
args: [{ selector: 'praxis-dynamic-form-dialog-host', standalone: true, imports: [
|
|
5778
5900
|
MatDialogModule,
|
|
5901
|
+
MatIconModule,
|
|
5779
5902
|
PraxisIconButtonComponent,
|
|
5903
|
+
PraxisIconDirective,
|
|
5780
5904
|
PraxisResourceIdentityComponent,
|
|
5781
5905
|
PraxisDynamicForm
|
|
5782
5906
|
], encapsulation: ViewEncapsulation.None, providers: [
|
|
@@ -5789,9 +5913,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5789
5913
|
'[class.praxis-drawer]': 'presentation === "drawer"',
|
|
5790
5914
|
}, template: `
|
|
5791
5915
|
<div mat-dialog-title class="dialog-header">
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5916
|
+
@if (dialogIcon; as icon) {
|
|
5917
|
+
<span class="dialog-title-icon" aria-hidden="true">
|
|
5918
|
+
<mat-icon [praxisIcon]="icon"></mat-icon>
|
|
5919
|
+
</span>
|
|
5920
|
+
}
|
|
5921
|
+
<span class="dialog-heading">
|
|
5922
|
+
<h2 id="crudDialogTitle" class="dialog-title">
|
|
5923
|
+
{{ dialogTitle }}
|
|
5924
|
+
</h2>
|
|
5925
|
+
@if (dialogSubtitle; as subtitle) {
|
|
5926
|
+
<span id="crudDialogDescription" class="dialog-subtitle">
|
|
5927
|
+
{{ subtitle }}
|
|
5928
|
+
</span>
|
|
5929
|
+
}
|
|
5930
|
+
</span>
|
|
5795
5931
|
<span class="spacer"></span>
|
|
5796
5932
|
@if (modal.canMaximize) {
|
|
5797
5933
|
<button
|
|
@@ -5815,6 +5951,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5815
5951
|
<mat-dialog-content
|
|
5816
5952
|
class="dialog-content"
|
|
5817
5953
|
aria-labelledby="crudDialogTitle"
|
|
5954
|
+
[attr.aria-describedby]="dialogSubtitle ? 'crudDialogDescription' : null"
|
|
5818
5955
|
>
|
|
5819
5956
|
@if (resourceIdentity) {
|
|
5820
5957
|
<div class="crud-resource-identity" data-testid="crud-resource-identity">
|
|
@@ -5850,7 +5987,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5850
5987
|
(formCancel)="onCancel()"
|
|
5851
5988
|
></praxis-dynamic-form>
|
|
5852
5989
|
</mat-dialog-content>
|
|
5853
|
-
`, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);
|
|
5990
|
+
`, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-resource-identity{position:sticky;top:0;z-index:1;display:grid;gap:.25rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"] }]
|
|
5854
5991
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
5855
5992
|
type: Inject,
|
|
5856
5993
|
args: [MatDialogRef]
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/crud",
|
|
3
|
-
"version": "9.0.4-rc.
|
|
3
|
+
"version": "9.0.4-rc.20",
|
|
4
4
|
"description": "CRUD building blocks for Praxis UI: integrates dynamic forms and tables with unified configuration and services.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
|
7
7
|
"@angular/core": "^21.0.0",
|
|
8
|
-
"@praxisui/dynamic-form": "^9.0.4-rc.
|
|
9
|
-
"@praxisui/table": "^9.0.4-rc.
|
|
10
|
-
"@praxisui/core": "^9.0.4-rc.
|
|
11
|
-
"@praxisui/dynamic-fields": "^9.0.4-rc.
|
|
12
|
-
"@praxisui/settings-panel": "^9.0.4-rc.
|
|
8
|
+
"@praxisui/dynamic-form": "^9.0.4-rc.20",
|
|
9
|
+
"@praxisui/table": "^9.0.4-rc.20",
|
|
10
|
+
"@praxisui/core": "^9.0.4-rc.20",
|
|
11
|
+
"@praxisui/dynamic-fields": "^9.0.4-rc.20",
|
|
12
|
+
"@praxisui/settings-panel": "^9.0.4-rc.20",
|
|
13
13
|
"@angular/cdk": "^21.0.0",
|
|
14
14
|
"@angular/forms": "^21.0.0",
|
|
15
15
|
"@angular/material": "^21.0.0",
|
|
16
16
|
"@angular/router": "^21.0.0",
|
|
17
|
-
"@praxisui/ai": "^9.0.4-rc.
|
|
17
|
+
"@praxisui/ai": "^9.0.4-rc.20",
|
|
18
18
|
"rxjs": "~7.8.0"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
package/types/praxisui-crud.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { NgZone, OnChanges, EventEmitter, SimpleChanges, OnInit, Provider, AfterViewInit, OnDestroy } from '@angular/core';
|
|
1
3
|
import * as _praxisui_core from '@praxisui/core';
|
|
2
4
|
import { RowAction, ToolbarAction, ApiEndpoint, ApiUrlEntry, DynamicFormLayoutPolicy, BackConfig, TableConfig, PraxisDataQueryContext, FormConfig, ResourceActionCatalogItem, ResourceSurfaceCatalogItem, MaterializedResourceIdentity, LoadingState, RestApiLinks, ResourceCapabilitySnapshot, GenericCrudService, AsyncConfigStorage, ComponentDocMeta, AiCapabilityCatalog, AiCapability, AiCapabilityCategory, AiValueKind, ComponentAuthoringManifest, SettingsValueProvider } from '@praxisui/core';
|
|
3
5
|
export { BackConfig } from '@praxisui/core';
|
|
4
|
-
import * as _angular_core from '@angular/core';
|
|
5
|
-
import { NgZone, OnChanges, EventEmitter, SimpleChanges, OnInit, Provider, AfterViewInit, OnDestroy } from '@angular/core';
|
|
6
6
|
import { MatDialogConfig, MatDialogRef, MatDialog } from '@angular/material/dialog';
|
|
7
7
|
export { MAT_DIALOG_DATA as DIALOG_DATA } from '@angular/material/dialog';
|
|
8
8
|
import { ComponentType } from '@angular/cdk/portal';
|
|
@@ -199,6 +199,7 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
199
199
|
tableQueryContext: Record<string, unknown> | null;
|
|
200
200
|
tableFilterCriteria: Record<string, unknown>;
|
|
201
201
|
tableCrudContext?: CrudContextValue;
|
|
202
|
+
readonly openingActionLabel: _angular_core.WritableSignal<string | null>;
|
|
202
203
|
private readonly launcher;
|
|
203
204
|
private readonly http;
|
|
204
205
|
private readonly destroyRef;
|
|
@@ -244,6 +245,8 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
244
245
|
onToolbarAction(event: CrudActionRuntimeEvent): Promise<void>;
|
|
245
246
|
ngOnChanges(changes: SimpleChanges): void;
|
|
246
247
|
onAction(action: string, row?: Record<string, unknown>, runtimeEvent?: CrudActionRuntimeEvent): Promise<void>;
|
|
248
|
+
getOpeningActionStatus(actionLabel: string): string;
|
|
249
|
+
private resolveOpeningActionLabel;
|
|
247
250
|
private hasExplicitOpenBinding;
|
|
248
251
|
getCurrentTableConfigSnapshot(): TableConfig | null;
|
|
249
252
|
onTableMetadataChange(): void;
|
|
@@ -294,6 +297,7 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
294
297
|
private resolveRowResourceId;
|
|
295
298
|
private mapSurfacePresentationToCrudMode;
|
|
296
299
|
private handleDiscoveredSurfaceResult;
|
|
300
|
+
private bindDiscoveredSurfaceLifecycle;
|
|
297
301
|
private buildEffectiveTableConfig;
|
|
298
302
|
private isAddLike;
|
|
299
303
|
private normalizeCrudActionName;
|
|
@@ -343,6 +347,7 @@ declare class CrudLauncherService {
|
|
|
343
347
|
private readonly storage;
|
|
344
348
|
private readonly global;
|
|
345
349
|
private readonly operationResolver;
|
|
350
|
+
private dialogHostPromise?;
|
|
346
351
|
private readonly drawerAdapter;
|
|
347
352
|
launch(action: CrudAction, row: Record<string, unknown> | undefined, metadata: CrudMetadata, componentKeyId?: string | null, drawerCallbacks?: {
|
|
348
353
|
onClose?: () => void;
|
|
@@ -356,6 +361,8 @@ declare class CrudLauncherService {
|
|
|
356
361
|
ref?: DialogRef<any>;
|
|
357
362
|
}>;
|
|
358
363
|
resolveOpenMode(action: CrudAction, metadata: CrudMetadata): FormOpenMode;
|
|
364
|
+
private isLikelyOverlayAction;
|
|
365
|
+
private loadDialogHost;
|
|
359
366
|
private buildRoute;
|
|
360
367
|
private mapInputs;
|
|
361
368
|
private resolveActionForLaunch;
|
|
@@ -421,6 +428,8 @@ declare class DynamicFormDialogHostComponent implements OnInit {
|
|
|
421
428
|
private extractInitialValue;
|
|
422
429
|
private resolveFormConfig;
|
|
423
430
|
get dialogTitle(): string;
|
|
431
|
+
get dialogSubtitle(): string | undefined;
|
|
432
|
+
get dialogIcon(): string | undefined;
|
|
424
433
|
private resolveActionDialogTitle;
|
|
425
434
|
private resolveResourceTitle;
|
|
426
435
|
private resolveFormActions;
|