@praxisui/core 9.0.0-beta.1 → 9.0.0-beta.2
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 +104 -1229
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,1323 +1,198 @@
|
|
|
1
1
|
# @praxisui/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Shared contracts, tokens, services, metadata models, widget runtime primitives, and utilities used by the public `@praxisui/*` Angular packages.
|
|
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
|
-
|
|
8
|
-
- Quickstart reference app: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
9
|
-
- Recommended for: hosts that need the shared contracts, tokens, icons and base services used across `@praxisui/*`
|
|
7
|
+
## Official Links
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- Documentation: https://praxisui.dev/docs/components
|
|
10
|
+
- Live demo: https://praxis-ui-4e602.web.app
|
|
11
|
+
- Quickstart app: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
12
|
+
- API quickstart: https://github.com/codexrodrigues/praxis-api-quickstart-public
|
|
13
|
+
- Source: https://github.com/codexrodrigues/praxis-ui-angular/tree/main/projects/praxis-core
|
|
14
|
+
- Issues: https://github.com/codexrodrigues/praxis-ui-angular/issues
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
- Keep icon, config and dynamic widget infrastructure aligned in the host app
|
|
15
|
-
- Avoid duplicating low-level primitives across multiple business libraries
|
|
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
|
-
## Runtime Component Observations
|
|
33
|
-
|
|
34
|
-
`PraxisRuntimeComponentObservationEnvelope` is the shared contract for active
|
|
35
|
-
runtime component observations. It lets hosts and component libraries publish a
|
|
36
|
-
small, serializable and redacted snapshot of the active instance, such as
|
|
37
|
-
identity, lifecycle, canonical refs, digests and affordance refs.
|
|
38
|
-
|
|
39
|
-
The envelope is intentionally not a capability source of truth. It must be
|
|
40
|
-
treated as an untrusted runtime observation that backend authoring services
|
|
41
|
-
reconcile against governed manifests, schemas, resource capabilities, actions,
|
|
42
|
-
surfaces and tenant/environment policy before any answer, preview or
|
|
43
|
-
materialization can use it.
|
|
44
|
-
|
|
45
|
-
Use `PraxisRuntimeComponentObservationRegistryService` or
|
|
46
|
-
`registerPraxisRuntimeComponentObservation` to register providers with Angular
|
|
47
|
-
lifecycle cleanup. Providers should produce snapshots lazily and must not expose
|
|
48
|
-
raw rows, full form values, secrets or complete schemas.
|
|
49
|
-
|
|
50
|
-
`praxis-dynamic-page` registers a runtime observation for the active page
|
|
51
|
-
composition. The page observation publishes page identity, active widget keys,
|
|
52
|
-
the selected widget when it still belongs to the rendered composition,
|
|
53
|
-
composition link refs and declared related surface refs. Related surface refs
|
|
54
|
-
include `runtimeSurfaceInstanceRef` when the page can derive a canonical runtime
|
|
55
|
-
surface identity from widget, component, surface and resource refs, so backend
|
|
56
|
-
grounding can disambiguate multiple widgets backed by the same resource path. It
|
|
57
|
-
does not publish widget input values, state values, raw events, rendered DOM or
|
|
58
|
-
intent decisions.
|
|
59
|
-
|
|
60
|
-
## Form Layout Contract
|
|
61
|
-
|
|
62
|
-
`FormColumn.items` and the exported `FormLayoutItem` contract define the
|
|
63
|
-
canonical ordered content of a form column. Items with `kind: 'field'` reference
|
|
64
|
-
`fieldMetadata[].name`; items with `kind: 'richContent'` host visual content and
|
|
65
|
-
do not participate in `fieldMetadata`, `formData`, or submit payloads.
|
|
66
|
-
|
|
67
|
-
`FormColumn.fields` is still accepted as migration input and as a derived
|
|
68
|
-
projection of `kind: 'field'` items. New authors and tools should use `items[]`
|
|
69
|
-
as the canonical source and the helpers exported from
|
|
70
|
-
`form-layout-items.model`.
|
|
71
|
-
|
|
72
|
-
## 🌟 Visão Geral
|
|
73
|
-
|
|
74
|
-
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.
|
|
75
|
-
|
|
76
|
-
### Concept Usage
|
|
77
|
-
|
|
78
|
-
- [Dynamic Component Rendering](https://github.com/codexrodrigues/praxis/blob/main/docs/concepts/dynamic-component-rendering.md)
|
|
79
|
-
- [Headless UI & Design Systems](https://github.com/codexrodrigues/praxis/blob/main/docs/concepts/headless-ui-and-design-systems.md)
|
|
80
|
-
- [Configuration‑driven development](https://github.com/codexrodrigues/praxis/blob/main/docs/concepts/configuration-driven-development.md)
|
|
81
|
-
- [Declarative UI](https://github.com/codexrodrigues/praxis/blob/main/docs/concepts/declarative-ui.md)
|
|
82
|
-
|
|
83
|
-
## ✨ Características Principais
|
|
84
|
-
|
|
85
|
-
### 🏗️ Arquitetura Unificada
|
|
86
|
-
|
|
87
|
-
- **TableConfig único**: Interface consolidada eliminando dualidade V1/V2
|
|
88
|
-
- **Type Safety**: Tipagem forte e consistente
|
|
89
|
-
- **Modular**: Interfaces bem definidas e organizadas
|
|
90
|
-
- **Extensível**: Arquitetura preparada para crescimento
|
|
91
|
-
|
|
92
|
-
### 🔧 Funcionalidades Core
|
|
93
|
-
|
|
94
|
-
- **Interfaces de Configuração**: Modelos robustos para tabelas e componentes
|
|
95
|
-
- **Serviços Base**: TableConfigService e utilitários essenciais
|
|
96
|
-
- **Type Guards**: Validação em runtime
|
|
97
|
-
- **Helper Functions**: Utilitários para manipulação de configurações
|
|
98
|
-
|
|
99
|
-
## 🚀 Instalação
|
|
16
|
+
## Install
|
|
100
17
|
|
|
101
18
|
```bash
|
|
102
|
-
npm
|
|
19
|
+
npm i @praxisui/core@latest
|
|
103
20
|
```
|
|
104
21
|
|
|
105
|
-
|
|
106
|
-
- Quickstart: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
107
|
-
|
|
108
|
-
### Peer dependencies (Angular v20)
|
|
109
|
-
|
|
110
|
-
- `@angular/core` `^20.0.0`
|
|
111
|
-
- `@angular/common` `^20.0.0`
|
|
112
|
-
|
|
113
|
-
## ⚡ Quick Start
|
|
22
|
+
Peer dependencies:
|
|
114
23
|
|
|
115
|
-
|
|
24
|
+
- `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/material`, `@angular/platform-browser`, `@angular/router` `^21.0.0`
|
|
25
|
+
- `rxjs` `~7.8.0`
|
|
116
26
|
|
|
117
|
-
|
|
27
|
+
## Theme And Icons
|
|
118
28
|
|
|
119
|
-
|
|
29
|
+
Import the theme bridge after Angular Material and CDK overlay styles.
|
|
120
30
|
|
|
121
31
|
```scss
|
|
122
32
|
@import "@angular/cdk/overlay-prebuilt.css";
|
|
123
33
|
@import "@praxisui/core/theme-bridge.css";
|
|
124
34
|
```
|
|
125
35
|
|
|
36
|
+
Use `PraxisIconDirective` to normalize Material Icons and Material Symbols names.
|
|
37
|
+
|
|
126
38
|
```ts
|
|
127
39
|
import { Component } from '@angular/core';
|
|
128
40
|
import { MatIconModule } from '@angular/material/icon';
|
|
129
41
|
import { PraxisIconDirective } from '@praxisui/core';
|
|
130
42
|
|
|
131
43
|
@Component({
|
|
132
|
-
selector: 'app-icons-demo',
|
|
133
44
|
standalone: true,
|
|
45
|
+
selector: 'app-icons',
|
|
134
46
|
imports: [MatIconModule, PraxisIconDirective],
|
|
135
47
|
template: `
|
|
136
|
-
<!-- Material Icons (ligatures) -->
|
|
137
48
|
<mat-icon [praxisIcon]="'mi:pending'"></mat-icon>
|
|
138
|
-
<!-- Material Symbols Outlined -->
|
|
139
49
|
<mat-icon [praxisIcon]="'mso:right_click'"></mat-icon>
|
|
140
50
|
`,
|
|
141
51
|
})
|
|
142
|
-
export class
|
|
52
|
+
export class IconsComponent {}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Hosts should load the icon fonts they use. Without the classic Material Icons font, ligature names such as `clear` can render as visible text.
|
|
56
|
+
|
|
57
|
+
## Component Metadata
|
|
58
|
+
|
|
59
|
+
`ComponentMetadataRegistry` is the shared registry used by builders and runtime loaders to resolve component metadata.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { ComponentDocMeta, ComponentMetadataRegistry } from '@praxisui/core';
|
|
63
|
+
|
|
64
|
+
const metadata: ComponentDocMeta = {
|
|
65
|
+
id: 'app-widget',
|
|
66
|
+
selector: 'app-widget',
|
|
67
|
+
component: AppWidgetComponent,
|
|
68
|
+
friendlyName: 'App widget',
|
|
69
|
+
description: 'Host-owned widget.',
|
|
70
|
+
icon: 'widgets',
|
|
71
|
+
lib: 'app-host',
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
registry.register(metadata);
|
|
143
75
|
```
|
|
144
76
|
|
|
145
|
-
|
|
77
|
+
Component-owned config editors and AI authoring manifests are declared on `ComponentDocMeta`. Hosts should discover and delegate through metadata instead of duplicating component-specific editors or operation manifests.
|
|
78
|
+
|
|
79
|
+
## Dynamic Page Runtime
|
|
80
|
+
|
|
81
|
+
`DynamicWidgetPageComponent` renders `WidgetPageDefinition` documents.
|
|
146
82
|
|
|
147
83
|
```ts
|
|
148
84
|
import { Component } from '@angular/core';
|
|
149
85
|
import { DynamicWidgetPageComponent, WidgetPageDefinition } from '@praxisui/core';
|
|
150
86
|
|
|
151
87
|
@Component({
|
|
152
|
-
selector: 'app-grid-demo',
|
|
153
88
|
standalone: true,
|
|
89
|
+
selector: 'app-page',
|
|
154
90
|
imports: [DynamicWidgetPageComponent],
|
|
155
|
-
template:
|
|
156
|
-
<praxis-dynamic-page [page]="page"></praxis-dynamic-page>
|
|
157
|
-
`,
|
|
91
|
+
template: `<praxis-dynamic-page [page]="page"></praxis-dynamic-page>`,
|
|
158
92
|
})
|
|
159
|
-
export class
|
|
93
|
+
export class PageComponent {
|
|
160
94
|
page: WidgetPageDefinition = {
|
|
161
95
|
widgets: [
|
|
162
96
|
{
|
|
163
|
-
key: '
|
|
97
|
+
key: 'summary',
|
|
164
98
|
definition: {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
inputs: { title: 'Hello' },
|
|
168
|
-
outputs: { loaded: 'emit' },
|
|
99
|
+
id: 'app-widget',
|
|
100
|
+
inputs: { title: 'Summary' },
|
|
169
101
|
},
|
|
170
102
|
},
|
|
171
103
|
],
|
|
104
|
+
composition: { links: [] },
|
|
172
105
|
};
|
|
173
106
|
}
|
|
174
107
|
```
|
|
175
108
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
#### Composition links e nested component ports
|
|
179
|
-
|
|
180
|
-
O wiring persistido de páginas dinâmicas deve usar `page.composition.links`.
|
|
181
|
-
`page.connections` é formato legado/residual e não deve ser usado para novas
|
|
182
|
-
páginas ou exemplos.
|
|
183
|
-
|
|
184
|
-
Para conectar componentes internos de containers como `praxis-tabs` e
|
|
185
|
-
`praxis-expansion`, use endpoints `component-port` com `ref.nestedPath`:
|
|
186
|
-
|
|
187
|
-
```json
|
|
188
|
-
{
|
|
189
|
-
"kind": "component-port",
|
|
190
|
-
"ref": {
|
|
191
|
-
"widget": "tabs-widget",
|
|
192
|
-
"nestedPath": [
|
|
193
|
-
{ "kind": "tab", "id": "analytics", "index": 0 },
|
|
194
|
-
{ "kind": "widget", "key": "sales-chart", "componentType": "praxis-chart" }
|
|
195
|
-
],
|
|
196
|
-
"port": "pointClick",
|
|
197
|
-
"direction": "output",
|
|
198
|
-
"componentType": "praxis-chart"
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Regras de plataforma:
|
|
204
|
-
|
|
205
|
-
- `ref.widget` é sempre o owner top-level presente em `page.widgets`;
|
|
206
|
-
- `nestedPath` é relativo ao owner e deve terminar com segmento
|
|
207
|
-
`kind: "widget"` contendo `key` estável;
|
|
208
|
-
- `ref.port` representa a porta real do componente filho;
|
|
209
|
-
- `widgetEvent` em containers compostos é bridge avançada/legado, não caminho
|
|
210
|
-
principal de authoring;
|
|
211
|
-
- `bindingPath` e dot-path profundo não são endereço canônico para nested
|
|
212
|
-
component ports.
|
|
213
|
-
|
|
214
|
-
### Component config editors
|
|
215
|
-
|
|
216
|
-
`ComponentDocMeta.configEditor` é a superfície pública canônica para um
|
|
217
|
-
componente declarar como seus `definition.inputs` devem ser editados em hosts
|
|
218
|
-
visuais como `praxis-dynamic-page` e `@praxisui/page-builder`.
|
|
219
|
-
|
|
220
|
-
O editor pertence à lib dona da semântica do componente, não ao host. O host
|
|
221
|
-
deve apenas descobrir `configEditor` via `ComponentMetadataRegistry`, abrir o
|
|
222
|
-
componente no `SETTINGS_PANEL_BRIDGE` e aplicar/salvar o payload retornado.
|
|
223
|
-
|
|
224
|
-
Contrato esperado:
|
|
225
|
-
|
|
226
|
-
```ts
|
|
227
|
-
registry.register({
|
|
228
|
-
id: 'praxis-rich-content',
|
|
229
|
-
selector: 'praxis-rich-content',
|
|
230
|
-
component: PraxisRichContent,
|
|
231
|
-
friendlyName: 'Praxis Rich Content',
|
|
232
|
-
configEditor: {
|
|
233
|
-
component: PraxisRichContentConfigEditor,
|
|
234
|
-
title: 'Configurar rich content',
|
|
235
|
-
},
|
|
236
|
-
});
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
Payload recomendado para editores de inputs de widget:
|
|
240
|
-
|
|
241
|
-
```ts
|
|
242
|
-
{
|
|
243
|
-
inputs: {
|
|
244
|
-
// mesmo shape consumido por WidgetDefinition.definition.inputs
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
Regra de plataforma: não crie editor local no host para uma semântica que já
|
|
250
|
-
tem dono canônico. Corrija ou publique o `configEditor` no metadata da lib dona
|
|
251
|
-
do componente.
|
|
252
|
-
|
|
253
|
-
### Component AI authoring manifests
|
|
254
|
-
|
|
255
|
-
`ComponentDocMeta.authoringManifestRef` é a superfície pública canônica para um
|
|
256
|
-
componente declarar que possui manifesto executável de authoring por IA. O
|
|
257
|
-
manifesto continua pertencendo à lib dona do componente; hosts e page builders
|
|
258
|
-
devem usar esse campo para discovery, delegação e readiness, não para redefinir
|
|
259
|
-
operações internas localmente.
|
|
260
|
-
|
|
261
|
-
Contrato esperado:
|
|
262
|
-
|
|
263
|
-
```ts
|
|
264
|
-
registry.register({
|
|
265
|
-
id: 'praxis-table',
|
|
266
|
-
selector: 'praxis-table',
|
|
267
|
-
component: PraxisTable,
|
|
268
|
-
friendlyName: 'Praxis Table',
|
|
269
|
-
authoringManifestRef: {
|
|
270
|
-
componentId: 'praxis-table',
|
|
271
|
-
source: 'PRAXIS_TABLE_AUTHORING_MANIFEST',
|
|
272
|
-
},
|
|
273
|
-
});
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### Widget Shell body layout
|
|
277
|
-
|
|
278
|
-
`WidgetShellConfig.bodyLayout` declares how projected widget content should use
|
|
279
|
-
the shell body:
|
|
280
|
-
|
|
281
|
-
- `content`: default natural document flow for tables, lists, forms and mixed content.
|
|
282
|
-
- `fill`: makes the shell body a flex container whose direct child fills the usable body; use it for resizable charts, maps and canvases that own their viewport.
|
|
283
|
-
- `scroll`: makes the shell body a flex container with body scrolling for content that may exceed the widget height.
|
|
284
|
-
|
|
285
|
-
For corporate dashboards, pair chart contracts that use
|
|
286
|
-
`sizing.mode = "fill-container"` with `bodyLayout: "fill"`. Avoid using `fill`
|
|
287
|
-
for long textual content unless the widget supplies its own compact or empty
|
|
288
|
-
state, because the fill body intentionally hides overflow.
|
|
289
|
-
|
|
290
|
-
## 📚 API Surface
|
|
291
|
-
|
|
292
|
-
- Exports públicos: consulte o arquivo
|
|
293
|
-
[`public-api.ts`](https://github.com/codexrodrigues/praxis/blob/main/frontend-libs/praxis-ui-workspace/projects/praxis-core/src/public-api.ts)
|
|
294
|
-
para a lista consolidada de serviços, tokens, modelos e utilitários disponíveis para importação.
|
|
295
|
-
|
|
296
|
-
### Collection Export
|
|
297
|
-
|
|
298
|
-
`PraxisCollectionExportService` é o contrato canônico para exportação de coleções usado por Table, List e próximos componentes de dados.
|
|
299
|
-
|
|
300
|
-
- sem provider registrado, CSV/JSON local usa `loadedItems` e aplica escape de fórmulas para planilhas;
|
|
301
|
-
- com `providePraxisHttpCollectionExportProvider()`, o host registra o provider HTTP oficial;
|
|
302
|
-
- o provider HTTP envia `POST /{resourcePath}/export` usando `API_URL`;
|
|
303
|
-
- escopos remotos `filtered` e `all` omitem `loadedItems` por padrão e delegam query/sort/paginação/seleção ao backend;
|
|
304
|
-
- a resposta pode ser um arquivo binário com `content-disposition` ou um `PraxisCollectionExportResult` JSON;
|
|
305
|
-
- resultados JSON suportam `status: 'completed' | 'deferred'`, `downloadUrl`, `jobId`, `warnings` e `metadata`;
|
|
306
|
-
- resultados `completed` sem `content` nem `downloadUrl` são tratados como erro de contrato pelo runtime.
|
|
307
|
-
|
|
308
|
-
```ts
|
|
309
|
-
import { providePraxisHttpCollectionExportProvider } from '@praxisui/core';
|
|
310
|
-
|
|
311
|
-
export const appConfig = {
|
|
312
|
-
providers: [
|
|
313
|
-
providePraxisHttpCollectionExportProvider(),
|
|
314
|
-
],
|
|
315
|
-
};
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
## 📄 Documentacao Tecnica da Lib
|
|
319
|
-
|
|
320
|
-
- `projects/praxis-core/docs/connection-editor.md` (historico legado; fora do fluxo ativo)
|
|
321
|
-
- `projects/praxis-core/docs/schema-flow.md`
|
|
322
|
-
- `projects/praxis-core/docs/rfc-json-logic-semantics.md`
|
|
323
|
-
|
|
324
|
-
## ⚙️ Global Config (bootstrap)
|
|
325
|
-
|
|
326
|
-
- Use `provideGlobalConfigTenant(...)` para definir o tenant e bloquear o bootstrap até a config remota ser carregada.
|
|
327
|
-
- Se não houver tenant, use `provideGlobalConfigReady()` para apenas aguardar o carregamento remoto.
|
|
328
|
-
|
|
329
|
-
## `resourcePath` vs `resourceKey`
|
|
330
|
-
|
|
331
|
-
No runtime Angular, os dois valores coexistem, mas cumprem papeis diferentes:
|
|
332
|
-
|
|
333
|
-
- `resourcePath` e o endereco operacional usado para CRUD, fetch de schema e submit
|
|
334
|
-
- `resourceKey` e a identidade semantica estavel recebida dos catalogos de discovery do backend
|
|
335
|
-
|
|
336
|
-
Na pratica:
|
|
337
|
-
|
|
338
|
-
- o backend publica links como `/schemas/surfaces?resource={resourceKey}` e `/schemas/actions?resource={resourceKey}`
|
|
339
|
-
- o `ResourceDiscoveryService` segue esses links HATEOAS e recebe `resourceKey` de volta nos payloads de surfaces, actions e capabilities
|
|
340
|
-
- os adapters de abertura preservam `resourceKey` no `context.resource` e o usam para gerar ids estaveis de runtime
|
|
341
|
-
|
|
342
|
-
Regra de leitura:
|
|
343
|
-
|
|
344
|
-
- se o problema for URL, submit, fetch ou schema, pense primeiro em `resourcePath`
|
|
345
|
-
- se o problema for discovery semantico, contexto de surface/action ou identidade estavel, pense primeiro em `resourceKey`
|
|
346
|
-
|
|
347
|
-
## `x-ui.optionSource` e Entity Lookup
|
|
348
|
-
|
|
349
|
-
`@praxisui/core` preserva `x-ui.optionSource` como contrato canônico de opções remotas e lookups de entidade publicados por `/schemas/filtered`.
|
|
109
|
+
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`.
|
|
350
110
|
|
|
351
|
-
|
|
111
|
+
## Resource Discovery
|
|
352
112
|
|
|
353
|
-
|
|
354
|
-
- `LookupFilteringMetadata`
|
|
355
|
-
- `LookupFilterDefinitionMetadata`
|
|
356
|
-
- `LookupSortOptionMetadata`
|
|
357
|
-
- `LookupFilterRequest`
|
|
358
|
-
- `OptionSourceFilterRequest`
|
|
359
|
-
- `LookupSelectionPolicyMetadata`
|
|
360
|
-
- `LookupCapabilitiesMetadata`
|
|
361
|
-
- `LookupDetailMetadata`
|
|
362
|
-
- `LookupCreateMetadata`
|
|
363
|
-
- `LookupDialogMetadata`
|
|
364
|
-
- `LookupResultColumnMetadata`
|
|
365
|
-
- `EntityLookupDisplayMetadata`
|
|
366
|
-
- `EntityLookupCollectionMetadata`
|
|
367
|
-
- `EntityLookupPayloadMode`
|
|
368
|
-
- `EntityLookupResult`
|
|
369
|
-
- `EntityRef`
|
|
113
|
+
`resourcePath` and `resourceKey` serve different purposes:
|
|
370
114
|
|
|
371
|
-
|
|
115
|
+
- `resourcePath`: operational URL/path for CRUD, fetch, schema, read, submit, and filter flows
|
|
116
|
+
- `resourceKey`: stable semantic identity from backend discovery catalogs, surfaces, actions, and capabilities
|
|
372
117
|
|
|
373
|
-
|
|
374
|
-
- exibição: `descriptionPropertyPaths`, `statusPropertyPath`, `disabledReasonPropertyPath`
|
|
375
|
-
- busca e cascata: `searchPropertyPaths`, `dependsOn`, `dependencyFilterMap`
|
|
376
|
-
- filtro rico: `filtering.availableFilters`, `defaultFilters`, `sortOptions`, `defaultSort`, `quickFilterFields`, `searchPlaceholder`
|
|
377
|
-
- seleção: `selectionPolicy.allowedStatuses`, `blockedStatuses`, `allowRetainInvalidExistingValue`
|
|
378
|
-
- operação: `capabilities.byIds`, `navigateToDetail`, `create`, `auditSnapshot`
|
|
379
|
-
- detalhe governado: `detail.kind = surface`, `surfaceId`, `presentation`, `preferredWidget`, `mode`
|
|
380
|
-
- UX de referência: `display.preset`, `usage`, `density`, `selectedLayout`, `resultLayout`, `fields`, `secondaryPropertyPaths`, `badgePropertyPaths`
|
|
118
|
+
If the problem is URL or HTTP execution, start with `resourcePath`. If the problem is semantic discovery, surface/action context, or stable runtime identity, start with `resourceKey`.
|
|
381
119
|
|
|
382
|
-
|
|
383
|
-
Presets como `directory`, `reference`, `status`, `hierarchical`, `rich` e
|
|
384
|
-
`compact` permitem que a mesma option-source seja usada em formulário, filtro,
|
|
385
|
-
tabela editável, dashboard ou revisão sem duplicar regras no host. O runtime
|
|
386
|
-
pode aplicar overrides locais quando o contexto exigir, mas a semântica
|
|
387
|
-
preferencial continua no `optionSource`.
|
|
388
|
-
Use `display.fields[]` para publicar subinformações ricas do resultado, como
|
|
389
|
-
`cargo`, `departamento`, `dataAdmissao`, `status` ou métricas. Cada campo carrega
|
|
390
|
-
`propertyPath`, `label`, `icon`, `presentation`, `tone` e `format`; o endpoint de
|
|
391
|
-
option-source pode materializar esses campos em `OptionDTO.extra.richFields[]`
|
|
392
|
-
para que runtimes exibam ícones, chips, badges ou valores formatados sem
|
|
393
|
-
heurística local.
|
|
120
|
+
## Schema And Metadata
|
|
394
121
|
|
|
395
|
-
|
|
396
|
-
Cut B para `POST /option-sources/{sourceKey}/options/filter`, preservando um
|
|
397
|
-
único shape para:
|
|
122
|
+
Core exports schema and metadata infrastructure used by form, table, list, chart, CRUD, and page-builder packages:
|
|
398
123
|
|
|
399
|
-
- `
|
|
400
|
-
- `
|
|
401
|
-
-
|
|
402
|
-
- `
|
|
403
|
-
- `
|
|
124
|
+
- `SchemaMetadataClient`
|
|
125
|
+
- `SchemaNormalizerService`
|
|
126
|
+
- ETag/cache helpers
|
|
127
|
+
- `FieldDefinition` and `FieldMetadata` models
|
|
128
|
+
- `x-ui.optionSource` models and serializers
|
|
129
|
+
- `x-ui.analytics` models and `AnalyticsSchemaContractService`
|
|
130
|
+
- `valuePresentation` models and resolver
|
|
131
|
+
- form layout item models
|
|
132
|
+
- JSON Logic models and runtime service
|
|
404
133
|
|
|
405
|
-
|
|
406
|
-
payload de coleção:
|
|
134
|
+
`valuePresentation` is the shared display contract for scalar read-only values such as currency, number, date, datetime, time, percentage, and boolean.
|
|
407
135
|
|
|
408
|
-
|
|
409
|
-
- `isEntityLookupPayloadModeCompatible(...)`
|
|
410
|
-
- `serializeEntityLookupValueForPayload(...)`
|
|
136
|
+
## Global Actions
|
|
411
137
|
|
|
412
|
-
|
|
413
|
-
compartilhada entre runtime, submit de formulário e integrações futuras.
|
|
414
|
-
|
|
415
|
-
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.
|
|
416
|
-
|
|
417
|
-
## `x-ui.analytics` no runtime
|
|
418
|
-
|
|
419
|
-
O `@praxisui/core` trata `x-ui.analytics` como a projeção semantica analitica canonica vinda do backend.
|
|
420
|
-
|
|
421
|
-
- o backend publica `x-ui.analytics.projections[]` com `intent`, `source`, `bindings`, `defaults` e `preferredFamilies`
|
|
422
|
-
- o `AnalyticsPresentationResolver` escolhe a familia de apresentacao no runtime
|
|
423
|
-
- `praxis-charts` continua sendo apenas um renderer possivel; ele nao vira a semantica-base do contrato
|
|
424
|
-
|
|
425
|
-
Regra atual do resolver:
|
|
426
|
-
|
|
427
|
-
- se houver uma projection com `preferredFamilies` compativel, ela orienta a escolha
|
|
428
|
-
- chart automatico so acontece quando a semantica temporal for inequivoca
|
|
429
|
-
- `analytic-table` nao e a sobra do resolver; ela e uma familia canonica escolhida quando a projection continua valida, mas nao e chart inequivoco
|
|
430
|
-
- nos casos ambiguos, o fallback conservador e `analytic-table`
|
|
431
|
-
- se o host nao expuser `analytic-table` e a semantica continuar ambigua, o resolver falha em vez de forcar `chart`
|
|
432
|
-
- projections `timeseries` devem publicar `defaults.granularity` quando o renderer precisar executar `praxis.stats` sem heuristica local
|
|
433
|
-
|
|
434
|
-
Shape publico da decisao:
|
|
435
|
-
|
|
436
|
-
- `projectionId`: id da projection escolhida
|
|
437
|
-
- `family`: familia resolvida (`chart`, `analytic-table`, `kpi`, `summary-list`)
|
|
438
|
-
- `reason`: motivo explicito da decisao, util para debug e suporte
|
|
439
|
-
|
|
440
|
-
## 🌐 Global Actions (shell + widgets)
|
|
441
|
-
|
|
442
|
-
O core agora suporta **ações globais** executadas por widgets e pelo Widget Shell, permitindo integrar navegação, dialog, toast, analytics, API e rotas dinâmicas de forma padronizada.
|
|
443
|
-
|
|
444
|
-
### 1) Providers (plug-and-play no host)
|
|
138
|
+
Global actions let widgets and shells request host-mediated work such as navigation, dialog, toast, analytics, API calls, or surface opening.
|
|
445
139
|
|
|
446
140
|
```ts
|
|
447
141
|
import {
|
|
448
142
|
providePraxisGlobalActions,
|
|
449
143
|
providePraxisToastGlobalActions,
|
|
450
|
-
providePraxisAnalyticsGlobalActions,
|
|
451
144
|
} from '@praxisui/core';
|
|
452
|
-
import { providePraxisDialogGlobalActions } from '@praxisui/dialog';
|
|
453
|
-
|
|
454
|
-
providers: [
|
|
455
|
-
...providePraxisGlobalActions({ dialog: false, toast: false, analytics: false }),
|
|
456
|
-
providePraxisDialogGlobalActions(),
|
|
457
|
-
providePraxisToastGlobalActions(),
|
|
458
|
-
providePraxisAnalyticsGlobalActions({ prefix: 'app' }),
|
|
459
|
-
]
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
### 2) Mapeando outputs para ações globais
|
|
463
|
-
|
|
464
|
-
`WidgetDefinition.outputs` pode apontar para ações globais:
|
|
465
|
-
|
|
466
|
-
```ts
|
|
467
|
-
definition: {
|
|
468
|
-
id: 'praxis-dynamic-form',
|
|
469
|
-
outputs: {
|
|
470
|
-
formSubmit: {
|
|
471
|
-
type: 'api.post',
|
|
472
|
-
params: { url: '/api/clientes', body: '${payload.formData}' }
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
### 3) Ação global no Widget Shell
|
|
479
|
-
|
|
480
|
-
```ts
|
|
481
|
-
shell: {
|
|
482
|
-
actions: [
|
|
483
|
-
{ id: 'back', icon: 'arrow_back', globalAction: { actionId: 'navigation.back' } }
|
|
484
|
-
]
|
|
485
|
-
}
|
|
486
|
-
```
|
|
487
145
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
- `navigation.back`
|
|
491
|
-
- `navigation.openExternal` → `{ url }`
|
|
492
|
-
- `dialog.alert` → `{ title, message, variant }`
|
|
493
|
-
- `dialog.prompt` → `{ title, message, placeholder, defaultValue }`
|
|
494
|
-
- `dialog.open` → `{ componentId, inputs, size, data }`
|
|
495
|
-
- `toast.success` / `toast.error` → `{ message }`
|
|
496
|
-
- `clipboard.copy` → `{ text }`
|
|
497
|
-
- `trackEvent` → `{ eventName, payload }`
|
|
498
|
-
- `log` → `{ level, message, payload }`
|
|
499
|
-
- `api.get` / `api.post` / `api.patch` → `{ url, params|body }`
|
|
500
|
-
- `navigation.openRoute` → `{ path, query?, fragment?, replaceUrl?, state? }`
|
|
501
|
-
- `route.register` → `{ path, componentId|loadChildren, data?, resolve?, guards?, canMatch?, canActivateChild?, replace?, position? }`
|
|
502
|
-
|
|
503
|
-
### 5) Rotas dinâmicas (route.register)
|
|
504
|
-
|
|
505
|
-
Requer `componentId` **ou** `loadChildren`. Guards são resolvidos pelo host via `GLOBAL_ROUTE_GUARD_RESOLVER`.
|
|
506
|
-
|
|
507
|
-
```ts
|
|
508
|
-
// payload
|
|
509
|
-
{
|
|
510
|
-
path: '/clientes/novo',
|
|
511
|
-
componentId: 'praxis-dynamic-page',
|
|
512
|
-
data: { pageId: 'clientes-novo' },
|
|
513
|
-
guards: ['auth', 'permission:clientes.create'],
|
|
514
|
-
position: 'before-wildcard'
|
|
515
|
-
}
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
As rotas registradas são persistidas em `GlobalConfig.routes.dynamic`. O host deve re‑hidratar isso no bootstrap (ex.: ler `GlobalConfigService` e re‑aplicar com `route.register`).
|
|
519
|
-
|
|
520
|
-
### 7) Output mapeado para ação global x conexões
|
|
521
|
-
|
|
522
|
-
Quando `WidgetDefinition.outputs[output]` aponta para uma ação global (não `'emit'`), o evento **não** é repassado para conexões locais — a ação global tem prioridade.
|
|
523
|
-
|
|
524
|
-
### 6) Estilo de toast
|
|
525
|
-
|
|
526
|
-
O estilo padrão usa as classes `.pdx-toast-success` / `.pdx-toast-error`.
|
|
527
|
-
Inclua estilos equivalentes no app host (ou sobrescreva com `providePraxisToastGlobalActions`).
|
|
528
|
-
|
|
529
|
-
## 🔎 Schema Viewer (para Showcases)
|
|
530
|
-
|
|
531
|
-
Para exibir os metadados e schemas usados por um exemplo (ex.: na aba “Schema” de um showcase), use o componente `SchemaViewerComponent` e (opcionalmente) injete o contexto via `SCHEMA_VIEWER_CONTEXT`.
|
|
532
|
-
|
|
533
|
-
```ts
|
|
534
|
-
import { Component, Provider } from '@angular/core';
|
|
535
|
-
import { PraxisTabs, TabsMetadata } from '@praxisui/tabs';
|
|
536
|
-
import { SchemaViewerComponent, SCHEMA_VIEWER_CONTEXT } from '@praxisui/core';
|
|
537
|
-
|
|
538
|
-
@Component({
|
|
539
|
-
standalone: true,
|
|
540
|
-
selector: 'app-tabs-showcase',
|
|
541
|
-
imports: [PraxisTabs, SchemaViewerComponent],
|
|
542
|
-
template: `
|
|
543
|
-
<!-- Aba Preview -->
|
|
544
|
-
<praxis-tabs [config]="tabs" tabsId="tabs-preview"></praxis-tabs>
|
|
545
|
-
|
|
546
|
-
<!-- Aba Schema -->
|
|
547
|
-
<praxis-schema-viewer [context]="schemaCtx"></praxis-schema-viewer>
|
|
548
|
-
`,
|
|
146
|
+
export const appConfig = {
|
|
549
147
|
providers: [
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
useFactory: () => ({
|
|
553
|
-
componentId: 'praxis-tabs',
|
|
554
|
-
title: 'Tabs — Schema & Metadata',
|
|
555
|
-
rawConfig: {
|
|
556
|
-
group: { alignTabs: 'center', dynamicHeight: true },
|
|
557
|
-
tabs: [ { id: 't1', textLabel: 'Dados', content: [] } ],
|
|
558
|
-
} satisfies TabsMetadata,
|
|
559
|
-
}),
|
|
560
|
-
} as Provider,
|
|
148
|
+
providePraxisGlobalActions(),
|
|
149
|
+
providePraxisToastGlobalActions(),
|
|
561
150
|
],
|
|
562
|
-
})
|
|
563
|
-
export class TabsShowcaseComponent {
|
|
564
|
-
tabs: TabsMetadata = { group: { dynamicHeight: true }, tabs: [] };
|
|
565
|
-
schemaCtx = {
|
|
566
|
-
componentId: 'praxis-tabs',
|
|
567
|
-
rawConfig: this.tabs,
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
Campos opcionais do contexto (`SchemaViewerContext`):
|
|
573
|
-
- `rawConfig` (JSON usado pelo exemplo), `effectiveConfig` (se houver merge de defaults);
|
|
574
|
-
- `backendSchema` (OpenAPI/JSON Schema) e `schemaMeta` (path/operation/schemaType/schemaHash);
|
|
575
|
-
- `normalizedFields` (se já normalizado; caso contrário, o componente aplica `SchemaNormalizerService`).
|
|
576
|
-
|
|
577
|
-
## 🧩 Compatibilidade
|
|
578
|
-
|
|
579
|
-
- `@praxisui/core` `1.0.0-beta.x` → Angular `20.x`
|
|
580
|
-
|
|
581
|
-
## 📦 Publicação
|
|
582
|
-
|
|
583
|
-
- Pacote ESM, gerado via `ng-packagr`.
|
|
584
|
-
- Licença: Apache-2.0 (incluída no pacote).
|
|
585
|
-
- Repositório e issues: [GitHub](https://github.com/codexrodrigues/praxis).
|
|
586
|
-
|
|
587
|
-
## 📄 Licença
|
|
588
|
-
|
|
589
|
-
Apache-2.0 — veja o arquivo `LICENSE` incluído no pacote.
|
|
590
|
-
- Module format: `ESM2022`
|
|
591
|
-
|
|
592
|
-
## 📝 Interfaces Principais
|
|
593
|
-
|
|
594
|
-
### MaterialTimepickerMetadata
|
|
595
|
-
|
|
596
|
-
```typescript
|
|
597
|
-
const workShift: MaterialTimepickerMetadata = {
|
|
598
|
-
name: "workStart",
|
|
599
|
-
label: "Início do expediente",
|
|
600
|
-
controlType: "timePicker",
|
|
601
|
-
min: "08:00",
|
|
602
|
-
max: "18:00",
|
|
603
|
-
stepMinute: 30,
|
|
604
|
-
format: "24h",
|
|
605
151
|
};
|
|
606
152
|
```
|
|
607
153
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
```typescript
|
|
611
|
-
interface TableConfig {
|
|
612
|
-
/** Metadados da configuração */
|
|
613
|
-
meta?: ConfigMetadata;
|
|
614
|
-
|
|
615
|
-
/** Definições de colunas */
|
|
616
|
-
columns: ColumnDefinition[];
|
|
617
|
-
|
|
618
|
-
/** Configurações de comportamento */
|
|
619
|
-
behavior?: TableBehaviorConfig;
|
|
620
|
-
|
|
621
|
-
/** Configurações de aparência */
|
|
622
|
-
appearance?: TableAppearanceConfig;
|
|
623
|
-
|
|
624
|
-
/** Configurações de toolbar */
|
|
625
|
-
toolbar?: ToolbarConfig;
|
|
626
|
-
|
|
627
|
-
/** Configurações de ações */
|
|
628
|
-
actions?: TableActionsConfig;
|
|
629
|
-
|
|
630
|
-
/** Configurações de exportação */
|
|
631
|
-
export?: ExportConfig;
|
|
632
|
-
|
|
633
|
-
/** Mensagens e textos */
|
|
634
|
-
messages?: MessagesConfig;
|
|
635
|
-
|
|
636
|
-
/** Localização e i18n */
|
|
637
|
-
localization?: LocalizationConfig;
|
|
638
|
-
|
|
639
|
-
/** Configurações de performance */
|
|
640
|
-
performance?: PerformanceConfig;
|
|
641
|
-
|
|
642
|
-
/** Configurações de acessibilidade */
|
|
643
|
-
accessibility?: AccessibilityConfig;
|
|
644
|
-
}
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
### ColumnDefinition
|
|
648
|
-
|
|
649
|
-
```typescript
|
|
650
|
-
interface ColumnDefinition {
|
|
651
|
-
/** Campo da fonte de dados */
|
|
652
|
-
field: string;
|
|
653
|
-
|
|
654
|
-
/** Cabeçalho da coluna */
|
|
655
|
-
header: string;
|
|
656
|
-
|
|
657
|
-
/** Tipo de dados para formatação */
|
|
658
|
-
type?: "string" | "number" | "date" | "boolean" | "currency" | "percentage" | "custom";
|
|
659
|
-
|
|
660
|
-
/** Largura da coluna */
|
|
661
|
-
width?: string;
|
|
662
|
-
|
|
663
|
-
/** Visibilidade da coluna */
|
|
664
|
-
visible?: boolean;
|
|
665
|
-
|
|
666
|
-
/** Permitir ordenação */
|
|
667
|
-
sortable?: boolean;
|
|
668
|
-
|
|
669
|
-
/** Permitir filtragem */
|
|
670
|
-
filterable?: boolean;
|
|
671
|
-
|
|
672
|
-
/** Permitir redimensionamento */
|
|
673
|
-
resizable?: boolean;
|
|
674
|
-
|
|
675
|
-
/** Coluna fixa (sticky) */
|
|
676
|
-
sticky?: boolean;
|
|
677
|
-
|
|
678
|
-
/** Alinhamento do conteúdo */
|
|
679
|
-
align?: "left" | "center" | "right";
|
|
680
|
-
|
|
681
|
-
/** Ordem de exibição */
|
|
682
|
-
order?: number;
|
|
683
|
-
|
|
684
|
-
/** Estilo CSS personalizado */
|
|
685
|
-
style?: string;
|
|
686
|
-
|
|
687
|
-
/** Formato de exibição dos dados */
|
|
688
|
-
format?: any;
|
|
689
|
-
|
|
690
|
-
/** Mapeamento de valores para exibição */
|
|
691
|
-
valueMapping?: { [key: string | number]: string };
|
|
692
|
-
}
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
### ConfigMetadata
|
|
696
|
-
|
|
697
|
-
```typescript
|
|
698
|
-
interface ConfigMetadata {
|
|
699
|
-
/** Versão da configuração */
|
|
700
|
-
version?: string;
|
|
701
|
-
|
|
702
|
-
/** Identificador único */
|
|
703
|
-
id?: string;
|
|
704
|
-
|
|
705
|
-
/** Nome amigável */
|
|
706
|
-
name?: string;
|
|
707
|
-
|
|
708
|
-
/** Descrição */
|
|
709
|
-
description?: string;
|
|
710
|
-
|
|
711
|
-
/** Tags para categorização */
|
|
712
|
-
tags?: string[];
|
|
713
|
-
|
|
714
|
-
/** Data de criação */
|
|
715
|
-
createdAt?: string;
|
|
716
|
-
|
|
717
|
-
/** Data de última modificação */
|
|
718
|
-
updatedAt?: string;
|
|
719
|
-
|
|
720
|
-
/** Autor da configuração */
|
|
721
|
-
author?: string;
|
|
722
|
-
}
|
|
723
|
-
```
|
|
724
|
-
|
|
725
|
-
## 🎛️ Configurações de Comportamento
|
|
726
|
-
|
|
727
|
-
### TableBehaviorConfig
|
|
728
|
-
|
|
729
|
-
```typescript
|
|
730
|
-
interface TableBehaviorConfig {
|
|
731
|
-
/** Configurações de paginação */
|
|
732
|
-
pagination?: PaginationConfig;
|
|
733
|
-
|
|
734
|
-
/** Configurações de ordenação */
|
|
735
|
-
sorting?: SortingConfig;
|
|
736
|
-
|
|
737
|
-
/** Configurações de filtragem */
|
|
738
|
-
filtering?: FilteringConfig;
|
|
739
|
-
|
|
740
|
-
/** Configurações de seleção */
|
|
741
|
-
selection?: SelectionConfig;
|
|
742
|
-
|
|
743
|
-
/** Configurações de interação */
|
|
744
|
-
interaction?: InteractionConfig;
|
|
745
|
-
|
|
746
|
-
/** Configurações de redimensionamento */
|
|
747
|
-
resizing?: ResizingConfig;
|
|
748
|
-
|
|
749
|
-
/** Configurações de arrastar e soltar */
|
|
750
|
-
dragging?: DraggingConfig;
|
|
751
|
-
}
|
|
752
|
-
```
|
|
753
|
-
|
|
754
|
-
### PaginationConfig
|
|
755
|
-
|
|
756
|
-
```typescript
|
|
757
|
-
interface PaginationConfig {
|
|
758
|
-
/** Habilitar paginação */
|
|
759
|
-
enabled: boolean;
|
|
760
|
-
|
|
761
|
-
/** Tamanho da página */
|
|
762
|
-
pageSize: number;
|
|
763
|
-
|
|
764
|
-
/** Opções de tamanho de página */
|
|
765
|
-
pageSizeOptions: number[];
|
|
766
|
-
|
|
767
|
-
/** Mostrar botões primeira/última */
|
|
768
|
-
showFirstLastButtons: boolean;
|
|
769
|
-
|
|
770
|
-
/** Mostrar números das páginas */
|
|
771
|
-
showPageNumbers: boolean;
|
|
772
|
-
|
|
773
|
-
/** Mostrar informações da página */
|
|
774
|
-
showPageInfo: boolean;
|
|
775
|
-
|
|
776
|
-
/** Posição do paginador */
|
|
777
|
-
position: "top" | "bottom" | "both";
|
|
778
|
-
|
|
779
|
-
/** Estilo do paginador */
|
|
780
|
-
style: "default" | "minimal" | "advanced";
|
|
781
|
-
|
|
782
|
-
/** Estratégia de paginação */
|
|
783
|
-
strategy: "client" | "server";
|
|
784
|
-
}
|
|
785
|
-
```
|
|
786
|
-
|
|
787
|
-
### SortingConfig
|
|
788
|
-
|
|
789
|
-
```typescript
|
|
790
|
-
interface SortingConfig {
|
|
791
|
-
/** Habilitar ordenação */
|
|
792
|
-
enabled: boolean;
|
|
793
|
-
|
|
794
|
-
/** Permitir ordenação múltipla (schema-only no runtime atual) */
|
|
795
|
-
multiSort: boolean;
|
|
796
|
-
|
|
797
|
-
/** Estratégia de ordenação */
|
|
798
|
-
strategy: "client" | "server";
|
|
799
|
-
|
|
800
|
-
/** Mostrar indicadores de ordenação */
|
|
801
|
-
showSortIndicators: boolean;
|
|
802
|
-
|
|
803
|
-
/** Posição do indicador */
|
|
804
|
-
indicatorPosition: "start" | "end";
|
|
805
|
-
|
|
806
|
-
/** Permitir limpar ordenação */
|
|
807
|
-
allowClearSort: boolean;
|
|
808
|
-
}
|
|
809
|
-
```
|
|
810
|
-
|
|
811
|
-
Observação enterprise: `multiSort` está disponível no contrato de schema, porém no runtime atual deve ser tratado como `schema-only` (apenas 1 critério de ordenação efetivo).
|
|
812
|
-
|
|
813
|
-
## 🎨 Configurações de Aparência
|
|
814
|
-
|
|
815
|
-
### TableAppearanceConfig
|
|
816
|
-
|
|
817
|
-
```typescript
|
|
818
|
-
interface TableAppearanceConfig {
|
|
819
|
-
/** Densidade da tabela */
|
|
820
|
-
density: "compact" | "comfortable" | "spacious";
|
|
821
|
-
|
|
822
|
-
/** Configurações de bordas */
|
|
823
|
-
borders?: BorderConfig;
|
|
824
|
-
|
|
825
|
-
/** Configurações de elevação */
|
|
826
|
-
elevation?: ElevationConfig;
|
|
827
|
-
|
|
828
|
-
/** Configurações de espaçamento */
|
|
829
|
-
spacing?: SpacingConfig;
|
|
830
|
-
|
|
831
|
-
/** Configurações de tipografia */
|
|
832
|
-
typography?: TypographyConfig;
|
|
833
|
-
}
|
|
834
|
-
```
|
|
835
|
-
|
|
836
|
-
### BorderConfig
|
|
837
|
-
|
|
838
|
-
```typescript
|
|
839
|
-
interface BorderConfig {
|
|
840
|
-
/** Mostrar bordas entre linhas */
|
|
841
|
-
showRowBorders: boolean;
|
|
842
|
-
|
|
843
|
-
/** Mostrar bordas entre colunas */
|
|
844
|
-
showColumnBorders: boolean;
|
|
845
|
-
|
|
846
|
-
/** Mostrar borda externa */
|
|
847
|
-
showOuterBorder: boolean;
|
|
848
|
-
|
|
849
|
-
/** Estilo da borda */
|
|
850
|
-
style: "solid" | "dashed" | "dotted";
|
|
851
|
-
|
|
852
|
-
/** Largura da borda */
|
|
853
|
-
width: number;
|
|
854
|
-
|
|
855
|
-
/** Cor da borda */
|
|
856
|
-
color: string;
|
|
857
|
-
}
|
|
858
|
-
```
|
|
859
|
-
|
|
860
|
-
## ⚡ Configurações de Performance
|
|
861
|
-
|
|
862
|
-
### PerformanceConfig
|
|
863
|
-
|
|
864
|
-
```typescript
|
|
865
|
-
interface PerformanceConfig {
|
|
866
|
-
/** Configurações de virtualização */
|
|
867
|
-
virtualization?: VirtualizationConfig;
|
|
868
|
-
|
|
869
|
-
/** Configurações de lazy loading */
|
|
870
|
-
lazyLoading?: LazyLoadingConfig;
|
|
871
|
-
}
|
|
872
|
-
```
|
|
873
|
-
|
|
874
|
-
### VirtualizationConfig
|
|
875
|
-
|
|
876
|
-
```typescript
|
|
877
|
-
interface VirtualizationConfig {
|
|
878
|
-
/** Habilitar virtualização */
|
|
879
|
-
enabled: boolean;
|
|
880
|
-
|
|
881
|
-
/** Altura do item */
|
|
882
|
-
itemHeight: number;
|
|
883
|
-
|
|
884
|
-
/** Tamanho do buffer */
|
|
885
|
-
bufferSize: number;
|
|
886
|
-
|
|
887
|
-
/** Altura mínima do container */
|
|
888
|
-
minContainerHeight: number;
|
|
889
|
-
|
|
890
|
-
/** Estratégia de virtualização */
|
|
891
|
-
strategy: "fixed" | "dynamic";
|
|
892
|
-
}
|
|
893
|
-
```
|
|
894
|
-
|
|
895
|
-
## 🔍 Configurações de Acessibilidade
|
|
896
|
-
|
|
897
|
-
### AccessibilityConfig
|
|
898
|
-
|
|
899
|
-
```typescript
|
|
900
|
-
interface AccessibilityConfig {
|
|
901
|
-
/** Habilitar recursos de acessibilidade */
|
|
902
|
-
enabled: boolean;
|
|
903
|
-
|
|
904
|
-
/** Configurações de anúncios */
|
|
905
|
-
announcements?: AnnouncementConfig;
|
|
906
|
-
|
|
907
|
-
/** Navegação por teclado */
|
|
908
|
-
keyboard?: KeyboardAccessibilityConfig;
|
|
909
|
-
|
|
910
|
-
/** Contraste alto */
|
|
911
|
-
highContrast?: boolean;
|
|
912
|
-
|
|
913
|
-
/** Reduzir movimento */
|
|
914
|
-
reduceMotion?: boolean;
|
|
915
|
-
|
|
916
|
-
/** Labels ARIA personalizados */
|
|
917
|
-
ariaLabels?: { [key: string]: string };
|
|
918
|
-
}
|
|
919
|
-
```
|
|
920
|
-
|
|
921
|
-
### AnnouncementConfig
|
|
922
|
-
|
|
923
|
-
```typescript
|
|
924
|
-
interface AnnouncementConfig {
|
|
925
|
-
/** Anunciar mudanças de dados */
|
|
926
|
-
dataChanges: boolean;
|
|
927
|
-
|
|
928
|
-
/** Anunciar ações do usuário */
|
|
929
|
-
userActions: boolean;
|
|
930
|
-
|
|
931
|
-
/** Anunciar estados de carregamento */
|
|
932
|
-
loadingStates: boolean;
|
|
933
|
-
|
|
934
|
-
/** Tipo de live region */
|
|
935
|
-
liveRegion: "polite" | "assertive";
|
|
936
|
-
}
|
|
937
|
-
```
|
|
938
|
-
|
|
939
|
-
## 🛠️ Serviços
|
|
940
|
-
|
|
941
|
-
### TableConfigService
|
|
942
|
-
|
|
943
|
-
```typescript
|
|
944
|
-
class TableConfigService {
|
|
945
|
-
/** Definir configuração atual */
|
|
946
|
-
setConfig(config: TableConfig): void;
|
|
947
|
-
|
|
948
|
-
/** Obter configuração atual */
|
|
949
|
-
getCurrentConfig(): TableConfig;
|
|
950
|
-
|
|
951
|
-
/** Verificar se um recurso está habilitado */
|
|
952
|
-
isFeatureEnabled(feature: string): boolean;
|
|
953
|
-
|
|
954
|
-
/** Obter resumo da configuração */
|
|
955
|
-
getConfigSummary(): ConfigSummary;
|
|
956
|
-
|
|
957
|
-
/** Obter configurações de paginação */
|
|
958
|
-
getPaginationConfig(): PaginationConfig | undefined;
|
|
959
|
-
|
|
960
|
-
/** Obter configurações de ordenação */
|
|
961
|
-
getSortingConfig(): SortingConfig | undefined;
|
|
962
|
-
|
|
963
|
-
/** Obter configurações de filtragem */
|
|
964
|
-
getFilteringConfig(): FilteringConfig | undefined;
|
|
965
|
-
}
|
|
966
|
-
```
|
|
967
|
-
|
|
968
|
-
### Exemplo de Uso do Serviço
|
|
969
|
-
|
|
970
|
-
```typescript
|
|
971
|
-
import { TableConfigService } from '@praxisui/core';
|
|
972
|
-
|
|
973
|
-
@Component({...})
|
|
974
|
-
export class MyComponent {
|
|
975
|
-
constructor(private configService: TableConfigService) {}
|
|
976
|
-
|
|
977
|
-
ngOnInit() {
|
|
978
|
-
// Definir configuração
|
|
979
|
-
this.configService.setConfig(this.tableConfig);
|
|
980
|
-
|
|
981
|
-
// Verificar recursos
|
|
982
|
-
// No runtime atual, multiSort permanece schema-only.
|
|
983
|
-
const hasMultiSort = false;
|
|
984
|
-
const hasBulkActions = this.configService.isFeatureEnabled('bulkActions');
|
|
985
|
-
const hasExport = this.configService.isFeatureEnabled('export');
|
|
986
|
-
|
|
987
|
-
// Obter configurações específicas
|
|
988
|
-
const paginationConfig = this.configService.getPaginationConfig();
|
|
989
|
-
const sortingConfig = this.configService.getSortingConfig();
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
```
|
|
993
|
-
|
|
994
|
-
## 🔧 Helper Functions
|
|
995
|
-
|
|
996
|
-
### Configuração Padrão
|
|
997
|
-
|
|
998
|
-
```typescript
|
|
999
|
-
import { createDefaultTableConfig } from "@praxisui/core";
|
|
1000
|
-
|
|
1001
|
-
// Criar configuração padrão
|
|
1002
|
-
const defaultConfig = createDefaultTableConfig();
|
|
1003
|
-
|
|
1004
|
-
console.log(defaultConfig);
|
|
1005
|
-
// {
|
|
1006
|
-
// meta: { version: '2.0.0', ... },
|
|
1007
|
-
// columns: [],
|
|
1008
|
-
// behavior: { pagination: { enabled: true, ... }, ... },
|
|
1009
|
-
// ...
|
|
1010
|
-
// }
|
|
1011
|
-
```
|
|
1012
|
-
|
|
1013
|
-
### Validação
|
|
1014
|
-
|
|
1015
|
-
```typescript
|
|
1016
|
-
import { isValidTableConfig, isTableConfigV2 } from '@praxisui/core';
|
|
1017
|
-
|
|
1018
|
-
// Validar configuração
|
|
1019
|
-
const config = { columns: [...] };
|
|
1020
|
-
|
|
1021
|
-
if (isValidTableConfig(config)) {
|
|
1022
|
-
console.log('Configuração válida');
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
if (isTableConfigV2(config)) {
|
|
1026
|
-
console.log('Configuração V2 detectada');
|
|
1027
|
-
}
|
|
1028
|
-
```
|
|
1029
|
-
|
|
1030
|
-
### Manipulação de Configurações
|
|
1031
|
-
|
|
1032
|
-
```typescript
|
|
1033
|
-
import { cloneTableConfig, mergeTableConfigs, getEssentialConfig } from "@praxisui/core";
|
|
1034
|
-
|
|
1035
|
-
// Clonar configuração
|
|
1036
|
-
const clonedConfig = cloneTableConfig(originalConfig);
|
|
1037
|
-
|
|
1038
|
-
// Merge configurações
|
|
1039
|
-
const mergedConfig = mergeTableConfigs(baseConfig, {
|
|
1040
|
-
behavior: {
|
|
1041
|
-
pagination: { pageSize: 25 },
|
|
1042
|
-
},
|
|
1043
|
-
});
|
|
1044
|
-
|
|
1045
|
-
// Extrair configurações essenciais
|
|
1046
|
-
const essentialConfig = getEssentialConfig(fullConfig);
|
|
1047
|
-
```
|
|
1048
|
-
|
|
1049
|
-
## 📊 Type Guards e Utilitários
|
|
1050
|
-
|
|
1051
|
-
### Type Guards
|
|
1052
|
-
|
|
1053
|
-
```typescript
|
|
1054
|
-
// Verificar se é configuração V2
|
|
1055
|
-
function isTableConfigV2(config: any): config is TableConfig;
|
|
1056
|
-
|
|
1057
|
-
// Validar estrutura da configuração
|
|
1058
|
-
function isValidTableConfig(config: any): config is TableConfig;
|
|
1059
|
-
```
|
|
1060
|
-
|
|
1061
|
-
### Utilitários de Configuração
|
|
1062
|
-
|
|
1063
|
-
```typescript
|
|
1064
|
-
// Criar configuração padrão
|
|
1065
|
-
function createDefaultTableConfig(): TableConfig;
|
|
1066
|
-
|
|
1067
|
-
// Clonar configuração profundamente
|
|
1068
|
-
function cloneTableConfig(config: TableConfig): TableConfig;
|
|
1069
|
-
|
|
1070
|
-
// Merge duas configurações
|
|
1071
|
-
function mergeTableConfigs(base: TableConfig, override: Partial<TableConfig>): TableConfig;
|
|
1072
|
-
|
|
1073
|
-
// Extrair configurações essenciais
|
|
1074
|
-
function getEssentialConfig(config: TableConfig): Partial<TableConfig>;
|
|
1075
|
-
```
|
|
1076
|
-
|
|
1077
|
-
## 🧪 Testando com @praxisui/core
|
|
1078
|
-
|
|
1079
|
-
### Setup de Testes
|
|
1080
|
-
|
|
1081
|
-
```typescript
|
|
1082
|
-
import { TestBed } from "@angular/core/testing";
|
|
1083
|
-
import { TableConfigService } from "@praxisui/core";
|
|
1084
|
-
|
|
1085
|
-
describe("TableConfigService", () => {
|
|
1086
|
-
let service: TableConfigService;
|
|
1087
|
-
|
|
1088
|
-
beforeEach(() => {
|
|
1089
|
-
TestBed.configureTestingModule({
|
|
1090
|
-
providers: [TableConfigService],
|
|
1091
|
-
});
|
|
1092
|
-
service = TestBed.inject(TableConfigService);
|
|
1093
|
-
});
|
|
1094
|
-
|
|
1095
|
-
it("should create", () => {
|
|
1096
|
-
expect(service).toBeTruthy();
|
|
1097
|
-
});
|
|
1098
|
-
|
|
1099
|
-
it("should set and get config", () => {
|
|
1100
|
-
const config: TableConfig = {
|
|
1101
|
-
columns: [{ field: "test", header: "Test" }],
|
|
1102
|
-
};
|
|
1103
|
-
|
|
1104
|
-
service.setConfig(config);
|
|
1105
|
-
expect(service.getCurrentConfig()).toEqual(config);
|
|
1106
|
-
});
|
|
1107
|
-
});
|
|
1108
|
-
```
|
|
1109
|
-
|
|
1110
|
-
### Testes de Helper Functions
|
|
1111
|
-
|
|
1112
|
-
```typescript
|
|
1113
|
-
import { createDefaultTableConfig, isValidTableConfig, cloneTableConfig } from "@praxisui/core";
|
|
1114
|
-
|
|
1115
|
-
describe("Helper Functions", () => {
|
|
1116
|
-
it("should create valid default config", () => {
|
|
1117
|
-
const config = createDefaultTableConfig();
|
|
1118
|
-
expect(isValidTableConfig(config)).toBe(true);
|
|
1119
|
-
});
|
|
1120
|
-
|
|
1121
|
-
it("should clone config correctly", () => {
|
|
1122
|
-
const original: TableConfig = {
|
|
1123
|
-
columns: [{ field: "test", header: "Test" }],
|
|
1124
|
-
behavior: { pagination: { enabled: true } },
|
|
1125
|
-
};
|
|
1126
|
-
|
|
1127
|
-
const cloned = cloneTableConfig(original);
|
|
1128
|
-
expect(cloned).toEqual(original);
|
|
1129
|
-
expect(cloned).not.toBe(original); // Different reference
|
|
1130
|
-
});
|
|
1131
|
-
});
|
|
1132
|
-
```
|
|
1133
|
-
|
|
1134
|
-
## 📋 Migration Guide
|
|
1135
|
-
|
|
1136
|
-
### Migração da Arquitetura V1/V2
|
|
1137
|
-
|
|
1138
|
-
#### Mudanças Principais
|
|
1139
|
-
|
|
1140
|
-
1. **Interface Unificada**:
|
|
1141
|
-
|
|
1142
|
-
```typescript
|
|
1143
|
-
// Antes
|
|
1144
|
-
import { TableConfigV1, TableConfigV2, TableConfigUnified } from "@praxisui/core";
|
|
1145
|
-
|
|
1146
|
-
// Depois
|
|
1147
|
-
import { TableConfig } from "@praxisui/core";
|
|
1148
|
-
```
|
|
1149
|
-
|
|
1150
|
-
2. **Serviços Simplificados**:
|
|
1151
|
-
|
|
1152
|
-
```typescript
|
|
1153
|
-
// Antes
|
|
1154
|
-
import { TableConfigAdapterService, TableConfigMigrationService } from "@praxisui/core";
|
|
1155
|
-
|
|
1156
|
-
// Depois
|
|
1157
|
-
import { TableConfigService } from "@praxisui/core";
|
|
1158
|
-
```
|
|
1159
|
-
|
|
1160
|
-
3. **Type Guards Atualizados**:
|
|
1161
|
-
|
|
1162
|
-
```typescript
|
|
1163
|
-
// Antes
|
|
1164
|
-
isTableConfigV1(config) || isTableConfigV2(config);
|
|
1165
|
-
|
|
1166
|
-
// Depois
|
|
1167
|
-
isTableConfigV2(config); // Sempre true para a nova arquitetura
|
|
1168
|
-
```
|
|
1169
|
-
|
|
1170
|
-
## 🔍 Troubleshooting
|
|
1171
|
-
|
|
1172
|
-
### Problemas Comuns
|
|
1173
|
-
|
|
1174
|
-
#### Erros de Tipagem
|
|
1175
|
-
|
|
1176
|
-
```typescript
|
|
1177
|
-
// Problema: Type error em propriedades opcionais
|
|
1178
|
-
// Solução: Usar optional chaining
|
|
1179
|
-
const pageSize = config.behavior?.pagination?.pageSize ?? 10;
|
|
1180
|
-
```
|
|
1181
|
-
|
|
1182
|
-
#### Validação de Configuração
|
|
154
|
+
Use `GlobalActionRef` and the catalog helpers when declaring or validating action payloads. The host remains responsible for registered executors and policy.
|
|
1183
155
|
|
|
1184
|
-
|
|
1185
|
-
// Verificar se configuração é válida antes de usar
|
|
1186
|
-
import { isValidTableConfig } from "@praxisui/core";
|
|
156
|
+
## Collection Export
|
|
1187
157
|
|
|
1188
|
-
|
|
1189
|
-
console.error("Configuração inválida:", userConfig);
|
|
1190
|
-
userConfig = createDefaultTableConfig();
|
|
1191
|
-
}
|
|
1192
|
-
```
|
|
158
|
+
`PraxisCollectionExportService` is the shared export contract used by table, list, and future collection components.
|
|
1193
159
|
|
|
1194
|
-
|
|
160
|
+
```ts
|
|
161
|
+
import { providePraxisHttpCollectionExportProvider } from '@praxisui/core';
|
|
1195
162
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
const optimizedConfig: TableConfig = {
|
|
1199
|
-
columns: [...],
|
|
1200
|
-
performance: {
|
|
1201
|
-
virtualization: {
|
|
1202
|
-
enabled: true,
|
|
1203
|
-
itemHeight: 48,
|
|
1204
|
-
bufferSize: 20
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
163
|
+
export const appConfig = {
|
|
164
|
+
providers: [providePraxisHttpCollectionExportProvider()],
|
|
1207
165
|
};
|
|
1208
166
|
```
|
|
1209
167
|
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
### Exports Principais
|
|
1213
|
-
|
|
1214
|
-
```typescript
|
|
1215
|
-
// Interfaces
|
|
1216
|
-
export interface TableConfig;
|
|
1217
|
-
export interface ColumnDefinition;
|
|
1218
|
-
export interface ConfigMetadata;
|
|
1219
|
-
export interface TableBehaviorConfig;
|
|
1220
|
-
export interface TableAppearanceConfig;
|
|
1221
|
-
export interface ToolbarConfig;
|
|
1222
|
-
export interface TableActionsConfig;
|
|
1223
|
-
export interface ExportConfig;
|
|
1224
|
-
export interface PraxisCollectionExportRequest;
|
|
1225
|
-
export interface PraxisCollectionExportProvider;
|
|
1226
|
-
export interface PraxisCollectionSelectionState;
|
|
1227
|
-
export interface MessagesConfig;
|
|
1228
|
-
export interface LocalizationConfig;
|
|
1229
|
-
export interface PerformanceConfig;
|
|
1230
|
-
export interface AccessibilityConfig;
|
|
1231
|
-
|
|
1232
|
-
// Serviços
|
|
1233
|
-
export class TableConfigService;
|
|
1234
|
-
export class PraxisCollectionExportService;
|
|
1235
|
-
export class PraxisHttpCollectionExportProvider;
|
|
1236
|
-
|
|
1237
|
-
// Helper Functions
|
|
1238
|
-
export function createDefaultTableConfig(): TableConfig;
|
|
1239
|
-
export function isValidTableConfig(config: any): config is TableConfig;
|
|
1240
|
-
export function isTableConfigV2(config: any): config is TableConfig;
|
|
1241
|
-
export function cloneTableConfig(config: TableConfig): TableConfig;
|
|
1242
|
-
export function mergeTableConfigs(base: TableConfig, override: Partial<TableConfig>): TableConfig;
|
|
1243
|
-
export function getEssentialConfig(config: TableConfig): Partial<TableConfig>;
|
|
1244
|
-
export function providePraxisHttpCollectionExportProvider();
|
|
1245
|
-
|
|
1246
|
-
// Type Aliases
|
|
1247
|
-
export type TableConfig = TableConfigV2;
|
|
1248
|
-
export type TableConfigModern = TableConfigV2;
|
|
1249
|
-
export type PraxisExportFormat;
|
|
1250
|
-
export type PraxisExportScope;
|
|
1251
|
-
|
|
1252
|
-
// Legacy (Deprecated)
|
|
1253
|
-
export type LegacyTableConfig = TableConfig;
|
|
1254
|
-
export const DEFAULT_TABLE_CONFIG = createDefaultTableConfig();
|
|
1255
|
-
```
|
|
1256
|
-
|
|
1257
|
-
## 🤝 Contribuição
|
|
1258
|
-
|
|
1259
|
-
### Como Contribuir
|
|
1260
|
-
|
|
1261
|
-
1. Fork o projeto
|
|
1262
|
-
2. Crie branch para feature (`git checkout -b feature/nova-interface`)
|
|
1263
|
-
3. Commit mudanças (`git commit -m 'Add: nova interface para X'`)
|
|
1264
|
-
4. Push para branch (`git push origin feature/nova-interface`)
|
|
1265
|
-
5. Abra Pull Request
|
|
1266
|
-
|
|
1267
|
-
### Guidelines para Interfaces
|
|
1268
|
-
|
|
1269
|
-
- Usar nomes descritivos e consistentes
|
|
1270
|
-
- Documentar todas as propriedades
|
|
1271
|
-
- Manter backward compatibility quando possível
|
|
1272
|
-
- Adicionar testes para novas interfaces
|
|
1273
|
-
|
|
1274
|
-
## 📊 Roadmap
|
|
1275
|
-
|
|
1276
|
-
### Próximas Versões
|
|
1277
|
-
|
|
1278
|
-
- ✅ Arquitetura unificada (v2.0.0)
|
|
1279
|
-
- 🔄 Enhanced validation (v2.1.0)
|
|
1280
|
-
- 📋 Plugin architecture (v2.2.0)
|
|
1281
|
-
- 🎨 Theme system integration (v2.3.0)
|
|
1282
|
-
|
|
1283
|
-
## 📄 Licença
|
|
168
|
+
Without an HTTP provider, local CSV/JSON export uses loaded items. With the HTTP provider, remote scopes such as `filtered` and `all` delegate execution to the backend export endpoint and should be gated by backend capabilities or HATEOAS links.
|
|
1284
169
|
|
|
1285
|
-
|
|
170
|
+
## Runtime Observations And AI
|
|
1286
171
|
|
|
1287
|
-
|
|
172
|
+
`PraxisRuntimeComponentObservationRegistryService` registers redacted runtime observations for active components. These snapshots are not a source of truth for capabilities. Backend authoring services must reconcile observations with manifests, schemas, resource capabilities, actions, surfaces, and tenant/environment policy.
|
|
1288
173
|
|
|
1289
|
-
|
|
1290
|
-
**Versão**: 2.0.0 (Unified Architecture)
|
|
1291
|
-
**Compatibilidade**: Angular 20.x | TypeScript 5.8+
|
|
1292
|
-
## Value Presentation
|
|
174
|
+
Core also exports shared AI authoring types, capability types, dynamic-page context packs, and domain catalog context packs used by component packages.
|
|
1293
175
|
|
|
1294
|
-
|
|
176
|
+
## Domain Governance
|
|
1295
177
|
|
|
1296
|
-
|
|
1297
|
-
- use `valuePresentation.type` para declarar a natureza do valor exibido (`currency`, `date`, `datetime`, `time`, `number`, `percentage`, `boolean`)
|
|
1298
|
-
- deixe `format` como override explicito quando quiser sair do default derivado de `type + localization`
|
|
1299
|
-
- use `localization` da superficie como base cultural; nao repita locale/moeda por coluna ou campo sem necessidade real
|
|
178
|
+
`DomainKnowledgeService` and `DomainRuleService` are shared clients for governed semantic decision flows exposed by `praxis-config-starter`. Runtime surfaces should treat materializations as derived projections of backend-governed decisions, not as frontend-owned business rules.
|
|
1300
179
|
|
|
1301
|
-
|
|
1302
|
-
1. override explicito do valor/campo
|
|
1303
|
-
2. `valuePresentation`
|
|
1304
|
-
3. configuracao da superficie
|
|
1305
|
-
4. `LOCALE_ID`
|
|
180
|
+
## Public API Areas
|
|
1306
181
|
|
|
1307
|
-
|
|
1308
|
-
- `valuePresentation` deve representar valor escalar de display/read-only; nao use para ranges, selections ou IDs semanticos
|
|
1309
|
-
- contratos legados como `format`, `numericFormat`, `currency` e `numberFormat` continuam aceitos como bridge de compatibilidade interna, mas novos metadados devem preferir `valuePresentation`
|
|
182
|
+
Core exports:
|
|
1310
183
|
|
|
1311
|
-
|
|
184
|
+
- shared services such as `GenericCrudService`, `GlobalConfigService`, `GlobalActionService`, `ResourceDiscoveryService`, `ComponentMetadataRegistry`, `PraxisJsonLogicService`, `LoadingOrchestratorService`
|
|
185
|
+
- tokens and providers for API URLs, global config, global actions, loading, i18n, settings panel bridge, surface drawer bridge, collection export, field selector registry, and overlay/layer scale
|
|
186
|
+
- models for table config, fields, forms, rich content, editorial content, widget pages, global actions, resource discovery, domain knowledge/rules, analytics, query context, loading, and collection export
|
|
187
|
+
- helpers for schema ids, ETag fetch, field mapping, config merge, validation, IDs, inline filter controls, global action refs, and form hooks
|
|
188
|
+
- dynamic widget/page runtime components and metadata
|
|
189
|
+
- UI helpers such as icon picker, empty state card, resource quick connect, schema viewer, and `PraxisIconDirective`
|
|
1312
190
|
|
|
1313
|
-
|
|
191
|
+
See the package `public-api.ts` for the full export list.
|
|
1314
192
|
|
|
1315
|
-
|
|
1316
|
-
- reutiliza `SchemaMetadataClient` + `fetchWithETag`
|
|
1317
|
-
- devolve `PraxisXUiAnalytics` tipado
|
|
1318
|
-
- falha explicitamente quando `x-ui.analytics.projections[]` nao foi publicado
|
|
193
|
+
## Notes
|
|
1319
194
|
|
|
1320
|
-
|
|
1321
|
-
-
|
|
1322
|
-
-
|
|
1323
|
-
-
|
|
195
|
+
- `@praxisui/core` centralizes shared Angular/runtime contracts, but backend metadata semantics are still defined by the appropriate backend starter.
|
|
196
|
+
- Do not use consuming apps to redefine contracts owned by core, metadata starter, config starter, or a component package.
|
|
197
|
+
- Prefer `composition.links` for page wiring and `valuePresentation` for scalar display semantics.
|
|
198
|
+
- Use the official documentation for full recipes on schema flow, option sources, analytics, global actions, dynamic pages, and governed AI flows.
|