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

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
@@ -4,12 +4,144 @@ Shared contracts, tokens, services, metadata models, widget runtime primitives,
4
4
 
5
5
  Use this package directly when a host application or library needs Praxis UI types, global actions, metadata registries, schema clients, resource discovery, i18n, theme bridge, dynamic widget contracts, or shared runtime services.
6
6
 
7
+ ## Contextual table defaults
8
+
9
+ `createDefaultTableConfig()` leaves `pagination.strategy` and `sorting.strategy`
10
+ unset. These shared contracts cannot choose a data source: `@praxisui/table`
11
+ infers server processing for remote data and client processing for local data.
12
+ Explicit `client` or `server` choices remain authored choices. Optional strategy
13
+ properties allow sparse metadata and editor resets to preserve contextual
14
+ resolution; `auto` is not a public serialized value.
15
+
16
+ ## Governed bulk client: basic synchronous slice
17
+
18
+ `BulkOperationClientService` consumes the Metadata published `BulkExecutionContract`
19
+ from an action or CRUD capability. `discoverAction` and `discoverCapability` use the
20
+ existing resource discovery surface; operation paths and filtered schema URLs come
21
+ from that descriptor. `evaluationSchema` loads the backend's filtered request schema
22
+ for a caller to render the operation's form. The client admits only `SYNC`,
23
+ `EXPLICIT` and `PER_ITEM` in this first Angular slice. A descriptor that also
24
+ advertises query selection is usable only with an explicit target request here.
25
+
26
+ The Quickstart candidate migrates its existing uniform update operation to an
27
+ `ASYNC`-only profile; that host adoption is still being validated. BASIC omits
28
+ an `ASYNC`-only operation without a `SYNC` fallback. Angular ASYNC support needs
29
+ its own consumer implementation and acceptance; this note does not establish a
30
+ Render deployment or an ASYNC UI journey.
31
+
32
+ Provide the exact wire ID and opaque resource `expectedVersion` for every selected
33
+ target. In particular, int64/Long IDs remain decimal strings; do not convert them
34
+ through JavaScript numbers. Evaluate first, review the returned READY or BLOCKED
35
+ proposal and its authorized paged results, then confirm a READY proposal using
36
+ only `{ proposalId }` and one `Idempotency-Key`. `BulkSyncStateService.createSession`
37
+ keeps that key fixed across a retry of the same confirmation. A new intention gets
38
+ a new session. The key and proposal live only in that session; it makes no claim
39
+ of recovery across a page reload.
40
+
41
+ For a selected collection row that publishes a `self` link,
42
+ `readTargetVersion(row._links, wireId, identityPath, options)` reads that exact
43
+ item, verifies its returned identity and returns the original strong quoted ETag
44
+ as `expectedVersion`. It rejects absent/weak ETags, foreign origins and mismatched
45
+ IDs. Callers should bound concurrent reads and cancel them when their resource
46
+ context closes. A row value, schema ETag or locally inferred URL is not a resource
47
+ version.
48
+
49
+ ```ts
50
+ const contract = await firstValueFrom(bulkClient.discoverCapability(resourceResponse, operationId));
51
+ const session = bulkState.createSession(contract);
52
+ const proposal = await session.evaluate(explicitSyncRequest);
53
+ const preview = await firstValueFrom(bulkClient.readProposalResults(contract, proposal.proposalId));
54
+ // Present proposal and preview to the person; a BLOCKED proposal cannot be confirmed.
55
+
56
+ // In a separate, explicit confirmation action for a READY proposal:
57
+ await session.confirm(idempotencyKeyForThisIntent);
58
+ // On an uncertain HTTP failure, retain this session and retry with the same key.
59
+ // The host schedules further authorized readbacks for an accepted nonterminal execution.
60
+ const reads = new AbortController(); // This view owns GET lifetime, not confirmation custody.
61
+ if (!session.isTerminal()) await session.refreshExecution(reads.signal);
62
+ if (session.isTerminal()) {
63
+ const results = await session.readResults(200, undefined, reads.signal);
64
+ }
65
+ ```
66
+
67
+ `resourceResponse`, `operationId`, the explicit request and the key come from the
68
+ caller's governed selection and form flow; the client resolves operation URLs from
69
+ the descriptor. The caller controls when to read status again and presents each
70
+ authorized page of results. This example is a service integration sketch, not a
71
+ ready visual workflow or a deployment claim.
72
+
73
+ `refreshExecution(signal?)` and `readResults(size?, after?, signal?)` retain their
74
+ Promise API and optionally accept a standard `AbortSignal`. An already aborted
75
+ signal dispatches no GET; abort unsubscribes the actual HTTP request, releases the
76
+ read slot, and prevents a late Promise continuation from updating the session.
77
+ Abort listeners are removed on success, failure and cancellation. A cancelled GET
78
+ keeps the original proposal, confirmation key and accepted execution; it does not
79
+ mark that execution terminal or prove rollback. A new authorized read may observe
80
+ the same execution. Overlapping execution refreshes remain rejected, while an
81
+ aborted generation cannot release the slot of its successor.
82
+
83
+ The caller owns GET cancellation and its observation budget; the Core session does
84
+ not invent a global read timeout. Use a fresh read lifetime for a fresh consultation
85
+ and abort reads when the owning view closes. Do not race a Promise with a timer:
86
+ connect the signal to the read itself so the HTTP subscription is torn down.
87
+ `evaluate` and `confirm` do not accept this signal: a dispatched POST and its original
88
+ key stay in intent custody across view teardown. GET failure/cancellation must never
89
+ start a new evaluation or confirmation automatically.
90
+
91
+ The backend is the authority on proposal expiry. A client clock hint must not
92
+ block a same-key replay after an uncertain confirmation; the backend may return
93
+ 409 or 410 and the host must explain that state without inventing a new intent.
94
+
95
+ HTTP 202, `RUNNING`, `CANCEL_REQUESTED` and `RECONCILIATION_REQUIRED` are not
96
+ business success. Read the authorized execution until its reconciled terminal
97
+ state and use the paged result reader for each item outcome. Preserve backend
98
+ errors (including 409, 410, 429 and 503) for the host's governed UX mapping;
99
+ do not turn them into a new submission with a new key. The backend continues to
100
+ own authorization, policy, identity, idempotency, limits and the domain transaction.
101
+ The table library has a candidate visual path for a published CRUD
102
+ `bulk-update` capability in `UNIFORM_UPDATE` mode. It uses this client and a
103
+ separate review/confirmation surface; it does not add a second backend contract.
104
+ The service also supports typed command and per-item requests, but that table
105
+ surface does not advertise them. Query selection, ASYNC jobs and ATOMIC mode are
106
+ outside this Angular slice. This is not a claim that the reference host or full
107
+ backend B7 acceptance is complete.
108
+
109
+ ## Published asynchronous execution tracking
110
+
111
+ `PraxisBulkClientService.waitForExecution` is separate from the BASIC client
112
+ above. Use its published execution operation only when that operation actually
113
+ supports the asynchronous profile; an enum member does not enable a backend
114
+ profile. The Observable emits one canonical terminal snapshot, preserving
115
+ `COMPLETED`, `COMPLETED_WITH_ERRORS`, `CANCELLED`, `STOPPED` and
116
+ `RECONCILIATION_REQUIRED`. `CANCEL_REQUESTED` remains pending.
117
+
118
+ Each subscription starts its own strict overall deadline. At most one GET is in
119
+ flight: interval ticks do not abort a useful slow read or queue overlapping reads.
120
+ Pending responses do not renew the deadline, which also bounds a GET that never
121
+ responds. Terminal completion, transport error, deadline and unsubscribe release
122
+ the active read and polling timers; a late response cannot revive an expired
123
+ subscription. Stopping a GET does not reverse server effects or cancel a POST.
124
+
125
+ A read failure means the outcome is unknown. Explicitly resume reads for the same
126
+ execution and preserve the original proposal and confirmation key; do not confirm
127
+ or evaluate again to restore progress. This transport does not provide custody
128
+ across closing/reopening a dialog, reload recovery or operational ASYNC acceptance.
129
+
7
130
  ## Governed color palettes
