@praxisui/core 8.0.0-beta.2 → 8.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,6 +14,33 @@
14
14
  - Keep icon, config and dynamic widget infrastructure aligned in the host app
15
15
  - Avoid duplicating low-level primitives across multiple business libraries
16
16
 
17
+ ## Governed Semantic Decisions
18
+
19
+ `DomainKnowledgeService` is the shared client for the governed Domain Knowledge
20
+ change-set lifecycle exposed by `praxis-config-starter` at
21
+ `/api/praxis/config/domain-knowledge/change-sets`. It intentionally models the
22
+ separate platform boundaries for `create`, `validate`, governed status
23
+ transition and `apply`, so consuming UIs can continue an AI-authored semantic
24
+ decision without treating the frontend as the primary source of business rules.
25
+
26
+ Use it when a cockpit or runtime needs to propose safe evidence, review a
27
+ change-set projection, approve/reject the proposal, apply an approved change set
28
+ or read back safe summaries. Runtime surfaces must continue to treat the
29
+ resulting materializations as derived projections of the canonical semantic
30
+ decision.
31
+
32
+ ## Form Layout Contract
33
+
34
+ `FormColumn.items` and the exported `FormLayoutItem` contract define the
35
+ canonical ordered content of a form column. Items with `kind: 'field'` reference
36
+ `fieldMetadata[].name`; items with `kind: 'richContent'` host visual content and
37
+ do not participate in `fieldMetadata`, `formData`, or submit payloads.
38
+
39
+ `FormColumn.fields` is still accepted as migration input and as a derived
40
+ projection of `kind: 'field'` items. New authors and tools should use `items[]`
41
+ as the canonical source and the helpers exported from
42
+ `form-layout-items.model`.
43
+
17
44
  ## 🌟 Visão Geral
18
45
 
19
46
  A biblioteca `@praxisui/core` é o núcleo do Praxis UI Workspace, fornecendo interfaces robustas, serviços base e utilitários essenciais para todas as outras bibliotecas do ecossistema. Com a arquitetura unificada, oferece uma experiência de desenvolvimento consistente e type-safe.
