@praxisui/core 10.0.0-rc.31 → 10.0.0-rc.33

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 CHANGED
@@ -873,7 +873,7 @@ Action-bearing components must use the semantic `--praxis-action-control-*` vari
873
873
 
874
874
  `ResourceQuickConnectComponent` apresenta recursos publicados em `/schemas/catalog` usando o seletor `pdx-material-select` registrado em `ComponentMetadataRegistry`. O host deve registrar os descritores oficiais de DynamicFields. O controle é inicializado pelo protocolo `setInputMetadata` e `ControlValueAccessor`; Core não importa a biblioteca de campos. A conexão avançada por rota continua disponível (com `<datalist>` de sugestões do catálogo e abertura automática da seção avançada quando o seletor dinâmico não está disponível ou quando o recurso atual é uma rota customizada fora do catálogo).
875
875
 
876
- O componente expõe `[resourcePath]`, `(resourcePathChange)`, `[endpointKey]`, `[apiUrlEntry]`, `ControlValueAccessor` (`ngModel` / `formControl`) e os hooks `reset()` / `acceptAppliedValue()` de `SettingsValueProvider`. A projeção e reconciliação de opções do catálogo são centralizadas em `ResourceDiscoveryService.getDiscoveredResources()`, `loadDiscoveredResources()`, `projectSchemaCatalogResources()` e `resolveCatalogResourceOptionValue()`, deduplicando chamadas concorrentes a `/schemas/catalog` por URL e reconciliando caminhos relativos com ou sem prefixo `/api`. `ResourceDiscoveryService` reutiliza a instância do injetor ancestral quando um componente standalone cria injetor filho sem override local de `API_URL`.
876
+ O componente expõe `[resourcePath]`, `(resourcePathChange)`, `[endpointKey]`, `[apiUrlEntry]`, `[intent]`, `ControlValueAccessor` (`ngModel` / `formControl`) e os hooks `reset()` / `acceptAppliedValue()` de `SettingsValueProvider`. A projeção e reconciliação de opções do catálogo são centralizadas em `ResourceDiscoveryService.getDiscoveredResources()`, `loadDiscoveredResources()`, `projectSchemaCatalogResources()` e `resolveCatalogResourceOptionValue()`, deduplicando chamadas concorrentes a `/schemas/catalog` por URL, consumindo `resourcePath`, `resourceReadOnly` e `resourceCapabilities` publicados pelo backend para eliminar falsos-positivos de capacidades (como endpoints herdados `/stats/*` desabilitados) e sinalizando recursos somente leitura no subtítulo do seletor. `ResourceDiscoveryService` reutiliza a instância do injetor ancestral quando um componente standalone cria injetor filho sem override local de `API_URL`.
877
877
 
878
878
  O editor de configurações da página recebe uma cópia da definição autoral. Dados carregados e entradas transitórias dos widgets não devem virar configuração ao alterar o layout.
879
879
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-16T17:45:27.774Z",
3
+ "generatedAt": "2026-10-18T21:58:32.782Z",
4
4
  "packageName": "@praxisui/core",
5
- "packageVersion": "10.0.0-rc.31",
5
+ "packageVersion": "10.0.0-rc.33",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 4,
@@ -2061,7 +2061,8 @@
2061
2061
  "Use ids estaveis para links e keys estaveis para widgets.",
2062
2062
  "Nested component ports usam endpoint component-port com nestedPath; o owner em ref.widget continua sendo o widget top-level.",
2063
2063
  "Objetivo: compor widgets e relacionamentos canonicos (ex.: master-detail).",
2064
- "Link tipico de master-detail: component-port(table.rowClick) -> component-port(form.resourceId) com transform map payload.row.id."
2064
+ "Link tipico de master-detail: component-port(table.rowClick) -> component-port(form.resourceId) com transform map payload.row.id.",
2065
+ "Templates {{state.<path> | pipe}} e ${state.<path> | pipe} em inputs de widgets suportam pipes declarativos CSP-safe (default/coalesce, round[:N], number[:N], percent[:N], currency[:BRL|USD|EUR|GBP], uppercase, lowercase) via applyDeclarativeValuePipe, tratando tokens não resolvidos e NaN como ausentes no fallback."
2065
2066
  ],
