forlogic-core 2.2.6 → 2.2.8
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/.note/memory/features/import/attachment-idempotency-registry.md +8 -8
- package/.note/memory/features/import/attachment-strategy.md +30 -30
- package/.note/memory/patterns/admin-i18n-policy.md +20 -20
- package/.note/memory/patterns/alias-url-resolution.md +69 -69
- package/.note/memory/patterns/doc-sync-rule.md +35 -35
- package/.note/memory/patterns/documentation-standard.md +17 -17
- package/.note/memory/patterns/dynamic-supabase-config.md +4 -4
- package/.note/memory/patterns/environment-detection-logic.md +35 -35
- package/.note/memory/patterns/i18n-architecture.md +3 -3
- package/README.md +120 -120
- package/dist/README.md +1079 -0
- package/dist/bin/bootstrap.js +40 -0
- package/dist/bin/pull-docs.js +186 -0
- package/dist/components/ui/color-picker.d.ts +2 -0
- package/dist/components/ui/combo-tree.d.ts +3 -1
- package/dist/components/ui/combobox.d.ts +2 -1
- package/dist/components/ui/icon-picker.d.ts +2 -0
- package/dist/components/ui/select.d.ts +9 -2
- package/dist/docs/KNOWLEDGE.md +109 -0
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/docs/PUBLISH.md +168 -168
- package/docs/STORAGE_BUCKETS.md +456 -456
- package/docs/SUPABASE_SECRETS.md +122 -122
- package/docs/WORKSPACE_KNOWLEDGE.md +154 -154
- package/docs/design-system/buttons-actions.md +130 -130
- package/docs/design-system/charts-dashboards.md +301 -340
- package/docs/design-system/crud.md +114 -174
- package/docs/design-system/data-display.md +106 -106
- package/docs/design-system/dialogs.md +212 -212
- package/docs/design-system/domain.md +329 -319
- package/docs/design-system/examples.md +275 -275
- package/docs/design-system/foundation.md +1 -1
- package/docs/design-system/inputs.md +137 -132
- package/docs/design-system/layout.md +154 -202
- package/docs/design-system/navigation.md +331 -272
- package/docs/design-system/notifications-feedback.md +34 -34
- package/docs/design-system/patterns/README.md +53 -53
- package/docs/design-system/patterns/action-button.md +22 -22
- package/docs/design-system/patterns/alertdialog-deletion.md +46 -46
- package/docs/design-system/patterns/baseform-custom-fields.md +59 -59
- package/docs/design-system/patterns/baseform-usage.md +42 -42
- package/docs/design-system/patterns/body-content-scroll.md +56 -56
- package/docs/design-system/patterns/combo-tree.md +23 -23
- package/docs/design-system/patterns/components-registry.md +17 -17
- package/docs/design-system/patterns/core-providers.md +41 -41
- package/docs/design-system/patterns/crud-bulk-actions.md +12 -12
- package/docs/design-system/patterns/crud-config-props.md +16 -16
- package/docs/design-system/patterns/crud-defaults.md +17 -17
- package/docs/design-system/patterns/crud-toolbar.md +28 -28
- package/docs/design-system/patterns/delete-confirmation.md +40 -40
- package/docs/design-system/patterns/dialog-body-scroll.md +26 -26
- package/docs/design-system/patterns/dialog-structure.md +32 -32
- package/docs/design-system/patterns/dialog-variants.md +41 -41
- package/docs/design-system/patterns/feature-flags.md +81 -81
- package/docs/design-system/patterns/header-metadata.md +57 -57
- package/docs/design-system/patterns/i18n-setup.md +117 -117
- package/docs/design-system/patterns/pagination.md +27 -27
- package/docs/design-system/patterns/single-scroll.md +39 -39
- package/docs/design-system/patterns/vite-tailwind-setup.md +49 -49
- package/docs/design-system/platform.md +18 -18
- package/docs/design-system/selectors.md +296 -260
- package/docs/design-system/tables-grids.md +38 -95
- package/package.json +152 -152
- package/dist/assets/docs-BEwTKYu3.css +0 -1
- package/dist/assets/docs-Bgpz6ETN.js +0 -10752
- package/dist/assets/index-SqMwTzMJ.js +0 -97
- package/dist/index.html +0 -34
|
@@ -11,24 +11,24 @@ Sistema de gráficos baseado em Recharts com suporte a temas e tooltips customiz
|
|
|
11
11
|
|
|
12
12
|
**Uso:**
|
|
13
13
|
```tsx
|
|
14
|
-
import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from "forlogic-core"
|
|
15
|
-
import { Bar, BarChart, XAxis, YAxis, CartesianGrid } from "recharts"
|
|
16
|
-
|
|
17
|
-
const chartConfig = {
|
|
18
|
-
desktop: { label: "Desktop", color: "hsl(var(--primary))" },
|
|
19
|
-
mobile: { label: "Mobile", color: "hsl(var(--secondary))" },
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
<ChartContainer config={chartConfig} className="h-[300px]">
|
|
23
|
-
<BarChart data={data}>
|
|
24
|
-
<CartesianGrid strokeDasharray="3 3" vertical={false} />
|
|
25
|
-
<XAxis dataKey="month" tickLine={false} axisLine={false} />
|
|
26
|
-
<YAxis tickLine={false} axisLine={false} />
|
|
27
|
-
<ChartTooltip content={<ChartTooltipContent />} />
|
|
28
|
-
<ChartLegend content={<ChartLegendContent />} />
|
|
29
|
-
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
30
|
-
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
|
31
|
-
</BarChart>
|
|
14
|
+
import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from "forlogic-core"
|
|
15
|
+
import { Bar, BarChart, XAxis, YAxis, CartesianGrid } from "recharts"
|
|
16
|
+
|
|
17
|
+
const chartConfig = {
|
|
18
|
+
desktop: { label: "Desktop", color: "hsl(var(--primary))" },
|
|
19
|
+
mobile: { label: "Mobile", color: "hsl(var(--secondary))" },
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
<ChartContainer config={chartConfig} className="h-[300px]">
|
|
23
|
+
<BarChart data={data}>
|
|
24
|
+
<CartesianGrid strokeDasharray="3 3" vertical={false} />
|
|
25
|
+
<XAxis dataKey="month" tickLine={false} axisLine={false} />
|
|
26
|
+
<YAxis tickLine={false} axisLine={false} />
|
|
27
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
28
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
29
|
+
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
30
|
+
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
|
31
|
+
</BarChart>
|
|
32
32
|
</ChartContainer>
|
|
33
33
|
```
|
|
34
34
|
|
|
@@ -44,7 +44,7 @@ const chartConfig = {
|
|
|
44
44
|
|
|
45
45
|
**Exemplos:**
|
|
46
46
|
```tsx
|
|
47
|
-
<BarChart data={data}>
|
|
47
|
+
<BarChart data={data}>
|
|
48
48
|
<Bar dataKey=
|
|
49
49
|
```
|
|
50
50
|
|
|
@@ -69,7 +69,7 @@ const chartConfig = {
|
|
|
69
69
|
- e
|
|
70
70
|
- para visual mais moderno
|
|
71
71
|
|
|
72
|
-
> Fonte: `src
|
|
72
|
+
> Fonte: `src\design-system\docs\components\ChartDoc.tsx`
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
@@ -79,30 +79,30 @@ Módulo completo de dashboards portado do qex-dashboards Angular. Inclui 14 tipo
|
|
|
79
79
|
|
|
80
80
|
**Uso:**
|
|
81
81
|
```tsx
|
|
82
|
-
import {
|
|
83
|
-
// Orquestrador principal
|
|
84
|
-
DashboardGeneralView,
|
|
85
|
-
|
|
86
|
-
// Componentes de página
|
|
87
|
-
DashboardView,
|
|
88
|
-
DashboardList,
|
|
89
|
-
DashboardForm,
|
|
90
|
-
DashboardGrid,
|
|
91
|
-
DashboardPanelRenderer,
|
|
92
|
-
|
|
93
|
-
// Painéis individuais
|
|
94
|
-
NumericPanel, TextPanel, ListPanel,
|
|
95
|
-
CartesianPanel, PiePanel, ParetoPanel,
|
|
96
|
-
BurndownPanel, PerformancePanel, MatrixRiskPanel,
|
|
97
|
-
|
|
98
|
-
// Shared de painel
|
|
99
|
-
PanelHeader, PanelError, PanelLoader, PanelNoData, PanelUnavailable,
|
|
100
|
-
|
|
101
|
-
// Types & Helpers
|
|
102
|
-
DashboardPanelType, PanelState, AggregationType,
|
|
103
|
-
type PanelConfig, type Dashboard, type DashboardPanel,
|
|
104
|
-
getDefaultPanelSize, getMinPanelSize,
|
|
105
|
-
currencyFormatter, processUrl, getLinkFromRow,
|
|
82
|
+
import {
|
|
83
|
+
// Orquestrador principal
|
|
84
|
+
DashboardGeneralView,
|
|
85
|
+
|
|
86
|
+
// Componentes de página
|
|
87
|
+
DashboardView,
|
|
88
|
+
DashboardList,
|
|
89
|
+
DashboardForm,
|
|
90
|
+
DashboardGrid,
|
|
91
|
+
DashboardPanelRenderer,
|
|
92
|
+
|
|
93
|
+
// Painéis individuais
|
|
94
|
+
NumericPanel, TextPanel, ListPanel,
|
|
95
|
+
CartesianPanel, PiePanel, ParetoPanel,
|
|
96
|
+
BurndownPanel, PerformancePanel, MatrixRiskPanel,
|
|
97
|
+
|
|
98
|
+
// Shared de painel
|
|
99
|
+
PanelHeader, PanelError, PanelLoader, PanelNoData, PanelUnavailable,
|
|
100
|
+
|
|
101
|
+
// Types & Helpers
|
|
102
|
+
DashboardPanelType, PanelState, AggregationType,
|
|
103
|
+
type PanelConfig, type Dashboard, type DashboardPanel,
|
|
104
|
+
getDefaultPanelSize, getMinPanelSize,
|
|
105
|
+
currencyFormatter, processUrl, getLinkFromRow,
|
|
106
106
|
} from 'forlogic-core';
|
|
107
107
|
```
|
|
108
108
|
|
|
@@ -120,15 +120,15 @@ import {
|
|
|
120
120
|
|
|
121
121
|
**Exemplos:**
|
|
122
122
|
```tsx
|
|
123
|
-
// O renderer mapeia typeId → componente automaticamente
|
|
124
|
-
<DashboardPanelRenderer
|
|
125
|
-
config={{ ...panelConfig, typeId: DashboardPanelType.Column }}
|
|
126
|
-
state={PanelState.Loaded}
|
|
127
|
-
cartesianData={chartData}
|
|
123
|
+
// O renderer mapeia typeId → componente automaticamente
|
|
124
|
+
<DashboardPanelRenderer
|
|
125
|
+
config={{ ...panelConfig, typeId: DashboardPanelType.Column }}
|
|
126
|
+
state={PanelState.Loaded}
|
|
127
|
+
cartesianData={chartData}
|
|
128
128
|
cartesianSeries={[{ dataKey:
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
> Fonte: `src
|
|
131
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardOverviewDoc.tsx`
|
|
132
132
|
|
|
133
133
|
---
|
|
134
134
|
|
|
@@ -138,49 +138,49 @@ Componente orquestrador que gerencia todo o ciclo de vida do módulo de Dashboar
|
|
|
138
138
|
|
|
139
139
|
**Uso:**
|
|
140
140
|
```tsx
|
|
141
|
-
import { DashboardGeneralView } from 'forlogic-core';
|
|
142
|
-
|
|
143
|
-
// Uso básico (uncontrolled — gerencia estado internamente)
|
|
144
|
-
<DashboardGeneralView
|
|
145
|
-
dashboards={dashboards}
|
|
146
|
-
limit={{ maxDashboards: 50, countDashboards: 12 }}
|
|
147
|
-
canAdd canEdit canRemove
|
|
148
|
-
activePanels={panels}
|
|
149
|
-
activePages={pages}
|
|
150
|
-
getPanelData={(panelId) => ({
|
|
151
|
-
state: PanelState.Loaded,
|
|
152
|
-
data: panelData[panelId],
|
|
153
|
-
})}
|
|
154
|
-
onOpen={(d) => loadPanels(d.id)}
|
|
155
|
-
onSave={(values) => createDashboard(values)}
|
|
156
|
-
onUpdate={(id, values) => updateDashboard(id, values)}
|
|
157
|
-
onRemove={(d) => removeDashboard(d.id)}
|
|
158
|
-
onToggleFavorite={(d) => toggleFav(d.id)}
|
|
159
|
-
/>
|
|
160
|
-
|
|
161
|
-
// Uso controlado (com react-router)
|
|
162
|
-
const [viewState, setViewState] = useState({ mode: 'list' });
|
|
163
|
-
|
|
164
|
-
<DashboardGeneralView
|
|
165
|
-
dashboards={dashboards}
|
|
166
|
-
viewState={viewState}
|
|
167
|
-
onViewStateChange={(state) => {
|
|
168
|
-
setViewState(state);
|
|
169
|
-
if (state.mode === 'view') navigate(\`/dashboards/\${state.dashboardId}\`);
|
|
170
|
-
if (state.mode === 'list') navigate('/dashboards');
|
|
171
|
-
}}
|
|
172
|
-
// ... demais props
|
|
141
|
+
import { DashboardGeneralView } from 'forlogic-core';
|
|
142
|
+
|
|
143
|
+
// Uso básico (uncontrolled — gerencia estado internamente)
|
|
144
|
+
<DashboardGeneralView
|
|
145
|
+
dashboards={dashboards}
|
|
146
|
+
limit={{ maxDashboards: 50, countDashboards: 12 }}
|
|
147
|
+
canAdd canEdit canRemove
|
|
148
|
+
activePanels={panels}
|
|
149
|
+
activePages={pages}
|
|
150
|
+
getPanelData={(panelId) => ({
|
|
151
|
+
state: PanelState.Loaded,
|
|
152
|
+
data: panelData[panelId],
|
|
153
|
+
})}
|
|
154
|
+
onOpen={(d) => loadPanels(d.id)}
|
|
155
|
+
onSave={(values) => createDashboard(values)}
|
|
156
|
+
onUpdate={(id, values) => updateDashboard(id, values)}
|
|
157
|
+
onRemove={(d) => removeDashboard(d.id)}
|
|
158
|
+
onToggleFavorite={(d) => toggleFav(d.id)}
|
|
159
|
+
/>
|
|
160
|
+
|
|
161
|
+
// Uso controlado (com react-router)
|
|
162
|
+
const [viewState, setViewState] = useState({ mode: 'list' });
|
|
163
|
+
|
|
164
|
+
<DashboardGeneralView
|
|
165
|
+
dashboards={dashboards}
|
|
166
|
+
viewState={viewState}
|
|
167
|
+
onViewStateChange={(state) => {
|
|
168
|
+
setViewState(state);
|
|
169
|
+
if (state.mode === 'view') navigate(\`/dashboards/\${state.dashboardId}\`);
|
|
170
|
+
if (state.mode === 'list') navigate('/dashboards');
|
|
171
|
+
}}
|
|
172
|
+
// ... demais props
|
|
173
173
|
/>
|
|
174
174
|
```
|
|
175
175
|
|
|
176
176
|
**Exemplos:**
|
|
177
177
|
```tsx
|
|
178
|
-
// DashboardViewState
|
|
179
|
-
type DashboardViewState =
|
|
178
|
+
// DashboardViewState
|
|
179
|
+
type DashboardViewState =
|
|
180
180
|
| { mode:
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
-
> Fonte: `src
|
|
183
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardGeneralViewDoc.tsx`
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
@@ -190,144 +190,105 @@ Lista/tabela de dashboards com busca integrada, filtros rápidos (Todos / Meus /
|
|
|
190
190
|
|
|
191
191
|
**Uso:**
|
|
192
192
|
```tsx
|
|
193
|
-
import { DashboardList, QuickFilterDashboard } from 'forlogic-core';
|
|
194
|
-
|
|
195
|
-
<DashboardList
|
|
196
|
-
dashboards={dashboards}
|
|
197
|
-
limit={{ maxDashboards: 50, countDashboards: 12 }}
|
|
198
|
-
language={DashboardLanguage.PtBr}
|
|
199
|
-
canAdd canEdit canRemove
|
|
200
|
-
onOpen={(d) => navigate(\`/dashboards/\${d.id}\`)}
|
|
201
|
-
onEdit={(d) => navigate(\`/dashboards/\${d.id}/edit\`)}
|
|
202
|
-
onShare={(d) => openShareDialog(d)}
|
|
203
|
-
onDuplicate={(d) => duplicateDashboard(d.id)}
|
|
204
|
-
onRemove={(d) => removeDashboard(d.id)}
|
|
205
|
-
onAdd={() => navigate('/dashboards/new')}
|
|
206
|
-
onToggleFavorite={(d) => toggleFavorite(d.id)}
|
|
207
|
-
onSearch={(q) => setSearch(q)}
|
|
208
|
-
onQuickFilterChange={(f) => setFilter(f)}
|
|
193
|
+
import { DashboardList, QuickFilterDashboard } from 'forlogic-core';
|
|
194
|
+
|
|
195
|
+
<DashboardList
|
|
196
|
+
dashboards={dashboards}
|
|
197
|
+
limit={{ maxDashboards: 50, countDashboards: 12 }}
|
|
198
|
+
language={DashboardLanguage.PtBr}
|
|
199
|
+
canAdd canEdit canRemove
|
|
200
|
+
onOpen={(d) => navigate(\`/dashboards/\${d.id}\`)}
|
|
201
|
+
onEdit={(d) => navigate(\`/dashboards/\${d.id}/edit\`)}
|
|
202
|
+
onShare={(d) => openShareDialog(d)}
|
|
203
|
+
onDuplicate={(d) => duplicateDashboard(d.id)}
|
|
204
|
+
onRemove={(d) => removeDashboard(d.id)}
|
|
205
|
+
onAdd={() => navigate('/dashboards/new')}
|
|
206
|
+
onToggleFavorite={(d) => toggleFavorite(d.id)}
|
|
207
|
+
onSearch={(q) => setSearch(q)}
|
|
208
|
+
onQuickFilterChange={(f) => setFilter(f)}
|
|
209
209
|
/>
|
|
210
210
|
```
|
|
211
211
|
|
|
212
212
|
**Exemplos:**
|
|
213
213
|
```tsx
|
|
214
|
-
<DashboardList
|
|
215
|
-
dashboards={dashboards}
|
|
216
|
-
limit={{ maxDashboards: 50, countDashboards: 12 }}
|
|
217
|
-
canAdd canEdit canRemove
|
|
218
|
-
onOpen={(d) => openDashboard(d)}
|
|
219
|
-
onToggleFavorite={(d) => toggleFav(d.id)}
|
|
220
|
-
onSearch={(q) => fetchFiltered(q)}
|
|
221
|
-
onQuickFilterChange={(filter) => {
|
|
222
|
-
// QuickFilterDashboard.All | OnlyMine | Favorites
|
|
223
|
-
refetch(filter);
|
|
224
|
-
}}
|
|
214
|
+
<DashboardList
|
|
215
|
+
dashboards={dashboards}
|
|
216
|
+
limit={{ maxDashboards: 50, countDashboards: 12 }}
|
|
217
|
+
canAdd canEdit canRemove
|
|
218
|
+
onOpen={(d) => openDashboard(d)}
|
|
219
|
+
onToggleFavorite={(d) => toggleFav(d.id)}
|
|
220
|
+
onSearch={(q) => fetchFiltered(q)}
|
|
221
|
+
onQuickFilterChange={(filter) => {
|
|
222
|
+
// QuickFilterDashboard.All | OnlyMine | Favorites
|
|
223
|
+
refetch(filter);
|
|
224
|
+
}}
|
|
225
225
|
/>
|
|
226
226
|
```
|
|
227
227
|
```tsx
|
|
228
|
-
// As ações são controladas por callbacks
|
|
229
|
-
<DashboardList
|
|
230
|
-
canEdit={true}
|
|
231
|
-
canRemove={true}
|
|
228
|
+
// As ações são controladas por callbacks
|
|
229
|
+
<DashboardList
|
|
230
|
+
canEdit={true}
|
|
231
|
+
canRemove={true}
|
|
232
232
|
onOpen={(d) => navigate(\
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
-
> Fonte: `src
|
|
235
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardListDoc.tsx`
|
|
236
236
|
|
|
237
237
|
---
|
|
238
238
|
|
|
239
|
-
###
|
|
239
|
+
### DashboardForm
|
|
240
240
|
|
|
241
|
-
|
|
241
|
+
Formulário de criação/edição de dashboards com títulos multilíngue (PT-BR, EN-US, ES-ES), intervalo de atualização, tipo de visualização (Normal/Carousel), switch de situação e aba de compartilhamento com três modos.
|
|
242
242
|
|
|
243
243
|
**Uso:**
|
|
244
244
|
```tsx
|
|
245
|
-
import {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return (
|
|
272
|
-
<Form {...form}>
|
|
273
|
-
<form onSubmit={form.handleSubmit(onSubmit)}>
|
|
274
|
-
<FormField
|
|
275
|
-
control={form.control}
|
|
276
|
-
name="username"
|
|
277
|
-
render={({ field }) => (
|
|
278
|
-
<FormItem>
|
|
279
|
-
<FormLabel>Username</FormLabel>
|
|
280
|
-
<FormControl>
|
|
281
|
-
<Input placeholder="shadcn" {...field} />
|
|
282
|
-
</FormControl>
|
|
283
|
-
<FormDescription>
|
|
284
|
-
This is your public display name.
|
|
285
|
-
</FormDescription>
|
|
286
|
-
<FormMessage />
|
|
287
|
-
</FormItem>
|
|
288
|
-
)}
|
|
289
|
-
/>
|
|
290
|
-
<Button type="submit">Submit</Button>
|
|
291
|
-
</form>
|
|
292
|
-
</Form>
|
|
293
|
-
)
|
|
294
|
-
}
|
|
245
|
+
import { DashboardForm, type DashboardFormValues } from 'forlogic-core';
|
|
246
|
+
|
|
247
|
+
// Criação
|
|
248
|
+
<DashboardForm
|
|
249
|
+
onSave={(values: DashboardFormValues) => {
|
|
250
|
+
// values: { titlePtBr, titleEnUs, titleEsEs, isActive,
|
|
251
|
+
// idUpdateTime, idViewType, idPageTime,
|
|
252
|
+
// idShare, groups?, places?, collaborators? }
|
|
253
|
+
createDashboard(values);
|
|
254
|
+
}}
|
|
255
|
+
onCancel={() => navigate('/dashboards')}
|
|
256
|
+
/>
|
|
257
|
+
|
|
258
|
+
// Edição
|
|
259
|
+
<DashboardForm
|
|
260
|
+
dashboard={existingDashboard}
|
|
261
|
+
users={usersList}
|
|
262
|
+
groups={groupsList}
|
|
263
|
+
places={placesList}
|
|
264
|
+
collaborators={collaboratorsList}
|
|
265
|
+
isSaving={mutation.isPending}
|
|
266
|
+
onSave={(values) => updateDashboard(dashboard.id, values)}
|
|
267
|
+
onCancel={() => goBack()}
|
|
268
|
+
/>
|
|
295
269
|
```
|
|
296
270
|
|
|
297
271
|
**Props:**
|
|
298
272
|
| Prop | Tipo | Padrão | Descrição |
|
|
299
273
|
|------|------|--------|-----------|
|
|
300
|
-
| `
|
|
301
|
-
| `
|
|
302
|
-
| `
|
|
303
|
-
| `
|
|
304
|
-
| `
|
|
305
|
-
| `
|
|
306
|
-
| `
|
|
307
|
-
| `
|
|
308
|
-
| `FormMessage` | `HTMLParagraphElement` | - | Exibe mensagens de erro de validação automaticamente |
|
|
274
|
+
| `dashboard` | `Dashboard | null` | - | Dashboard existente para edição. null para criação. |
|
|
275
|
+
| `initialTab` | `DashboardFormTab` | - | Aba inicial (General ou Share). Default: General. |
|
|
276
|
+
| `isSaving` | `boolean` | - | Desabilita o botão salvar e mostra spinner. |
|
|
277
|
+
| `isQualitfy` | `boolean` | - | Dashboard padrão Qualitfy — bloqueia campos de configuração. |
|
|
278
|
+
| `users` | `Array<{ id, name }>` | - | Lista para seletor de responsável. |
|
|
279
|
+
| `groups / places / collaborators` | `Array<{ id, name }>` | - | Listas para aba de compartilhamento. |
|
|
280
|
+
| `onSave` | `(values: DashboardFormValues) => void` | - | Chamado ao clicar Salvar com valores válidos. |
|
|
281
|
+
| `onCancel` | `() => void` | - | Chamado ao clicar Cancelar. |
|
|
309
282
|
|
|
310
283
|
**Exemplos:**
|
|
311
284
|
```tsx
|
|
312
|
-
<
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
```tsx
|
|
317
|
-
const formSchema = z.object({
|
|
318
|
-
username: z.string().min(3, {
|
|
319
|
-
message:
|
|
285
|
+
<DashboardForm
|
|
286
|
+
dashboard={null} // null = criação
|
|
287
|
+
users={[
|
|
288
|
+
{ id:
|
|
320
289
|
```
|
|
321
290
|
|
|
322
|
-
|
|
323
|
-
- Labels são automaticamente associados aos controles via aria-describedby
|
|
324
|
-
- Mensagens de erro são anunciadas por leitores de tela
|
|
325
|
-
- Suporta navegação por teclado nativa dos controles
|
|
326
|
-
- Estados de erro são indicados visualmente e semanticamente
|
|
327
|
-
- Usa React Hook Form para gerenciamento de estado de formulário
|
|
328
|
-
- Integra com Zod para validação de schema
|
|
329
|
-
|
|
330
|
-
> Fonte: `src/design-system/docs/components/FormDoc.tsx`
|
|
291
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardFormDoc.tsx`
|
|
331
292
|
|
|
332
293
|
---
|
|
333
294
|
|
|
@@ -343,32 +304,32 @@ Grid de 8 colunas com posicionamento por col/row e dimensão por sizeX/sizeY. Su
|
|
|
343
304
|
|
|
344
305
|
**Uso:**
|
|
345
306
|
```tsx
|
|
346
|
-
import { DashboardGrid, getDefaultPanelSize, getMinPanelSize } from 'forlogic-core';
|
|
347
|
-
|
|
348
|
-
<DashboardGrid
|
|
349
|
-
panels={[
|
|
350
|
-
{ id: 'p1', col: 0, row: 0, sizeX: 4, sizeY: 2 },
|
|
351
|
-
{ id: 'p2', col: 4, row: 0, sizeX: 4, sizeY: 2 },
|
|
352
|
-
{ id: 'p3', col: 0, row: 2, sizeX: 8, sizeY: 2 },
|
|
353
|
-
]}
|
|
354
|
-
columns={8} // padrão: 8
|
|
355
|
-
cellHeight={160} // padrão: 160px
|
|
356
|
-
cellGap={10} // padrão: 10px
|
|
357
|
-
allowDragging={canEdit}
|
|
358
|
-
showGridLines={canEdit}
|
|
359
|
-
renderPanel={(panelId) => <MyPanelComponent id={panelId} />}
|
|
360
|
-
onLayoutChange={(updatedPanels) => saveLayout(updatedPanels)}
|
|
307
|
+
import { DashboardGrid, getDefaultPanelSize, getMinPanelSize } from 'forlogic-core';
|
|
308
|
+
|
|
309
|
+
<DashboardGrid
|
|
310
|
+
panels={[
|
|
311
|
+
{ id: 'p1', col: 0, row: 0, sizeX: 4, sizeY: 2 },
|
|
312
|
+
{ id: 'p2', col: 4, row: 0, sizeX: 4, sizeY: 2 },
|
|
313
|
+
{ id: 'p3', col: 0, row: 2, sizeX: 8, sizeY: 2 },
|
|
314
|
+
]}
|
|
315
|
+
columns={8} // padrão: 8
|
|
316
|
+
cellHeight={160} // padrão: 160px
|
|
317
|
+
cellGap={10} // padrão: 10px
|
|
318
|
+
allowDragging={canEdit}
|
|
319
|
+
showGridLines={canEdit}
|
|
320
|
+
renderPanel={(panelId) => <MyPanelComponent id={panelId} />}
|
|
321
|
+
onLayoutChange={(updatedPanels) => saveLayout(updatedPanels)}
|
|
361
322
|
/>
|
|
362
323
|
```
|
|
363
324
|
|
|
364
325
|
**Exemplos:**
|
|
365
326
|
```tsx
|
|
366
|
-
<DashboardGrid
|
|
367
|
-
panels={[
|
|
327
|
+
<DashboardGrid
|
|
328
|
+
panels={[
|
|
368
329
|
{ id:
|
|
369
330
|
```
|
|
370
331
|
|
|
371
|
-
> Fonte: `src
|
|
332
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardGridDoc.tsx`
|
|
372
333
|
|
|
373
334
|
---
|
|
374
335
|
|
|
@@ -378,37 +339,37 @@ Componente de roteamento que mapeia DashboardPanelType para o componente React c
|
|
|
378
339
|
|
|
379
340
|
**Uso:**
|
|
380
341
|
```tsx
|
|
381
|
-
import { DashboardPanelRenderer, PanelState, DashboardPanelType } from 'forlogic-core';
|
|
382
|
-
|
|
383
|
-
// O renderer resolve automaticamente qual componente usar
|
|
384
|
-
<DashboardPanelRenderer
|
|
385
|
-
config={{
|
|
386
|
-
id: 'p1',
|
|
387
|
-
title: 'Ocorrências por Mês',
|
|
388
|
-
typeId: DashboardPanelType.Column,
|
|
389
|
-
// ... demais campos de PanelConfig
|
|
390
|
-
}}
|
|
391
|
-
state={PanelState.Loaded}
|
|
392
|
-
cartesianData={[
|
|
393
|
-
{ key: 'Jan', value: 42 },
|
|
394
|
-
{ key: 'Fev', value: 58 },
|
|
395
|
-
]}
|
|
396
|
-
cartesianSeries={[{ dataKey: 'value', name: 'Total' }]}
|
|
397
|
-
/>
|
|
398
|
-
|
|
399
|
-
// Para NumericPanel, use numericValue:
|
|
400
|
-
<DashboardPanelRenderer
|
|
401
|
-
config={{ ...config, typeId: DashboardPanelType.Numeric }}
|
|
402
|
-
state={PanelState.Loaded}
|
|
403
|
-
numericValue={1247}
|
|
404
|
-
/>
|
|
405
|
-
|
|
406
|
-
// Para MatrixRisk, use matrixRule + matrixRisks:
|
|
407
|
-
<DashboardPanelRenderer
|
|
408
|
-
config={{ ...config, typeId: DashboardPanelType.RiskMatrix }}
|
|
409
|
-
state={PanelState.Loaded}
|
|
410
|
-
matrixRule={rule}
|
|
411
|
-
matrixRisks={risks}
|
|
342
|
+
import { DashboardPanelRenderer, PanelState, DashboardPanelType } from 'forlogic-core';
|
|
343
|
+
|
|
344
|
+
// O renderer resolve automaticamente qual componente usar
|
|
345
|
+
<DashboardPanelRenderer
|
|
346
|
+
config={{
|
|
347
|
+
id: 'p1',
|
|
348
|
+
title: 'Ocorrências por Mês',
|
|
349
|
+
typeId: DashboardPanelType.Column,
|
|
350
|
+
// ... demais campos de PanelConfig
|
|
351
|
+
}}
|
|
352
|
+
state={PanelState.Loaded}
|
|
353
|
+
cartesianData={[
|
|
354
|
+
{ key: 'Jan', value: 42 },
|
|
355
|
+
{ key: 'Fev', value: 58 },
|
|
356
|
+
]}
|
|
357
|
+
cartesianSeries={[{ dataKey: 'value', name: 'Total' }]}
|
|
358
|
+
/>
|
|
359
|
+
|
|
360
|
+
// Para NumericPanel, use numericValue:
|
|
361
|
+
<DashboardPanelRenderer
|
|
362
|
+
config={{ ...config, typeId: DashboardPanelType.Numeric }}
|
|
363
|
+
state={PanelState.Loaded}
|
|
364
|
+
numericValue={1247}
|
|
365
|
+
/>
|
|
366
|
+
|
|
367
|
+
// Para MatrixRisk, use matrixRule + matrixRisks:
|
|
368
|
+
<DashboardPanelRenderer
|
|
369
|
+
config={{ ...config, typeId: DashboardPanelType.RiskMatrix }}
|
|
370
|
+
state={PanelState.Loaded}
|
|
371
|
+
matrixRule={rule}
|
|
372
|
+
matrixRisks={risks}
|
|
412
373
|
/>
|
|
413
374
|
```
|
|
414
375
|
|
|
@@ -418,7 +379,7 @@ import { DashboardPanelRenderer, PanelState, DashboardPanelType } from 'forlogic
|
|
|
418
379
|
| `config` | `PanelConfig` | - | Configuração do painel — inclui typeId que determina qual componente renderizar. |
|
|
419
380
|
| `state` | `PanelState` | - | Estado atual do painel (Loading, Loaded, Error, NoData, Unavailable). |
|
|
420
381
|
|
|
421
|
-
> Fonte: `src
|
|
382
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardPanelRendererDoc.tsx`
|
|
422
383
|
|
|
423
384
|
---
|
|
424
385
|
|
|
@@ -428,31 +389,31 @@ Os três painéis não-gráficos do módulo de dashboards: NumericPanel (valor n
|
|
|
428
389
|
|
|
429
390
|
**Uso:**
|
|
430
391
|
```tsx
|
|
431
|
-
import { NumericPanel, TextPanel, ListPanel, PanelState } from 'forlogic-core';
|
|
432
|
-
|
|
433
|
-
// Painel Numérico
|
|
434
|
-
<NumericPanel
|
|
435
|
-
config={panelConfig}
|
|
436
|
-
state={PanelState.Loaded}
|
|
437
|
-
value={1247}
|
|
438
|
-
label="Contagem" // override do label automático
|
|
439
|
-
onClick={() => openPopover()}
|
|
440
|
-
/>
|
|
441
|
-
|
|
442
|
-
// Painel de Texto
|
|
443
|
-
<TextPanel
|
|
444
|
-
config={{ ...panelConfig, textTypeString: '<h3>Título</h3><p>Conteúdo</p>' }}
|
|
445
|
-
state={PanelState.Loaded}
|
|
446
|
-
/>
|
|
447
|
-
|
|
448
|
-
// Painel de Lista
|
|
449
|
-
<ListPanel
|
|
450
|
-
config={panelConfig}
|
|
451
|
-
state={PanelState.Loaded}
|
|
452
|
-
data={rows}
|
|
453
|
-
columns={columnDefinitions}
|
|
454
|
-
enableRowLinks={true}
|
|
455
|
-
onRowClick={(row) => openDetail(row)}
|
|
392
|
+
import { NumericPanel, TextPanel, ListPanel, PanelState } from 'forlogic-core';
|
|
393
|
+
|
|
394
|
+
// Painel Numérico
|
|
395
|
+
<NumericPanel
|
|
396
|
+
config={panelConfig}
|
|
397
|
+
state={PanelState.Loaded}
|
|
398
|
+
value={1247}
|
|
399
|
+
label="Contagem" // override do label automático
|
|
400
|
+
onClick={() => openPopover()}
|
|
401
|
+
/>
|
|
402
|
+
|
|
403
|
+
// Painel de Texto
|
|
404
|
+
<TextPanel
|
|
405
|
+
config={{ ...panelConfig, textTypeString: '<h3>Título</h3><p>Conteúdo</p>' }}
|
|
406
|
+
state={PanelState.Loaded}
|
|
407
|
+
/>
|
|
408
|
+
|
|
409
|
+
// Painel de Lista
|
|
410
|
+
<ListPanel
|
|
411
|
+
config={panelConfig}
|
|
412
|
+
state={PanelState.Loaded}
|
|
413
|
+
data={rows}
|
|
414
|
+
columns={columnDefinitions}
|
|
415
|
+
enableRowLinks={true}
|
|
416
|
+
onRowClick={(row) => openDetail(row)}
|
|
456
417
|
/>
|
|
457
418
|
```
|
|
458
419
|
|
|
@@ -466,29 +427,29 @@ import { NumericPanel, TextPanel, ListPanel, PanelState } from 'forlogic-core';
|
|
|
466
427
|
|
|
467
428
|
**Exemplos:**
|
|
468
429
|
```tsx
|
|
469
|
-
// Contagem simples
|
|
470
|
-
<NumericPanel config={config} state={PanelState.Loaded} value={1247} />
|
|
471
|
-
|
|
430
|
+
// Contagem simples
|
|
431
|
+
<NumericPanel config={config} state={PanelState.Loaded} value={1247} />
|
|
432
|
+
|
|
472
433
|
// Com formatação de moeda (detectado pelo campo
|
|
473
434
|
```
|
|
474
435
|
```tsx
|
|
475
|
-
<TextPanel
|
|
476
|
-
config={{
|
|
477
|
-
...config,
|
|
436
|
+
<TextPanel
|
|
437
|
+
config={{
|
|
438
|
+
...config,
|
|
478
439
|
textTypeString:
|
|
479
440
|
```
|
|
480
441
|
```tsx
|
|
481
|
-
<ListPanel
|
|
482
|
-
config={config}
|
|
483
|
-
state={PanelState.Loaded}
|
|
484
|
-
data={[
|
|
442
|
+
<ListPanel
|
|
443
|
+
config={config}
|
|
444
|
+
state={PanelState.Loaded}
|
|
445
|
+
data={[
|
|
485
446
|
{ code:
|
|
486
447
|
```
|
|
487
448
|
```tsx
|
|
488
449
|
OC-002
|
|
489
450
|
```
|
|
490
451
|
|
|
491
|
-
> Fonte: `src
|
|
452
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardPanelsBasicDoc.tsx`
|
|
492
453
|
|
|
493
454
|
---
|
|
494
455
|
|
|
@@ -498,43 +459,43 @@ CartesianPanel é um componente unificado que renderiza 6 variantes de gráfico
|
|
|
498
459
|
|
|
499
460
|
**Uso:**
|
|
500
461
|
```tsx
|
|
501
|
-
import { CartesianPanel, PanelState, type CartesianSeries } from 'forlogic-core';
|
|
502
|
-
|
|
503
|
-
// Uso básico — série única
|
|
504
|
-
<CartesianPanel
|
|
505
|
-
config={panelConfig}
|
|
506
|
-
variant="column" // 'bar' | 'column' | 'stacked-column' | 'area' | 'line' | 'evolution-line'
|
|
507
|
-
state={PanelState.Loaded}
|
|
508
|
-
data={[
|
|
509
|
-
{ key: 'Jan', value: 42 },
|
|
510
|
-
{ key: 'Fev', value: 58 },
|
|
511
|
-
]}
|
|
512
|
-
/>
|
|
513
|
-
|
|
514
|
-
// Múltiplas séries
|
|
515
|
-
<CartesianPanel
|
|
516
|
-
config={panelConfig}
|
|
517
|
-
variant="column"
|
|
518
|
-
state={PanelState.Loaded}
|
|
519
|
-
data={data}
|
|
520
|
-
series={[
|
|
521
|
-
{ dataKey: 'opened', name: 'Abertas', color: '#4e79a7' },
|
|
522
|
-
{ dataKey: 'closed', name: 'Fechadas', color: '#59a14f' },
|
|
523
|
-
]}
|
|
524
|
-
categoryKey="month" // chave do eixo X (default: 'key')
|
|
525
|
-
yAxisFormat="R$ {value}" // formato do eixo Y
|
|
526
|
-
onPointClick={(data, index) => openDetail(data)}
|
|
462
|
+
import { CartesianPanel, PanelState, type CartesianSeries } from 'forlogic-core';
|
|
463
|
+
|
|
464
|
+
// Uso básico — série única
|
|
465
|
+
<CartesianPanel
|
|
466
|
+
config={panelConfig}
|
|
467
|
+
variant="column" // 'bar' | 'column' | 'stacked-column' | 'area' | 'line' | 'evolution-line'
|
|
468
|
+
state={PanelState.Loaded}
|
|
469
|
+
data={[
|
|
470
|
+
{ key: 'Jan', value: 42 },
|
|
471
|
+
{ key: 'Fev', value: 58 },
|
|
472
|
+
]}
|
|
473
|
+
/>
|
|
474
|
+
|
|
475
|
+
// Múltiplas séries
|
|
476
|
+
<CartesianPanel
|
|
477
|
+
config={panelConfig}
|
|
478
|
+
variant="column"
|
|
479
|
+
state={PanelState.Loaded}
|
|
480
|
+
data={data}
|
|
481
|
+
series={[
|
|
482
|
+
{ dataKey: 'opened', name: 'Abertas', color: '#4e79a7' },
|
|
483
|
+
{ dataKey: 'closed', name: 'Fechadas', color: '#59a14f' },
|
|
484
|
+
]}
|
|
485
|
+
categoryKey="month" // chave do eixo X (default: 'key')
|
|
486
|
+
yAxisFormat="R$ {value}" // formato do eixo Y
|
|
487
|
+
onPointClick={(data, index) => openDetail(data)}
|
|
527
488
|
/>
|
|
528
489
|
```
|
|
529
490
|
|
|
530
491
|
**Exemplos:**
|
|
531
492
|
```tsx
|
|
532
|
-
<CartesianPanel
|
|
533
|
-
config={config}
|
|
493
|
+
<CartesianPanel
|
|
494
|
+
config={config}
|
|
534
495
|
variant=
|
|
535
496
|
```
|
|
536
497
|
|
|
537
|
-
> Fonte: `src
|
|
498
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardPanelsCartesianDoc.tsx`
|
|
538
499
|
|
|
539
500
|
---
|
|
540
501
|
|
|
@@ -544,43 +505,43 @@ Cinco painéis especializados: PiePanel (pizza com percentuais), ParetoPanel (ba
|
|
|
544
505
|
|
|
545
506
|
**Uso:**
|
|
546
507
|
```tsx
|
|
547
|
-
import {
|
|
548
|
-
PiePanel, ParetoPanel, BurndownPanel,
|
|
549
|
-
PerformancePanel, MatrixRiskPanel,
|
|
550
|
-
PanelState, MatrixViewType,
|
|
551
|
-
} from 'forlogic-core';
|
|
552
|
-
|
|
553
|
-
// Pie
|
|
554
|
-
<PiePanel config={config} state={PanelState.Loaded} data={pieData} />
|
|
555
|
-
|
|
556
|
-
// Pareto
|
|
557
|
-
<ParetoPanel config={config} state={PanelState.Loaded} data={paretoData} />
|
|
558
|
-
|
|
559
|
-
// Burndown
|
|
560
|
-
<BurndownPanel config={config} state={PanelState.Loaded} data={burndownData} />
|
|
561
|
-
|
|
562
|
-
// Performance
|
|
563
|
-
<PerformancePanel config={config} state={PanelState.Loaded} data={performanceData} />
|
|
564
|
-
|
|
565
|
-
// Matrix Risk
|
|
566
|
-
<MatrixRiskPanel
|
|
567
|
-
config={config}
|
|
568
|
-
state={PanelState.Loaded}
|
|
569
|
-
rule={matrixRule}
|
|
570
|
-
risks={risks}
|
|
571
|
-
matrixViewType={MatrixViewType.Quantity}
|
|
508
|
+
import {
|
|
509
|
+
PiePanel, ParetoPanel, BurndownPanel,
|
|
510
|
+
PerformancePanel, MatrixRiskPanel,
|
|
511
|
+
PanelState, MatrixViewType,
|
|
512
|
+
} from 'forlogic-core';
|
|
513
|
+
|
|
514
|
+
// Pie
|
|
515
|
+
<PiePanel config={config} state={PanelState.Loaded} data={pieData} />
|
|
516
|
+
|
|
517
|
+
// Pareto
|
|
518
|
+
<ParetoPanel config={config} state={PanelState.Loaded} data={paretoData} />
|
|
519
|
+
|
|
520
|
+
// Burndown
|
|
521
|
+
<BurndownPanel config={config} state={PanelState.Loaded} data={burndownData} />
|
|
522
|
+
|
|
523
|
+
// Performance
|
|
524
|
+
<PerformancePanel config={config} state={PanelState.Loaded} data={performanceData} />
|
|
525
|
+
|
|
526
|
+
// Matrix Risk
|
|
527
|
+
<MatrixRiskPanel
|
|
528
|
+
config={config}
|
|
529
|
+
state={PanelState.Loaded}
|
|
530
|
+
rule={matrixRule}
|
|
531
|
+
risks={risks}
|
|
532
|
+
matrixViewType={MatrixViewType.Quantity}
|
|
572
533
|
/>
|
|
573
534
|
```
|
|
574
535
|
|
|
575
536
|
**Exemplos:**
|
|
576
537
|
```tsx
|
|
577
|
-
<PiePanel
|
|
578
|
-
config={config}
|
|
579
|
-
state={PanelState.Loaded}
|
|
580
|
-
data={[
|
|
538
|
+
<PiePanel
|
|
539
|
+
config={config}
|
|
540
|
+
state={PanelState.Loaded}
|
|
541
|
+
data={[
|
|
581
542
|
{ key:
|
|
582
543
|
```
|
|
583
544
|
|
|
584
|
-
> Fonte: `src
|
|
545
|
+
> Fonte: `src\design-system\docs\components\dashboards\DashboardPanelsSpecialDoc.tsx`
|
|
585
546
|
|
|
586
547
|
---
|