@oondemand/create-central-oon 0.5.5 → 0.6.0

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.
Files changed (70) hide show
  1. package/README.md +41 -89
  2. package/bin/cli.js +4 -17
  3. package/docs/ADVANCED_UX_PATTERNS.md +3 -2
  4. package/docs/AGENTS.md +3 -4
  5. package/docs/BACKEND_API.md +2 -4
  6. package/docs/BACKEND_PATTERNS.md +1 -2
  7. package/docs/BACKEND_PROCESS_MANIFEST.md +6 -6
  8. package/docs/CAPABILITIES.md +2 -3
  9. package/docs/CHECKLIST_IMPLEMENTACAO.md +4 -4
  10. package/docs/FRONTEND_API.md +20 -23
  11. package/docs/FRONTEND_CODE_FIRST.md +35 -0
  12. package/docs/FRONTEND_PATTERNS.md +13 -15
  13. package/docs/METADATA_CRUD_UI.md +1 -1
  14. package/docs/PORTAL_COCKPIT_PATTERNS.md +10 -145
  15. package/docs/REACTIVE_DOMAIN_FORMULAS.md +2 -2
  16. package/package.json +1 -1
  17. package/schemas/central.app.schema.json +2 -16
  18. package/src/conformance.js +42 -106
  19. package/src/index.js +4 -28
  20. package/src/render.js +2 -1
  21. package/templates/_base/README.md +7 -6
  22. package/templates/_base/backend/package.json +1 -1
  23. package/templates/_base/central.app.json +4 -9
  24. package/templates/_base/frontend/package.json +1 -1
  25. package/templates/_base/frontend/src/app/app.tsx +25 -0
  26. package/templates/_base/frontend/src/app/navigation.ts +5 -0
  27. package/templates/_base/frontend/src/app/routes.tsx +6 -0
  28. package/templates/_base/frontend/src/app/theme.ts +8 -0
  29. package/templates/_base/frontend/src/components/gitkeep +1 -0
  30. package/templates/_base/frontend/src/features/gitkeep +1 -0
  31. package/templates/_base/frontend/src/layouts/gitkeep +1 -0
  32. package/templates/_base/frontend/src/main.tsx +3 -8
  33. package/templates/_base/frontend/src/pages/HomePage.tsx +25 -0
  34. package/templates/_base/frontend/tsconfig.json +1 -1
  35. package/templates/_base/package.json +1 -1
  36. package/docs/CONNECTORS_AND_INTEGRATIONS.md +0 -66
  37. package/docs/FRONTEND_MANIFEST_REFERENCE.md +0 -487
  38. package/templates/_base/backend/src/integrations/gitkeep +0 -0
  39. package/templates/_base/frontend/central.ui.json +0 -8
  40. package/templates/_base/frontend/src/collections/gitkeep +0 -0
  41. package/templates/_base/frontend/src/dashboards/gitkeep +0 -0
  42. package/templates/_base/frontend/src/documents/gitkeep +0 -0
  43. package/templates/_base/frontend/src/overrides/gitkeep +0 -0
  44. package/templates/_base/frontend/src/pipelines/gitkeep +0 -0
  45. package/templates/basic/backend/src/models/Pessoa.js +0 -21
  46. package/templates/basic/frontend/central.ui.json +0 -8
  47. package/templates/documentos-fiscais/backend/central.config.js +0 -32
  48. package/templates/documentos-fiscais/backend/src/models/DocumentoFiscal.js +0 -23
  49. package/templates/documentos-fiscais/frontend/central.ui.json +0 -16
  50. package/templates/multi-moedas/backend/central.config.js +0 -32
  51. package/templates/multi-moedas/backend/src/models/Cotacao.js +0 -23
  52. package/templates/multi-moedas/backend/src/models/Moeda.js +0 -15
  53. package/templates/multi-moedas/frontend/central.ui.json +0 -11
  54. package/templates/omie-sidecar/backend/central.config.js +0 -33
  55. package/templates/omie-sidecar/backend/src/mappings/pessoa-cliente.js +0 -20
  56. package/templates/omie-sidecar/backend/src/models/Pessoa.js +0 -24
  57. package/templates/omie-sidecar/backend/src/triggers/Pessoa.js +0 -14
  58. package/templates/omie-sidecar/frontend/central.ui.json +0 -8
  59. package/templates/pedidos-marketplace/backend/central.config.js +0 -32
  60. package/templates/pedidos-marketplace/backend/src/models/Pedido.js +0 -22
  61. package/templates/pedidos-marketplace/backend/src/models/Produto.js +0 -16
  62. package/templates/pedidos-marketplace/frontend/central.ui.json +0 -10
  63. package/templates/servicos-prestados/backend/central.config.js +0 -32
  64. package/templates/servicos-prestados/backend/src/models/Cliente.js +0 -15
  65. package/templates/servicos-prestados/backend/src/models/ServicoPrestado.js +0 -22
  66. package/templates/servicos-prestados/frontend/central.ui.json +0 -10
  67. package/templates/servicos-tomados/backend/central.config.js +0 -32
  68. package/templates/servicos-tomados/backend/src/models/Pessoa.js +0 -15
  69. package/templates/servicos-tomados/backend/src/models/Servico.js +0 -22
  70. package/templates/servicos-tomados/frontend/central.ui.json +0 -10
