@praxisui/core 9.0.26 → 9.0.28

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
@@ -193,6 +193,13 @@ export class PageComponent {
193
193
 
194
194
  Use `page.composition.links` for persisted wiring. `page.connections` is legacy/residual and should not be used for new pages or examples. Nested component ports should use `component-port` endpoints with `ref.nestedPath`.
195
195
 
196
+ When a host enables dynamic-page customization, it can pass a transient
197
+ `WidgetPageAuthoringCapabilities` grant through `authoringCapabilities` to expose only the canvas,
198
+ page settings, widget shell, component-input, removal and child-customization operations that the
199
+ host actually supports. Omitted entries preserve full authoring for backward compatibility. This
200
+ grant controls visible authoring operations only: it is not persisted in `WidgetPageDefinition` and
201
+ does not replace component manifests, backend capabilities, authorization or validation.
202
+
196
203
  Page-owned business copy can use `page.i18n` plus explicit `PraxisTextValue`
197
204
  descriptors inside widget shells or nested widget inputs. The runtime resolves
198
205
  those descriptors only in its render projection, so the authored and persisted
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-26T21:39:46.376Z",
3
+ "generatedAt": "2026-08-28T04:22:11.708Z",
4
4
  "packageName": "@praxisui/core",
5
- "packageVersion": "9.0.26",
5
+ "packageVersion": "9.0.28",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 4,
@@ -480,6 +480,12 @@
480
480
  "required": false,
481
481
  "description": "Habilita affordances de edição na página."
482
482
  },