8
131
 
9
132
  `materializeGovernedPaletteEntries(palette, purposes)` returns `MaterializedGovernedColorToken[]`, pairing each original `entry` with its resolved `color`. It preserves distinct token IDs even when CSS references/colors match, applies purpose filtering, and resolves fallback dependencies against the complete palette. Use this projection for identified swatches; do not zip color arrays to entries or infer identity from color equality. `materializeGovernedPaletteColors` remains the string-only projection of the same resolver.
10
133
 
11
134
  `GovernedColorPaletteService` is the canonical Angular client for color-palette projections published by Praxis Config. Published palettes carry a stable `familyKey`, an explicit `variant` identity and token-level `displayName`/`aliases`; incomplete legacy projections are rejected before caching. The service supports list/read/capabilities/preview, exact `list(familyKey)` queries, tenant/environment-isolated caching, conditional ETag revalidation and deterministic `version`/`etag` pins. Consumers may use names and aliases for presentation and discovery only: `paletteKey` and `tokenId` remain the persisted identities, and local metadata must not become a second source of governance. `GovernedColorTokenSelection` carries the exact palette/version/ETag/token observation beside the existing CSS-string field value; applications persist it only through an explicit domain field or mapping.
12
135
 
136
+ ## Declarative Page DataSources (`page.dataSources`)
137
+
138
+ `WidgetPageDefinition.dataSources` and `WidgetPageDataSourceRuntimeService` allow dynamic pages and dashboards to fetch backend KPIs, group-by aggregations, and time-series metrics without imperative host `HttpClient` orchestration:
139
+
140
+ - **Endpoint resolution (`endpointKey` + `resourcePath`)**: resolves URLs through the `API_URL` token using `endpointKey` (falling back to `'default'`) so multi-service enterprise hosts route each DataSource to its target microservice.
141
+ - **Transform presets & JsonLogic**: supports `{ kind: 'path', path }`, `{ kind: 'group-by-map', mappings, totalField }` (initializing declared keys with `0` for sparse buckets), `{ kind: 'timeseries-last', mappings }`, or arbitrary JsonLogic expressions.
142
+ - **Transient state overlay (`targetStatePath`)**: merges resolved payloads into a non-persisted runtime overlay over `page.state.values[targetStatePath]` and coalesces concurrent emissions via microtask batching before re-evaluating `page.state.derived` and `composition.links`. Live runtime payloads never dirty `authoredPageDefinition` or trigger `autoPersist` writes.
143
+ - **Resilience & visibility-aware polling**: `errorPolicy` (`'fallback' | 'silent' | 'propagate'`) applies `fallbackValue` only before the first successful response so transient network errors during polling (`refreshIntervalMs`) never overwrite live data with static fallbacks. Subsequent poll ticks pause while `document.visibilityState === 'hidden'` and resume immediately on `visibilitychange`.
144
+
13
145
  ## LLM Recommendation Guide
14
146
 
15
147
  - `BUILTIN_WIDGET_SHELL_PRESETS` is the canonical catalog for reusable shell
@@ -209,9 +341,45 @@ Peer dependencies:
209
341
  - `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/material`, `@angular/platform-browser`, `@angular/router` `^21.0.0`
210
342
  - `rxjs` `~7.8.0`
211
343
 
344
+ ## Resource HTTP responses and revision custody
345
+
346
+ `GenericCrudService.getByIdHttpResponse(id, options?)` and `updateHttpResponse(id, entity, options?)` expose the original `HttpResponse<RestApiResponse<T>>`, pairing a representation with its response headers. Existing `getById`, `getByIdResponse`, `update` and `updateResponse` keep their original DTO/envelope return shapes.
347
+
348
+ `CrudOperationOptions.resourceVersion` overrides a write's shared item cache: a strong quoted ETag supplies the exact `If-Match`, `null` intentionally omits that precondition, and `undefined` preserves existing cache → DTO `resourceVersion` fallback (or the configured header when neither is present). Consumers that edit a captured representation must provide its original revision, rather than a revision obtained by another read. `readStrongResourceEtag` validates a single strong tag without normalizing its bytes; weak, unquoted and multi-valued headers cannot stand in for a write revision. An explicitly invalid/weak response header clears the previous cached token. When the header is absent, the existing Core cache can capture DTO `resourceVersion`; this legacy/manual fallback does not authorize an automatic Form snapshot. Explicit overrides never fall back to cached, DTO or configured tokens.
349
+
212
350
  ## Theme And Icons
213
351
 
214
- Import the theme bridge after Angular Material and CDK overlay styles.
352
+ ### Canonical SCSS Theming (Recommended)
353
+
354
+ Import the canonical theming mixins to bridge host design tokens (OKLCH, Material 3, Tailwind, etc.) to Praxis components:
355
+
356
+ ```scss
357
+ @use "@angular/cdk/overlay-prebuilt.css";
358
+ @use "@praxisui/core/theming" as praxis;
359
+
360
+ // Option A: Bundle light theme, dark mode overrides, widget shell, and tooltip enhancements
361
+ @include praxis.praxis-theme-bundle();
362
+
363
+ // Option B: Granular configuration with custom design tokens
364
+ :root {
365
+ @include praxis.define-praxis-theme((
366
+ 'primary': var(--primary),
367
+ 'surface': var(--card),
368
+ 'border': var(--border)
369
+ ));
370
+ }
371
+
372
+ .dark {
373
+ @include praxis.praxis-dark-theme-overrides();
374
+ }
375
+
376
+ @include praxis.praxis-shell-styles();
377
+ @include praxis.praxis-tooltip-styles();
378
+ ```
379
+
380
+ ### Static Theme Bridge (Legacy)
381
+
382
+ For simple or static setups, you can still import the prebuilt CSS bridge directly:
215
383
 