@@ -0,0 +1,8 @@
1
+ import { createOonTheme, oonDefaultTheme } from "@oondemand/oon-core-front/theme";
2
+
3
+ export const theme = createOonTheme({
4
+ id: "__SLUG__",
5
+ label: "__NAME__",
6
+ extends: oonDefaultTheme,
7
+ density: "comfortable",
8
+ });
@@ -1,9 +1,4 @@
1
- import { startCentralFromManifest } from "@oondemand/oon-core-front";
2
- import app from "../../central.app.json";
3
- import ui from "../central.ui.json";
1
+ import { startOonApp } from "@oondemand/oon-core-front";
2
+ import { app } from "./app/app";
4
3
 
5
- startCentralFromManifest({ app, ui }, {
6
- apiBaseUrl: import.meta.env.VITE_API_URL ?? "/api",
7
- runtimeMode: import.meta.env.DEV ? "local" : "platform",
8
- meusAppsUrl: import.meta.env.DEV ? undefined : import.meta.env.VITE_MEUS_APPS_URL,
9
- });
4
+ startOonApp(app);
@@ -0,0 +1,25 @@
1
+ import { Stack, Text } from "@chakra-ui/react";
2
+ import { CorePage, CorePageHeader, CoreStatusPanel, CoreSummaryCards } from "@oondemand/oon-core-front/ui";
3
+
4
+ export function HomePage() {
5
+ return (
6
+ <CorePage>
7
+ <CorePageHeader
8
+ title="Boas-vindas ao __NAME__"
9
+ description="A fundação técnica está pronta para receber a experiência e o domínio do app."
10
+ />
11
+ <Stack gap={6}>
12
+ <CoreSummaryCards items={[
13
+ { id: "core", label: "OonCore", value: "Pronto", description: "Shell, autenticação, sessão, tenant e RBAC." },
14
+ { id: "platform", label: "Plataforma Oon", value: "Governada", description: "Publicação, ambientes, acesso e proveniência." },
15
+ ]} />
16
+ <CoreStatusPanel
17
+ title="Próximos passos"
18
+ status="Code-first"
19
+ description="Crie páginas em src/pages, componentes em src/components e organize o domínio em src/features."
20
+ />
21
+ <Text color="text.muted">Menus, rotas, layouts e temas ficam em src/app e podem combinar componentes locais com blocos públicos do OonCore.</Text>
22
+ </Stack>
23
+ </CorePage>
24
+ );
25
+ }
@@ -13,5 +13,5 @@
13
13
  "isolatedModules": true,
14
14
  "types": ["vite/client"]
15
15
  },
16
- "include": ["src", "central.ui.json", "vite.config.ts"]
16
+ "include": ["src", "vite.config.ts"]
17
17
  }
@@ -13,6 +13,6 @@
13
13
  "dev:frontend": "npm run dev --prefix frontend"
14
14
  },
15
15
  "devDependencies": {
16
- "@oondemand/create-central-oon": "0.5.5"
16
+ "@oondemand/create-central-oon": "0.6.0"
17
17
  }
18
18
  }
