@controleonline/ui-default 1.0.270 → 1.0.272

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 (89) hide show
  1. package/.github/workflows/integration-source-gate.yml +68 -0
  2. package/.github/workflows/manager-worker.yml +19 -0
  3. package/AGENTS.md +46 -50
  4. package/docs/technical/Contrato-de-colunas.md +67 -0
  5. package/docs/technical/Default-Components.md +76 -0
  6. package/docs/technical/DefaultForm.md +80 -0
  7. package/docs/technical/DefaultInput-e-DefaultSelect.md +73 -0
  8. package/docs/technical/DefaultTable.md +203 -0
  9. package/docs/wiki.md +1 -0
  10. package/package.json +22 -21
  11. package/scripts/validate-wiki-pointer.cjs +13 -0
  12. package/src/react/components/address/DefaultAddress.js +435 -0
  13. package/src/react/components/address/DefaultAddress.styles.js +133 -0
  14. package/src/react/components/address/DefaultAddressMapPane.js +55 -0
  15. package/src/react/components/address/LatLonReadonlyFields.js +51 -0
  16. package/src/react/components/address/defaultAddressHelpers.js +163 -0
  17. package/src/react/components/address/defaultAddressStyles.js +136 -0
  18. package/src/react/components/address/defaultAddressUtils.js +129 -0
  19. package/src/react/components/extra-data/DefaultExtraData.js +152 -0
  20. package/src/react/components/extra-data/DefaultExtraData.styles.js +61 -0
  21. package/src/react/components/files/DefaultFile.js +231 -46
  22. package/src/react/components/files/DefaultFileColumn.js +123 -0
  23. package/src/react/components/files/DefaultFileColumn.styles.js +52 -0
  24. package/src/react/components/files/DefaultFileColumn.utils.js +104 -0
  25. package/src/react/components/filters/CompactFilterSelector.js +51 -35
  26. package/src/react/components/filters/DefaultColumnFilter.js +58 -41
  27. package/src/react/components/filters/DefaultExternalFilters.js +331 -265
  28. package/src/react/components/form/DefaultForm.js +99 -79
  29. package/src/react/components/help/DefaultTooltip.js +59 -33
  30. package/src/react/components/help/DefaultTooltip.styles.js +23 -3
  31. package/src/react/components/inputs/DefaultColorInput.js +153 -0
  32. package/src/react/components/inputs/DefaultFeatherIconPicker.js +146 -0
  33. package/src/react/components/inputs/DefaultFeatherIconPicker.styles.js +113 -0
  34. package/src/react/components/inputs/DefaultInput.js +69 -5
  35. package/src/react/components/inputs/DefaultInput.styles.js +26 -0
  36. package/src/react/components/inputs/DefaultSelect.js +134 -123
  37. package/src/react/components/inputs/defaultInputUtils.js +69 -43
  38. package/src/react/components/map/DefaultMap.native.js +73 -73
  39. package/src/react/components/map/DefaultMap.shared.js +911 -762
  40. package/src/react/components/map/DefaultMap.web.js +124 -68
  41. package/src/react/components/table/DefaultColumnMenu.js +109 -108
  42. package/src/react/components/table/DefaultDebug.js +44 -37
  43. package/src/react/components/table/DefaultSearchModal.js +9 -1
  44. package/src/react/components/table/DefaultTable.grouping.js +98 -0
  45. package/src/react/components/table/DefaultTable.js +213 -107
  46. package/src/react/components/table/DefaultTable.styles.js +367 -314
  47. package/src/react/components/table/DefaultTableBody.js +13 -8
  48. package/src/react/components/table/DefaultTableCards.js +20 -1
  49. package/src/react/components/table/DefaultTableControls.js +180 -205
  50. package/src/react/components/table/DefaultTableImportModal.js +108 -0
  51. package/src/react/components/table/DefaultTableInput.js +1 -0
  52. package/src/react/components/table/DefaultTableRowActions.js +1 -1
  53. package/src/react/components/table/DefaultTableRows.js +224 -363
  54. package/src/react/components/table/DefaultTableSearch.js +28 -5
  55. package/src/react/components/table/DefaultTableToolbar.js +92 -3
  56. package/src/react/components/table/useDefaultTablePagination.js +56 -7
  57. package/src/react/components/table/useDefaultTableStoreSync.js +164 -0
  58. package/src/react/components/upload/DefaultUpload.js +436 -0
  59. package/src/react/components/upload/DefaultUpload.styles.js +153 -0
  60. package/src/react/components/upload/DefaultUploadAttachmentsList.js +138 -0
  61. package/src/react/components/upload/DefaultUploadManagerModal.js +247 -0
  62. package/src/react/components/upload/defaultUploadHelpers.js +108 -0
  63. package/src/react/components/upload/defaultUploadLibrary.js +248 -0
  64. package/src/react/components/upload/fileUpload.js +93 -0
  65. package/src/react/hooks/usePostalCodeLookup.js +145 -0
  66. package/src/react/index.js +6 -0
  67. package/src/react/services/addressFormUtils.js +196 -0
  68. package/src/react/services/addressGeo.js +227 -0
  69. package/src/react/utils/tableVisibleColumnsPreferences.js +29 -12
  70. package/src/tests/react/components/address/defaultAddressHelpers.test.js +104 -0
  71. package/src/tests/react/components/files/DefaultFile.test.js +6 -6
  72. package/src/tests/react/components/form/DefaultForm.test.js +123 -0
  73. package/src/tests/react/components/inputs/DefaultSelect.test.js +108 -79
  74. package/src/tests/react/components/table/DefaultTable.grouping.test.js +49 -0
  75. package/src/tests/react/components/table/DefaultTable.test.js +53 -2
  76. package/src/tests/react/components/table/DefaultTableControls.filters.test.mjs +21 -0
  77. package/src/tests/react/components/table/resolveRowBackgroundColor.test.mjs +45 -0
  78. package/src/tests/react/components/table/useDefaultTableStoreSync.test.js +161 -0
  79. package/src/tests/react/components/upload/DefaultUpload.test.js +353 -0
  80. package/src/tests/react/components/upload/defaultUploadLibrary.test.js +82 -0
  81. package/src/tests/react/components/upload/peopleMediaLibraryPreview.test.mjs +57 -0
  82. package/src/tests/react/hooks/usePostalCodeLookup.test.js +40 -0
  83. package/src/tests/react/services/SMOKE-637-cep-hydrate.md +45 -0
  84. package/src/tests/react/services/addressFormUtils.test.js +176 -0
  85. package/src/tests/react/services/addressGeoLookup.async.test.js +104 -0
  86. package/src/tests/react/services/addressGeoLookup.test.js +105 -0
  87. package/src/tests/react/services/smoke-637/form-cep-12941040.png +0 -0
  88. package/src/tests/react/services/smoke-637/index.html +132 -0
  89. package/src/tests/react/utils/tableVisibleColumnsPreferences.test.js +84 -48