@@ -120,6 +147,42 @@ export class GridDemoComponent {
120
147
 
121
148
  Observação: os IDs de widgets usados na página devem estar registrados via `ComponentMetadataRegistry` para que o carregador dinâmico resolva os componentes.
122
149
 
150
+ #### Composition links e nested component ports
151
+
152
+ O wiring persistido de páginas dinâmicas deve usar `page.composition.links`.
153
+ `page.connections` é formato legado/residual e não deve ser usado para novas
154
+ páginas ou exemplos.
155
+
156
+ Para conectar componentes internos de containers como `praxis-tabs` e
157
+ `praxis-expansion`, use endpoints `component-port` com `ref.nestedPath`:
158
+
159
+ ```json
160
+ {
161
+ "kind": "component-port",
162
+ "ref": {
163
+ "widget": "tabs-widget",
164
+ "nestedPath": [
165
+ { "kind": "tab", "id": "analytics", "index": 0 },
166
+ { "kind": "widget", "key": "sales-chart", "componentType": "praxis-chart" }
167
+ ],
168
+ "port": "pointClick",
169
+ "direction": "output",
170
+ "componentType": "praxis-chart"
171
+ }
172
+ }
173
+ ```
174
+
175
+ Regras de plataforma:
176
+
177
+ - `ref.widget` é sempre o owner top-level presente em `page.widgets`;
178
+ - `nestedPath` é relativo ao owner e deve terminar com segmento
179
+ `kind: "widget"` contendo `key` estável;
180
+ - `ref.port` representa a porta real do componente filho;
181
+ - `widgetEvent` em containers compostos é bridge avançada/legado, não caminho
182
+ principal de authoring;
183
+ - `bindingPath` e dot-path profundo não são endereço canônico para nested
184
+ component ports.
185
+
123
186
  ### Component config editors
124
187
 
125
188
  `ComponentDocMeta.configEditor` é a superfície pública canônica para um
@@ -179,6 +242,28 @@ state, because the fill body intentionally hides overflow.
179
242
  [`public-api.ts`](https://github.com/codexrodrigues/praxis/blob/main/frontend-libs/praxis-ui-workspace/projects/praxis-core/src/public-api.ts)
180
243
  para a lista consolidada de serviços, tokens, modelos e utilitários disponíveis para importação.
181
244
 
245
+ ### Collection Export
246
+
247
+ `PraxisCollectionExportService` é o contrato canônico para exportação de coleções usado por Table, List e próximos componentes de dados.
248
+
249
+ - sem provider registrado, CSV/JSON local usa `loadedItems` e aplica escape de fórmulas para planilhas;
250
+ - com `providePraxisHttpCollectionExportProvider()`, o host registra o provider HTTP oficial;
251
+ - o provider HTTP envia `POST /{resourcePath}/export` usando `API_URL`;
252
+ - escopos remotos `filtered` e `all` omitem `loadedItems` por padrão e delegam query/sort/paginação/seleção ao backend;
253
+ - a resposta pode ser um arquivo binário com `content-disposition` ou um `PraxisCollectionExportResult` JSON;
254
+ - resultados JSON suportam `status: 'completed' | 'deferred'`, `downloadUrl`, `jobId`, `warnings` e `metadata`;
255
+ - resultados `completed` sem `content` nem `downloadUrl` são tratados como erro de contrato pelo runtime.
256
+
257
+ ```ts
258
+ import { providePraxisHttpCollectionExportProvider } from '@praxisui/core';
259
+
260
+ export const appConfig = {
261
+ providers: [
262
+ providePraxisHttpCollectionExportProvider(),
263
+ ],
264
+ };
265
+ ```
266
+
182
267
  ## 📄 Documentacao Tecnica da Lib
183
268
 
184
269
  - `projects/praxis-core/docs/connection-editor.md` (historico legado; fora do fluxo ativo)
@@ -208,6 +293,62 @@ Regra de leitura:
208
293
  - se o problema for URL, submit, fetch ou schema, pense primeiro em `resourcePath`
209
294
  - se o problema for discovery semantico, contexto de surface/action ou identidade estavel, pense primeiro em `resourceKey`
210
295
 
296
+ ## `x-ui.optionSource` e Entity Lookup
297
+
298
+ `@praxisui/core` preserva `x-ui.optionSource` como contrato canônico de opções remotas e lookups de entidade publicados por `/schemas/filtered`.
299
+
300
+ Os tipos públicos exportados para esse contrato ficam em `option-source.model`:
301
+
302
+ - `OptionSourceMetadata`
303
+ - `LookupFilteringMetadata`
304
+ - `LookupFilterDefinitionMetadata`
305
+ - `LookupSortOptionMetadata`
306
+ - `LookupFilterRequest`
307
+ - `OptionSourceFilterRequest`
308
+ - `LookupSelectionPolicyMetadata`
309
+ - `LookupCapabilitiesMetadata`
310
+ - `LookupDetailMetadata`
311
+ - `LookupCreateMetadata`
312
+ - `LookupDialogMetadata`
313
+ - `LookupResultColumnMetadata`
314
+ - `EntityLookupDisplayMetadata`
315
+ - `EntityLookupCollectionMetadata`
316
+ - `EntityLookupPayloadMode`
317
+ - `EntityLookupResult`
318
+ - `EntityRef`
319
+
320
+ Para `RESOURCE_ENTITY`, o `SchemaNormalizerService` mantém a semântica enriquecida usada pelos consumidores:
321
+
322
+ - identidade: `entityKey`, `valuePropertyPath`, `labelPropertyPath`, `codePropertyPath`
323
+ - exibição: `descriptionPropertyPaths`, `statusPropertyPath`, `disabledReasonPropertyPath`
324
+ - busca e cascata: `searchPropertyPaths`, `dependsOn`, `dependencyFilterMap`
325
+ - filtro rico: `filtering.availableFilters`, `defaultFilters`, `sortOptions`, `defaultSort`, `quickFilterFields`, `searchPlaceholder`
326
+ - seleção: `selectionPolicy.allowedStatuses`, `blockedStatuses`, `allowRetainInvalidExistingValue`
327
+ - operação: `capabilities.byIds`, `navigateToDetail`, `create`, `auditSnapshot`
328
+ - navegação: `detail.hrefTemplate`, `routeTemplate`, `openDetailMode`
329
+
330
+ O helper `serializeOptionSourceFilterRequest(...)` monta o envelope canônico de
331
+ Cut B para `POST /option-sources/{sourceKey}/options/filter`, preservando um
332
+ único shape para:
333
+
334
+ - `filter`: filtro legado do recurso hospedeiro
335
+ - `filters`: filtros estruturados do lookup
336
+ - `search`: quick search
337
+ - `sort`: chave metadata-driven de ordenação
338
+ - `includeIds`: reidratação e retenção fora da página atual
339
+
340
+ Para Cut C, o core também publica helpers canônicos para cardinalidade e
341
+ payload de coleção:
342
+
343
+ - `resolveEntityLookupPayloadMode(...)`
344
+ - `isEntityLookupPayloadModeCompatible(...)`
345
+ - `serializeEntityLookupValueForPayload(...)`
346
+
347
+ Assim, `id`, `entityRef`, `ids` e `entityRefs` continuam sob a mesma semântica
348
+ compartilhada entre runtime, submit de formulário e integrações futuras.
349
+
350
+ O mapper de `FieldDefinition` para `FieldMetadata` deriva apenas a ponte runtime necessária (`dependencyFields` e `dependencyFilterMap`) a partir de `optionSource.dependsOn`. Ele não inventa política de reset, reload ou persistência; essas decisões continuam explícitas no metadata do campo.
351
+
211
352
  ## `x-ui.analytics` no runtime
212
353
 
213
354
  O `@praxisui/core` trata `x-ui.analytics` como a projeção semantica analitica canonica vinda do backend.
@@ -274,7 +415,7 @@ definition: {
274
415
  ```ts
275
416
  shell: {
276
417
  actions: [
277
- { id: 'back', icon: 'arrow_back', command: 'global:navigation.back' }
418
+ { id: 'back', icon: 'arrow_back', globalAction: { actionId: 'navigation.back' } }
278
419
  ]
279
420
  }
280
421
  ```
@@ -291,6 +432,7 @@ shell: {
291
432
  - `trackEvent` → `{ eventName, payload }`
292
433
  - `log` → `{ level, message, payload }`
293
434
  - `api.get` / `api.post` / `api.patch` → `{ url, params|body }`
435
+ - `navigation.openRoute` → `{ path, query?, fragment?, replaceUrl?, state? }`
294
436
  - `route.register` → `{ path, componentId|loadChildren, data?, resolve?, guards?, canMatch?, canActivateChild?, replace?, position? }`
295
437
 
296
438
  ### 5) Rotas dinâmicas (route.register)
@@ -1014,6 +1156,9 @@ export interface TableAppearanceConfig;
1014
1156
  export interface ToolbarConfig;
1015
1157
  export interface TableActionsConfig;
1016
1158
  export interface ExportConfig;
1159
+ export interface PraxisCollectionExportRequest;
1160
+ export interface PraxisCollectionExportProvider;
1161
+ export interface PraxisCollectionSelectionState;
1017
1162
  export interface MessagesConfig;
1018
1163
  export interface LocalizationConfig;
1019
1164
  export interface PerformanceConfig;
@@ -1021,6 +1166,8 @@ export interface AccessibilityConfig;
1021
1166
 
1022
1167
  // Serviços
1023
1168
  export class TableConfigService;
1169
+ export class PraxisCollectionExportService;
1170
+ export class PraxisHttpCollectionExportProvider;
1024
1171
 
1025
1172
  // Helper Functions
1026
1173
  export function createDefaultTableConfig(): TableConfig;
@@ -1029,10 +1176,13 @@ export function isTableConfigV2(config: any): config is TableConfig;
1029
1176
  export function cloneTableConfig(config: TableConfig): TableConfig;
1030
1177
  export function mergeTableConfigs(base: TableConfig, override: Partial<TableConfig>): TableConfig;
1031
1178
  export function getEssentialConfig(config: TableConfig): Partial<TableConfig>;
1179
+ export function providePraxisHttpCollectionExportProvider();
1032
1180
 
1033
1181
  // Type Aliases
1034
1182
  export type TableConfig = TableConfigV2;
1035
1183
  export type TableConfigModern = TableConfigV2;
1184
+ export type PraxisExportFormat;
1185
+ export type PraxisExportScope;
1036
1186
 
1037
1187
  // Legacy (Deprecated)
1038
1188
  export type LegacyTableConfig = TableConfig;