2066
2067
  "componentContext": {
2067
2068
  "version": "v1.0",
@@ -3152,9 +3153,9 @@
3152
3153
  {
3153
3154
  "chunkIndex": 6,
3154
3155
  "chunkKind": "capabilities",
3155
- "content": "Component Capability:\n - Path: page.deviceLayouts.mobile\n Category: layout\n Kind: object\n Description: Overrides de layout para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.layout\n Category: layout\n Kind: object\n Description: Override de WidgetPageLayout para desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.canvas\n Category: layout\n Kind: object\n Description: Override de canvas para desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.groupingOverrides\n Category: layout\n Kind: array\n Description: Overrides de agrupamentos para desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.widgetOverrides\n Category: layout\n Kind: object\n Description: Overrides por widget key para desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.widgetOverrides.<widgetKey>.hidden\n Category: layout\n Kind: boolean\n Description: Oculta o widget em desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.layout\n Category: layout\n Kind: object\n Description: Override de WidgetPageLayout para tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.canvas\n Category: layout\n Kind: object\n Description: Override de canvas para tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.groupingOverrides\n Category: layout\n Kind: array\n Description: Overrides de agrupamentos para tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.widgetOverrides\n Category: layout\n Kind: object\n Description: Overrides por widget key para tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.widgetOverrides.<widgetKey>.hidden\n Category: layout\n Kind: boolean\n Description: Oculta o widget em tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.layout\n Category: layout\n Kind: object\n Description: Override de WidgetPageLayout para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.canvas\n Category: layout\n Kind: object\n Description: Override de canvas para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.groupingOverrides\n Category: layout\n Kind: array\n Description: Overrides de agrupamentos para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.widgetOverrides\n Category: layout\n Kind: object\n Description: Overrides por widget key para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.widgetOverrides.<widgetKey>.hidden\n Category: layout\n Kind: boolean\n Description: Oculta o widget em mobile.\n\nCapability Note:\n - page segue o modelo canonico WidgetPageDefinition (widgets, composition.links, context e state opcional); composition.links pode despachar actions globais via to.kind = global-action e receber continuations exatas via from.kind = global-action.\n\nCapability Note:\n - Conteudo editorial rico deve ser modelado como widget praxis-rich-content com definition.inputs.document: RichContentDocument, nao como DSL local do page-builder.\n\nCapability Note:\n - Quando definition.id = praxis-rich-content em uma pagina dinamica, definition.inputs.document continua sendo o contrato persistido; hostCapabilities e mediado em runtime pelo host praxis-dynamic-page e nao deve ser serializado no JSON da pagina.\n\nCapability Note:\n - Edicao visual de inputs de widget deve usar ComponentDocMeta.configEditor ou ComponentDocMeta.authoringManifestRef publicado pela lib dona do componente; nao criar editor local no page-builder para semantica de outro pacote.\n\nCapability Note:\n - Canvas e o modelo espacial canonico da pagina quando houver posicionamento explicito.\n\nCapability Note:\n - Taxonomia editorial: condition usa Json Logic canonico; transform usa pipeline declarativo; policy cobre apenas comportamento operacional.\n\nCapability Note:\n - Para criacao agentic de paginas, o preview pode trazer uiCompositionPlan como plano intermediario validavel; o page-builder compila esse plano para WidgetPageDefinition antes de aplicar.\n\nCapability Note:\n - UiCompositionPlan usa widgets[].componentId e bindings declarativos. UiCompositionPlanTemplateReference pode piná-lo por registryKey + configSha256, mas precisa ser resolvido pelo backend governado antes da compilação. O JSON persistido continua sendo page.widgets[].definition.id e page.composition.links.\n\nCapability Note:\n - Nested component ports usam endpoint component-port com nestedPath. O owner em ref.widget ou bindings[].*.widget continua sendo o widget top-level; a porta real do filho fica em port/direction e o caminho ate o filho fica em nestedPath.\n\nCapability Note:\n - Nao gere links nested via owner.widgetEvent, bindingPath profundo, page.connections ou wrappers host-specific. widgetEvent e bridge legada/avancada, nao contrato principal de authoring.\n\nCapability Note:\n - Payloads legados de layout ainda podem ser ingeridos, mas sao normalizados para canvas e nao devem ser reemitidos.\n\nCapability Note:\n - pageIdentity identifica o escopo de persistencia e nao pertence ao objeto page.\n\nCapability Note:\n - authoringCapabilities é um grant transitório do host para limitar affordances visíveis; não integra WidgetPageDefinition, não é persistido e não concede autoridade de edição à IA.\n\nCapability Note:\n - Este catálogo é específico para o runtime praxis-dynamic-page; operações de authoring/mutação pertencem ao manifesto do praxis-page-builder.\n\nCapability Note:\n - WidgetPageDefinition e o contrato canonico persistido: widgets, composition.links, state, context, i18n, layout, canvas, presets, grouping, slotAssignments, deviceLayouts e themePreset.\n\nCapability Note:\n - Widgets e page.composition.links sao arrays; ferramentas de patch legadas fazem merge por key estavel e id estavel.\n\nCapability Note:\n - page.canvas.items é um mapa por widget key; não modele canvas.items como array.\n\nCapability Note:\n - Taxonomia editorial: condition usa Json Logic canônico; transform usa pipeline declarativo; não trate ambos como a mesma \"expression\".\n\nCapability Note:\n - Para remocao/replace, use flags {_remove:true} ou {_replace:true} no item.\n\nCapability Note:\n - Para renomear um link, inclua {_beforeKey:\"link-id-anterior\"} no item.\n\nCapability Note:\n - Inputs de widgets dependem do componente (ex: praxis-table, praxis-dynamic-form). Evite inventar campos; prefira pedir confirmação.\n\nCapability Note:\n - Quando page.widgets[].definition.id for praxis-rich-content, o host praxis-dynamic-page injeta hostCapabilities em runtime para actions e capability gating; não serialize funções nem tente persistir page.widgets[].definition.inputs.hostCapabilities.\n\nCapability Note:\n - Use ids estaveis para links e keys estaveis para widgets.\n\nCapability Note:\n - Nested component ports usam endpoint component-port com nestedPath; o owner em ref.widget continua sendo o widget top-level.\n\nCapability Note:\n - Objetivo: compor widgets e relacionamentos canonicos (ex.: master-detail).\n\nCapability Note:\n - Link tipico de master-detail: component-port(table.rowClick) -> component-port(form.resourceId) com transform map payload.row.id.",
3156
+ "content": "Component Capability:\n - Path: page.deviceLayouts.mobile\n Category: layout\n Kind: object\n Description: Overrides de layout para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.layout\n Category: layout\n Kind: object\n Description: Override de WidgetPageLayout para desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.canvas\n Category: layout\n Kind: object\n Description: Override de canvas para desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.groupingOverrides\n Category: layout\n Kind: array\n Description: Overrides de agrupamentos para desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.widgetOverrides\n Category: layout\n Kind: object\n Description: Overrides por widget key para desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.desktop.widgetOverrides.<widgetKey>.hidden\n Category: layout\n Kind: boolean\n Description: Oculta o widget em desktop.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.layout\n Category: layout\n Kind: object\n Description: Override de WidgetPageLayout para tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.canvas\n Category: layout\n Kind: object\n Description: Override de canvas para tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.groupingOverrides\n Category: layout\n Kind: array\n Description: Overrides de agrupamentos para tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.widgetOverrides\n Category: layout\n Kind: object\n Description: Overrides por widget key para tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.tablet.widgetOverrides.<widgetKey>.hidden\n Category: layout\n Kind: boolean\n Description: Oculta o widget em tablet.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.layout\n Category: layout\n Kind: object\n Description: Override de WidgetPageLayout para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.canvas\n Category: layout\n Kind: object\n Description: Override de canvas para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.groupingOverrides\n Category: layout\n Kind: array\n Description: Overrides de agrupamentos para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.widgetOverrides\n Category: layout\n Kind: object\n Description: Overrides por widget key para mobile.\n\nComponent Capability:\n - Path: page.deviceLayouts.mobile.widgetOverrides.<widgetKey>.hidden\n Category: layout\n Kind: boolean\n Description: Oculta o widget em mobile.\n\nCapability Note:\n - page segue o modelo canonico WidgetPageDefinition (widgets, composition.links, context e state opcional); composition.links pode despachar actions globais via to.kind = global-action e receber continuations exatas via from.kind = global-action.\n\nCapability Note:\n - Conteudo editorial rico deve ser modelado como widget praxis-rich-content com definition.inputs.document: RichContentDocument, nao como DSL local do page-builder.\n\nCapability Note:\n - Quando definition.id = praxis-rich-content em uma pagina dinamica, definition.inputs.document continua sendo o contrato persistido; hostCapabilities e mediado em runtime pelo host praxis-dynamic-page e nao deve ser serializado no JSON da pagina.\n\nCapability Note:\n - Edicao visual de inputs de widget deve usar ComponentDocMeta.configEditor ou ComponentDocMeta.authoringManifestRef publicado pela lib dona do componente; nao criar editor local no page-builder para semantica de outro pacote.\n\nCapability Note:\n - Canvas e o modelo espacial canonico da pagina quando houver posicionamento explicito.\n\nCapability Note:\n - Taxonomia editorial: condition usa Json Logic canonico; transform usa pipeline declarativo; policy cobre apenas comportamento operacional.\n\nCapability Note:\n - Para criacao agentic de paginas, o preview pode trazer uiCompositionPlan como plano intermediario validavel; o page-builder compila esse plano para WidgetPageDefinition antes de aplicar.\n\nCapability Note:\n - UiCompositionPlan usa widgets[].componentId e bindings declarativos. UiCompositionPlanTemplateReference pode piná-lo por registryKey + configSha256, mas precisa ser resolvido pelo backend governado antes da compilação. O JSON persistido continua sendo page.widgets[].definition.id e page.composition.links.\n\nCapability Note:\n - Nested component ports usam endpoint component-port com nestedPath. O owner em ref.widget ou bindings[].*.widget continua sendo o widget top-level; a porta real do filho fica em port/direction e o caminho ate o filho fica em nestedPath.\n\nCapability Note:\n - Nao gere links nested via owner.widgetEvent, bindingPath profundo, page.connections ou wrappers host-specific. widgetEvent e bridge legada/avancada, nao contrato principal de authoring.\n\nCapability Note:\n - Payloads legados de layout ainda podem ser ingeridos, mas sao normalizados para canvas e nao devem ser reemitidos.\n\nCapability Note:\n - pageIdentity identifica o escopo de persistencia e nao pertence ao objeto page.\n\nCapability Note:\n - authoringCapabilities é um grant transitório do host para limitar affordances visíveis; não integra WidgetPageDefinition, não é persistido e não concede autoridade de edição à IA.\n\nCapability Note:\n - Este catálogo é específico para o runtime praxis-dynamic-page; operações de authoring/mutação pertencem ao manifesto do praxis-page-builder.\n\nCapability Note:\n - WidgetPageDefinition e o contrato canonico persistido: widgets, composition.links, state, context, i18n, layout, canvas, presets, grouping, slotAssignments, deviceLayouts e themePreset.\n\nCapability Note:\n - Widgets e page.composition.links sao arrays; ferramentas de patch legadas fazem merge por key estavel e id estavel.\n\nCapability Note:\n - page.canvas.items é um mapa por widget key; não modele canvas.items como array.\n\nCapability Note:\n - Taxonomia editorial: condition usa Json Logic canônico; transform usa pipeline declarativo; não trate ambos como a mesma \"expression\".\n\nCapability Note:\n - Para remocao/replace, use flags {_remove:true} ou {_replace:true} no item.\n\nCapability Note:\n - Para renomear um link, inclua {_beforeKey:\"link-id-anterior\"} no item.\n\nCapability Note:\n - Inputs de widgets dependem do componente (ex: praxis-table, praxis-dynamic-form). Evite inventar campos; prefira pedir confirmação.\n\nCapability Note:\n - Quando page.widgets[].definition.id for praxis-rich-content, o host praxis-dynamic-page injeta hostCapabilities em runtime para actions e capability gating; não serialize funções nem tente persistir page.widgets[].definition.inputs.hostCapabilities.\n\nCapability Note:\n - Use ids estaveis para links e keys estaveis para widgets.\n\nCapability Note:\n - Nested component ports usam endpoint component-port com nestedPath; o owner em ref.widget continua sendo o widget top-level.\n\nCapability Note:\n - Objetivo: compor widgets e relacionamentos canonicos (ex.: master-detail).\n\nCapability Note:\n - Link tipico de master-detail: component-port(table.rowClick) -> component-port(form.resourceId) com transform map payload.row.id.\n\nCapability Note:\n - Templates {{state.<path> | pipe}} e ${state.<path> | pipe} em inputs de widgets suportam pipes declarativos CSP-safe (default/coalesce, round[:N], number[:N], percent[:N], currency[:BRL|USD|EUR|GBP], uppercase, lowercase) via applyDeclarativeValuePipe, tratando tokens não resolvidos e NaN como ausentes no fallback.",
3156
3157
  "sourcePointer": "projects/praxis-core/src/lib/ai/dynamic-page-ai-capabilities.ts",
3157
- "contentHash": "5ead390a37077baba38267ff156ee549773b4706b728e829085305bdfe4b8db3",
3158
+ "contentHash": "482367709c3dd025d57e8a5a77ce9a4f2122d2a82da17798072bb55f6c1f0b23",
3158
3159
  "sourceKind": "component_definition",
3159
3160
  "sourceId": "praxis-dynamic-page",
3160
3161
  "corpusVersion": "1.0.0"
@@ -3322,9 +3323,9 @@
3322
3323
  {
3323
3324
  "chunkIndex": 23,
3324
3325
  "chunkKind": "recipe",
3325
- "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"authoringGuidance\",\"authoringGuidance\":[\"Resolve projection ids from x-ui.analytics; never infer a query or chart kind from labels.\",\"Keep queryContext when changing between chart and analytic-table.\",\"Use single-point cross-filter toggle semantics: selecting another bucket replaces the filter and repeating the active bucket clears it.\",\"Offer KPI only when an installed canonical KPI renderer is eligible for the projection.\",\"Keep remote results out of the page document; the recipe stores only contracts and query context.\"]}",
3326
+ "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"authoringGuidance\",\"authoringGuidance\":[\"Resolve projection ids from x-ui.analytics; never infer a query or chart kind from labels.\",\"Keep queryContext when changing between chart and analytic-table.\",\"Use single-point cross-filter toggle semantics: selecting another bucket replaces the filter and repeating the active bucket clears it.\",\"Offer KPI only when an installed canonical KPI renderer is eligible for the projection.\",\"Configure motion presets (subtle, standard, expressive) on chartDocument.motion when tailoring data-transition cadence across filter and cross-filter updates.\",\"Keep remote results out of the page document; the recipe stores only contracts and query context.\"]}",
3326
3327
  "sourcePointer": "examples/ai-recipes/praxis-dynamic-page.analytics-dashboard-showcase.json",
3327
- "contentHash": "75e7e49e332963450bafece618bdbef38a40ffbdac69acf33d1d044ceb6440b7",
3328
+ "contentHash": "035ec073b14d40772ec1beb392d21fc62433849ce2b1b29e39d4ade4d77d4eae",
3328
3329
  "sourceKind": "component_definition",
3329
3330
  "sourceId": "praxis-dynamic-page",
3330
3331
  "corpusVersion": "1.0.0"
@@ -3342,9 +3343,9 @@
3342
3343
  {
3343
3344
  "chunkIndex": 25,
3344
3345
  "chunkKind": "recipe",
3345
- "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"page.widgets\",\"page\":{\"widgets\":[{\"key\":\"procurementFilter\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"filter_alt\",\"title\":\"Filtros governados\",\"subtitle\":\"O DTO remoto preserva a empresa selecionada em todas as apresentações do funil\"},\"definition\":{\"id\":\"praxis-filter\",\"bindingOrder\":[\"resourcePath\",\"filterId\",\"formId\",\"alwaysVisibleFields\",\"selectedFieldIds\",\"disablePersistence\",\"showFilterSettings\",\"showAdvancedButton\",\"showAddButton\",\"showSearchButton\"],\"inputs\":{\"resourcePath\":\"procurement/vw-supplier-procurement-funnel\",\"filterId\":\"analytics-dashboard-procurement-filter\",\"formId\":\"analytics-dashboard-procurement-filter-form\",\"componentInstanceId\":\"analytics-dashboard-procurement-filter\",\"alwaysVisibleFields\":[\"companyId\"],\"selectedFieldIds\":[\"companyId\"],\"disablePersistence\":true,\"showFilterSettings\":false,\"showAdvancedButton\":false,\"showAddButton\":false,\"showSearchButton\":false},\"outputs\":{\"change\":\"emit\",\"clear\":\"emit\"}}},{\"key\":\"procurementPresentation\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"view_quilt\",\"title\":\"Uma projection, três apresentações\",\"subtitle\":\"Gráfico, tabela e indicadores executam o mesmo contrato e preservam o mesmo queryContext\"},\"definition\":{\"id\":\"praxis-analytics-presentation\",\"bindingOrder\":[\"analytics\",\"projectionId\",\"availableFamilies\",\"preferredFamily\",\"queryContext\",\"title\",\"subtitle\",\"enableCustomization\"],\"inputs\":{\"analytics\":{\"projections\":[{\"id\":\"supplier-procurement-funnel\",\"intent\":\"composition\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/procurement/vw-supplier-procurement-funnel\",\"operation\":\"group-by\"},\"bindings\":{\"primaryDimension\":{\"field\":\"stage\",\"role\":\"category\",\"label\":\"Etapa\"},\"primaryMetrics\":[{\"field\":\"volume\",\"aggregation\":\"sum\",\"label\":\"Fornecedores\"}]},\"defaults\":{\"sort\":[{\"field\":\"stage\",\"direction\":\"asc\"}],\"limit\":6},\"presentationHints\":{\"preferredFamilies\":[\"chart\",\"analytic-table\",\"kpi\"]},\"interactions\":{\"pointSelection\":true}}]},\"projectionId\":\"supplier-procurement-funnel\",\"availableFamilies\":[\"chart\",\"analytic-table\",\"kpi\"],\"preferredFamily\":\"chart\",\"queryContext\":{\"filters\":{}},\"title\":\"Funil de fornecedores\",\"subtitle\":\"Etapas cumulativas derivadas de fatos operacionais persistidos\",\"enableCustomization\":true},\"outputs\":{\"presentationChange\":\"emit\",\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"crossFilter\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"procurementFunnel\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"filter_alt\",\"title\":\"Funnel\",\"subtitle\":\"Ordem canônica 1→6 por bucket rotulado do stats\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"queryContext\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"supplier-procurement-funnel-chart\",\"kind\":\"funnel\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/procurement/vw-supplier-procurement-funnel\",\"operation\":\"group-by\",\"options\":{\"limit\":6,\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"stage\",\"label\":\"Etapa\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"volume\",\"label\":\"Fornecedores\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"queryContext\":{\"filters\":{}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"procurementPyramid\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"change_history\",\"title\":\"Pyramid\",\"subtitle\":\"A mesma série remota com ordem visual invertida pelo renderer\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"queryContext\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"supplier-procurement-pyramid-chart\",\"kind\":\"pyramid\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/procurement/vw-supplier-procurement-funnel\",\"operation\":\"group-by\",\"options\":{\"limit\":6,\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"stage\",\"label\":\"Etapa\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"volume\",\"label\":\"Fornecedores\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"queryContext\":{\"filters\":{}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"procurementGauge\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"speed\",\"title\":\"Conversão no recebimento\",\"subtitle\":\"AVG conversionRate da etapa 6 em uma única faixa governada de 0 a 100%\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"queryContext\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"supplier-procurement-receipt-conversion-gauge\",\"kind\":\"gauge\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/procurement/vw-supplier-procurement-funnel\",\"operation\":\"group-by\",\"options\":{\"limit\":1,\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"stage\",\"label\":\"Etapa\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"conversionRate\",\"label\":\"Conversão\",\"aggregation\":\"avg\",\"format\":\"percent\"}],\"filters\":[{\"field\":\"stageOrdersIn\",\"operator\":\"in\",\"values\":[6]}],\"gauge\":{\"scale\":{\"min\":0,\"max\":1}},\"legend\":{\"enabled\":false},\"labels\":{\"enabled\":true,\"format\":\"percent\"},\"tooltip\":{\"enabled\":true}},\"queryContext\":{\"filters\":{}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"missionStatusChart\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"bar_chart\",\"title\":\"Status das missões\",\"subtitle\":\"Selecione uma barra para filtrar; selecione-a novamente para limpar\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"queryContext\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-mission-status\",\"kind\":\"horizontal-bar\",\"orientation\":\"horizontal\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/operations/vw-resumo-missoes\",\"operation\":\"group-by\",\"options\":{\"limit\":10,\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"status\",\"label\":\"Status\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"missions\",\"label\":\"Missões\",\"aggregation\":\"count\"}],\"events\":{\"pointClick\":{\"action\":\"emit\"},\"selectionChange\":{\"action\":\"emit\",\"mapping\":{\"key\":\"status\"}},\"crossFilter\":{\"action\":\"filter-widget\",\"target\":\"missionStatusTable\",\"mapping\":{\"key\":\"status\"}}},\"legend\":{\"enabled\":false},\"tooltip\":{\"enabled\":true}},\"queryContext\":{\"filters\":{}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"crossFilter\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"missionStatusTable\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"table_rows\",\"title\":\"Portfólio filtrável\",\"subtitle\":\"A tabela remota recebe o filtro emitido pelo chart\"},\"definition\":{\"id\":\"praxis-table\",\"bindingOrder\":[\"config\",\"resourcePath\",\"queryContext\"],\"inputs\":{\"resourcePath\":\"operations/vw-resumo-missoes\",\"tableId\":\"analytics-dashboard-mission-status-table\",\"queryContext\":{\"filters\":{}},\"config\":{\"toolbar\":{\"visible\":true,\"title\":\"Missões\",\"subtitle\":\"Resultado operacional remoto\"},\"columns\":[{\"field\":\"titulo\",\"header\":\"Missão\",\"type\":\"text\",\"sticky\":\"start\"},{\"field\":\"status\",\"header\":\"Status\",\"type\":\"badge\"},{\"field\":\"prioridade\",\"header\":\"Prioridade\",\"type\":\"badge\"},{\"field\":\"ameaca\",\"header\":\"Ameaça\",\"type\":\"text\"},{\"field\":\"qtdEventos\",\"header\":\"Eventos\",\"type\":\"number\"}],\"behavior\":{\"selection\":{\"enabled\":true,\"type\":\"single\"}}}},\"outputs\":{\"rowClick\":\"emit\",\"selectionChange\":\"emit\",\"loadingStateChange\":\"emit\"}}}]}}",
3346
+ "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"page.widgets\",\"page\":{\"widgets\":[{\"key\":\"procurementFilter\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"filter_alt\",\"title\":\"Filtros governados\",\"subtitle\":\"O DTO remoto preserva a empresa selecionada em todas as apresentações do funil\"},\"definition\":{\"id\":\"praxis-filter\",\"bindingOrder\":[\"resourcePath\",\"filterId\",\"formId\",\"alwaysVisibleFields\",\"selectedFieldIds\",\"disablePersistence\",\"showFilterSettings\",\"showAdvancedButton\",\"showAddButton\",\"showSearchButton\"],\"inputs\":{\"resourcePath\":\"procurement/vw-supplier-procurement-funnel\",\"filterId\":\"analytics-dashboard-procurement-filter\",\"formId\":\"analytics-dashboard-procurement-filter-form\",\"componentInstanceId\":\"analytics-dashboard-procurement-filter\",\"alwaysVisibleFields\":[\"companyId\"],\"selectedFieldIds\":[\"companyId\"],\"disablePersistence\":true,\"showFilterSettings\":false,\"showAdvancedButton\":false,\"showAddButton\":false,\"showSearchButton\":false},\"outputs\":{\"change\":\"emit\",\"clear\":\"emit\"}}},{\"key\":\"procurementPresentation\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"view_quilt\",\"title\":\"Uma projection, três apresentações\",\"subtitle\":\"Gráfico, tabela e indicadores executam o mesmo contrato e preservam o mesmo queryContext\"},\"definition\":{\"id\":\"praxis-analytics-presentation\",\"bindingOrder\":[\"analytics\",\"projectionId\",\"availableFamilies\",\"preferredFamily\",\"queryContext\",\"title\",\"subtitle\",\"enableCustomization\"],\"inputs\":{\"analytics\":{\"projections\":[{\"id\":\"supplier-procurement-funnel\",\"intent\":\"composition\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/procurement/vw-supplier-procurement-funnel\",\"operation\":\"group-by\"},\"bindings\":{\"primaryDimension\":{\"field\":\"stage\",\"role\":\"category\",\"label\":\"Etapa\"},\"primaryMetrics\":[{\"field\":\"volume\",\"aggregation\":\"sum\",\"label\":\"Fornecedores\"}]},\"defaults\":{\"sort\":[{\"field\":\"stage\",\"direction\":\"asc\"}],\"limit\":6},\"presentationHints\":{\"preferredFamilies\":[\"chart\",\"analytic-table\",\"kpi\"]},\"interactions\":{\"pointSelection\":true}}]},\"projectionId\":\"supplier-procurement-funnel\",\"availableFamilies\":[\"chart\",\"analytic-table\",\"kpi\"],\"preferredFamily\":\"chart\",\"queryContext\":{\"filters\":{}},\"title\":\"Funil de fornecedores\",\"subtitle\":\"Etapas cumulativas derivadas de fatos operacionais persistidos\",\"enableCustomization\":true},\"outputs\":{\"presentationChange\":\"emit\",\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"crossFilter\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"procurementFunnel\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"filter_alt\",\"title\":\"Funnel\",\"subtitle\":\"Ordem canônica 1→6 por bucket rotulado do stats\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"queryContext\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"supplier-procurement-funnel-chart\",\"kind\":\"funnel\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/procurement/vw-supplier-procurement-funnel\",\"operation\":\"group-by\",\"options\":{\"limit\":6,\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"stage\",\"label\":\"Etapa\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"volume\",\"label\":\"Fornecedores\",\"aggregation\":\"sum\"}],\"motion\":{\"enabled\":true,\"preset\":\"standard\"},\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"queryContext\":{\"filters\":{}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"procurementPyramid\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"change_history\",\"title\":\"Pyramid\",\"subtitle\":\"A mesma série remota com ordem visual invertida pelo renderer\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"queryContext\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"supplier-procurement-pyramid-chart\",\"kind\":\"pyramid\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/procurement/vw-supplier-procurement-funnel\",\"operation\":\"group-by\",\"options\":{\"limit\":6,\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"stage\",\"label\":\"Etapa\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"volume\",\"label\":\"Fornecedores\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"queryContext\":{\"filters\":{}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"procurementGauge\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"speed\",\"title\":\"Conversão no recebimento\",\"subtitle\":\"AVG conversionRate da etapa 6 em uma única faixa governada de 0 a 100%\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"queryContext\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"supplier-procurement-receipt-conversion-gauge\",\"kind\":\"gauge\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/procurement/vw-supplier-procurement-funnel\",\"operation\":\"group-by\",\"options\":{\"limit\":1,\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"stage\",\"label\":\"Etapa\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"conversionRate\",\"label\":\"Conversão\",\"aggregation\":\"avg\",\"format\":\"percent\"}],\"filters\":[{\"field\":\"stageOrdersIn\",\"operator\":\"in\",\"values\":[6]}],\"gauge\":{\"scale\":{\"min\":0,\"max\":1}},\"motion\":{\"enabled\":true,\"preset\":\"expressive\"},\"legend\":{\"enabled\":false},\"labels\":{\"enabled\":true,\"format\":\"percent\"},\"tooltip\":{\"enabled\":true}},\"queryContext\":{\"filters\":{}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"missionStatusChart\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"bar_chart\",\"title\":\"Status das missões\",\"subtitle\":\"Selecione uma barra para filtrar; selecione-a novamente para limpar\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"queryContext\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-mission-status\",\"kind\":\"horizontal-bar\",\"orientation\":\"horizontal\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/operations/vw-resumo-missoes\",\"operation\":\"group-by\",\"options\":{\"limit\":10,\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"status\",\"label\":\"Status\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"missions\",\"label\":\"Missões\",\"aggregation\":\"count\"}],\"motion\":{\"enabled\":true,\"preset\":\"subtle\"},\"events\":{\"pointClick\":{\"action\":\"emit\"},\"selectionChange\":{\"action\":\"emit\",\"mapping\":{\"key\":\"status\"}},\"crossFilter\":{\"action\":\"filter-widget\",\"target\":\"missionStatusTable\",\"mapping\":{\"key\":\"status\"}}},\"legend\":{\"enabled\":false},\"tooltip\":{\"enabled\":true}},\"queryContext\":{\"filters\":{}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"crossFilter\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"missionStatusTable\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"table_rows\",\"title\":\"Portfólio filtrável\",\"subtitle\":\"A tabela remota recebe o filtro emitido pelo chart\"},\"definition\":{\"id\":\"praxis-table\",\"bindingOrder\":[\"config\",\"resourcePath\",\"queryContext\"],\"inputs\":{\"resourcePath\":\"operations/vw-resumo-missoes\",\"tableId\":\"analytics-dashboard-mission-status-table\",\"queryContext\":{\"filters\":{}},\"config\":{\"toolbar\":{\"visible\":true,\"title\":\"Missões\",\"subtitle\":\"Resultado operacional remoto\"},\"columns\":[{\"field\":\"titulo\",\"header\":\"Missão\",\"type\":\"text\",\"sticky\":\"start\"},{\"field\":\"status\",\"header\":\"Status\",\"type\":\"badge\"},{\"field\":\"prioridade\",\"header\":\"Prioridade\",\"type\":\"badge\"},{\"field\":\"ameaca\",\"header\":\"Ameaça\",\"type\":\"text\"},{\"field\":\"qtdEventos\",\"header\":\"Eventos\",\"type\":\"number\"}],\"behavior\":{\"selection\":{\"enabled\":true,\"type\":\"single\"}}}},\"outputs\":{\"rowClick\":\"emit\",\"selectionChange\":\"emit\",\"loadingStateChange\":\"emit\"}}}]}}",
3346
3347
  "sourcePointer": "examples/ai-recipes/praxis-dynamic-page.analytics-dashboard-showcase.json",
3347
- "contentHash": "750bc9fbddd8ce603c637edde33d9f475f9f89ef5f00a65e6cd18befc343befe",
3348
+ "contentHash": "7847873092f86e3149ac0bbc507b5c5eb7825e9ecdc1fc9ec208d893515867e6",
3348
3349
  "sourceKind": "component_definition",
3349
3350
  "sourceId": "praxis-dynamic-page",
3350
3351
  "corpusVersion": "1.0.0"