@@ -0,0 +1,68 @@
1
+ name: Integration source gate
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [dev, staging, master]
6
+ types: [opened, synchronize, reopened, edited, ready_for_review]
7
+
8
+ permissions:
9
+ contents: read
10
+ pull-requests: read
11
+
12
+ jobs:
13
+ source-policy:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Enforce task or frozen RC source
17
+ env:
18
+ HEAD_REF: ${{ github.head_ref }}
19
+ BASE_REF: ${{ github.base_ref }}
20
+ run: |
21
+ set -eu
22
+ if [ "$BASE_REF" = "dev" ]; then
23
+ echo "$HEAD_REF" | grep -Eq '^task-[1-9][0-9]*$' || {
24
+ echo "::error::dev only accepts task-<numeric issue>."
25
+ exit 1
26
+ }
27
+ exit 0
28
+ fi
29
+ echo "$HEAD_REF" | grep -Eq '^rc/[0-9]+\.[0-9]+\.[0-9]+-rc\.[1-9][0-9]*$' || {
30
+ echo "::error::$BASE_REF only accepts a frozen rc/X.Y.Z-rc.N source."
31
+ exit 1
32
+ }
33
+
34
+ - uses: actions/checkout@v4
35
+ if: github.base_ref != 'dev'
36
+ with:
37
+ ref: ${{ github.head_ref }}
38
+
39
+ - name: Validate frozen RC manifest
40
+ if: github.base_ref != 'dev'
41
+ env:
42
+ HEAD_REF: ${{ github.head_ref }}
43
+ run: |
44
+ set -eu
45
+ test -f .release/rc-manifest.json || {
46
+ echo "::error::Missing .release/rc-manifest.json"
47
+ exit 1
48
+ }
49
+ node --input-type=module <<'NODE'
50
+ import fs from 'node:fs';
51
+ const m = JSON.parse(fs.readFileSync('.release/rc-manifest.json', 'utf8'));
52
+ const branch = process.env.HEAD_REF;
53
+ const match = /^rc\/(\d+\.\d+\.\d+)-rc\.([1-9][0-9]*)$/.exec(branch);
54
+ if (!match) throw new Error('invalid RC branch');
55
+ if (m.branch !== branch || m.version !== match[1] || Number(m.rc) !== Number(match[2])) throw new Error('manifest identity mismatch');
56
+ if (m.frozen !== true) throw new Error('manifest is not frozen');
57
+ if (!Array.isArray(m.tasks) || m.tasks.length < 1 || m.tasks.length > 5) throw new Error('RC must contain 1..5 tasks');
58
+ const tasks = m.tasks.map(Number);
59
+ if (tasks.some((id) => !Number.isInteger(id) || id < 1)) throw new Error('invalid task id');
60
+ if (new Set(tasks).size !== tasks.length) throw new Error('duplicate RC tasks');
61
+ if (!/^[0-9a-f]{40}$/i.test(String(m.baseMaster || ''))) throw new Error('invalid baseMaster');
62
+ const repos = m.repositories || {};
63
+ if (!Object.keys(repos).length) throw new Error('empty repositories manifest');
64
+ for (const [repo, sha] of Object.entries(repos)) {
65
+ if (!/^ControleOnline\/[A-Za-z0-9_.-]+$/.test(repo) || !/^[0-9a-f]{40}$/i.test(String(sha))) throw new Error('invalid repository manifest entry');
66
+ }
67
+ console.log('Frozen RC manifest valid:', branch, tasks);
68
+ NODE
@@ -0,0 +1,19 @@
1
+ name: Manager Worker
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ # PAUSA CTO ControleOnline/agents-mcp#201 (2026-08-29)
7
+ # Trigger original desativado: push em master, dev, staging.
8
+
9
+ permissions:
10
+ contents: read
11
+ issues: write
12
+ pull-requests: write
13
+
14
+ jobs:
15
+ manager:
16
+ name: Manager — paused
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - run: echo "Manager Worker paused by ControleOnline/agents-mcp#201"
package/AGENTS.md CHANGED
@@ -1,50 +1,46 @@
1
- # ui-default
2
-
3
- ## Escopo
4
-
5
- - Biblioteca base de componentes reutilizaveis do front.
6
- - `DefaultTable` e o shell canonico de listagens React deste sistema.
7
-
8
- ## Contrato do DefaultTable
9
-
10
- - A tela deve passar preferencialmente apenas `storeName` e contexto minimo, como `requestParams`, `onRowPress`, `renderCard`, `onAdd`, `onEdit` ou componentes extras realmente especificos.
11
- - O componente pode receber componentes de composicao para variacoes visuais, como `renderCard`, add personalizado, toolbar customizada, acoes auxiliares e modais de apoio; isso nao muda o contrato de que a listagem continua sendo responsabilidade do `DefaultTable`.
12
- - Quando `data` nao e informada e existe `storeName`, o `DefaultTable` trabalha em modo automatico e carrega os itens pelas actions do store.
13
- - O componente e responsavel por busca, ordenacao, filtros, paginação, infinite scroll, loading, erro, resumo, visibilidade de colunas, modo desktop e modo card no mobile.
14
- - Preferencias de usuario do `DefaultTable`, incluindo filtros, busca, ordenacao, modo de exibicao e visibilidade de colunas, devem ser salvas em `localStorage` na chave `default-table`, sempre no formato `[store][rota] = valores`. Nunca usar chave apenas por store ou apenas por rota.
15
- - O store nao e fallback: ele e a regra. Se `columns` define um comportamento, o `DefaultTable` deve obedecer sem recriar uma segunda regra na tela.
16
- - `columns` e a fonte de verdade para label, visibilidade, ordem, `editable`, `sortable`, `inputType`, `list`, `format`, `formatList`, `formatFilter`, `saveFormat`, `searchParam`, `externalFilter`, `summary` e `defaultSort`. `show:false` e um alias aceito para ocultar coluna, junto com `visible:false` e `table:false`.
17
- - Se uma coluna vier como `editable: false`, ela continua nao editavel mesmo que seja ordenavel. Se vier como `sortable: true`, a ordenacao precisa continuar funcionando.
18
- - `inputType: 'date-range'` exige filtro de intervalo. `externalFilter: true` habilita o filtro externo quando a listagem suporta esse contrato.
19
- - Campos `list` e selects com listas nao devem ser pre-carregados no mount nem na abertura do modal inteiro. O carregamento das opcoes acontece no `onBeforeOpen` do proprio campo ou filtro, para evitar requests globais desnecessarios.
20
- - Nada de search local, sort local, paginacao manual, contador local, total calculado por `reduce` ou cards paralelos quando o `DefaultTable` ja puder resolver isso pelo store.
21
- - `requestParams` serve para contexto fixo do fluxo, nao para duplicar estado de filtro que ja vive no store.
22
- - `pageSize` so deve ser usado quando o contrato externo exigir e com justificativa clara no modulo.
23
- - `summary` e `totalItems` vem do backend/store e pertencem ao rodape interno do `DefaultTable`.
24
- - `add: true` abre o `DefaultForm` quando a tela nao prover `onAdd`.
25
- - `rowActionsComponent` e o slot canonico para acoes por linha quando a tela precisa renderizar mais do que o botao padrao de edicao. Ele pode ser componente, funcao ou elemento React, recebe `row`, `storeName`, `openEdit`, `openRow` e `helpers`, e a largura da coluna deve ser ajustada com `rowActionsWidth` quando houver mais de uma acao.
26
- - O modo controlado continua existindo apenas para excecoes reais de integracao; o padrao do sistema e o modo store-driven.
27
- - Loadings e erros devem seguir o fluxo central do sistema, sem banners ou estados paralelos na tela.
28
- - O `get` do store default pode preservar o `item` atual durante refresh quando receber `__storeMeta.preserveItem = true`; use esse modo quando a tela precisa atualizar o registro sem desmontar o detalhe em exibição.
29
- - Explicacoes permanentes de tela devem sair do corpo principal e ir para o `DefaultTooltip`, acionado por `?`, quando houver contexto necessario para o usuario.
30
-
31
- ## Componentes de feedback
32
-
33
- - `StateStore` e o shell compartilhado para loading e saving de tela/seção.
34
- - O `mode` do `StateStore` e um preset generico do shell e pode variar conforme a tela; exemplos validos incluem `compact`, `display` e outros modos reais do fluxo.
35
- - `DefaultErrors` e o shell compartilhado para erro local/inline de tela ou tab; ele lê o `error` dos stores informados, aparece como popup, auto-fecha em 5 segundos e limpa o erro do store ao ser fechado.
36
- - `showError` continua sendo feedback transitório global; nao deve substituir `DefaultErrors` quando o erro for inline ou local.
37
- - Telas e componentes visuais nao devem usar `ActivityIndicator` direto quando o estado puder ser representado por `StateStore`.
38
- - O contrato de explicacao permanente continua sendo `DefaultTooltip`, sempre acionado por `?` e fora do corpo principal da tela.
39
-
40
- ## Arquivos e imagens
41
-
42
- - `DefaultFile` e o componente compartilhado para arquivos/imagens vindos do backend.
43
- - Quando a fonte for um arquivo de download do backend, o componente deve resolver a URL com `app-domain=<dominio configurado>` e enviar o mesmo valor em `headers` quando a plataforma permitir.
44
- - Telas que exibem logo, fundo, avatar, banner ou qualquer arquivo de empresa devem preferir `DefaultFile` em vez de `Image` direto quando o contrato vier do backend.
45
-
46
- ## Regra de uso
47
-
48
- - Telas antigas devem ser simplificadas para passar o store e apenas as excecoes declarativas que o store nao cobre.
49
- - Se a listagem precisa de outra regra de exibicao, a primeira opcao e mover essa regra para `columns` ou para o store correspondente.
50
- - Se duas telas repetem a mesma logica de listagem, a resposta e um componente default ou um ajuste no `DefaultTable`, nunca uma copia local do comportamento.
1
+ ## Ponto de entrada
2
+
3
+ - A documentação funcional e de regras deste modulo vive na **wiki do proprio repositório** e na wiki principal do app.
4
+ - Regras transversais de qualidade, modularizacao e limites de componente vivem em `https://github.com/ControleOnline/agents-mcp/blob/master/skills/shared/code-quality.md`.
5
+ - Quando houver detalhe especifico de implementacao, prefira comentar no codigo em ingles perto da regra.
6
+ - Este arquivo deve ficar curto e servir apenas como ponte para as fontes oficiais.
7
+
8
+ ## Documentação (navegação humana)
9
+
10
+ | Categoria | Destino |
11
+ | --- | --- |
12
+ | Home do módulo | https://github.com/ControleOnline/ui-default/wiki |
13
+ | Wiki principal do app | https://github.com/ControleOnline/app-community/wiki |
14
+
15
+ ### Componentes Default*
16
+
17
+ | Página | O que documenta |
18
+ | --- | --- |
19
+ | [Índice Default*](https://github.com/ControleOnline/ui-default/wiki/Default-Components) | Mapa da família e arquitetura |
20
+ | [DefaultTable](https://github.com/ControleOnline/ui-default/wiki/DefaultTable) | Listagens, store contract, view modes |
21
+ | [DefaultForm](https://github.com/ControleOnline/ui-default/wiki/DefaultForm) | Create/edit genérico |
22
+ | [DefaultInput e DefaultSelect](https://github.com/ControleOnline/ui-default/wiki/DefaultInput-e-DefaultSelect) | Campos e listas |
23
+ | [Contrato de colunas](https://github.com/ControleOnline/ui-default/wiki/Contrato-de-colunas) | Flags e serialização |
24
+
25
+ Cópias versionadas: `docs/technical/*.md`
26
+
27
+ ### Visão deste módulo
28
+
29
+ `ui-default` é a **biblioteca de UI genérica** (tabela, form, inputs, filtros, upload, mapa) consumida pelos submódulos do `app-community`. Não carrega regra de domínio de um `APP_TYPE` específico; o domínio entra via `storeName` + `columns`.
30
+
31
+ ### DefaultUpload (app-community#296)
32
+
33
+ | Página / arquivo | O que documenta |
34
+ | --- | --- |
35
+ | `src/react/components/upload/DefaultUpload.js` | Mini gerenciador de arquivos por **contexto** (biblioteca + anexos da entidade) |
36
+ | `DefaultUploadManagerModal.js` | Modal de biblioteca / upload / attach |
37
+ | `DefaultUploadAttachmentsList.js` | Lista inline de anexos + capa |
38
+ | `defaultUploadHelpers.js` / `defaultUploadLibrary.js` / `fileUpload.js` | Helpers puros e fetch da biblioteca |
39
+
40
+ **Contrato de uso**
41
+
42
+ - Props principais: `context` (obrigatório — escopo dos arquivos), `companyId` / people da empresa, `entityId` + `relationResource` / `relationField` para vínculo, `fileActions` / `relationActions` (stores), `fileType`, `maxFiles`, `attachmentRows`, callbacks `onChanged` / `onCoverChanged` / `onAttachFile` / `onUploadFile`.
43
+ - Todo upload abre o mini gerenciador já limitado ao `context` (e `people` da company quando informado).
44
+ - Listagem da biblioteca chama `fileActions.getItems({ context, people, ... })` — o backend aplica `FileService::securityFilter` (company-scoped).
45
+ - Não chamar API de files diretamente nas telas consumidoras; usar stores/actions.
46
+ - Reutilizar `DefaultFile` para preview/download.
@@ -0,0 +1,67 @@
1
+ # Contrato de colunas (`defaultInputUtils`)
2
+
3
+ **Arquivo:** `src/react/components/inputs/defaultInputUtils.js`
4
+
5
+ A coluna é o **contrato de UI + serialização** compartilhado por Table, Form e Inputs.
6
+
7
+ ## Identidade
8
+
9
+ | Campo | Uso |
10
+ | --- | --- |
11
+ | `key` ou `name` | Nome do campo (`getColumnKey`) |
12
+ | `label` | Rótulo (i18n via `formatStoreColumnLabel`) |
13
+ | `isIdentity` | PK visual; fora do form; largura própria na tabela |
14
+
15
+ ## Visibilidade e edição
16
+
17
+ | Flag | Efeito |
18
+ | --- | --- |
19
+ | `show` / `visible` / `table` | Inclusão na tabela (`shouldIncludeColumn` em utils da table) |
20
+ | `form` | `false` remove do form |
21
+ | `add` | `false` remove do create |
22
+ | `editable` | `false` bloqueia edição |
23
+ | `visibleForm` | bool ou fn |
24
+ | `multiline` | excluído do DefaultForm atual |
25
+ | `sortable` / `sortField` / `defaultSort` | Sort |
26
+ | `summary` | Agregações no footer |
27
+
28
+ ## Tipos de input
29
+
30
+ | `inputType` / `type` | Comportamento |
31
+ | --- | --- |
32
+ | `date` / `date-range` / `range-date` | `DefaultDateInput`; save via `Formatter` |
33
+ | `color` / `hexcolor` ou nome color-like | `DefaultColorInput` |
34
+ | `file` / `image` / `document` / … | `DefaultFileColumn` (não editável inline) |
35
+ | `extradata` | `DefaultExtraData` |
36
+ | `number` / `float` | teclado numérico |
37
+ | `increase` | não editável |
38
+
39
+ ## Listas (select)
40
+
41
+ | Campo | Uso |
42
+ | --- | --- |
43
+ | `list` | Array local **ou** `"store/action"` |
44
+ | `listRequestParams` | Filtros extras do load |
45
+ | `listSearchParam` / `searchParam` | Query de busca |
46
+ | `formatList` | Normaliza item → label/meta |
47
+ | `translate` | Força/desliga i18n de labels de opção |
48
+
49
+ ## Formatação
50
+
51
+ | Campo | Uso |
52
+ | --- | --- |
53
+ | `format` | Apresentação de célula (pode retornar objeto com color/icon) |
54
+ | `editFormat` | Valor ao entrar em edição |
55
+ | `saveFormat` | Valor ao persistir |
56
+ | `prefix` / `sufix`/`suffix` | Decoração textual |
57
+ | `style` | estilo estático ou fn(row) |
58
+ | `width` / `minWidth` / `flexBasis` | Layout de coluna na table |
59
+ | `defaultValue` / `initialValue` / `defaultColor` | Defaults de form/cor |
60
+
61
+ ## Helpers exportados (referência rápida)
62
+
63
+ `normalizeText`, `getColumnKey`, `isEditableColumn`, `isDateLikeColumn`, `isColorColumn`, `isFileColumn`, `isExtraDataColumn`, `normalizeId`, `normalizeOptionKey`, `mapOptions`, `buildOptionsFromColumn`, `resolveCellText`, `resolveCellPresentation`, `buildReadPresentationStyles`, `resolveEditValue`, `formatSaveValue`, `resolveStoreNameFromList`, `resolveColorToken`
64
+
65
+ ## Campos traduzíveis por convenção
66
+
67
+ Sem `translate: true`, ainda traduz labels de opção se o nome do campo estiver em: `active`, `app`, `channel`, `status`, `ordertype`, `peopletype`, etc. (`DEFAULT_TRANSLATABLE_FIELDS`).
@@ -0,0 +1,76 @@
1
+ # Componentes Default* (`ui-default`)
2
+
3
+ Documentação técnica da família de componentes genéricos do módulo **`ControleOnline/ui-default`**.
4
+
5
+ > Público: desenvolvedores e agents internos.
6
+ > Issue: `ControleOnline/ui-default#2`.
7
+
8
+ ## Objetivo do módulo
9
+
10
+ `ui-default` concentra UI reutilizável orientada a **stores** (`useStore(storeName)`): tabelas, formulários, inputs, filtros, upload, mapas e anexos. O contrato central é a **definição de colunas** (`columns`) + estado do store (`items`, `filters`, `configs`, `actions`).
11
+
12
+ ```mermaid
13
+ flowchart TB
14
+ subgraph app [Módulo de domínio]
15
+ Page[Page / Screen]
16
+ Store[useStore storeName]
17
+ end
18
+ subgraph defaults [ui-default]
19
+ DT[DefaultTable]
20
+ DF[DefaultForm]
21
+ DI[DefaultInput]
22
+ DS[DefaultSelect]
23
+ end
24
+ Page --> DT
25
+ Page --> DF
26
+ DT --> Store
27
+ DF --> DI
28
+ DI --> DS
29
+ DI --> Store
30
+ DS --> Store
31
+ ```
32
+
33
+ ## Mapa de componentes
34
+
35
+ | Família | Componentes principais | Pasta |
36
+ | --- | --- | --- |
37
+ | Tabela | `DefaultTable`, Body, Rows, Cards, Toolbar, Footer, Search, Controls… | `src/react/components/table/` |
38
+ | Formulário | `DefaultForm` | `src/react/components/form/` |
39
+ | Inputs | `DefaultInput`, `DefaultSelect`, `DefaultDateInput`, `DefaultColorInput`, `DefaultFeatherIconPicker` | `src/react/components/inputs/` |
40
+ | Filtros | `DefaultSearch`, `DefaultColumnFilter`, `DefaultExternalFilters`, `DateShortcutFilter`, `CompactFilterSelector` | `src/react/components/filters/` |
41
+ | Arquivos | `DefaultFile`, `DefaultFileColumn` | `src/react/components/files/` |
42
+ | Upload | `DefaultUpload` | `src/react/components/upload/` |
43
+ | Extra | `DefaultExtraData` | `src/react/components/extra-data/` |
44
+ | Erros | `DefaultErrors` | `src/react/components/errors/` |
45
+ | Ajuda | `DefaultTooltip` | `src/react/components/help/` |
46
+ | Mapa | `DefaultMap`, `DefaultGoogleMap`, `DefaultNativeMap` | `src/react/components/map/` |
47
+
48
+ ## Páginas detalhadas
49
+
50
+ | Página | Conteúdo |
51
+ | --- | --- |
52
+ | [DefaultTable](DefaultTable) | Orquestração, props, store contract, view modes, preferências |
53
+ | [DefaultForm](DefaultForm) | Create/edit, draft, payload de save |
54
+ | [DefaultInput-e-DefaultSelect](DefaultInput-e-DefaultSelect) | Roteamento por tipo de coluna, list remote, apresentação |
55
+ | [Contrato-de-colunas](Contrato-de-colunas) | Flags e helpers de `defaultInputUtils` |
56
+
57
+ ## Dependências transversais
58
+
59
+ - `@store` — `useStore` / `getAllStores`
60
+ - `@controleonline/ui-common` — `MessageService`, `Formatter`, `formatStoreColumnLabel` / `formatStoreColumnValue`, date range helpers
61
+ - `@react-navigation/native` — foco e escopo de preferências da tabela
62
+ - Tema via store `theme` e tokens em `useDefaultTableTheme`
63
+
64
+ ## Quando usar
65
+
66
+ | Situação | Preferir |
67
+ | --- | --- |
68
+ | Listagem CRUD ligada a store com `getItems` / `save` | `DefaultTable` (+ `DefaultForm` no modal de add/edit) |
69
+ | Campo isolado em tela custom | `DefaultInput` / `DefaultSelect` |
70
+ | Upload de arquivos | `DefaultUpload` |
71
+ | Mapa web/native | família `DefaultMap*` |
72
+
73
+ ## Não objetivos
74
+
75
+ - Não substituir telas de domínio com regras de negócio específicas sem `columns`/`store`.
76
+ - Não publicar esta documentação na Central de Ajuda do cliente (`tutorial-assistant`); é documentação **técnica**.
@@ -0,0 +1,80 @@
1
+ # DefaultForm
2
+
3
+ Formulário genérico create/edit orientado a **colunas** e `actions.save`.
4
+
5
+ **Arquivo:** `src/react/components/form/DefaultForm.js`
6
+
7
+ ## Responsabilidade
8
+
9
+ - Filtrar colunas elegíveis ao formulário
10
+ - Montar **draft** a partir da row / defaults
11
+ - Salvar apenas campos alterados (edit) ou preenchidos (create)
12
+ - Renderizar cada campo com `DefaultInput` em `variant="form"`
13
+
14
+ ## Props
15
+
16
+ | Prop | Default | Função |
17
+ | --- | --- | --- |
18
+ | `storeName` | `''` | i18n de labels/botões |
19
+ | `columns` | `[]` | Definição de campos |
20
+ | `row` | `{}` | Registro em edição |
21
+ | `mode` | `'edit'` | `'create'` \| `'edit'` |
22
+ | `actions` | `{}` | Precisa de `actions.save(payload)` |
23
+ | `getOptionsForColumn` | null | Options locais |
24
+ | `onBeforeOpen` | null | Antes de abrir select (`(column) => ...`) |
25
+ | `onCancel` | null | Cancelar |
26
+ | `onSaved` | null | `(savedItem, previousRow) => ...` |
27
+
28
+ ## Inclusão de coluna no form
29
+
30
+ `shouldIncludeColumn(column, row, mode)`:
31
+
32
+ - precisa de `key`/`name`
33
+ - **exclui** `isIdentity === true`
34
+ - **exclui** `form === false` ou `multiline === true`
35
+ - em `create`: respeita `add === false`
36
+ - em `edit`: exige `isEditableColumn(column)`
37
+ - `visibleForm` (bool ou fn `(row, column) => boolean`)
38
+
39
+ ## Draft e defaults
40
+
41
+ Ordem em `resolveDefaultValue`:
42
+
43
+ 1. `row[field]`
44
+ 2. `column.defaultValue` (valor ou fn)
45
+ 3. `column.initialValue` (valor ou fn)
46
+
47
+ `resolveEditValue` normaliza para edição (list → option key, date → dmY, `editFormat`).
48
+
49
+ ## Payload de save
50
+
51
+ **Create:** objeto só com campos que `hasValue`.
52
+ **Edit:** sempre inclui `id` (`@id` ou `id` normalizado) + campos cujo texto normalizado **mudou**.
53
+
54
+ `formatSaveValue(column, value, row)`:
55
+
56
+ - `column.saveFormat` se existir
57
+ - objetos com `value` / `@id`
58
+ - datas → formato americano via `Formatter`
59
+ - números quando aplicável
60
+
61
+ Se não há nada a salvar → chama `onCancel` e não bate no backend.
62
+
63
+ ## UI
64
+
65
+ - Grid scrollável de campos
66
+ - Botões Cancelar / Salvar (tema: store `theme`)
67
+ - Estado `isSaving` desabilita botão primário
68
+
69
+ ## Exemplo
70
+
71
+ ```jsx
72
+ <DefaultForm
73
+ mode="create"
74
+ storeName="customers"
75
+ columns={store.getters.columns}
76
+ actions={{ save: store.actions.save }}
77
+ onCancel={close}
78
+ onSaved={(item) => { close(); refresh(); }}
79
+ />
80
+ ```
@@ -0,0 +1,73 @@
1
+ # DefaultInput e DefaultSelect
2
+
3
+ Camada de campo único usada por **tabela** (`variant="cell"`) e **form** (`variant="form"`).
4
+
5
+ ## DefaultInput
6
+
7
+ **Arquivo:** `src/react/components/inputs/DefaultInput.js`
8
+
9
+ ### Roteamento por tipo de coluna
10
+
11
+ | Condição | Componente |
12
+ | --- | --- |
13
+ | `column.list` truthy | `DefaultSelect` |
14
+ | `isColorColumn(column)` | `DefaultColorInput` |
15
+ | `isDateLikeColumn(column)` | `DefaultDateInput` |
16
+ | leitura + extra data | `DefaultExtraData` |
17
+ | leitura + file | `DefaultFileColumn` |
18
+ | senão | `TextInput` ou modo leitura com badge/ícone/imagem |
19
+
20
+ ### Props relevantes
21
+
22
+ | Prop | Função |
23
+ | --- | --- |
24
+ | `column` / `columns` / `row` | Contrato de coluna e contexto |
25
+ | `editing` | Alterna leitura × edição (cell) |
26
+ | `variant` | `'cell'` \| `'form'` |
27
+ | `autoSave` | `true`: `onSave` no blur/submit; `false`: só `onChangeValue` |
28
+ | `onStartEditing` / `onCancelEditing` / `onSave` | Ciclo de edição inline |
29
+ | `getOptionsForColumn` | Options injetadas |
30
+ | `showLabel` | Label acima do campo |
31
+ | `displayValue` | Override de texto lido |
32
+ | `accentColor` / `defaultColor` | Tema / cor default |
33
+
34
+ ### Modo leitura
35
+
36
+ - `resolveCellText` + `resolveCellPresentation` (cor, ícone Feather, image, badge)
37
+ - Ícone de editar se `isEditableColumn` e existe `onStartEditing`
38
+ - Prefixo/sufixo da coluna
39
+
40
+ ### Modo edição texto
41
+
42
+ - `keyboardType` numérico se `inputType` number/float
43
+ - Cancel (X) só fora de form
44
+
45
+ ## DefaultSelect
46
+
47
+ **Arquivo:** `src/react/components/inputs/DefaultSelect.js`
48
+
49
+ ### Fontes de opções
50
+
51
+ 1. `getOptionsForColumn(column)`
52
+ 2. `column.list` como **array** estática
53
+ 3. `column.list` como string `"storeName/actionName"` → `getAllStores()[store].actions[action]`
54
+ 4. Cache em memória por chave serializada de params
55
+
56
+ ### Params de load remoto
57
+
58
+ `resolveColumnListLoadParams`:
59
+
60
+ - escopo empresa para `categories` (`company`), `paymentType` / `wallet` (`people`)
61
+ - `column.listRequestParams` (objeto ou fn)
62
+ - busca: `listSearchParam` \|\| `searchParam` \|\| `'search'`
63
+
64
+ ### UX
65
+
66
+ - Toque abre `Modal` com busca e lista
67
+ - `autoSave`: `onSave({ value, label, object })`
68
+ - form: `onChangeValue(key, meta)`
69
+ - `onBeforeOpen` pode pré-carregar items
70
+
71
+ ### Meta visual de opção
72
+
73
+ `formatList` / item pode expor `color`, `icon`, `image` para badges na lista e no valor selecionado.