@@ -1,66 +0,0 @@
1
- # Conectores e Integrações
2
-
3
- Toda integração deve ser modelada como um processo rastreável, não como chamada solta dentro de controller.
4
-
5
- ## Objetivo
6
-
7
- Transformar cada integração em:
8
-
9
- ```txt
10
- configuração + mapping + execução + status + rastreabilidade
11
- ```
12
-
13
- ## Estrutura recomendada
14
-
15
- ```txt
16
- backend/src/integrations/
17
- ├── <sistema>/
18
- │ ├── client.js
19
- │ ├── mappings/
20
- │ ├── services/
21
- │ └── README.md
22
- ```
23
-
24
- ## Client
25
-
26
- O client deve concentrar:
27
-
28
- - URL base;
29
- - autenticação;
30
- - headers;
31
- - timeout;
32
- - retry técnico;
33
- - normalização de erro.
34
-
35
- Não coloque regra de negócio no client.
36
-
37
- ## Mapping
38
-
39
- Mappings devem transformar dados entre a Central e o sistema externo.
40
-
41
- Regras:
42
-
43
- - mapping deve ser explícito;
44
- - campos obrigatórios devem ser validados antes do envio;
45
- - resposta externa deve ser normalizada;
46
- - erros devem ser compreensíveis para operação.
47
-
48
- ## Esteira de integração
49
-
50
- Toda integração relevante deve gerar registro operacional com:
51
-
52
- - origem;
53
- - destino;
54
- - payload resumido ou referência;
55
- - status;
56
- - tentativas;
57
- - erro normalizado;
58
- - data/hora;
59
- - usuário ou processo responsável.
60
-
61
- ## Segurança
62
-
63
- - Nunca versionar app key, secret, token ou credencial.
64
- - Não logar payloads sensíveis sem necessidade.
65
- - Não expor credenciais no frontend.
66
- - Usar `.env` e configuração de ambiente.
@@ -1,487 +0,0 @@
1
- # Referência do Manifesto Frontend OonCore
2
-
3
- Este documento é a referência operacional para qualquer Agent criar ou alterar manifestos do frontend OonCore.
4
-
5
- Use este arquivo junto com `FRONTEND_PATTERNS.md`. O arquivo de padrões explica como pensar a UI; este arquivo lista as opções do contrato atual e das extensões planejadas para UX avançada.
6
-
7
- Para modal com abas, grids relacionados editáveis e ações por linha, leia também:
8
-
9
- - `ADVANCED_UX_PATTERNS.md`
10
- - `DETAIL_MODAL_AND_RELATED_GRIDS.md`
11
-
12
- ## Arquivos envolvidos
13
-
14
- ```txt
15
- frontend/central.ui.json # manifesto declarativo da Central
16
- frontend/src/main.tsx # bootstrap do frontend
17
- packages/oonCore-front/src/manifest.ts # conversão central.ui.json -> OonCoreFrontConfig
18
- packages/oonCore-front/src/types.ts # tipos oficiais do contrato
19
- ```
20
-
21
- ## Regra principal
22
-
23
- O manifesto JSON não deve carregar componentes React. Ele só pode declarar dados e chaves de renderer, como:
24
-
25
- ```txt
26
- custom:MeusAppsHeader
27
- fields.password
28
- cells.statusBadge
29
- cards.appLauncher
30
- actions.ativarApp
31
- menus.portal
32
- ```
33
-
34
- Os componentes reais devem ser registrados em código TypeScript/React pelo `registry`.
35
-
36
- ## Níveis de contrato
37
-
38
- Existem três níveis importantes:
39
-
40
- 1. `central.ui.json`: entrada declarativa usada pelas Centrais geradas.
41
- 2. `CentralUiManifest`: contrato lido por `startFromManifest`.
42
- 3. `OonUiManifest` / `OonCoreFrontConfig`: contrato interno mais completo do Core Front.
43
-
44
- Para Agents, a ordem recomendada é:
45
-
46
- 1. Começar pelo `central.ui.json`.
47
- 2. Usar `pages` e `blocks` quando precisar de UI v2.
48
- 3. Usar `collections[].list`, `collections[].detailModal`, `form.groups`, `relations` e `relatedGrid` para UX operacional avançada.
49
- 4. Usar registry/overrides em TypeScript quando precisar de componentes customizados.
50
- 5. Evitar recriar shell, rotas, menu, grid, cards ou formulários manualmente.
51
-
52
- ## CentralUiManifest
53
-
54
- Contrato aceito por `startFromManifest(manifest, runtime)`.
55
-
56
- ```ts
57
- interface CentralUiManifest {
58
- name: string;
59
- slug: string;
60
- backend?: { metadataUrl?: string };
61
- schemaVersion?: 1 | 2;
62
- layout?: OonLayoutConfig;
63
- registry?: OonComponentRegistry;
64
- navigation?: OonNavigationConfig;
65
- pages?: OonPageDef[];
66
- collections?: OonCollectionManifestDef[];
67
- pipelines?: Array<{
68
- name?: string;
69
- model?: string;
70
- mode?: string;
71
- stageField?: string;
72
- path?: string;
73
- label?: string;
74
- section?: string;
75
- }>;
76
- documents?: Array<{
77
- model: string;
78
- mode?: string;
79
- path?: string;
80
- label?: string;
81
- section?: string;
82
- approval?: boolean;
83
- attachments?: boolean;
84
- }>;
85
- }
86
- ```
87
-
88
- ## Opções de raiz
89
-
90
- | Campo | Tipo | Uso |
91
- | --- | --- | --- |
92
- | `name` | `string` | Nome exibido da Central. |
93
- | `slug` | `string` | Identificador da Central/app. |
94
- | `backend.metadataUrl` | `string` | URL explícita de metadata, quando aplicável. |
95
- | `schemaVersion` | `1 \| 2` | Sem valor = compatibilidade v1. Use `2` para UI v2. |
96
- | `layout` | `OonLayoutConfig` | Shell, sidebar, topbar, header, footer e slots. |
97
- | `navigation` | `OonNavigationConfig` | Modo do menu e itens manuais. |
98
- | `pages` | `OonPageDef[]` | Páginas por blocos da UI v2. |
99
- | `collections` | `Array` | Views de coleção, simples ou avançadas. |
100
- | `pipelines` | `Array` | Atalho para gerar esteiras. |
101
- | `documents` | `Array` | Atalho para gerar documentos. |
102
-
103
- ## Layout
104
-
105
- ```ts
106
- type OonSlotConfig = "core" | "none" | `custom:${string}`;
107
-
108
- interface OonLayoutConfig {
109
- shell?: "default" | "portal" | "content-only" | `custom:${string}`;
110
- sidebar?: OonSlotConfig;
111
- topbar?: OonSlotConfig;
112
- header?: "none" | `custom:${string}`;
113
- footer?: "core" | "none" | `custom:${string}`;
114
- assistant?: "core" | "none" | `custom:${string}`;
115
- main?: "core";
116
- }
117
- ```
118
-
119
- ### Valores de `layout.shell`
120
-
121
- | Valor | Comportamento |
122
- | --- | --- |
123
- | `default` | Shell operacional padrão com sidebar/topbar. |
124
- | `portal` | Shell para portal, útil para Meus Apps ou home de cards. |
125
- | `content-only` | Experiência focada em conteúdo. |
126
- | `custom:<key>` | Shell registrado em `registry.layoutSlots`. |
127
-
128
- ## Navigation
129
-
130
- ```ts
131
- type OonNavigationMode = "auto" | "manual" | "mixed";
132
-
133
- interface OonNavigationConfig {
134
- mode?: OonNavigationMode;
135
- items?: OonMenuItem[];
136
- }
137
- ```
138
-
139
- ## Collections no central.ui.json
140
-
141
- Atalho para coleções simples ou avançadas.
142
-
143
- ```ts
144
- interface OonCollectionManifestDef {
145
- model: string;
146
- mode?: "full" | "minimal" | "dynamic";
147
- path?: string;
148
- label?: string;
149
- section?: string;
150
- list?: OonCollectionListConfig;
151
- relations?: Record<string, OonRelationDef>;
152
- detailModal?: OonDetailModalConfig;
153
- }
154
- ```
155
-
156
- ### Exemplo simples
157
-
158
- ```json
159
- {
160
- "collections": [
161
- {
162
- "model": "Cliente",
163
- "mode": "dynamic",
164
- "path": "/clientes",
165
- "label": "Clientes",
166
- "section": "Cadastros"
167
- }
168
- ]
169
- }
170
- ```
171
-
172
- ### Exemplo avançado
173
-
174
- ```json
175
- {
176
- "collections": [
177
- {
178
- "model": "OrcamentoProjeto",
179
- "mode": "dynamic",
180
- "path": "/orcamentos-projetos",
181
- "label": "Orçamentos/Projetos",
182
- "section": "Operação",
183
- "list": {
184
- "filters": [
185
- {
186
- "field": "tipoRegistro",
187
- "label": "Tipo",
188
- "type": "select",
189
- "options": [
190
- { "label": "Todos", "value": "" },
191
- { "label": "Orçamento", "value": "Orçamento" },
192
- { "label": "Projeto", "value": "Projeto" }
193
- ]
194
- }
195
- ],
196
- "rowActions": [
197
- { "type": "openDetailModal", "icon": "edit", "label": "Editar", "initialTab": "resumo" }
198
- ]
199
- },
200
- "relations": {
201
- "itens": { "model": "OrcamentoItem", "foreignKey": "projetoId", "parentKey": "_id" },
202
- "pagamentos": { "model": "Pagamento", "foreignKey": "projetoId", "parentKey": "_id" }
203
- },
204
- "detailModal": {
205
- "enabled": true,
206
- "titleField": "nome",
207
- "defaultTab": "resumo",
208
- "tabs": []
209
- }
210
- }
211
- ]
212
- }
213
- ```
214
-
215
- ## list
216
-
217
- Configura filtros, colunas e ações do grid principal.
218
-
219
- ```ts
220
- interface OonCollectionListConfig {
221
- filters?: OonListFilterDef[];
222
- columns?: Array<string | OonColumnDef>;
223
- rowActions?: OonRowActionDef[];
224
- }
225
- ```
226
-
227
- ### list.filters
228
-
229
- ```json
230
- {
231
- "field": "tipoRegistro",
232
- "label": "Tipo",
233
- "type": "select",
234
- "options": [
235
- { "label": "Todos", "value": "" },
236
- { "label": "Orçamento", "value": "Orçamento" }
237
- ]
238
- }
239
- ```
240
-
241
- Tipos previstos:
242
-
243
- - `text`
244
- - `select`
245
- - `date`
246
- - `dateRange`
247
- - `numberRange`
248
- - `boolean`
249
- - `ref`
250
-
251
- ### list.rowActions
252
-
253
- ```json
254
- {
255
- "type": "openDetailModal",
256
- "label": "Editar",
257
- "icon": "edit",
258
- "initialTab": "resumo"
259
- }
260
- ```
261
-
262
- ## relations
263
-
264
- Relações nomeadas entre model pai e models filhos.
265
-
266
- ```json
267
- {
268
- "relations": {
269
- "itens": {
270
- "model": "OrcamentoItem",
271
- "foreignKey": "projetoId",
272
- "parentKey": "_id"
273
- }
274
- }
275
- }
276
- ```
277
-
278
- ## detailModal
279
-
280
- Configura modal de detalhe/criação com abas.
281
-
282
- ```ts
283
- interface OonDetailModalConfig {
284
- enabled?: boolean;
285
- titleField?: string;
286
- size?: "md" | "lg" | "xl" | "full";
287
- defaultTab?: string;
288
- tabs: OonDetailTabDef[];
289
- }
290
- ```
291
-
292
- ### Abas suportadas
293
-
294
- - `summary`
295
- - `form`
296
- - `relatedGrid`
297
- - `readonlyGrid`
298
- - `customComponent`
299
-
300
- ### Aba summary
301
-
302
- ```json
303
- {
304
- "id": "resumo",
305
- "label": "Resumo",
306
- "type": "summary",
307
- "cards": [
308
- { "label": "Itens", "source": "relatedCount", "relation": "itens" },
309
- { "label": "Total", "field": "total", "format": "currency" }
310
- ]
311
- }
312
- ```
313
-
314
- ### Aba form
315
-
316
- ```json
317
- {
318
- "id": "dados",
319
- "label": "Dados Principais",
320
- "type": "form",
321
- "groups": [
322
- { "label": "Identificação", "fields": ["codigo", "nome", "status"] }
323
- ]
324
- }
325
- ```
326
-
327
- ### Aba relatedGrid
328
-
329
- ```json
330
- {
331
- "id": "itens",
332
- "label": "Itens",
333
- "type": "relatedGrid",
334
- "relation": "itens",
335
- "editable": true,
336
- "editMode": "inline",
337
- "columns": [
338
- { "field": "item", "editable": true },
339
- { "field": "status", "editable": true },
340
- { "field": "total", "editable": true, "format": "currency" }
341
- ],
342
- "rowActions": []
343
- }
344
- ```
345
-
346
- ### Aba readonlyGrid
347
-
348
- ```json
349
- {
350
- "id": "pagamentos",
351
- "label": "Pagamentos",
352
- "type": "readonlyGrid",
353
- "relation": "pagamentos",
354
- "columns": ["codigo", "descricao", "status", "valor"]
355
- }
356
- ```
357
-
358
- ## rowActions
359
-
360
- Ações reutilizáveis em grid principal ou grids relacionados.
361
-
362
- ```ts
363
- interface OonRowActionDef {
364
- id?: string;
365
- label: string;
366
- icon?: string;
367
- type: "openDetailModal" | "navigate" | "apiAction" | "customAction";
368
- method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
369
- endpoint?: string;
370
- initialTab?: string;
371
- confirm?: { title?: string; description?: string };
372
- disabledWhen?: OonConditionDef;
373
- hiddenWhen?: OonConditionDef;
374
- refresh?: string[];
375
- roles?: string[];
376
- permissions?: string[];
377
- }
378
- ```
379
-
380
- ### apiAction
381
-
382
- ```json
383
- {
384
- "id": "gerarPagamento",
385
- "label": "Gerar pagamento",
386
- "type": "apiAction",
387
- "method": "POST",
388
- "endpoint": "/api/ss-eventos/orcamentos-itens/:id/gerar-pagamento",
389
- "disabledWhen": { "field": "pagamentoId", "exists": true },
390
- "refresh": ["self", "pagamentos", "resumo", "parent"]
391
- }
392
- ```
393
-
394
- ## CollectionViewDef completo
395
-
396
- Contrato interno completo quando a coleção já está em `ui.views` ou em blocos.
397
-
398
- ```ts
399
- interface CollectionViewDef {
400
- type: "collection";
401
- id?: string;
402
- model: string;
403
- label?: string;
404
- path?: string;
405
- icon?: ReactNode;
406
- section?: string;
407
- mode?: "full" | "minimal" | "dynamic";
408
- columns?: OonColumnDef[];
409
- form?: OonFormFieldDef[];
410
- importExport?: boolean;
411
- renderer?: string;
412
- cardRenderer?: string;
413
- actions?: OonActionDef[];
414
- permissions?: string[];
415
- list?: OonCollectionListConfig;
416
- relations?: Record<string, OonRelationDef>;
417
- detailModal?: OonDetailModalConfig;
418
- }
419
- ```
420
-
421
- ## Compatibilidade
422
-
423
- - Os campos `list`, `relations` e `detailModal` são opcionais.
424
- - Manifestos existentes continuam funcionando.
425
- - Sem `detailModal`, o Core mantém comportamento atual.
426
- - Sem `form.groups`, o Core mantém formulário padrão.
427
-
428
- ## UX avançada implementada
429
-
430
- Campos aceitos em `collections[]`:
431
-
432
- - `list.filters`: filtros acima do grid principal.
433
- - `list.columns`: colunas declarativas opcionais.
434
- - `list.rowActions`: ações por linha (`openDetailModal`, `navigate`, `apiAction`, `customAction`).
435
- - `relations`: mapa de relações `{ model, foreignKey, parentKey }`.
436
- - `detailModal`: modal genérica com `titleField`, `defaultTab`, `size` e `tabs`.
437
-
438
- Tipos de aba:
439
-
440
- - `summary`: cards com `field`, `relatedCount`, `relatedSum`, `relatedAvg` ou `customMetric`.
441
- - `form`: campos ou `groups` do registro principal.
442
- - `relatedGrid`: registros filhos, opcionalmente editáveis inline.
443
- - `readonlyGrid`: registros filhos sem edição.
444
- - `customComponent`: chave de componente registrado.
445
-
446
- `apiAction.endpoint` aceita `:id`, `:parentId`, `:fieldName` e `:parent.fieldName`. `refresh` aceita `self`, `parent`, `all` ou ids de abas.
447
-
448
-
449
- ## Opções remotas em campos de formulário
450
-
451
- Campos `enum` podem carregar opções de um endpoint dependente do formulário atual ou do registro pai. O contrato funciona em formulários principais e em criação/edição de `relatedGrid`.
452
-
453
- ```ts
454
- {
455
- field: "roleCode",
456
- label: "Perfil",
457
- kind: "enum",
458
- optionsEndpoint: "/control-plane/app-role-catalogs/:appId?tenantId=:parentId",
459
- optionsResponsePath: "options",
460
- optionsValueField: "value",
461
- optionsLabelField: "label",
462
- optionsDescriptionField: "description",
463
- optionsEditablePath: "editable",
464
- optionsDependsOn: ["appId", "tenantId"],
465
- fallbackOptions: [{ value: "admin", label: "Administrador" }],
466
- readonlyOnFallback: true,
467
- optionsUnavailableMessage: "Catálogo indisponível; perfil admin aplicado."
468
- }
469
- ```
470
-
471
- | Campo | Uso |
472
- | --- | --- |
473
- | `optionsEndpoint` | Endpoint relativo. Aceita `:field`, `:parentId` e `:parent.field`; valores são codificados para URL. |
474
- | `optionsResponsePath` | Caminho da lista na resposta. Sem valor, a própria resposta deve ser um array. |
475
- | `optionsValueField` | Campo usado como valor da opção; padrão `value`. |
476
- | `optionsLabelField` | Campo usado como rótulo; padrão `label`. |
477
- | `optionsDescriptionField` | Campo opcional de descrição. |
478
- | `optionsEditablePath` | Booleano remoto que permite ou bloqueia a edição. |
479
- | `optionsDependsOn` | Campos que precisam estar preenchidos e cuja mudança invalida a seleção atual. |
480
- | `fallbackOptions` | Opções seguras usadas quando o endpoint falha ou retorna lista vazia. |
481
- | `readonlyOnFallback` | Bloqueia a seleção durante o fallback; padrão `true`. |
482
- | `optionsUnavailableMessage` | Mensagem explicando o fallback ao usuário. |
483
- | `readonly` | Bloqueia o campo em qualquer estado. |
484
-
485
- Durante a edição, a interpolação também considera os valores iniciais completos do registro, inclusive campos somente leitura que não são renderizados no formulário. Valores alterados pelo usuário prevalecem sobre os valores iniciais.
486
-
487
- O backend continua responsável por validar o valor selecionado. Opções remotas melhoram a experiência, mas não substituem autorização nem validação de domínio.
File without changes
@@ -1,8 +0,0 @@
1
- {
2
- "schemaVersion": 2,
3
- "backend": { "metadataUrl": "/core/metadata" },
4
- "navigation": { "mode": "auto" },
5
- "collections": [],
6
- "pipelines": [],
7
- "documents": []
8
- }
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,21 +0,0 @@
1
- const { defineModel, fields } = require("@oondemand/oon-core-back");
2
-
3
- /**
4
- * Pessoa — domínio puro: só schema + CRUD. Auth, RBAC, paginação, auditoria e
5
- * metadata vêm do Core. A tela é renderizada pelo front a partir da metadata.
6
- */
7
- defineModel({
8
- name: "Pessoa",
9
- singular: "pessoa",
10
- basePath: "/pessoas",
11
- schema: {
12
- nome: fields.string({ required: true, label: "Nome" }),
13
- email: fields.string({ label: "E-mail" }),
14
- documento: fields.string({ label: "Documento" }),
15
- tipo: fields.enum(["pf", "pj"], { label: "Tipo", default: "pf" }),
16
- status: fields.enum(["ativo", "inativo"], { label: "Status", default: "ativo" }),
17
- },
18
- // A ativação de desenvolvimento concede o perfil "desenvolvedor".
19
- // O papel "admin" permanece autorizado globalmente pelo RBAC do Core.
20
- crud: { enabled: true, roles: { write: ["desenvolvedor"] } },
21
- });
@@ -1,8 +0,0 @@
1
- {
2
- "schemaVersion": 2,
3
- "backend": { "metadataUrl": "/core/metadata" },
4
- "navigation": { "mode": "auto" },
5
- "collections": [{ "model": "Pessoa", "mode": "dynamic" }],
6
- "pipelines": [],
7
- "documents": []
8
- }