483
+ {
484
+ "name": "authoringCapabilities",
485
+ "type": "WidgetPageAuthoringCapabilities",
486
+ "required": false,
487
+ "description": "Restringe granularmente as operações de authoring permitidas pelo host."
488
+ },
483
489
  {
484
490
  "name": "showPageSettingsButton",
485
491
  "type": "boolean",
@@ -1938,6 +1944,7 @@
1938
1944
  "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.",
1939
1945
  "Payloads legados de layout ainda podem ser ingeridos, mas sao normalizados para canvas e nao devem ser reemitidos.",
1940
1946
  "pageIdentity identifica o escopo de persistencia e nao pertence ao objeto page.",
1947
+ "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.",
1941
1948
  "Este catálogo é específico para o runtime praxis-dynamic-page; operações de authoring/mutação pertencem ao manifesto do praxis-page-builder.",
1942
1949
  "WidgetPageDefinition e o contrato canonico persistido: widgets, composition.links, state, context, i18n, layout, canvas, presets, grouping, slotAssignments, deviceLayouts e themePreset.",
1943
1950
  "Widgets e page.composition.links sao arrays; ferramentas de patch legadas fazem merge por key estavel e id estavel.",
@@ -2981,9 +2988,9 @@
2981
2988
  {
2982
2989
  "chunkIndex": 0,
2983
2990
  "chunkKind": "summary",
2984
- "content": "Component ID: praxis-dynamic-page\nSelector: praxis-dynamic-page\nFriendly Name: Dynamic Page\nDescription: Página dinâmica com widgets e composition.links em layout responsivo, incluindo mediação runtime para rich-content hospedado.\nCategory: page\nLib/Package: @praxisui/core\nTags: widget, page, dynamic, layout\nInputs:\n - page (WidgetPageDefinition)\n - context (Record<string, any>)\n - strictValidation (boolean)\n - enableCustomization (boolean)\n - showPageSettingsButton (boolean)\n - shellEditorComponent (Type<any>)\n - pageEditorComponent (Type<any>)\n - autoPersist (boolean)\n - pageIdentity (PageIdentity)\n - componentInstanceId (string)\nOutputs:\n - pageChange (WidgetPageDefinition)\n - widgetEvent (WidgetEventEnvelope)\n - widgetDiagnosticsChange (Record<string, WidgetResolutionDiagnostic>)\n",
2991
+ "content": "Component ID: praxis-dynamic-page\nSelector: praxis-dynamic-page\nFriendly Name: Dynamic Page\nDescription: Página dinâmica com widgets e composition.links em layout responsivo, incluindo mediação runtime para rich-content hospedado.\nCategory: page\nLib/Package: @praxisui/core\nTags: widget, page, dynamic, layout\nInputs:\n - page (WidgetPageDefinition)\n - context (Record<string, any>)\n - strictValidation (boolean)\n - enableCustomization (boolean)\n - authoringCapabilities (WidgetPageAuthoringCapabilities)\n - showPageSettingsButton (boolean)\n - shellEditorComponent (Type<any>)\n - pageEditorComponent (Type<any>)\n - autoPersist (boolean)\n - pageIdentity (PageIdentity)\n - componentInstanceId (string)\nOutputs:\n - pageChange (WidgetPageDefinition)\n - widgetEvent (WidgetEventEnvelope)\n - widgetDiagnosticsChange (Record<string, WidgetResolutionDiagnostic>)\n",
2985
2992
  "sourcePointer": "projects/praxis-core/src/lib/widgets/dynamic-widget-page.metadata.ts",
2986
- "contentHash": "7575dbf241f37111a9acc2367fc82ced61f9ddf28586125b3a3b346d35a1fb7a",
2993
+ "contentHash": "27a7ae1a0c39ca506ccadd06b095f4370d5e57e34558965fbd40da1d82b3143d",
2987
2994
  "sourceKind": "component_definition",
2988
2995
  "sourceId": "praxis-dynamic-page",
2989
2996
  "corpusVersion": "1.0.0"
@@ -3041,9 +3048,9 @@
3041
3048
  {
3042
3049
  "chunkIndex": 6,
3043
3050
  "chunkKind": "capabilities",
3044
- "content": "Component 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 tambem pode despachar actions globais via to.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 - 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.",
3051
+ "content": "Component 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 tambem pode despachar actions globais via to.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.",
3045
3052
  "sourcePointer": "projects/praxis-core/src/lib/ai/dynamic-page-ai-capabilities.ts",
3046
- "contentHash": "8c2505b24e90fa2a568ab51e9ba82bd22360fb10f9deee8e2ff18f50a0caaed0",
3053
+ "contentHash": "56c5c10d5c3f63e96f2da523775d1549bf1fa8d0f6ab49007ab76d1731520138",
3047
3054
  "sourceKind": "component_definition",
3048
3055
  "sourceId": "praxis-dynamic-page",
3049
3056
  "corpusVersion": "1.0.0"
@@ -3231,9 +3238,9 @@
3231
3238
  {
3232
3239
  "chunkIndex": 25,
3233
3240
  "chunkKind": "recipe",
3234
- "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, duas apresentações\",\"subtitle\":\"Chart e tabela 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\"]},\"interactions\":{\"pointSelection\":true}}]},\"projectionId\":\"supplier-procurement-funnel\",\"availableFamilies\":[\"chart\",\"analytic-table\"],\"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\":\"missionStatusChart\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"bar_chart\",\"title\":\"Status das missões\",\"subtitle\":\"Selecione uma barra para filtrar a tabela operacional\"},\"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\":{\"status\":\"status\"}},\"crossFilter\":{\"action\":\"filter-widget\",\"target\":\"missionStatusTable\",\"mapping\":{\"status\":\"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\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollTrend\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"show_chart\",\"title\":\"Tendência mensal\",\"subtitle\":\"Linha remota de salário líquido por competência\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-trend\",\"kind\":\"line\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"timeseries\",\"options\":{\"granularity\":\"month\",\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"competencia\",\"label\":\"Competência\",\"role\":\"time\"}],\"metrics\":[{\"field\":\"salarioLiquido\",\"label\":\"Salário líquido\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}}]}}",
3241
+ "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\":\"missionStatusChart\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"bar_chart\",\"title\":\"Status das missões\",\"subtitle\":\"Selecione uma barra para filtrar a tabela operacional\"},\"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\":{\"status\":\"status\"}},\"crossFilter\":{\"action\":\"filter-widget\",\"target\":\"missionStatusTable\",\"mapping\":{\"status\":\"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\"}}},{\"key\":\"missionStatusVerticalBar\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"bar_chart\",\"title\":\"Status em barras verticais\",\"subtitle\":\"A mesma distribuição remota em apresentação vertical\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-mission-status-vertical\",\"kind\":\"bar\",\"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\"}],\"legend\":{\"enabled\":false},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollTrend\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"show_chart\",\"title\":\"Tendência mensal\",\"subtitle\":\"Linha remota de salário líquido por competência\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-trend\",\"kind\":\"line\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"timeseries\",\"options\":{\"granularity\":\"month\",\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"competencia\",\"label\":\"Competência\",\"role\":\"time\"}],\"metrics\":[{\"field\":\"salarioLiquido\",\"label\":\"Salário líquido\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}}]}}",
3235
3242
  "sourcePointer": "examples/ai-recipes/praxis-dynamic-page.analytics-dashboard-showcase.json",
3236
- "contentHash": "894488106710cdab3e61d4c0aa1fd3f1821e937776114b170805d80910895e85",
3243
+ "contentHash": "3791927abe1e28bf1823139f2e6f256fab1f42b8320ecc673fa5f76e66d864f8",
3237
3244
  "sourceKind": "component_definition",
3238
3245
  "sourceId": "praxis-dynamic-page",
3239
3246
  "corpusVersion": "1.0.0"
@@ -3241,9 +3248,9 @@
3241
3248
  {
3242
3249
  "chunkIndex": 26,
3243
3250
  "chunkKind": "recipe",
3244
- "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"page.widgets\",\"page\":{\"widgets\":[{\"key\":\"payrollStackedArea\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"area_chart\",\"title\":\"Composição da folha\",\"subtitle\":\"Área empilhada com séries legítimas do mesmo endpoint\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-stacked-area\",\"kind\":\"stacked-area\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"timeseries\",\"options\":{\"granularity\":\"month\",\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"competencia\",\"label\":\"Competência\",\"role\":\"time\"}],\"metrics\":[{\"field\":\"salarioBruto\",\"label\":\"Massa bruta\",\"aggregation\":\"sum\"},{\"field\":\"totalDescontos\",\"label\":\"Descontos\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollProfile\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"donut_large\",\"title\":\"Perfis da folha\",\"subtitle\":\"Rosca remota por perfil calculado\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-profile\",\"kind\":\"donut\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"group-by\",\"options\":{\"limit\":8,\"orderBy\":\"value-desc\"}},\"dimensions\":[{\"field\":\"payrollProfile\",\"label\":\"Perfil\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"count\",\"label\":\"Registros\",\"aggregation\":\"count\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollCombo\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"multiline_chart\",\"title\":\"Bruto × descontos\",\"subtitle\":\"Combo remoto com descontos no eixo secundário\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-combo\",\"kind\":\"combo\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"timeseries\",\"options\":{\"granularity\":\"month\",\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"competencia\",\"label\":\"Competência\",\"role\":\"time\"}],\"metrics\":[{\"field\":\"salarioBruto\",\"label\":\"Massa bruta\",\"aggregation\":\"sum\",\"seriesKind\":\"bar\",\"axis\":\"primary\"},{\"field\":\"totalDescontos\",\"label\":\"Descontos\",\"aggregation\":\"sum\",\"seriesKind\":\"line\",\"axis\":\"secondary\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"absenceCorrelation\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"scatter_plot\",\"title\":\"Pessoas × dias afastados\",\"subtitle\":\"Dispersão remota por departamento\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"config\",\"enableCustomization\"],\"inputs\":{\"config\":{\"id\":\"analytics-dashboard-absence-correlation\",\"type\":\"scatter\",\"axes\":{\"x\":{\"field\":\"employees\",\"type\":\"value\",\"label\":\"Colaboradores\"},\"y\":{\"field\":\"days\",\"type\":\"value\",\"label\":\"Dias afastados\"}},\"series\":[{\"id\":\"absence-department-correlation\",\"name\":\"Departamentos\",\"metric\":{\"field\":\"days\",\"aggregation\":\"sum\"}}],\"dataSource\":{\"kind\":\"remote\",\"resourcePath\":\"/api/human-resources/vw-analytics-afastamentos\",\"schemaId\":\"/api/human-resources/vw-analytics-afastamentos\",\"query\":{\"sourceKind\":\"praxis.stats\",\"statsOperation\":\"group-by\",\"statsPath\":\"/api/human-resources/vw-analytics-afastamentos/stats/group-by\",\"statsRequest\":{\"filter\":{},\"field\":\"departamento\",\"metric\":{\"operation\":\"DISTINCT_COUNT\",\"field\":\"funcionarioId\",\"alias\":\"employees\"},\"metrics\":[{\"operation\":\"DISTINCT_COUNT\",\"field\":\"funcionarioId\",\"alias\":\"employees\"},{\"operation\":\"SUM\",\"field\":\"diasAfastado\",\"alias\":\"days\"}],\"limit\":20,\"orderBy\":\"VALUE_DESC\"},\"dimensions\":[{\"field\":\"departamento\"}],\"metrics\":[{\"field\":\"funcionarioId\",\"aggregation\":\"distinct-count\",\"alias\":\"employees\"},{\"field\":\"diasAfastado\",\"aggregation\":\"sum\",\"alias\":\"days\"}]}},\"interactions\":{\"pointClick\":true,\"selection\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}}]}}",
3251
+ "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"page.widgets\",\"page\":{\"widgets\":[{\"key\":\"payrollAreaTrend\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"area_chart\",\"title\":\"Massa líquida em área\",\"subtitle\":\"A tendência mensal remota com preenchimento de área\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-area-trend\",\"kind\":\"area\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"timeseries\",\"options\":{\"granularity\":\"month\",\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"competencia\",\"label\":\"Competência\",\"role\":\"time\"}],\"metrics\":[{\"field\":\"salarioLiquido\",\"label\":\"Salário líquido\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollStackedArea\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"area_chart\",\"title\":\"Composição da folha\",\"subtitle\":\"Área empilhada com séries legítimas do mesmo endpoint\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-stacked-area\",\"kind\":\"stacked-area\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"timeseries\",\"options\":{\"granularity\":\"month\",\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"competencia\",\"label\":\"Competência\",\"role\":\"time\"}],\"metrics\":[{\"field\":\"salarioBruto\",\"label\":\"Massa bruta\",\"aggregation\":\"sum\"},{\"field\":\"totalDescontos\",\"label\":\"Descontos\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollStackedBar\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"stacked_bar_chart\",\"title\":\"Composição em barras empilhadas\",\"subtitle\":\"As mesmas séries remotas em comparação mensal discreta\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-stacked-bar\",\"kind\":\"stacked-bar\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"timeseries\",\"options\":{\"granularity\":\"month\",\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"competencia\",\"label\":\"Competência\",\"role\":\"time\"}],\"metrics\":[{\"field\":\"salarioBruto\",\"label\":\"Massa bruta\",\"aggregation\":\"sum\"},{\"field\":\"totalDescontos\",\"label\":\"Descontos\",\"aggregation\":\"sum\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollProfile\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"donut_large\",\"title\":\"Perfis da folha\",\"subtitle\":\"Rosca remota por perfil calculado\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-profile\",\"kind\":\"donut\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"group-by\",\"options\":{\"limit\":8,\"orderBy\":\"value-desc\"}},\"dimensions\":[{\"field\":\"payrollProfile\",\"label\":\"Perfil\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"count\",\"label\":\"Registros\",\"aggregation\":\"count\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollProfilePie\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"pie_chart\",\"title\":\"Perfis em pizza\",\"subtitle\":\"A mesma composição remota em setores preenchidos\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-profile-pie\",\"kind\":\"pie\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"group-by\",\"options\":{\"limit\":8,\"orderBy\":\"value-desc\"}},\"dimensions\":[{\"field\":\"payrollProfile\",\"label\":\"Perfil\",\"role\":\"category\"}],\"metrics\":[{\"field\":\"count\",\"label\":\"Registros\",\"aggregation\":\"count\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"payrollCombo\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"multiline_chart\",\"title\":\"Bruto × descontos\",\"subtitle\":\"Combo remoto com descontos no eixo secundário\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"chartDocument\",\"enableCustomization\"],\"inputs\":{\"chartDocument\":{\"version\":\"0.1.0\",\"chartId\":\"analytics-dashboard-payroll-combo\",\"kind\":\"combo\",\"source\":{\"kind\":\"praxis.stats\",\"resource\":\"/api/human-resources/vw-analytics-folha-pagamento\",\"operation\":\"timeseries\",\"options\":{\"granularity\":\"month\",\"orderBy\":\"key-asc\"}},\"dimensions\":[{\"field\":\"competencia\",\"label\":\"Competência\",\"role\":\"time\"}],\"metrics\":[{\"field\":\"salarioBruto\",\"label\":\"Massa bruta\",\"aggregation\":\"sum\",\"seriesKind\":\"bar\",\"axis\":\"primary\"},{\"field\":\"totalDescontos\",\"label\":\"Descontos\",\"aggregation\":\"sum\",\"seriesKind\":\"line\",\"axis\":\"secondary\"}],\"legend\":{\"enabled\":true},\"tooltip\":{\"enabled\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}},{\"key\":\"absenceCorrelation\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"scatter_plot\",\"title\":\"Pessoas × dias afastados\",\"subtitle\":\"Dispersão remota por departamento\"},\"definition\":{\"id\":\"praxis-chart\",\"bindingOrder\":[\"config\",\"enableCustomization\"],\"inputs\":{\"config\":{\"id\":\"analytics-dashboard-absence-correlation\",\"type\":\"scatter\",\"axes\":{\"x\":{\"field\":\"employees\",\"type\":\"value\",\"label\":\"Colaboradores\"},\"y\":{\"field\":\"days\",\"type\":\"value\",\"label\":\"Dias afastados\"}},\"series\":[{\"id\":\"absence-department-correlation\",\"name\":\"Departamentos\",\"metric\":{\"field\":\"days\",\"aggregation\":\"sum\"}}],\"dataSource\":{\"kind\":\"remote\",\"resourcePath\":\"/api/human-resources/vw-analytics-afastamentos\",\"schemaId\":\"/api/human-resources/vw-analytics-afastamentos\",\"query\":{\"sourceKind\":\"praxis.stats\",\"statsOperation\":\"group-by\",\"statsPath\":\"/api/human-resources/vw-analytics-afastamentos/stats/group-by\",\"statsRequest\":{\"filter\":{},\"field\":\"departamento\",\"metric\":{\"operation\":\"DISTINCT_COUNT\",\"field\":\"funcionarioId\",\"alias\":\"employees\"},\"metrics\":[{\"operation\":\"DISTINCT_COUNT\",\"field\":\"funcionarioId\",\"alias\":\"employees\"},{\"operation\":\"SUM\",\"field\":\"diasAfastado\",\"alias\":\"days\"}],\"limit\":20,\"orderBy\":\"VALUE_DESC\"},\"dimensions\":[{\"field\":\"departamento\"}],\"metrics\":[{\"field\":\"funcionarioId\",\"aggregation\":\"distinct-count\",\"alias\":\"employees\"},{\"field\":\"diasAfastado\",\"aggregation\":\"sum\",\"alias\":\"days\"}]}},\"interactions\":{\"pointClick\":true,\"selection\":true}},\"enableCustomization\":true},\"outputs\":{\"pointClick\":\"emit\",\"selectionChange\":\"emit\",\"loadStateChange\":\"emit\"}}}]}}",
3245
3252
  "sourcePointer": "examples/ai-recipes/praxis-dynamic-page.analytics-dashboard-showcase.json",
3246
- "contentHash": "e7123c572ad718907e5a0d6fea7729cd14302588120d07b7b93ffb699f49543d",
3253
+ "contentHash": "3b970d3e283c39a2917b69cf45133cef11dbaf3b23f6ae54c71b1f6803aaef21",
3247
3254
  "sourceKind": "component_definition",
3248
3255
  "sourceId": "praxis-dynamic-page",
3249
3256
  "corpusVersion": "1.0.0"