216
384
  ```scss
217
385
  @import "@angular/cdk/overlay-prebuilt.css";
@@ -421,6 +589,20 @@ Hosts that maintain an authored source separately from runtime state should cons
421
589
  `pageChange` remains the compatibility stream for every canonical page update, including persistent
422
590
  runtime state; transient composition projections remain excluded from both outputs.
423
591
 
592
+ With `autoPersist` enabled, pass a stable `pageIdentity` to scope the document and
593
+ listen to `persistenceChange: WidgetPagePersistenceState` for `loading`, `saving`,
594
+ `saved`, `resetting`, `idle` or `error`. `savedAt` is emitted only after the
595
+ storage confirms a save. An empty `{ widgets: [] }` document is a valid customized
596
+ page; absence of a stored document falls back to the host's page. The runtime
597
+ serializes save and reset operations for the identity so each storage call uses
598
+ the latest provider ETag. A 409/412 conflict blocks later writes until the host
599
+ explicitly calls `reloadPersistedPage(defaultPage)`, which discards the current
600
+ draft. `resetPersistedPage(defaultPage)` clears storage and applies the factory
601
+ page only after acknowledgement. `persistCurrentPage(page?)` requests an
602
+ explicit save or retries a recoverable save failure; callers can pass the exact
603
+ authored snapshot they want saved. Completion without a storage value reports
604
+ `errorKind: 'unacknowledged'` rather than claiming success.
605
+
424
606
  Pointer drag/resize in the canvas snapshots rendered CSS Grid track sizes and gutters at gesture
425
607
  start. Content-sized rows are not treated as uniformly sized `rowUnit` rows. Horizontal resize
426
608
  snaps to columns; vertical resize in `autoRows: 'content'` authors the item's independent
@@ -689,7 +871,9 @@ Action-bearing components must use the semantic `--praxis-action-control-*` vari
689
871
 
690
872
  ### Catálogo no quick connect e isolamento do editor de página
691
873
 
692
- `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.
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
+
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`.
693
877
 
694
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.
695
879
 
@@ -869,10 +1053,17 @@ widget appearance/size, or registered content editor session. It uses the existi
869
1053
  `owner` option; no session identity is persisted in the page document.
870
1054
 
871
1055
  The session is cancelled when its panel closes, the page is destroyed, or an external
872
- page/context/identity/authoring input change invalidates it. A page-only acknowledgement
873
- identical to the current authored document keeps the session alive for subsequent
874
- Apply/Save. This is deliberately conservative: a different external document cancels
875
- open editors even when a particular widget happens to be unchanged.
1056
+ page/context/identity/authoring input change invalidates it. An acknowledgement identical
1057
+ to the current authored page keeps the session alive for subsequent Apply/Save, including
1058
+ when the host resends an equivalent `pageIdentity` object. After the first input change,
1059
+ identity equivalence means strict equality of its five fields: `appId`, `tenantId`,
1060
+ `userId`, `routePath` and `locale`; whitespace, delimiters and missing values are not
1061
+ normalized. Core retains a private snapshot of those accepted primitive values, so
1062
+ mutating the host's previous object before resending a clone still changes the scope.
1063
+ Resending only that equivalent identity also preserves data-source overlays,
1064
+ composition and persistence scope. Context, instance and authoring capability changes
1065
+ remain invalidating. A different external document cancels open editors even when a
1066
+ particular widget happens to be unchanged. This does not confirm an HTTP save.
876
1067
 
877
1068
  Confirmed widget removal cancels sessions targeting that key, plus page-wide settings
878
1069
  that could restore the removed widget. Asynchronous editor results cannot open a panel
@@ -1035,6 +1226,26 @@ blur does not become an inner widget's default. Intentional inheritance through
1035
1226
  `context.ui.shell.preset/presets` remains supported. This isolation does not remove
1036
1227
  the host's shared theme tokens.
1037
1228
 
1229
+ ## App shell: host appearance
1230
+
1231
+ `PraxisAppShellComponent` materializes the host theme for both the sidebar and
1232
+ header. The existing theme roles `--sidebar` (falling back to `--card`),
1233
+ `--surface-gradient` (falling back to `--card`), `--command-gradient`,
1234
+ `--sidebar-foreground`, `--sidebar-primary`, `--sidebar-accent`,
1235
+ `--sidebar-accent-foreground`, `--primary-deep`, `--primary-foreground`,
1236
+ `--accent`, `--secondary`, `--overlay`
1237
+ and `--shadow-panel` apply to the native chrome and brand icon. Navigation,
1238
+ loading and mobile behavior do not change when these colors change. Without host
1239
+ theme tokens, the brand uses a dark blue fallback with a white icon; custom host
1240
+ colors should always supply their corresponding foreground roles.
1241
+
1242
+ Semantic badges use tinted surfaces with the host's foreground. Success,
1243
+ warning and info consume `--praxis-success`, `--praxis-warning` and
1244
+ `--praxis-info`; the established `--ready`/`--warning` variables and bounded
1245
+ fallbacks remain available. Error consumes `--destructive`. Hosts should use
1246
+ these existing roles rather than overriding private shell selectors. No new
1247
+ shell input, saved layout field or theme-specific component is required.
1248
+
1038
1249
  <!-- praxis-npm-catalog-links:start -->
1039
1250
  ## Official documentation and examples
1040
1251
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-07T02:07:06.204Z",
3
+ "generatedAt": "2026-10-16T17:45:27.774Z",
4
4
  "packageName": "@praxisui/core",
5
- "packageVersion": "10.0.0-rc.3",
5
+ "packageVersion": "10.0.0-rc.31",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 4,
@@ -530,6 +530,12 @@
530
530
  "required": false,
531
531
  "description": "Emitido quando a página canônica muda por authoring ou por estado runtime persistente; projeções transitórias permanecem somente no runtime."
532
532
  },
533
+ {
534
+ "name": "persistenceChange",
535
+ "type": "WidgetPagePersistenceState",
536
+ "required": false,
537
+ "description": "Estado da carga, gravação ou reset da página após resposta do storage, incluindo customized, savedAt e falhas de conflito ou ausência de confirmação."
538
+ },
533
539
  {
534
540
  "name": "pageAuthoringChange",
535
541
  "type": "WidgetPageDefinition",
@@ -1414,7 +1420,8 @@
1414
1420
  "valueKind": "enum",
1415
1421
  "allowedValues": [
1416
1422
  "block",
1417
- "swap"
1423
+ "swap",
1424
+ "push-down"
1418
1425
  ],
1419
1426
  "description": "Politica de colisao do canvas espacial."
1420
1427
  },
@@ -3085,9 +3092,9 @@
3085
3092
  {
3086
3093
  "chunkIndex": 0,
3087
3094
  "chunkKind": "summary",
3088
- "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 - pageAuthoringChange (WidgetPageDefinition)\n - widgetEvent (WidgetEventEnvelope)\n - widgetDiagnosticsChange (Record<string, WidgetResolutionDiagnostic>)\n",
3095
+ "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 - persistenceChange (WidgetPagePersistenceState)\n - pageAuthoringChange (WidgetPageDefinition)\n - widgetEvent (WidgetEventEnvelope)\n - widgetDiagnosticsChange (Record<string, WidgetResolutionDiagnostic>)\n",
3089
3096
  "sourcePointer": "projects/praxis-core/src/lib/widgets/dynamic-widget-page.metadata.ts",
3090
- "contentHash": "d3f9a1519379d733fb13af496aff99953cd5a37399555955cbf747457185c2e3",
3097
+ "contentHash": "d16589daf72efcc199d385b1147bf0764f30a33343d9fe16486fdc2836a15d78",
3091
3098
  "sourceKind": "component_definition",
3092
3099
  "sourceId": "praxis-dynamic-page",
3093
3100
  "corpusVersion": "1.0.0"
@@ -3885,9 +3892,9 @@
3885
3892
  {
3886
3893
  "chunkIndex": 80,
3887
3894
  "chunkKind": "recipe",
3888
- "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"page.widgets\",\"page\":{\"widgets\":[{\"key\":\"employeePortfolio\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"groups\",\"title\":{\"key\":\"employeeOperations.portfolio.shell.title\",\"text\":\"Gestão de pessoas\"},\"subtitle\":{\"key\":\"employeeOperations.portfolio.shell.subtitle\",\"text\":\"Encontre funcionários, atualize vínculos e consulte o dossiê sem sair da carteira\"},\"windowActions\":{\"collapsible\":false,\"fullscreen\":true}},\"definition\":{\"id\":\"praxis-crud\",\"bindingOrder\":[\"crudId\",\"componentInstanceId\",\"tableConfigPersistenceStrategy\",\"metadata\"],\"inputs\":{\"crudId\":\"employee-operations-casework\",\"componentInstanceId\":\"employee-operations-casework\",\"tableConfigPersistenceStrategy\":\"volatile\",\"metadata\":{\"component\":\"praxis-crud\",\"resource\":{\"path\":\"human-resources/funcionarios\",\"idField\":\"id\",\"endpointKey\":\"human-resources.funcionarios\",\"title\":{\"key\":\"employeeOperations.portfolio.resource.title\",\"text\":\"Funcionários\"},\"formTitle\":{\"key\":\"employeeOperations.portfolio.resource.formTitle\",\"text\":\"Cadastro do funcionário\"}},\"form\":{\"actions\":{\"placement\":\"afterSections\",\"sticky\":true}},\"table\":{\"ai\":{\"assistant\":{\"enabled\":false}},\"toolbar\":{\"visible\":true,\"title\":{\"key\":\"employeeOperations.portfolio.toolbar.title\",\"text\":\"Carteira de funcionários\"},\"subtitle\":{\"key\":\"employeeOperations.portfolio.toolbar.subtitle\",\"text\":\"Dados cadastrais, área, vínculo e remuneração em uma única visão\"},\"search\":{\"enabled\":true,\"placeholder\":{\"key\":\"employeeOperations.portfolio.search.placeholder\",\"text\":\"Buscar por nome, e-mail, cargo ou departamento\"}},\"filters\":{\"enabled\":true,\"showAdvancedButton\":true,\"quickFilters\":[{\"id\":\"active-employees\",\"label\":{\"key\":\"employeeOperations.portfolio.quickFilter.active\",\"text\":\"Ativos\"},\"icon\":\"check_circle\",\"filter\":{\"ativo\":true}},{\"id\":\"inactive-employees\",\"label\":{\"key\":\"employeeOperations.portfolio.quickFilter.inactive\",\"text\":\"Inativos\"},\"icon\":\"block\",\"filter\":{\"ativo\":false}}]},\"columnsVisibility\":{\"enabled\":true},\"densityToggle\":{\"enabled\":true}},\"columns\":[{\"field\":\"avatarUrl\",\"header\":{\"key\":\"employeeOperations.portfolio.column.person\",\"text\":\"Pessoa\"},\"type\":\"string\",\"width\":\"64px\",\"renderer\":{\"type\":\"avatar\",\"avatar\":{\"srcField\":\"avatarUrl\",\"altField\":\"nomeCompleto\",\"initialsField\":\"nomeCompleto\",\"shape\":\"circle\",\"size\":36}}},{\"field\":\"nomeCompleto\",\"header\":{\"key\":\"employeeOperations.portfolio.column.employee\",\"text\":\"Funcionário\"},\"type\":\"string\",\"width\":\"180px\",\"sticky\":\"start\"},{\"field\":\"ativo\",\"header\":{\"key\":\"employeeOperations.portfolio.column.employment\",\"text\":\"Vínculo\"},\"type\":\"boolean\",\"format\":\"active-inactive\",\"width\":\"104px\",\"align\":\"center\",\"conditionalRenderers\":[{\"condition\":{\"==\":[{\"var\":\"ativo\"},true]},\"renderer\":{\"type\":\"badge\",\"badge\":{\"text\":{\"key\":\"employeeOperations.portfolio.status.active\",\"text\":\"Ativo\"},\"color\":\"success\",\"variant\":\"filled\",\"icon\":\"check_circle\"}}},{\"condition\":{\"==\":[{\"var\":\"ativo\"},false]},\"renderer\":{\"type\":\"badge\",\"badge\":{\"text\":{\"key\":\"employeeOperations.portfolio.status.inactive\",\"text\":\"Inativo\"},\"color\":\"warn\",\"variant\":\"outlined\",\"icon\":\"block\"}}}]},{\"field\":\"cargoNome\",\"header\":{\"key\":\"employeeOperations.portfolio.column.role\",\"text\":\"Cargo\"},\"type\":\"string\",\"width\":\"190px\",\"renderer\":{\"type\":\"chip\",\"chip\":{\"textField\":\"cargoNome\",\"variant\":\"outlined\",\"color\":\"primary\"}}},{\"field\":\"departamentoNome\",\"header\":{\"key\":\"employeeOperations.portfolio.column.department\",\"text\":\"Departamento\"},\"type\":\"string\",\"width\":\"244px\",\"renderer\":{\"type\":\"badge\",\"badge\":{\"textField\":\"departamentoNome\",\"variant\":\"soft\",\"color\":\"accent\"}}},{\"field\":\"dataAdmissao\",\"header\":{\"key\":\"employeeOperations.portfolio.column.hiredAt\",\"text\":\"Admissão\"},\"type\":\"date\",\"format\":\"dd/MM/yyyy\",\"width\":\"132px\"},{\"field\":\"salario\",\"header\":{\"key\":\"employeeOperations.portfolio.column.salary\",\"text\":\"Salário base\"},\"type\":\"currency\",\"format\":\"BRL|symbol|2\",\"align\":\"end\",\"width\":\"150px\"},{\"field\":\"email\",\"header\":{\"key\":\"employeeOperations.portfolio.column.contact\",\"text\":\"Contato\"},\"type\":\"string\",\"width\":\"240px\"}],\"behavior\":{\"pagination\":{\"enabled\":true,\"strategy\":\"server\",\"pageSize\":8,\"pageSizeOptions\":[8,16,32],\"position\":\"bottom\"},\"sorting\":{\"enabled\":true,\"strategy\":\"server\",\"defaultSort\":{\"column\":\"id\",\"direction\":\"asc\"}},\"filtering\":{\"enabled\":true,\"strategy\":\"server\",\"debounceTime\":300,\"advancedFilters\":{\"enabled\":true,\"settings\":{\"alwaysVisibleFields\":[\"departamentoIdsIn\",\"dataAdmissaoRange\",\"salarioBetween\"],\"allowSaveTags\":true,\"tags\":[{\"id\":\"executive-pay-band\",\"label\":\"Faixa executiva\",\"patch\":{\"salarioBetween\":[39000,40000]}}],\"advancedOpenMode\":\"modal\",\"advancedClearButtonsEnabled\":true,\"changeDebounceMs\":300}}},\"selection\":{\"enabled\":true,\"type\":\"single\",\"mode\":\"row\",\"persistSelection\":false},\"density\":\"compact\"},\"actions\":{\"row\":{\"enabled\":true,\"display\":\"icons\",\"position\":\"end\",\"sticky\":\"end\",\"header\":{\"label\":{\"key\":\"employeeOperations.portfolio.actions.header\",\"text\":\"Ações\"},\"icon\":\"bolt\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.actions.tooltip\",\"text\":\"Visualizar, editar ou atualizar o vínculo\"}},\"behavior\":{\"enabled\":true,\"maxInline\":{\"xs\":0,\"sm\":1,\"md\":2,\"lg\":1},\"autoStrategy\":\"breakpoints\"},\"actions\":[{\"id\":\"view\",\"label\":{\"key\":\"employeeOperations.portfolio.action.view\",\"text\":\"Visualizar\"},\"icon\":\"visibility\",\"action\":\"view\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.view.tooltip\",\"text\":\"Ver dados do funcionário\"}},{\"id\":\"edit\",\"label\":{\"key\":\"employeeOperations.portfolio.action.edit\",\"text\":\"Editar\"},\"icon\":\"edit\",\"action\":\"edit\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.edit.tooltip\",\"text\":\"Editar dados do funcionário\"}},{\"id\":\"deactivate\",\"label\":{\"key\":\"employeeOperations.portfolio.action.deactivate\",\"text\":\"Inativar\"},\"icon\":\"person_off\",\"color\":\"warn\",\"action\":\"deactivate\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.deactivate.tooltip\",\"text\":\"Inativar vínculo e registrar motivo e vigência\"},\"visibleWhen\":{\"==\":[{\"var\":\"ativo\"},true]}},{\"id\":\"reactivate\",\"label\":{\"key\":\"employeeOperations.portfolio.action.reactivate\",\"text\":\"Reativar\"},\"icon\":\"person_add\",\"color\":\"primary\",\"action\":\"reactivate\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.reactivate.tooltip\",\"text\":\"Reativar vínculo e registrar motivo e vigência\"},\"visibleWhen\":{\"==\":[{\"var\":\"ativo\"},false]}}]}},\"appearance\":{\"density\":\"compact\",\"stickyHeader\":true,\"stripedRows\":false,\"hoverHighlight\":true,\"responsive\":{\"breakpoints\":{\"mobile\":640},\"mobile\":{\"horizontalScroll\":false,\"cardMode\":true,\"priorityColumns\":[\"nomeCompleto\",\"ativo\",\"cargoNome\"]}}},\"export\":{\"enabled\":true,\"formats\":[\"csv\",\"excel\"],\"general\":{\"includeHeaders\":true,\"respectFilters\":true,\"applyFormatting\":true,\"defaultFileName\":\"carteira-funcionarios\",\"includeColumns\":\"visible\",\"scope\":\"currentPage\",\"maxRows\":500},\"excel\":{\"sheetName\":\"Funcionários\",\"autoFitColumns\":true,\"freezeHeaders\":true}}},\"defaults\":{\"openMode\":\"drawer\"},\"actions\":[{\"action\":\"create\",\"openMode\":\"drawer\"},{\"action\":\"view\",\"openMode\":\"drawer\"},{\"action\":\"edit\",\"openMode\":\"drawer\"}]}},\"outputs\":{\"rowClick\":\"emit\",\"rowAction\":\"emit\",\"selectionChange\":\"emit\",\"afterSave\":\"emit\",\"afterDelete\":\"emit\"}}}]}}",
3895
+ "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"page.widgets\",\"page\":{\"widgets\":[{\"key\":\"employeePortfolio\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"groups\",\"title\":{\"key\":\"employeeOperations.portfolio.shell.title\",\"text\":\"Gestão de pessoas\"},\"subtitle\":{\"key\":\"employeeOperations.portfolio.shell.subtitle\",\"text\":\"Encontre funcionários, atualize vínculos e consulte o dossiê sem sair da carteira\"},\"windowActions\":{\"collapsible\":false,\"fullscreen\":true}},\"definition\":{\"id\":\"praxis-crud\",\"bindingOrder\":[\"crudId\",\"componentInstanceId\",\"tableConfigPersistenceStrategy\",\"metadata\"],\"inputs\":{\"crudId\":\"employee-operations-casework\",\"componentInstanceId\":\"employee-operations-casework\",\"tableConfigPersistenceStrategy\":\"volatile\",\"metadata\":{\"component\":\"praxis-crud\",\"resource\":{\"path\":\"human-resources/funcionarios\",\"idField\":\"id\",\"endpointKey\":\"human-resources.funcionarios\",\"title\":{\"key\":\"employeeOperations.portfolio.resource.title\",\"text\":\"Funcionários\"},\"formTitle\":{\"key\":\"employeeOperations.portfolio.resource.formTitle\",\"text\":\"Cadastro do funcionário\"}},\"form\":{\"actions\":{\"placement\":\"afterSections\",\"sticky\":true}},\"table\":{\"ai\":{\"assistant\":{\"enabled\":false}},\"toolbar\":{\"visible\":true,\"title\":{\"key\":\"employeeOperations.portfolio.toolbar.title\",\"text\":\"Carteira de funcionários\"},\"subtitle\":{\"key\":\"employeeOperations.portfolio.toolbar.subtitle\",\"text\":\"Dados cadastrais, área, vínculo e remuneração em uma única visão\"},\"search\":{\"enabled\":true,\"placeholder\":{\"key\":\"employeeOperations.portfolio.search.placeholder\",\"text\":\"Buscar por nome, e-mail, cargo ou departamento\"}},\"filters\":{\"enabled\":true,\"showAdvancedButton\":true,\"quickFilters\":[{\"id\":\"active-employees\",\"label\":{\"key\":\"employeeOperations.portfolio.quickFilter.active\",\"text\":\"Ativos\"},\"icon\":\"check_circle\",\"filter\":{\"ativo\":true}},{\"id\":\"inactive-employees\",\"label\":{\"key\":\"employeeOperations.portfolio.quickFilter.inactive\",\"text\":\"Inativos\"},\"icon\":\"block\",\"filter\":{\"ativo\":false}}]},\"columnsVisibility\":{\"enabled\":true},\"densityToggle\":{\"enabled\":true}},\"columns\":[{\"field\":\"avatarUrl\",\"header\":{\"key\":\"employeeOperations.portfolio.column.person\",\"text\":\"Pessoa\"},\"type\":\"string\",\"width\":\"64px\",\"renderer\":{\"type\":\"avatar\",\"avatar\":{\"srcField\":\"avatarUrl\",\"altField\":\"nomeCompleto\",\"initialsField\":\"nomeCompleto\",\"shape\":\"circle\",\"size\":36}}},{\"field\":\"nomeCompleto\",\"header\":{\"key\":\"employeeOperations.portfolio.column.employee\",\"text\":\"Funcionário\"},\"type\":\"string\",\"width\":\"180px\",\"sticky\":\"start\"},{\"field\":\"ativo\",\"header\":{\"key\":\"employeeOperations.portfolio.column.employment\",\"text\":\"Vínculo\"},\"type\":\"boolean\",\"format\":\"active-inactive\",\"width\":\"104px\",\"align\":\"center\",\"conditionalRenderers\":[{\"condition\":{\"==\":[{\"var\":\"ativo\"},true]},\"renderer\":{\"type\":\"badge\",\"badge\":{\"text\":{\"key\":\"employeeOperations.portfolio.status.active\",\"text\":\"Ativo\"},\"color\":\"success\",\"variant\":\"filled\",\"icon\":\"check_circle\"}}},{\"condition\":{\"==\":[{\"var\":\"ativo\"},false]},\"renderer\":{\"type\":\"badge\",\"badge\":{\"text\":{\"key\":\"employeeOperations.portfolio.status.inactive\",\"text\":\"Inativo\"},\"color\":\"warn\",\"variant\":\"outlined\",\"icon\":\"block\"}}}]},{\"field\":\"cargoNome\",\"header\":{\"key\":\"employeeOperations.portfolio.column.role\",\"text\":\"Cargo\"},\"type\":\"string\",\"width\":\"190px\",\"renderer\":{\"type\":\"chip\",\"chip\":{\"textField\":\"cargoNome\",\"variant\":\"outlined\",\"color\":\"primary\"}}},{\"field\":\"departamentoNome\",\"header\":{\"key\":\"employeeOperations.portfolio.column.department\",\"text\":\"Departamento\"},\"type\":\"string\",\"width\":\"244px\",\"renderer\":{\"type\":\"badge\",\"badge\":{\"textField\":\"departamentoNome\",\"variant\":\"soft\",\"color\":\"accent\"}}},{\"field\":\"dataAdmissao\",\"header\":{\"key\":\"employeeOperations.portfolio.column.hiredAt\",\"text\":\"Admissão\"},\"type\":\"date\",\"format\":\"dd/MM/yyyy\",\"width\":\"132px\"},{\"field\":\"salario\",\"header\":{\"key\":\"employeeOperations.portfolio.column.salary\",\"text\":\"Salário base\"},\"type\":\"currency\",\"format\":\"BRL|symbol|2\",\"align\":\"end\",\"width\":\"150px\"},{\"field\":\"email\",\"header\":{\"key\":\"employeeOperations.portfolio.column.contact\",\"text\":\"Contato\"},\"type\":\"string\",\"width\":\"240px\"}],\"behavior\":{\"pagination\":{\"enabled\":true,\"strategy\":\"server\",\"pageSize\":8,\"pageSizeOptions\":[8,16,32],\"position\":\"bottom\"},\"sorting\":{\"enabled\":true,\"strategy\":\"server\",\"defaultSort\":{\"column\":\"id\",\"direction\":\"asc\"}},\"filtering\":{\"enabled\":true,\"strategy\":\"server\",\"debounceTime\":300,\"advancedFilters\":{\"enabled\":true,\"settings\":{\"alwaysVisibleFields\":[\"departamentoIdsIn\",\"dataAdmissaoRange\",\"salarioBetween\"],\"allowSaveTags\":true,\"tags\":[{\"id\":\"executive-pay-band\",\"label\":\"Faixa executiva\",\"patch\":{\"salarioBetween\":[39000,40000]}}],\"advancedOpenMode\":\"modal\",\"advancedClearButtonsEnabled\":true,\"changeDebounceMs\":300}}},\"selection\":{\"enabled\":true,\"type\":\"single\",\"mode\":\"row\",\"persistSelection\":false},\"drawer\":{\"openOnRowClick\":false},\"density\":\"compact\"},\"actions\":{\"row\":{\"enabled\":true,\"display\":\"icons\",\"position\":\"end\",\"sticky\":\"end\",\"header\":{\"label\":{\"key\":\"employeeOperations.portfolio.actions.header\",\"text\":\"Ações\"},\"icon\":\"bolt\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.actions.tooltip\",\"text\":\"Visualizar, editar ou atualizar o vínculo\"}},\"behavior\":{\"enabled\":true,\"maxInline\":{\"xs\":0,\"sm\":1,\"md\":2,\"lg\":1},\"autoStrategy\":\"breakpoints\"},\"actions\":[{\"id\":\"view\",\"label\":{\"key\":\"employeeOperations.portfolio.action.view\",\"text\":\"Visualizar\"},\"icon\":\"visibility\",\"action\":\"view\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.view.tooltip\",\"text\":\"Ver dados do funcionário\"}},{\"id\":\"edit\",\"label\":{\"key\":\"employeeOperations.portfolio.action.edit\",\"text\":\"Editar\"},\"icon\":\"edit\",\"action\":\"edit\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.edit.tooltip\",\"text\":\"Editar dados do funcionário\"}},{\"id\":\"deactivate\",\"label\":{\"key\":\"employeeOperations.portfolio.action.deactivate\",\"text\":\"Inativar\"},\"icon\":\"person_off\",\"color\":\"warn\",\"action\":\"deactivate\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.deactivate.tooltip\",\"text\":\"Inativar vínculo e registrar motivo e vigência\"},\"visibleWhen\":{\"==\":[{\"var\":\"ativo\"},true]}},{\"id\":\"reactivate\",\"label\":{\"key\":\"employeeOperations.portfolio.action.reactivate\",\"text\":\"Reativar\"},\"icon\":\"person_add\",\"color\":\"primary\",\"action\":\"reactivate\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.reactivate.tooltip\",\"text\":\"Reativar vínculo e registrar motivo e vigência\"},\"visibleWhen\":{\"==\":[{\"var\":\"ativo\"},false]}}]}},\"appearance\":{\"density\":\"compact\",\"stickyHeader\":true,\"stripedRows\":false,\"hoverHighlight\":true,\"responsive\":{\"breakpoints\":{\"mobile\":640},\"mobile\":{\"horizontalScroll\":false,\"cardMode\":true,\"priorityColumns\":[\"nomeCompleto\",\"ativo\",\"cargoNome\"]}}},\"export\":{\"enabled\":true,\"formats\":[\"csv\",\"excel\"],\"general\":{\"includeHeaders\":true,\"respectFilters\":true,\"applyFormatting\":true,\"defaultFileName\":\"carteira-funcionarios\",\"includeColumns\":\"visible\",\"scope\":\"currentPage\",\"maxRows\":500},\"excel\":{\"sheetName\":\"Funcionários\",\"autoFitColumns\":true,\"freezeHeaders\":true}}},\"defaults\":{\"openMode\":\"drawer\"},\"actions\":[{\"action\":\"create\",\"openMode\":\"drawer\"},{\"action\":\"view\",\"openMode\":\"drawer\"},{\"action\":\"edit\",\"openMode\":\"drawer\"}]}},\"outputs\":{\"rowClick\":\"emit\",\"rowAction\":\"emit\",\"selectionChange\":\"emit\",\"afterSave\":\"emit\",\"afterDelete\":\"emit\"}}}]}}",
3889
3896
  "sourcePointer": "examples/ai-recipes/praxis-dynamic-page.employee-operations-casework.json",
3890
- "contentHash": "32a3c8de260c471cd7b3153f5436a392d11201d71c556bbc507efee2ecbe943b",
3897
+ "contentHash": "5b94dc593942c987943f7330f161f46f64ebe971df2ccf48553df1fa73e97294",
3891
3898
  "sourceKind": "component_definition",
3892
3899
  "sourceId": "praxis-dynamic-page",
3893
3900
  "corpusVersion": "1.0.0"
@@ -4045,9 +4052,9 @@
4045
4052
  {
4046
4053
  "chunkIndex": 96,
4047
4054
  "chunkKind": "recipe",
4048
- "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"authoringPlan.widgets\",\"authoringPlan\":{\"widgets\":[{\"key\":\"employeePortfolio\",\"componentId\":\"praxis-crud\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"groups\",\"title\":{\"key\":\"employeeOperations.portfolio.shell.title\"},\"subtitle\":{\"key\":\"employeeOperations.portfolio.shell.subtitle\"},\"windowActions\":{\"collapsible\":false,\"fullscreen\":true}},\"bindingOrder\":[\"crudId\",\"componentInstanceId\",\"tableConfigPersistenceStrategy\",\"metadata\"],\"inputs\":{\"crudId\":\"employee-operations-casework\",\"componentInstanceId\":\"employee-operations-casework\",\"tableConfigPersistenceStrategy\":\"volatile\",\"metadata\":{\"component\":\"praxis-crud\",\"resource\":{\"path\":\"human-resources/funcionarios\",\"idField\":\"id\",\"endpointKey\":\"human-resources.funcionarios\",\"title\":{\"key\":\"employeeOperations.portfolio.resource.title\"},\"formTitle\":{\"key\":\"employeeOperations.portfolio.resource.formTitle\"}},\"form\":{\"actions\":{\"placement\":\"afterSections\",\"sticky\":true}},\"table\":{\"ai\":{\"assistant\":{\"enabled\":false}},\"toolbar\":{\"visible\":true,\"title\":{\"key\":\"employeeOperations.portfolio.toolbar.title\"},\"subtitle\":{\"key\":\"employeeOperations.portfolio.toolbar.subtitle\"},\"search\":{\"enabled\":true,\"placeholder\":{\"key\":\"employeeOperations.portfolio.search.placeholder\"}},\"filters\":{\"enabled\":true,\"showAdvancedButton\":true,\"quickFilters\":[{\"id\":\"active-employees\",\"label\":{\"key\":\"employeeOperations.portfolio.quickFilter.active\"},\"icon\":\"check_circle\",\"filter\":{\"ativo\":true}},{\"id\":\"inactive-employees\",\"label\":{\"key\":\"employeeOperations.portfolio.quickFilter.inactive\"},\"icon\":\"block\",\"filter\":{\"ativo\":false}}]},\"columnsVisibility\":{\"enabled\":true},\"densityToggle\":{\"enabled\":true}},\"columns\":[{\"field\":\"avatarUrl\",\"header\":{\"key\":\"employeeOperations.portfolio.column.person\"},\"type\":\"string\",\"width\":\"64px\",\"renderer\":{\"type\":\"avatar\",\"avatar\":{\"srcField\":\"avatarUrl\",\"altField\":\"nomeCompleto\",\"initialsField\":\"nomeCompleto\",\"shape\":\"circle\",\"size\":36}}},{\"field\":\"nomeCompleto\",\"header\":{\"key\":\"employeeOperations.portfolio.column.employee\"},\"type\":\"string\",\"width\":\"180px\",\"sticky\":\"start\"},{\"field\":\"ativo\",\"header\":{\"key\":\"employeeOperations.portfolio.column.employment\"},\"type\":\"boolean\",\"format\":\"active-inactive\",\"width\":\"104px\",\"align\":\"center\",\"conditionalRenderers\":[{\"condition\":{\"==\":[{\"var\":\"ativo\"},true]},\"renderer\":{\"type\":\"badge\",\"badge\":{\"text\":{\"key\":\"employeeOperations.portfolio.status.active\"},\"color\":\"success\",\"variant\":\"filled\",\"icon\":\"check_circle\"}}},{\"condition\":{\"==\":[{\"var\":\"ativo\"},false]},\"renderer\":{\"type\":\"badge\",\"badge\":{\"text\":{\"key\":\"employeeOperations.portfolio.status.inactive\"},\"color\":\"warn\",\"variant\":\"outlined\",\"icon\":\"block\"}}}]},{\"field\":\"cargoNome\",\"header\":{\"key\":\"employeeOperations.portfolio.column.role\"},\"type\":\"string\",\"width\":\"190px\",\"renderer\":{\"type\":\"chip\",\"chip\":{\"textField\":\"cargoNome\",\"variant\":\"outlined\",\"color\":\"primary\"}}},{\"field\":\"departamentoNome\",\"header\":{\"key\":\"employeeOperations.portfolio.column.department\"},\"type\":\"string\",\"width\":\"244px\",\"renderer\":{\"type\":\"badge\",\"badge\":{\"textField\":\"departamentoNome\",\"variant\":\"soft\",\"color\":\"accent\"}}},{\"field\":\"dataAdmissao\",\"header\":{\"key\":\"employeeOperations.portfolio.column.hiredAt\"},\"type\":\"date\",\"format\":\"dd/MM/yyyy\",\"width\":\"132px\"},{\"field\":\"salario\",\"header\":{\"key\":\"employeeOperations.portfolio.column.salary\"},\"type\":\"currency\",\"format\":\"BRL|symbol|2\",\"align\":\"end\",\"width\":\"150px\"},{\"field\":\"email\",\"header\":{\"key\":\"employeeOperations.portfolio.column.contact\"},\"type\":\"string\",\"width\":\"240px\"}],\"behavior\":{\"pagination\":{\"enabled\":true,\"strategy\":\"server\",\"pageSize\":8,\"pageSizeOptions\":[8,16,32],\"position\":\"bottom\"},\"sorting\":{\"enabled\":true,\"strategy\":\"server\",\"defaultSort\":{\"column\":\"id\",\"direction\":\"asc\"}},\"filtering\":{\"enabled\":true,\"strategy\":\"server\",\"debounceTime\":300,\"advancedFilters\":{\"enabled\":true,\"settings\":{\"alwaysVisibleFields\":[\"departamentoIdsIn\",\"dataAdmissaoRange\",\"salarioBetween\"],\"allowSaveTags\":true,\"tags\":[{\"id\":\"executive-pay-band\",\"label\":\"Faixa executiva\",\"patch\":{\"salarioBetween\":[39000,40000]}}],\"advancedOpenMode\":\"modal\",\"advancedClearButtonsEnabled\":true,\"changeDebounceMs\":300}}},\"selection\":{\"enabled\":true,\"type\":\"single\",\"mode\":\"row\",\"persistSelection\":false},\"density\":\"compact\"},\"actions\":{\"row\":{\"enabled\":true,\"display\":\"icons\",\"position\":\"end\",\"sticky\":\"end\",\"header\":{\"label\":{\"key\":\"employeeOperations.portfolio.actions.header\"},\"icon\":\"bolt\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.actions.tooltip\"}},\"behavior\":{\"enabled\":true,\"maxInline\":{\"xs\":0,\"sm\":1,\"md\":2,\"lg\":1},\"autoStrategy\":\"breakpoints\"},\"actions\":[{\"id\":\"view\",\"label\":{\"key\":\"employeeOperations.portfolio.action.view\"},\"icon\":\"visibility\",\"action\":\"view\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.view.tooltip\"}},{\"id\":\"edit\",\"label\":{\"key\":\"employeeOperations.portfolio.action.edit\"},\"icon\":\"edit\",\"action\":\"edit\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.edit.tooltip\"}},{\"id\":\"deactivate\",\"label\":{\"key\":\"employeeOperations.portfolio.action.deactivate\"},\"icon\":\"person_off\",\"color\":\"warn\",\"action\":\"deactivate\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.deactivate.tooltip\"},\"visibleWhen\":{\"==\":[{\"var\":\"ativo\"},true]}},{\"id\":\"reactivate\",\"label\":{\"key\":\"employeeOperations.portfolio.action.reactivate\"},\"icon\":\"person_add\",\"color\":\"primary\",\"action\":\"reactivate\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.reactivate.tooltip\"},\"visibleWhen\":{\"==\":[{\"var\":\"ativo\"},false]}}]}},\"appearance\":{\"density\":\"compact\",\"stickyHeader\":true,\"stripedRows\":false,\"hoverHighlight\":true,\"responsive\":{\"breakpoints\":{\"mobile\":640},\"mobile\":{\"horizontalScroll\":false,\"cardMode\":true,\"priorityColumns\":[\"nomeCompleto\",\"ativo\",\"cargoNome\"]}}},\"export\":{\"enabled\":true,\"formats\":[\"csv\",\"excel\"],\"general\":{\"includeHeaders\":true,\"respectFilters\":true,\"applyFormatting\":true,\"defaultFileName\":\"carteira-funcionarios\",\"includeColumns\":\"visible\",\"scope\":\"currentPage\",\"maxRows\":500},\"excel\":{\"sheetName\":\"Funcionários\",\"autoFitColumns\":true,\"freezeHeaders\":true}}},\"defaults\":{\"openMode\":\"drawer\"},\"actions\":[{\"action\":\"create\",\"openMode\":\"drawer\"},{\"action\":\"view\",\"openMode\":\"drawer\"},{\"action\":\"edit\",\"openMode\":\"drawer\"}]}},\"outputs\":{\"rowClick\":\"emit\",\"rowAction\":\"emit\",\"selectionChange\":\"emit\",\"afterSave\":\"emit\",\"afterDelete\":\"emit\"}}]}}",
4055
+ "content": "{\"componentId\":\"praxis-dynamic-page\",\"chunkSection\":\"authoringPlan.widgets\",\"authoringPlan\":{\"widgets\":[{\"key\":\"employeePortfolio\",\"componentId\":\"praxis-crud\",\"shell\":{\"kind\":\"dashboard-card\",\"icon\":\"groups\",\"title\":{\"key\":\"employeeOperations.portfolio.shell.title\"},\"subtitle\":{\"key\":\"employeeOperations.portfolio.shell.subtitle\"},\"windowActions\":{\"collapsible\":false,\"fullscreen\":true}},\"bindingOrder\":[\"crudId\",\"componentInstanceId\",\"tableConfigPersistenceStrategy\",\"metadata\"],\"inputs\":{\"crudId\":\"employee-operations-casework\",\"componentInstanceId\":\"employee-operations-casework\",\"tableConfigPersistenceStrategy\":\"volatile\",\"metadata\":{\"component\":\"praxis-crud\",\"resource\":{\"path\":\"human-resources/funcionarios\",\"idField\":\"id\",\"endpointKey\":\"human-resources.funcionarios\",\"title\":{\"key\":\"employeeOperations.portfolio.resource.title\"},\"formTitle\":{\"key\":\"employeeOperations.portfolio.resource.formTitle\"}},\"form\":{\"actions\":{\"placement\":\"afterSections\",\"sticky\":true}},\"table\":{\"ai\":{\"assistant\":{\"enabled\":false}},\"toolbar\":{\"visible\":true,\"title\":{\"key\":\"employeeOperations.portfolio.toolbar.title\"},\"subtitle\":{\"key\":\"employeeOperations.portfolio.toolbar.subtitle\"},\"search\":{\"enabled\":true,\"placeholder\":{\"key\":\"employeeOperations.portfolio.search.placeholder\"}},\"filters\":{\"enabled\":true,\"showAdvancedButton\":true,\"quickFilters\":[{\"id\":\"active-employees\",\"label\":{\"key\":\"employeeOperations.portfolio.quickFilter.active\"},\"icon\":\"check_circle\",\"filter\":{\"ativo\":true}},{\"id\":\"inactive-employees\",\"label\":{\"key\":\"employeeOperations.portfolio.quickFilter.inactive\"},\"icon\":\"block\",\"filter\":{\"ativo\":false}}]},\"columnsVisibility\":{\"enabled\":true},\"densityToggle\":{\"enabled\":true}},\"columns\":[{\"field\":\"avatarUrl\",\"header\":{\"key\":\"employeeOperations.portfolio.column.person\"},\"type\":\"string\",\"width\":\"64px\",\"renderer\":{\"type\":\"avatar\",\"avatar\":{\"srcField\":\"avatarUrl\",\"altField\":\"nomeCompleto\",\"initialsField\":\"nomeCompleto\",\"shape\":\"circle\",\"size\":36}}},{\"field\":\"nomeCompleto\",\"header\":{\"key\":\"employeeOperations.portfolio.column.employee\"},\"type\":\"string\",\"width\":\"180px\",\"sticky\":\"start\"},{\"field\":\"ativo\",\"header\":{\"key\":\"employeeOperations.portfolio.column.employment\"},\"type\":\"boolean\",\"format\":\"active-inactive\",\"width\":\"104px\",\"align\":\"center\",\"conditionalRenderers\":[{\"condition\":{\"==\":[{\"var\":\"ativo\"},true]},\"renderer\":{\"type\":\"badge\",\"badge\":{\"text\":{\"key\":\"employeeOperations.portfolio.status.active\"},\"color\":\"success\",\"variant\":\"filled\",\"icon\":\"check_circle\"}}},{\"condition\":{\"==\":[{\"var\":\"ativo\"},false]},\"renderer\":{\"type\":\"badge\",\"badge\":{\"text\":{\"key\":\"employeeOperations.portfolio.status.inactive\"},\"color\":\"warn\",\"variant\":\"outlined\",\"icon\":\"block\"}}}]},{\"field\":\"cargoNome\",\"header\":{\"key\":\"employeeOperations.portfolio.column.role\"},\"type\":\"string\",\"width\":\"190px\",\"renderer\":{\"type\":\"chip\",\"chip\":{\"textField\":\"cargoNome\",\"variant\":\"outlined\",\"color\":\"primary\"}}},{\"field\":\"departamentoNome\",\"header\":{\"key\":\"employeeOperations.portfolio.column.department\"},\"type\":\"string\",\"width\":\"244px\",\"renderer\":{\"type\":\"badge\",\"badge\":{\"textField\":\"departamentoNome\",\"variant\":\"soft\",\"color\":\"accent\"}}},{\"field\":\"dataAdmissao\",\"header\":{\"key\":\"employeeOperations.portfolio.column.hiredAt\"},\"type\":\"date\",\"format\":\"dd/MM/yyyy\",\"width\":\"132px\"},{\"field\":\"salario\",\"header\":{\"key\":\"employeeOperations.portfolio.column.salary\"},\"type\":\"currency\",\"format\":\"BRL|symbol|2\",\"align\":\"end\",\"width\":\"150px\"},{\"field\":\"email\",\"header\":{\"key\":\"employeeOperations.portfolio.column.contact\"},\"type\":\"string\",\"width\":\"240px\"}],\"behavior\":{\"pagination\":{\"enabled\":true,\"strategy\":\"server\",\"pageSize\":8,\"pageSizeOptions\":[8,16,32],\"position\":\"bottom\"},\"sorting\":{\"enabled\":true,\"strategy\":\"server\",\"defaultSort\":{\"column\":\"id\",\"direction\":\"asc\"}},\"filtering\":{\"enabled\":true,\"strategy\":\"server\",\"debounceTime\":300,\"advancedFilters\":{\"enabled\":true,\"settings\":{\"alwaysVisibleFields\":[\"departamentoIdsIn\",\"dataAdmissaoRange\",\"salarioBetween\"],\"allowSaveTags\":true,\"tags\":[{\"id\":\"executive-pay-band\",\"label\":\"Faixa executiva\",\"patch\":{\"salarioBetween\":[39000,40000]}}],\"advancedOpenMode\":\"modal\",\"advancedClearButtonsEnabled\":true,\"changeDebounceMs\":300}}},\"selection\":{\"enabled\":true,\"type\":\"single\",\"mode\":\"row\",\"persistSelection\":false},\"drawer\":{\"openOnRowClick\":false},\"density\":\"compact\"},\"actions\":{\"row\":{\"enabled\":true,\"display\":\"icons\",\"position\":\"end\",\"sticky\":\"end\",\"header\":{\"label\":{\"key\":\"employeeOperations.portfolio.actions.header\"},\"icon\":\"bolt\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.actions.tooltip\"}},\"behavior\":{\"enabled\":true,\"maxInline\":{\"xs\":0,\"sm\":1,\"md\":2,\"lg\":1},\"autoStrategy\":\"breakpoints\"},\"actions\":[{\"id\":\"view\",\"label\":{\"key\":\"employeeOperations.portfolio.action.view\"},\"icon\":\"visibility\",\"action\":\"view\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.view.tooltip\"}},{\"id\":\"edit\",\"label\":{\"key\":\"employeeOperations.portfolio.action.edit\"},\"icon\":\"edit\",\"action\":\"edit\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.edit.tooltip\"}},{\"id\":\"deactivate\",\"label\":{\"key\":\"employeeOperations.portfolio.action.deactivate\"},\"icon\":\"person_off\",\"color\":\"warn\",\"action\":\"deactivate\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.deactivate.tooltip\"},\"visibleWhen\":{\"==\":[{\"var\":\"ativo\"},true]}},{\"id\":\"reactivate\",\"label\":{\"key\":\"employeeOperations.portfolio.action.reactivate\"},\"icon\":\"person_add\",\"color\":\"primary\",\"action\":\"reactivate\",\"tooltip\":{\"key\":\"employeeOperations.portfolio.action.reactivate.tooltip\"},\"visibleWhen\":{\"==\":[{\"var\":\"ativo\"},false]}}]}},\"appearance\":{\"density\":\"compact\",\"stickyHeader\":true,\"stripedRows\":false,\"hoverHighlight\":true,\"responsive\":{\"breakpoints\":{\"mobile\":640},\"mobile\":{\"horizontalScroll\":false,\"cardMode\":true,\"priorityColumns\":[\"nomeCompleto\",\"ativo\",\"cargoNome\"]}}},\"export\":{\"enabled\":true,\"formats\":[\"csv\",\"excel\"],\"general\":{\"includeHeaders\":true,\"respectFilters\":true,\"applyFormatting\":true,\"defaultFileName\":\"carteira-funcionarios\",\"includeColumns\":\"visible\",\"scope\":\"currentPage\",\"maxRows\":500},\"excel\":{\"sheetName\":\"Funcionários\",\"autoFitColumns\":true,\"freezeHeaders\":true}}},\"defaults\":{\"openMode\":\"drawer\"},\"actions\":[{\"action\":\"create\",\"openMode\":\"drawer\"},{\"action\":\"view\",\"openMode\":\"drawer\"},{\"action\":\"edit\",\"openMode\":\"drawer\"}]}},\"outputs\":{\"rowClick\":\"emit\",\"rowAction\":\"emit\",\"selectionChange\":\"emit\",\"afterSave\":\"emit\",\"afterDelete\":\"emit\"}}]}}",
4049
4056
  "sourcePointer": "examples/ai-recipes/praxis-dynamic-page.employee-operations-casework.json",
4050
- "contentHash": "9cdcb385ff9e2758e5f3ea792c2c2f69f36e597626d434665f3f83e5aa413ce1",
4057
+ "contentHash": "83df8a6267ce143c0c824e854feeee948b7d1aac1f5ce59579b9d392b7ee302b",
4051
4058
  "sourceKind": "component_definition",
4052
4059
  "sourceId": "praxis-dynamic-page",
4053
4060
  "corpusVersion": "1.0.0"