@controleonline/ui-default 1.0.270 → 1.0.273
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/.github/workflows/integration-source-gate.yml +68 -0
- package/.github/workflows/manager-worker.yml +19 -0
- package/.github/workflows/publish-npm.yml +91 -0
- package/AGENTS.md +46 -50
- package/docs/technical/Contrato-de-colunas.md +67 -0
- package/docs/technical/Default-Components.md +76 -0
- package/docs/technical/DefaultForm.md +80 -0
- package/docs/technical/DefaultInput-e-DefaultSelect.md +73 -0
- package/docs/technical/DefaultTable.md +272 -0
- package/docs/wiki.md +1 -0
- package/package.json +4 -3
- package/scripts/validate-wiki-pointer.cjs +13 -0
- package/src/react/components/address/DefaultAddress.js +446 -0
- package/src/react/components/address/DefaultAddress.styles.js +133 -0
- package/src/react/components/address/DefaultAddressCoordFields.js +59 -0
- package/src/react/components/address/DefaultAddressMapPane.js +55 -0
- package/src/react/components/address/LatLonReadonlyFields.js +51 -0
- package/src/react/components/address/defaultAddressHelpers.js +163 -0
- package/src/react/components/address/defaultAddressStyles.js +148 -0
- package/src/react/components/address/defaultAddressUtils.js +129 -0
- package/src/react/components/extra-data/DefaultExtraData.js +152 -0
- package/src/react/components/extra-data/DefaultExtraData.styles.js +61 -0
- package/src/react/components/files/DefaultFile.js +231 -46
- package/src/react/components/files/DefaultFileColumn.js +123 -0
- package/src/react/components/files/DefaultFileColumn.styles.js +52 -0
- package/src/react/components/files/DefaultFileColumn.utils.js +104 -0
- package/src/react/components/filters/CompactFilterSelector.js +51 -35
- package/src/react/components/filters/DefaultColumnFilter.js +60 -48
- package/src/react/components/filters/DefaultExternalFilters.js +324 -265
- package/src/react/components/filters/filterValue.js +65 -0
- package/src/react/components/form/DefaultForm.js +99 -79
- package/src/react/components/help/DefaultTooltip.js +48 -12
- package/src/react/components/help/DefaultTooltip.styles.js +20 -0
- package/src/react/components/inputs/DefaultColorInput.js +153 -0
- package/src/react/components/inputs/DefaultFeatherIconPicker.js +146 -0
- package/src/react/components/inputs/DefaultFeatherIconPicker.styles.js +113 -0
- package/src/react/components/inputs/DefaultInput.js +296 -141
- package/src/react/components/inputs/DefaultInput.styles.js +26 -0
- package/src/react/components/inputs/DefaultSelect.js +134 -123
- package/src/react/components/inputs/defaultInputUtils.js +262 -213
- package/src/react/components/map/DefaultMap.native.js +73 -73
- package/src/react/components/map/DefaultMap.shared.js +911 -762
- package/src/react/components/map/DefaultMap.web.js +124 -68
- package/src/react/components/table/DefaultColumnMenu.js +22 -3
- package/src/react/components/table/DefaultDebug.js +44 -37
- package/src/react/components/table/DefaultSearchModal.js +9 -1
- package/src/react/components/table/DefaultTable.grouping.js +98 -0
- package/src/react/components/table/DefaultTable.js +217 -111
- package/src/react/components/table/DefaultTable.styles.js +369 -310
- package/src/react/components/table/DefaultTable.utils.js +38 -4
- package/src/react/components/table/DefaultTableBody.js +13 -8
- package/src/react/components/table/DefaultTableCards.js +20 -1
- package/src/react/components/table/DefaultTableControls.js +180 -205
- package/src/react/components/table/DefaultTableImportModal.js +108 -0
- package/src/react/components/table/DefaultTableInput.js +1 -0
- package/src/react/components/table/DefaultTableRowActions.js +1 -1
- package/src/react/components/table/DefaultTableRows.js +357 -325
- package/src/react/components/table/DefaultTableSearch.js +28 -5
- package/src/react/components/table/DefaultTableToolbar.js +92 -3
- package/src/react/components/table/useDefaultTablePagination.js +56 -7
- package/src/react/components/table/useDefaultTableStoreSync.js +164 -0
- package/src/react/components/upload/DefaultUpload.js +406 -0
- package/src/react/components/upload/DefaultUpload.styles.js +153 -0
- package/src/react/components/upload/DefaultUploadAttachmentsList.js +146 -0
- package/src/react/components/upload/DefaultUploadManagerModal.js +247 -0
- package/src/react/components/upload/defaultUploadHelpers.js +108 -0
- package/src/react/components/upload/defaultUploadLibrary.js +248 -0
- package/src/react/components/upload/fileUpload.js +93 -0
- package/src/react/hooks/usePostalCodeLookup.js +159 -0
- package/src/react/index.js +6 -0
- package/src/react/services/addressFormUtils.js +262 -0
- package/src/react/services/addressGeo.js +230 -0
- package/src/react/utils/tableVisibleColumnsPreferences.js +113 -15
- package/src/tests/react/components/address/defaultAddressHelpers.test.js +104 -0
- package/src/tests/react/components/files/DefaultFile.test.js +22 -6
- package/src/tests/react/components/files/DefaultFileColumn.company.test.js +24 -0
- package/src/tests/react/components/form/DefaultForm.test.js +123 -0
- package/src/tests/react/components/help/DefaultTooltip.test.js +93 -0
- package/src/tests/react/components/inputs/DefaultSelect.test.js +108 -79
- package/src/tests/react/components/table/DefaultTable.grouping.test.js +49 -0
- package/src/tests/react/components/table/DefaultTable.test.js +53 -2
- package/src/tests/react/components/table/DefaultTable.utils.test.js +10 -0
- package/src/tests/react/components/table/DefaultTableControls.filters.test.mjs +21 -0
- package/src/tests/react/components/table/DefaultTableRowActions.test.js +23 -0
- package/src/tests/react/components/table/DefaultTableRows.rowActions.test.js +152 -0
- package/src/tests/react/components/table/resolveRowBackgroundColor.test.mjs +45 -0
- package/src/tests/react/components/table/useDefaultTableStoreSync.test.js +161 -0
- package/src/tests/react/components/upload/DefaultUpload.test.js +353 -0
- package/src/tests/react/components/upload/defaultUploadLibrary.test.js +104 -0
- package/src/tests/react/components/upload/peopleMediaLibraryPreview.test.mjs +57 -0
- package/src/tests/react/filters/filterValue.test.js +46 -0
- package/src/tests/react/hooks/usePostalCodeLookup.test.js +107 -0
- package/src/tests/react/inputs/defaultInputUtils.test.js +9 -1
- package/src/tests/react/services/SMOKE-637-cep-hydrate.md +45 -0
- package/src/tests/react/services/addressFormUtils.test.js +179 -0
- package/src/tests/react/services/addressGeoLookup.async.test.js +104 -0
- package/src/tests/react/services/addressGeoLookup.test.js +105 -0
- package/src/tests/react/services/smoke-637/form-cep-12941040.png +0 -0
- package/src/tests/react/services/smoke-637/index.html +132 -0
- package/src/tests/react/utils/tableVisibleColumnsPreferences.test.js +96 -49
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# DefaultTable
|
|
2
|
+
|
|
3
|
+
Componente orquestrador de listagens genéricas em React Native / RN Web.
|
|
4
|
+
|
|
5
|
+
**Arquivo:** `src/react/components/table/DefaultTable.js`
|
|
6
|
+
**Composição:** `DefaultTableToolbar` → `DefaultTableBody` → `DefaultTableFooter` (+ botões de add)
|
|
7
|
+
|
|
8
|
+
## Responsabilidade
|
|
9
|
+
|
|
10
|
+
1. Resolver **colunas** (store ou prop).
|
|
11
|
+
2. Em **autoMode** (`data === undefined` e `storeName` preenchido), paginar/ordenar/filtrar via `store.actions`.
|
|
12
|
+
3. Publicar um objeto **`configs`** no store para filhos lerem sem prop-drilling.
|
|
13
|
+
4. Persistir preferências (colunas visíveis, filtros, view mode, sort) por escopo **empresa / store / rota**.
|
|
14
|
+
|
|
15
|
+
## Auto mode vs dados controlados
|
|
16
|
+
|
|
17
|
+
| Modo | Condição | Comportamento |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| **autoMode** | `data === undefined` e `storeName` não vazio | Pagination hook chama actions do store; `items` / `totalItems` vêm do store |
|
|
20
|
+
| **Controlado** | `data` é array | `items` do store são sobrescritos com `data`; refresh/endReached podem ser callbacks externos |
|
|
21
|
+
|
|
22
|
+
## Props (principais)
|
|
23
|
+
|
|
24
|
+
| Prop | Tipo / default | Função |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| `storeName` | string | Nome do store (`useStore`) |
|
|
27
|
+
| `columns` | array | Fallback se `store.getters.columns` vazio |
|
|
28
|
+
| `data` | array \| undefined | Dados controlados; `undefined` ativa autoMode |
|
|
29
|
+
| `actions` | object | Merge sobre `store.actions` |
|
|
30
|
+
| `filters` | object | Filtros iniciais / seed |
|
|
31
|
+
| `requestParams` | object | Params extras em toda request |
|
|
32
|
+
| `pageSize` | number \| null | Tamanho de página |
|
|
33
|
+
| `sort` | `{ field, direction }` \| null | Sort controlado |
|
|
34
|
+
| `onSortChange` | fn | Callback de sort |
|
|
35
|
+
| `hasMore` / `onEndReached` | | Infinite scroll |
|
|
36
|
+
| `isLoading` / `onRefresh` | | Pull-to-refresh |
|
|
37
|
+
| `initialViewMode` | `'table'` \| `'cards'` | Preferência inicial |
|
|
38
|
+
| `forceCardsOnCompact` | true | Cards quando `width <= compactBreakpoint` |
|
|
39
|
+
| `compactBreakpoint` | 768 | Breakpoint de compactação |
|
|
40
|
+
| `showToolbar` / `showSearch` / `showRowActions` | | UI chrome |
|
|
41
|
+
| `showColumnFiltersButton` | true | Botão de filtros de coluna |
|
|
42
|
+
| `add` / `onAdd` / `addLabel` / `addButtonPlacement` | | `'toolbar'` \| `'bottom'` \| `'floating'` |
|
|
43
|
+
| `importAction` / `onImport` / `exportAction` / `onExport` | | Import/export |
|
|
44
|
+
| `onRowPress` / `onEditRow` / `onSaved` | | Interação de linha |
|
|
45
|
+
| `rowActionsComponent` / `rowActionsWidth` / `pinRowActions` | | Ações por linha |
|
|
46
|
+
| `renderCard` / `cardListProps` | | Customização de cards |
|
|
47
|
+
| `summary` / `summaryLabels` | | Rodapé agregado |
|
|
48
|
+
| `footerComponent` | | Slot de footer |
|
|
49
|
+
| `toolbarActions` | array | Ações extras na toolbar |
|
|
50
|
+
| `getOptionsForColumn` | fn | Options locais para selects |
|
|
51
|
+
| `searchKey` | `'search'` | Param de busca textual |
|
|
52
|
+
| `searchPlaceholder` | string | Placeholder |
|
|
53
|
+
| `visibleColumnsPreferenceKey` | string | Chave extra de preferência |
|
|
54
|
+
| `accentColor` / `defaultColor` | | Tema / cor padrão de campos cor |
|
|
55
|
+
| `rowStyle` | | Estilo por linha |
|
|
56
|
+
|
|
57
|
+
## Contrato do store
|
|
58
|
+
|
|
59
|
+
Esperado em `useStore(storeName)`:
|
|
60
|
+
|
|
61
|
+
| Getter / action | Uso |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `getters.columns` | Definição de colunas (preferencial) |
|
|
64
|
+
| `getters.items` | Linhas |
|
|
65
|
+
| `getters.totalItems` | Paginação |
|
|
66
|
+
| `getters.filters` | Filtros ativos |
|
|
67
|
+
| `getters.visibleColumns` | Mapa de colunas visíveis |
|
|
68
|
+
| `getters.configs` | Publicado pelo `DefaultTable` para filhos |
|
|
69
|
+
| `getters.add` | Se `true`, habilita add com `actions.save` ou `onAdd` |
|
|
70
|
+
| `actions.getItems` (ou equivalente na paginação) | Load |
|
|
71
|
+
| `actions.save` | Persistência (form/inline) |
|
|
72
|
+
| `actions.setColumns` / `setItems` / `setFilters` / `setVisibleColumns` / `setConfigs` | Preferidos; senão muta getters |
|
|
73
|
+
|
|
74
|
+
Helpers de publicação interna: `publishStoreValue` / `assignGetterValue`.
|
|
75
|
+
|
|
76
|
+
### Objeto `configs` (publicação)
|
|
77
|
+
|
|
78
|
+
O table monta `defaultTableConfigs` e grava em `store.getters.configs`, incluindo: view mode efetivo, sort resolvido, callbacks de refresh/endReached, flags de UI, `sortedData`, `debugFallbackParameters`, preferência scope, etc. Filhos (`Toolbar`, `Body`, `Footer`) leem **só** `storeName` e usam `configs`.
|
|
79
|
+
|
|
80
|
+
## View modes
|
|
81
|
+
|
|
82
|
+
1. Preferência persistida (`resolveStoredTableViewModePreference`)
|
|
83
|
+
2. `configs.viewMode` corrente
|
|
84
|
+
3. Compacto: se `width <= compactBreakpoint` e `forceCardsOnCompact`, força `'cards'`
|
|
85
|
+
4. Senão `initialViewMode` (default `'table'`)
|
|
86
|
+
|
|
87
|
+
`DefaultTableBody` escolhe `DefaultTableRows` vs `DefaultTableCards`.
|
|
88
|
+
|
|
89
|
+
## Preferências persistidas (escopo por empresa)
|
|
90
|
+
|
|
91
|
+
Escopo via `resolveDefaultTablePreferenceScope({ companyId, preferenceKey, route, storeName })`.
|
|
92
|
+
|
|
93
|
+
Estrutura no `localStorage` (chave raiz `default-table`):
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
default-table[companyKey][storeKey][routeKey] = {
|
|
97
|
+
visibleColumns,
|
|
98
|
+
filters,
|
|
99
|
+
viewMode,
|
|
100
|
+
sort
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- `companyKey` = identificador estável da empresa ativa (normalizado).
|
|
105
|
+
- `storeKey` = nome do store (`storeName`).
|
|
106
|
+
- `routeKey` = `preferenceKey` explícito, pathname, `route.name` ou `route.key`.
|
|
107
|
+
|
|
108
|
+
**O que é persistido:** colunas visíveis, filtros de tabela, view mode e sort.
|
|
109
|
+
|
|
110
|
+
**Sanitização:** `sanitizeVisibleColumnsPreference` / `sanitizeTableFiltersPreference` (só campos de colunas filtráveis + `search`; ignora chaves desconhecidas ou bloqueadas com `filter: false`).
|
|
111
|
+
|
|
112
|
+
### Comportamento na troca de empresa
|
|
113
|
+
|
|
114
|
+
1. O escopo muda (`companyKey` novo).
|
|
115
|
+
2. Filtros, colunas, sort e view mode da empresa anterior **não** são reutilizados.
|
|
116
|
+
3. O table hidrata as preferências salvas para a nova empresa (ou defaults se não houver).
|
|
117
|
+
4. Listas/opções de filtros (selects de coluna e filtros externos) devem ser **recarregadas** no contexto da empresa ativa — não reutilizar opções carregadas para a empresa anterior.
|
|
118
|
+
5. Stores e rotas diferentes continuam isolados entre si.
|
|
119
|
+
|
|
120
|
+
**Compatibilidade com formato legado:** preferências antigas no formato `default-table[store][route]` (sem `companyKey`) **não** são copiadas automaticamente para todas as empresas. Escopos sem `companyKey` são ignorados na leitura/gravação (ver testes em `tableVisibleColumnsPreferences.test.js`).
|
|
121
|
+
|
|
122
|
+
Referência de implementação: `src/react/utils/tableVisibleColumnsPreferences.js`.
|
|
123
|
+
|
|
124
|
+
## Paginação e sort
|
|
125
|
+
|
|
126
|
+
- `useDefaultTablePagination` — monta query (`buildRequestQuery`), página corrente, refresh, end reached
|
|
127
|
+
- `useDefaultTableSortState` / `useDefaultTableSortedData` — sort remoto/local
|
|
128
|
+
- Utils: `resolveDefaultSort`, `isSortableColumn`, `getSortField`, `mergeSortedDataWithLiveItems`
|
|
129
|
+
|
|
130
|
+
Constantes úteis (`DefaultTable.utils.js`):
|
|
131
|
+
|
|
132
|
+
- `DEFAULT_COMPACT_BREAKPOINT = 768`
|
|
133
|
+
- `END_REACHED_THRESHOLD = 0.75`
|
|
134
|
+
- larguras mínimas de célula (identity / money / default)
|
|
135
|
+
|
|
136
|
+
## Composição interna
|
|
137
|
+
|
|
138
|
+
| Peça | Papel |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `DefaultTableToolbar` | Search, controles, import modal, ações |
|
|
141
|
+
| `DefaultTableControls` | Column menu, filters modal, debug |
|
|
142
|
+
| `DefaultTableSearch` / `DefaultSearchModal` | Busca (compacta ou modal) |
|
|
143
|
+
| `DefaultTableRows` | Cabeçalho, filtros por coluna, células, inline edit |
|
|
144
|
+
| `DefaultTableCards` | Layout card + `renderCard` opcional |
|
|
145
|
+
| `DefaultTableInput` | Ponte célula → `DefaultInput` |
|
|
146
|
+
| `DefaultTableFooter` | Totais / summary / paginação visual |
|
|
147
|
+
| `DefaultTableEmptyState` | Empty + `StateStore` |
|
|
148
|
+
| `DefaultTableRowActions` | Slot de ações |
|
|
149
|
+
| `useDefaultTableTheme` | Cores de painel/borda/botão a partir do theme store |
|
|
150
|
+
|
|
151
|
+
## Fluxo de dados (autoMode)
|
|
152
|
+
|
|
153
|
+
```mermaid
|
|
154
|
+
sequenceDiagram
|
|
155
|
+
participant T as DefaultTable
|
|
156
|
+
participant P as useDefaultTablePagination
|
|
157
|
+
participant S as Store
|
|
158
|
+
participant API as Backend
|
|
159
|
+
T->>P: buildRequestQuery(page)
|
|
160
|
+
P->>S: actions.getItems(params)
|
|
161
|
+
S->>API: HTTP
|
|
162
|
+
API-->>S: items + totalItems
|
|
163
|
+
S-->>T: getters.items
|
|
164
|
+
T->>T: sortedData + configs
|
|
165
|
+
T->>T: Body/Footer render
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Integração mínima
|
|
169
|
+
|
|
170
|
+
```jsx
|
|
171
|
+
<DefaultTable
|
|
172
|
+
storeName="customers"
|
|
173
|
+
onAdd={() => openCreateModal()}
|
|
174
|
+
onRowPress={(row) => openDetails(row)}
|
|
175
|
+
/>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Com colunas só via prop (store ainda sem columns):
|
|
179
|
+
|
|
180
|
+
```jsx
|
|
181
|
+
<DefaultTable
|
|
182
|
+
storeName="customers"
|
|
183
|
+
columns={[
|
|
184
|
+
{ name: 'id', label: 'ID', isIdentity: true, editable: false },
|
|
185
|
+
{ name: 'name', label: 'Nome', editable: true },
|
|
186
|
+
{ name: 'status', label: 'Status', list: 'status/getItems', editable: true },
|
|
187
|
+
]}
|
|
188
|
+
/>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
## Sincronização com o store (`useDefaultTableStoreSync`)
|
|
193
|
+
|
|
194
|
+
Hook interno que mantém props controladas do `DefaultTable` alinhadas ao slice Zustand **sem depender da identidade do objeto `store`** (Zustand troca a referência a cada commit).
|
|
195
|
+
|
|
196
|
+
**Arquivo:** `src/react/components/table/useDefaultTableStoreSync.js`
|
|
197
|
+
**Testes:** `src/tests/react/components/table/useDefaultTableStoreSync.test.js`
|
|
198
|
+
|
|
199
|
+
### O que sincroniza
|
|
200
|
+
|
|
201
|
+
| Efeito | Origem → destino | Guard anti-loop |
|
|
202
|
+
| --- | --- | --- |
|
|
203
|
+
| Colunas | prop `columns` → `actions.setColumns` / `getters.columns` | só se o store ainda não tiver colunas |
|
|
204
|
+
| Itens controlados | prop `data` → `actions.setItems` | mesma referência de array (`lastPublishedItemsRef`) |
|
|
205
|
+
| Colunas visíveis | `localStorage` (escopo empresa/store/rota) → `setVisibleColumns` | sanitização por colunas atuais |
|
|
206
|
+
| Filtros persistidos | `localStorage` → `setFilters` | **hydrate uma vez por scopeKey** + `areTableFiltersEqual` |
|
|
207
|
+
| Configs | `defaultTableConfigs` → `setConfigs` | assinatura estável (`defaultTableConfigsSignature`) |
|
|
208
|
+
|
|
209
|
+
Helpers exportados: `publishStoreValue`, `assignGetterValue`, `areTableFiltersEqual`.
|
|
210
|
+
|
|
211
|
+
### Preferências de filtro — regra de hydrate único
|
|
212
|
+
|
|
213
|
+
Filtros de tabela são lidos de `resolveStoredTableFiltersPreference(tablePreferenceScope)` e aplicados via `sanitizeTableFiltersPreference`.
|
|
214
|
+
|
|
215
|
+
**`scopeKey`** (estável):
|
|
216
|
+
|
|
217
|
+
```text
|
|
218
|
+
companyKey :: storeKey :: routeKey :: colunas(key|name)|...
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Regras canônicas (app-community#448 / ui-orders OrderHistoryPage):
|
|
222
|
+
|
|
223
|
+
1. Hydrate de filtros persistidos ocorre **no máximo uma vez** por `scopeKey` (`lastHydratedFiltersKeyRef`).
|
|
224
|
+
2. **Não** reagir a mudanças de `storeFilters` após o hydrate — perseguir o store recria o payload e gera React **#185** (Maximum update depth exceeded).
|
|
225
|
+
3. Antes de `setFilters`, comparar com `areTableFiltersEqual` (JSON estável). Se já for equivalente, só marca o `scopeKey` e sai.
|
|
226
|
+
4. Toggle típico que quebrava: período `today → all → today` em `OrderHistoryPage` (filtro externo de data + DefaultTable). O guard em `useOrderHistoryFilters` (`areHistoryFiltersEqual`) **não basta** se o loop nascer no hydrate do DefaultTable.
|
|
227
|
+
|
|
228
|
+
```mermaid
|
|
229
|
+
flowchart TD
|
|
230
|
+
A[DefaultTable mount / columns ready] --> B{stored filters?}
|
|
231
|
+
B -->|não| C[marca scopeKey]
|
|
232
|
+
B -->|sim| D[sanitize]
|
|
233
|
+
D --> E{scopeKey já hydrated?}
|
|
234
|
+
E -->|sim| F[return — não chase storeFilters]
|
|
235
|
+
E -->|não| G{areTableFiltersEqual?}
|
|
236
|
+
G -->|sim| C
|
|
237
|
+
G -->|não| H[setFilters + marca scopeKey]
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Por que não colocar `storeFilters` nas deps
|
|
241
|
+
|
|
242
|
+
Incluir `storeFilters` no array de dependências do efeito de hydrate faz:
|
|
243
|
+
|
|
244
|
+
`setFilters` → nova referência no store → efeito roda de novo → `setFilters` → **#185**.
|
|
245
|
+
|
|
246
|
+
A correção remove `storeFilters` das deps e usa `storeFiltersRef` só para a comparação de igualdade no momento do hydrate.
|
|
247
|
+
|
|
248
|
+
### Visões (`APP_TYPE`)
|
|
249
|
+
|
|
250
|
+
`ui-default` **não** conhece domínio de pedido/CRM/POS. Qualquer tela que use `DefaultTable` + filtros de período (ex.: histórico de pedidos em `ui-orders`, listagens CRM) herda este contrato. O módulo consumidor não deve reaplicar filtros persistidos em todo change do store; o orquestrador já faz o hydrate único.
|
|
251
|
+
|
|
252
|
+
### Testes mínimos esperados
|
|
253
|
+
|
|
254
|
+
- Publicação de `data` uma vez por referência de array (Devices / #185 histórico).
|
|
255
|
+
- Hydrate de filtros uma vez; após churn de `storeFilters` (simular today→all→today), `setFilters` continua 1×.
|
|
256
|
+
- `areTableFiltersEqual` trata payloads de período equivalentes como iguais.
|
|
257
|
+
|
|
258
|
+
## Limites e cuidados
|
|
259
|
+
|
|
260
|
+
- Filhos dependem de `configs` no store: não renderize Body isolado sem o orquestrador.
|
|
261
|
+
- Preferências são por **empresa + store + rota**: mudou empresa ou rota, o escopo muda.
|
|
262
|
+
- `stableSerialize` evita loops de `setConfigs`.
|
|
263
|
+
- Hydrate de filtros persistidos é **único por scopeKey** — não recoloque `storeFilters` nas deps do efeito de hydrate (React #185; ver seção `useDefaultTableStoreSync`).
|
|
264
|
+
- List stores com escopo de empresa (`categories`, `paymentType`, `wallet`) recebem `company`/`people` automaticamente nos loads de select/coluna.
|
|
265
|
+
|
|
266
|
+
## Arquivos relacionados
|
|
267
|
+
|
|
268
|
+
- `DefaultTable.js`, `DefaultTable.utils.js`, `DefaultTable.styles.js`
|
|
269
|
+
- Hooks: `useDefaultTablePagination.js`, `useDefaultTableSorting.js`, `useDefaultTableTheme.js`, **`useDefaultTableStoreSync.js`**
|
|
270
|
+
- Preferências: `src/react/utils/tableVisibleColumnsPreferences`
|
|
271
|
+
- Testes: `src/tests/react/utils/tableVisibleColumnsPreferences.test.js`
|
|
272
|
+
- Testes store sync: `src/tests/react/components/table/useDefaultTableStoreSync.test.js`
|
package/docs/wiki.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
https://github.com/ControleOnline/ui-default/wiki
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@controleonline/ui-default",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.273",
|
|
4
4
|
"author": "ControleOnline",
|
|
5
5
|
"description": "ControleOnline Default Quasar UI Component",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"scripts": {},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/ControleOnline/
|
|
11
|
+
"url": "https://github.com/ControleOnline/ui-default"
|
|
12
12
|
},
|
|
13
13
|
"bugs": "",
|
|
14
14
|
"homepage": "https://www.controleonline.com/devs/plugins",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"last 1 version, not dead, ie >= 11"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@controleonline/ui-common": "*"
|
|
19
|
+
"@controleonline/ui-common": "*",
|
|
20
|
+
"react-native-vector-icons": "^10.3.0"
|
|
20
21
|
}
|
|
21
22
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const root = path.resolve(__dirname, '..');
|
|
4
|
+
const repo = path.basename(root);
|
|
5
|
+
const pointer = fs.readFileSync(path.join(root, 'docs/wiki.md'), 'utf8');
|
|
6
|
+
const expected = `https://github.com/ControleOnline/${repo}/wiki\n`;
|
|
7
|
+
if (pointer !== expected) throw new Error(`docs/wiki.md must contain only ${expected.trim()}`);
|
|
8
|
+
const gitmodulesPath = path.join(root, '.gitmodules');
|
|
9
|
+
if (fs.existsSync(gitmodulesPath)) {
|
|
10
|
+
const gitmodules = fs.readFileSync(gitmodulesPath, 'utf8');
|
|
11
|
+
if (/path\s*=\s*docs\/wiki/.test(gitmodules) || new RegExp(`${repo}\\.wiki\\.git`).test(gitmodules)) throw new Error('docs/wiki must not be configured as a wiki submodule');
|
|
12
|
+
}
|
|
13
|
+
console.log(`Validated wiki pointer for ${repo}.`);
|