forlogic-core 2.1.4 → 2.1.5
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 +68 -68
- package/dist/action-plans/components/ActionPlanStatusBadge.d.ts +6 -2
- package/dist/components/ui/__tests__/status-badge.test.d.ts +1 -0
- package/dist/components/ui/status-badge.d.ts +49 -0
- package/dist/crud/primitives/Table.d.ts +1 -1
- package/dist/crud/primitives/types.d.ts +6 -0
- package/dist/exports/crud.d.ts +5 -0
- package/dist/exports/ui.d.ts +1 -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/dist/utils/color.d.ts +26 -0
- package/dist/utils/index.d.ts +1 -0
- package/docs/PUBLISH.md +168 -0
- package/docs/WORKSPACE_KNOWLEDGE.md +119 -119
- package/docs/design-system/README.md +1 -1
- package/docs/design-system/buttons-actions.md +130 -130
- package/docs/design-system/charts-dashboards.md +340 -301
- package/docs/design-system/crud.md +174 -114
- package/docs/design-system/data-display.md +108 -103
- package/docs/design-system/dialogs.md +212 -212
- package/docs/design-system/domain.md +317 -317
- package/docs/design-system/examples.md +275 -275
- package/docs/design-system/foundation.md +1 -1
- package/docs/design-system/inputs.md +131 -131
- package/docs/design-system/layout.md +202 -154
- package/docs/design-system/navigation.md +271 -325
- 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 +39 -39
- 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 +24 -20
- 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 +48 -48
- package/docs/design-system/platform.md +18 -18
- package/docs/design-system/selectors.md +236 -236
- package/docs/design-system/tables-grids.md +95 -38
- package/package.json +144 -144
- package/dist/README.md +0 -1079
- package/dist/bin/bootstrap.js +0 -40
- package/dist/bin/pull-docs.js +0 -186
- package/dist/docs/KNOWLEDGE.md +0 -109
|
@@ -11,19 +11,19 @@ Componente de notificação toast usando Sonner. Feedback temporário e não blo
|
|
|
11
11
|
|
|
12
12
|
**Uso:**
|
|
13
13
|
```tsx
|
|
14
|
-
import { toast } from "sonner"
|
|
15
|
-
|
|
16
|
-
// Informativo (BG #FFFFFF)
|
|
17
|
-
toast("Mensagem simples")
|
|
18
|
-
toast.info("Informação importante")
|
|
19
|
-
|
|
20
|
-
// Sucesso (BG #E0FBE8)
|
|
21
|
-
toast.success("Operação concluída")
|
|
22
|
-
|
|
23
|
-
// Alerta (BG #FEF3C8)
|
|
24
|
-
toast.warning("Atenção necessária")
|
|
25
|
-
|
|
26
|
-
// Erro (BG #FEE1E1)
|
|
14
|
+
import { toast } from "sonner"
|
|
15
|
+
|
|
16
|
+
// Informativo (BG #FFFFFF)
|
|
17
|
+
toast("Mensagem simples")
|
|
18
|
+
toast.info("Informação importante")
|
|
19
|
+
|
|
20
|
+
// Sucesso (BG #E0FBE8)
|
|
21
|
+
toast.success("Operação concluída")
|
|
22
|
+
|
|
23
|
+
// Alerta (BG #FEF3C8)
|
|
24
|
+
toast.warning("Atenção necessária")
|
|
25
|
+
|
|
26
|
+
// Erro (BG #FEE1E1)
|
|
27
27
|
toast.error("Algo deu errado")
|
|
28
28
|
```
|
|
29
29
|
|
|
@@ -43,19 +43,19 @@ toast.error("Algo deu errado")
|
|
|
43
43
|
|
|
44
44
|
**Exemplos:**
|
|
45
45
|
```tsx
|
|
46
|
-
// Toast é um feedback temporário e não bloqueante
|
|
47
|
-
// - Informa rapidamente o usuário
|
|
48
|
-
// - Não compete visualmente com outros Toasts
|
|
49
|
-
// - Empilhamento vertical sem sobreposição
|
|
46
|
+
// Toast é um feedback temporário e não bloqueante
|
|
47
|
+
// - Informa rapidamente o usuário
|
|
48
|
+
// - Não compete visualmente com outros Toasts
|
|
49
|
+
// - Empilhamento vertical sem sobreposição
|
|
50
50
|
// - Ordem previsível: mais recente no topo
|
|
51
51
|
```
|
|
52
52
|
```tsx
|
|
53
|
-
// Empilhamento vertical com espaçamento consistente
|
|
53
|
+
// Empilhamento vertical com espaçamento consistente
|
|
54
54
|
toast.success(
|
|
55
55
|
```
|
|
56
56
|
```tsx
|
|
57
|
-
// Configuração de posição no Toaster:
|
|
58
|
-
<Sonner
|
|
57
|
+
// Configuração de posição no Toaster:
|
|
58
|
+
<Sonner
|
|
59
59
|
position=
|
|
60
60
|
```
|
|
61
61
|
|
|
@@ -80,7 +80,7 @@ toast.success(
|
|
|
80
80
|
- 🎨 **Padrão v2**: Toasts possuem
|
|
81
81
|
- como identidade visual herdada da v2.
|
|
82
82
|
|
|
83
|
-
> Fonte: `src
|
|
83
|
+
> Fonte: `src/design-system/docs/components/ToastDoc.tsx`
|
|
84
84
|
|
|
85
85
|
---
|
|
86
86
|
|
|
@@ -90,18 +90,18 @@ Botão com popover para exibir notificações de atualização das aplicações.
|
|
|
90
90
|
|
|
91
91
|
**Uso:**
|
|
92
92
|
```tsx
|
|
93
|
-
// Modo automático — basta importar e usar, sem props
|
|
94
|
-
// O componente busca dados da API internamente usando useAuth() e useUpdatesNotification()
|
|
95
|
-
import { UpdatesNotification } from 'forlogic-core';
|
|
96
|
-
|
|
97
|
-
<UpdatesNotification />
|
|
98
|
-
|
|
99
|
-
// Modo controlado — para testes, docs ou lógica customizada
|
|
100
|
-
<UpdatesNotification
|
|
101
|
-
updates={[{ id: '1', title: 'Nova versão', text: 'Descrição' }]}
|
|
102
|
-
badgeCount={1}
|
|
103
|
-
onOpen={() => markAsViewed()}
|
|
104
|
-
onViewAll={() => window.open('https://apps4.qualiex.com/common/alias/up/view', '_blank')}
|
|
93
|
+
// Modo automático — basta importar e usar, sem props
|
|
94
|
+
// O componente busca dados da API internamente usando useAuth() e useUpdatesNotification()
|
|
95
|
+
import { UpdatesNotification } from 'forlogic-core';
|
|
96
|
+
|
|
97
|
+
<UpdatesNotification />
|
|
98
|
+
|
|
99
|
+
// Modo controlado — para testes, docs ou lógica customizada
|
|
100
|
+
<UpdatesNotification
|
|
101
|
+
updates={[{ id: '1', title: 'Nova versão', text: 'Descrição' }]}
|
|
102
|
+
badgeCount={1}
|
|
103
|
+
onOpen={() => markAsViewed()}
|
|
104
|
+
onViewAll={() => window.open('https://apps4.qualiex.com/common/alias/up/view', '_blank')}
|
|
105
105
|
/>
|
|
106
106
|
```
|
|
107
107
|
|
|
@@ -122,7 +122,7 @@ import { UpdatesNotification } from
|
|
|
122
122
|
- Em caso de 401, o hook faz retry automático regenerando o token via QualiexErrorInterceptor.
|
|
123
123
|
- Em produção, o componente deve ser colocado no AppHeader — já está integrado no forlogic-core.
|
|
124
124
|
|
|
125
|
-
> Fonte: `src
|
|
125
|
+
> Fonte: `src/design-system/docs/components/UpdatesNotificationDoc.tsx`
|
|
126
126
|
|
|
127
127
|
---
|
|
128
128
|
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
# Design System — Padrões Universais
|
|
2
|
-
|
|
3
|
-
> Padrões obrigatórios para todos os projetos que consomem `forlogic-core`.
|
|
4
|
-
> Acessível via cross-project: `@Admin docs/design-system/patterns/`
|
|
5
|
-
|
|
6
|
-
## Índice
|
|
7
|
-
|
|
8
|
-
### Componentes
|
|
9
|
-
|
|
10
|
-
| Arquivo | Descrição |
|
|
11
|
-
|---------|-----------|
|
|
12
|
-
| [action-button.md](action-button.md) | Uso obrigatório do ActionButton em tabelas |
|
|
13
|
-
| [alertdialog-deletion.md](alertdialog-deletion.md) | AlertDialog para exclusões permanentes |
|
|
14
|
-
| [baseform-usage.md](baseform-usage.md) | BaseForm — formulário dinâmico CRUD |
|
|
15
|
-
| [baseform-custom-fields.md](baseform-custom-fields.md) | Campos customizados no BaseForm |
|
|
16
|
-
| [combo-tree.md](combo-tree.md) | ComboTree — seleção hierárquica |
|
|
17
|
-
| [delete-confirmation.md](delete-confirmation.md) | Dialog de confirmação de exclusão |
|
|
18
|
-
| [dialog-structure.md](dialog-structure.md) | Tamanhos e estrutura obrigatória do Dialog |
|
|
19
|
-
| [dialog-variants.md](dialog-variants.md) | Variantes semânticas do Dialog |
|
|
20
|
-
| [pagination.md](pagination.md) | Paginação padronizada |
|
|
21
|
-
|
|
22
|
-
### Padrões de Layout & Scroll
|
|
23
|
-
|
|
24
|
-
| Arquivo | Descrição |
|
|
25
|
-
|---------|-----------|
|
|
26
|
-
| [dialog-body-scroll.md](dialog-body-scroll.md) | Scroll interno em Dialogs |
|
|
27
|
-
| [body-content-scroll.md](body-content-scroll.md) | Scroll em páginas (BodyContent) |
|
|
28
|
-
| [single-scroll.md](single-scroll.md) | Padrão de scroll único no viewport |
|
|
29
|
-
|
|
30
|
-
### Padrões CRUD
|
|
31
|
-
|
|
32
|
-
| Arquivo | Descrição |
|
|
33
|
-
|---------|-----------|
|
|
34
|
-
| [crud-toolbar.md](crud-toolbar.md) | Layout 3 zonas da toolbar |
|
|
35
|
-
| [crud-bulk-actions.md](crud-bulk-actions.md) | Ações em lote via dropdown |
|
|
36
|
-
| [crud-defaults.md](crud-defaults.md) | Defaults obrigatórios (resize, sort, etc.) |
|
|
37
|
-
| [crud-config-props.md](crud-config-props.md) | Props padronizadas de configuração |
|
|
38
|
-
|
|
39
|
-
### Setup & Configuração
|
|
40
|
-
|
|
41
|
-
| Arquivo | Descrição |
|
|
42
|
-
|---------|-----------|
|
|
43
|
-
| [core-providers.md](core-providers.md) | Setup obrigatório do CoreProviders |
|
|
44
|
-
| [vite-tailwind-setup.md](vite-tailwind-setup.md) | Configuração Vite + Tailwind |
|
|
45
|
-
| [i18n-setup.md](i18n-setup.md) | Setup de internacionalização |
|
|
46
|
-
| [feature-flags.md](feature-flags.md) | Feature flags disponíveis |
|
|
47
|
-
| [header-metadata.md](header-metadata.md) | Padrão de título/subtítulo via header |
|
|
48
|
-
|
|
49
|
-
### Referência
|
|
50
|
-
|
|
51
|
-
| Arquivo | Descrição |
|
|
52
|
-
|---------|-----------|
|
|
53
|
-
| [components-registry.md](components-registry.md) | Registry de componentes consolidados |
|
|
1
|
+
# Design System — Padrões Universais
|
|
2
|
+
|
|
3
|
+
> Padrões obrigatórios para todos os projetos que consomem `forlogic-core`.
|
|
4
|
+
> Acessível via cross-project: `@Admin docs/design-system/patterns/`
|
|
5
|
+
|
|
6
|
+
## Índice
|
|
7
|
+
|
|
8
|
+
### Componentes
|
|
9
|
+
|
|
10
|
+
| Arquivo | Descrição |
|
|
11
|
+
|---------|-----------|
|
|
12
|
+
| [action-button.md](action-button.md) | Uso obrigatório do ActionButton em tabelas |
|
|
13
|
+
| [alertdialog-deletion.md](alertdialog-deletion.md) | AlertDialog para exclusões permanentes |
|
|
14
|
+
| [baseform-usage.md](baseform-usage.md) | BaseForm — formulário dinâmico CRUD |
|
|
15
|
+
| [baseform-custom-fields.md](baseform-custom-fields.md) | Campos customizados no BaseForm |
|
|
16
|
+
| [combo-tree.md](combo-tree.md) | ComboTree — seleção hierárquica |
|
|
17
|
+
| [delete-confirmation.md](delete-confirmation.md) | Dialog de confirmação de exclusão |
|
|
18
|
+
| [dialog-structure.md](dialog-structure.md) | Tamanhos e estrutura obrigatória do Dialog |
|
|
19
|
+
| [dialog-variants.md](dialog-variants.md) | Variantes semânticas do Dialog |
|
|
20
|
+
| [pagination.md](pagination.md) | Paginação padronizada |
|
|
21
|
+
|
|
22
|
+
### Padrões de Layout & Scroll
|
|
23
|
+
|
|
24
|
+
| Arquivo | Descrição |
|
|
25
|
+
|---------|-----------|
|
|
26
|
+
| [dialog-body-scroll.md](dialog-body-scroll.md) | Scroll interno em Dialogs |
|
|
27
|
+
| [body-content-scroll.md](body-content-scroll.md) | Scroll em páginas (BodyContent) |
|
|
28
|
+
| [single-scroll.md](single-scroll.md) | Padrão de scroll único no viewport |
|
|
29
|
+
|
|
30
|
+
### Padrões CRUD
|
|
31
|
+
|
|
32
|
+
| Arquivo | Descrição |
|
|
33
|
+
|---------|-----------|
|
|
34
|
+
| [crud-toolbar.md](crud-toolbar.md) | Layout 3 zonas da toolbar |
|
|
35
|
+
| [crud-bulk-actions.md](crud-bulk-actions.md) | Ações em lote via dropdown |
|
|
36
|
+
| [crud-defaults.md](crud-defaults.md) | Defaults obrigatórios (resize, sort, etc.) |
|
|
37
|
+
| [crud-config-props.md](crud-config-props.md) | Props padronizadas de configuração |
|
|
38
|
+
|
|
39
|
+
### Setup & Configuração
|
|
40
|
+
|
|
41
|
+
| Arquivo | Descrição |
|
|
42
|
+
|---------|-----------|
|
|
43
|
+
| [core-providers.md](core-providers.md) | Setup obrigatório do CoreProviders |
|
|
44
|
+
| [vite-tailwind-setup.md](vite-tailwind-setup.md) | Configuração Vite + Tailwind |
|
|
45
|
+
| [i18n-setup.md](i18n-setup.md) | Setup de internacionalização |
|
|
46
|
+
| [feature-flags.md](feature-flags.md) | Feature flags disponíveis |
|
|
47
|
+
| [header-metadata.md](header-metadata.md) | Padrão de título/subtítulo via header |
|
|
48
|
+
|
|
49
|
+
### Referência
|
|
50
|
+
|
|
51
|
+
| Arquivo | Descrição |
|
|
52
|
+
|---------|-----------|
|
|
53
|
+
| [components-registry.md](components-registry.md) | Registry de componentes consolidados |
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
# Padrão: ActionButton para Tabelas
|
|
2
|
-
|
|
3
|
-
Uso de `ActionButton` é **OBRIGATÓRIO** para menus de ação em linhas de tabela.
|
|
4
|
-
|
|
5
|
-
```tsx
|
|
6
|
-
// ❌ PROIBIDO - botão genérico com ícone manual
|
|
7
|
-
<Button variant="ghost" size="icon">
|
|
8
|
-
<MoreHorizontal className="h-4 w-4" />
|
|
9
|
-
</Button>
|
|
10
|
-
|
|
11
|
-
// ✅ CORRETO - ActionButton padronizado
|
|
12
|
-
import { ActionButton } from 'forlogic-core';
|
|
13
|
-
|
|
14
|
-
<ActionButton
|
|
15
|
-
items={[
|
|
16
|
-
{ label: 'Editar', icon: Edit, onClick: handleEdit },
|
|
17
|
-
{ label: 'Excluir', icon: Trash, onClick: handleDelete, variant: 'destructive' }
|
|
18
|
-
]}
|
|
19
|
-
/>
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
**Motivo**: Garante mesma estética e comportamento em todas as tabelas do sistema.
|
|
1
|
+
# Padrão: ActionButton para Tabelas
|
|
2
|
+
|
|
3
|
+
Uso de `ActionButton` é **OBRIGATÓRIO** para menus de ação em linhas de tabela.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
// ❌ PROIBIDO - botão genérico com ícone manual
|
|
7
|
+
<Button variant="ghost" size="icon">
|
|
8
|
+
<MoreHorizontal className="h-4 w-4" />
|
|
9
|
+
</Button>
|
|
10
|
+
|
|
11
|
+
// ✅ CORRETO - ActionButton padronizado
|
|
12
|
+
import { ActionButton } from 'forlogic-core';
|
|
13
|
+
|
|
14
|
+
<ActionButton
|
|
15
|
+
items={[
|
|
16
|
+
{ label: 'Editar', icon: Edit, onClick: handleEdit },
|
|
17
|
+
{ label: 'Excluir', icon: Trash, onClick: handleDelete, variant: 'destructive' }
|
|
18
|
+
]}
|
|
19
|
+
/>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Motivo**: Garante mesma estética e comportamento em todas as tabelas do sistema.
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
# Padrão: AlertDialog para Exclusão Permanente
|
|
2
|
-
|
|
3
|
-
AlertDialog é usado **apenas** para exclusões permanentes que requerem digitação de confirmação:
|
|
4
|
-
|
|
5
|
-
```tsx
|
|
6
|
-
<AlertDialog open={open} onOpenChange={setOpen}>
|
|
7
|
-
<AlertDialogContent>
|
|
8
|
-
<AlertDialogHeader className="border-b pb-4">
|
|
9
|
-
<AlertDialogTitle className="text-center">
|
|
10
|
-
Exclusão Permanente
|
|
11
|
-
</AlertDialogTitle>
|
|
12
|
-
</AlertDialogHeader>
|
|
13
|
-
|
|
14
|
-
<div className="py-4 space-y-4">
|
|
15
|
-
<div className="flex justify-center">
|
|
16
|
-
<AlertTriangle className="h-12 w-12 text-destructive" />
|
|
17
|
-
</div>
|
|
18
|
-
<AlertDialogDescription className="text-center">
|
|
19
|
-
Esta ação é irreversível. Digite <strong>EXCLUIR</strong> para confirmar.
|
|
20
|
-
</AlertDialogDescription>
|
|
21
|
-
<Input
|
|
22
|
-
value={confirmation}
|
|
23
|
-
onChange={(e) => setConfirmation(e.target.value)}
|
|
24
|
-
placeholder="Digite EXCLUIR"
|
|
25
|
-
className="text-center"
|
|
26
|
-
/>
|
|
27
|
-
</div>
|
|
28
|
-
|
|
29
|
-
<AlertDialogFooter>
|
|
30
|
-
<AlertDialogCancel>Cancelar</AlertDialogCancel>
|
|
31
|
-
<AlertDialogAction
|
|
32
|
-
disabled={confirmation !== 'EXCLUIR'}
|
|
33
|
-
onClick={handlePermanentDelete}
|
|
34
|
-
className="bg-destructive hover:bg-destructive/90"
|
|
35
|
-
>
|
|
36
|
-
Excluir Permanentemente
|
|
37
|
-
</AlertDialogAction>
|
|
38
|
-
</AlertDialogFooter>
|
|
39
|
-
</AlertDialogContent>
|
|
40
|
-
</AlertDialog>
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
**Quando usar:**
|
|
44
|
-
- ✅ Exclusão de dados sem possibilidade de recuperação
|
|
45
|
-
- ✅ Ações destrutivas em massa críticas
|
|
46
|
-
- ❌ NÃO usar para soft deletes (usar Dialog padrão)
|
|
1
|
+
# Padrão: AlertDialog para Exclusão Permanente
|
|
2
|
+
|
|
3
|
+
AlertDialog é usado **apenas** para exclusões permanentes que requerem digitação de confirmação:
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
<AlertDialog open={open} onOpenChange={setOpen}>
|
|
7
|
+
<AlertDialogContent>
|
|
8
|
+
<AlertDialogHeader className="border-b pb-4">
|
|
9
|
+
<AlertDialogTitle className="text-center">
|
|
10
|
+
Exclusão Permanente
|
|
11
|
+
</AlertDialogTitle>
|
|
12
|
+
</AlertDialogHeader>
|
|
13
|
+
|
|
14
|
+
<div className="py-4 space-y-4">
|
|
15
|
+
<div className="flex justify-center">
|
|
16
|
+
<AlertTriangle className="h-12 w-12 text-destructive" />
|
|
17
|
+
</div>
|
|
18
|
+
<AlertDialogDescription className="text-center">
|
|
19
|
+
Esta ação é irreversível. Digite <strong>EXCLUIR</strong> para confirmar.
|
|
20
|
+
</AlertDialogDescription>
|
|
21
|
+
<Input
|
|
22
|
+
value={confirmation}
|
|
23
|
+
onChange={(e) => setConfirmation(e.target.value)}
|
|
24
|
+
placeholder="Digite EXCLUIR"
|
|
25
|
+
className="text-center"
|
|
26
|
+
/>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<AlertDialogFooter>
|
|
30
|
+
<AlertDialogCancel>Cancelar</AlertDialogCancel>
|
|
31
|
+
<AlertDialogAction
|
|
32
|
+
disabled={confirmation !== 'EXCLUIR'}
|
|
33
|
+
onClick={handlePermanentDelete}
|
|
34
|
+
className="bg-destructive hover:bg-destructive/90"
|
|
35
|
+
>
|
|
36
|
+
Excluir Permanentemente
|
|
37
|
+
</AlertDialogAction>
|
|
38
|
+
</AlertDialogFooter>
|
|
39
|
+
</AlertDialogContent>
|
|
40
|
+
</AlertDialog>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Quando usar:**
|
|
44
|
+
- ✅ Exclusão de dados sem possibilidade de recuperação
|
|
45
|
+
- ✅ Ações destrutivas em massa críticas
|
|
46
|
+
- ❌ NÃO usar para soft deletes (usar Dialog padrão)
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
# Padrão: BaseForm — Campos Customizados
|
|
2
|
-
|
|
3
|
-
Campos customizados no BaseForm usam `type: 'custom'` com `component` ou `render`:
|
|
4
|
-
|
|
5
|
-
```tsx
|
|
6
|
-
// Opção 1: Componente externo
|
|
7
|
-
{
|
|
8
|
-
name: 'module_id',
|
|
9
|
-
label: 'Módulo',
|
|
10
|
-
type: 'custom',
|
|
11
|
-
required: true,
|
|
12
|
-
component: ModuleCombobox,
|
|
13
|
-
componentProps: {
|
|
14
|
-
placeholder: 'Selecione...',
|
|
15
|
-
},
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Opção 2: Props dinâmicas baseadas em formData
|
|
19
|
-
{
|
|
20
|
-
name: 'file',
|
|
21
|
-
label: 'Arquivo',
|
|
22
|
-
type: 'custom',
|
|
23
|
-
component: FileUpload,
|
|
24
|
-
componentProps: (formData) => ({
|
|
25
|
-
required: !formData?.id,
|
|
26
|
-
accept: '.pdf,.doc',
|
|
27
|
-
}),
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Opção 3: Render function inline
|
|
31
|
-
{
|
|
32
|
-
name: 'priority',
|
|
33
|
-
label: 'Prioridade',
|
|
34
|
-
type: 'custom',
|
|
35
|
-
render: ({ value, onChange, error }) => (
|
|
36
|
-
<div className="flex gap-2">
|
|
37
|
-
{['low', 'medium', 'high'].map(p => (
|
|
38
|
-
<Button
|
|
39
|
-
key={p}
|
|
40
|
-
variant={value === p ? 'default' : 'outline'}
|
|
41
|
-
onClick={() => onChange(p)}
|
|
42
|
-
>
|
|
43
|
-
{p}
|
|
44
|
-
</Button>
|
|
45
|
-
))}
|
|
46
|
-
</div>
|
|
47
|
-
),
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
**Interface do componente customizado:**
|
|
52
|
-
```tsx
|
|
53
|
-
interface CustomFieldProps {
|
|
54
|
-
value: any;
|
|
55
|
-
onChange: (value: any) => void;
|
|
56
|
-
error?: string;
|
|
57
|
-
disabled?: boolean;
|
|
58
|
-
}
|
|
59
|
-
```
|
|
1
|
+
# Padrão: BaseForm — Campos Customizados
|
|
2
|
+
|
|
3
|
+
Campos customizados no BaseForm usam `type: 'custom'` com `component` ou `render`:
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
// Opção 1: Componente externo
|
|
7
|
+
{
|
|
8
|
+
name: 'module_id',
|
|
9
|
+
label: 'Módulo',
|
|
10
|
+
type: 'custom',
|
|
11
|
+
required: true,
|
|
12
|
+
component: ModuleCombobox,
|
|
13
|
+
componentProps: {
|
|
14
|
+
placeholder: 'Selecione...',
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Opção 2: Props dinâmicas baseadas em formData
|
|
19
|
+
{
|
|
20
|
+
name: 'file',
|
|
21
|
+
label: 'Arquivo',
|
|
22
|
+
type: 'custom',
|
|
23
|
+
component: FileUpload,
|
|
24
|
+
componentProps: (formData) => ({
|
|
25
|
+
required: !formData?.id,
|
|
26
|
+
accept: '.pdf,.doc',
|
|
27
|
+
}),
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Opção 3: Render function inline
|
|
31
|
+
{
|
|
32
|
+
name: 'priority',
|
|
33
|
+
label: 'Prioridade',
|
|
34
|
+
type: 'custom',
|
|
35
|
+
render: ({ value, onChange, error }) => (
|
|
36
|
+
<div className="flex gap-2">
|
|
37
|
+
{['low', 'medium', 'high'].map(p => (
|
|
38
|
+
<Button
|
|
39
|
+
key={p}
|
|
40
|
+
variant={value === p ? 'default' : 'outline'}
|
|
41
|
+
onClick={() => onChange(p)}
|
|
42
|
+
>
|
|
43
|
+
{p}
|
|
44
|
+
</Button>
|
|
45
|
+
))}
|
|
46
|
+
</div>
|
|
47
|
+
),
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Interface do componente customizado:**
|
|
52
|
+
```tsx
|
|
53
|
+
interface CustomFieldProps {
|
|
54
|
+
value: any;
|
|
55
|
+
onChange: (value: any) => void;
|
|
56
|
+
error?: string;
|
|
57
|
+
disabled?: boolean;
|
|
58
|
+
}
|
|
59
|
+
```
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
# Padrão: BaseForm — Formulário Dinâmico
|
|
2
|
-
|
|
3
|
-
BaseForm é o formulário dinâmico do sistema CRUD, configurado via `sections` e `fields`.
|
|
4
|
-
|
|
5
|
-
```tsx
|
|
6
|
-
import BaseForm from 'forlogic-core/crud/components/BaseForm';
|
|
7
|
-
|
|
8
|
-
const sections: FormSection[] = [
|
|
9
|
-
{
|
|
10
|
-
id: 'basic',
|
|
11
|
-
title: 'Informações Básicas',
|
|
12
|
-
fields: [
|
|
13
|
-
{ name: 'title', label: 'Título', type: 'text', required: true },
|
|
14
|
-
{ name: 'email', label: 'E-mail', type: 'email' },
|
|
15
|
-
{ name: 'is_active', label: 'Ativo', type: 'switch' },
|
|
16
|
-
],
|
|
17
|
-
},
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
<BaseForm
|
|
21
|
-
title="Novo Item"
|
|
22
|
-
sections={sections}
|
|
23
|
-
initialData={data}
|
|
24
|
-
open={isOpen}
|
|
25
|
-
onSubmit={handleSubmit}
|
|
26
|
-
onCancel={() => setIsOpen(false)}
|
|
27
|
-
/>
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
**Tipos de campo suportados:**
|
|
31
|
-
`text`, `email`, `password`, `number`, `textarea`, `select`, `multiselect`, `date`, `datetime-local`, `switch`, `checkbox`, `color`, `color-picker`, `icon-picker`, `user-select`, `custom`
|
|
32
|
-
|
|
33
|
-
**Grupos de campos:**
|
|
34
|
-
```tsx
|
|
35
|
-
{
|
|
36
|
-
name: 'row1',
|
|
37
|
-
type: 'group',
|
|
38
|
-
layout: 'horizontal', // ou 'vertical'
|
|
39
|
-
wrapperClassName: 'col-span-full',
|
|
40
|
-
fields: [...]
|
|
41
|
-
}
|
|
42
|
-
```
|
|
1
|
+
# Padrão: BaseForm — Formulário Dinâmico
|
|
2
|
+
|
|
3
|
+
BaseForm é o formulário dinâmico do sistema CRUD, configurado via `sections` e `fields`.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import BaseForm from 'forlogic-core/crud/components/BaseForm';
|
|
7
|
+
|
|
8
|
+
const sections: FormSection[] = [
|
|
9
|
+
{
|
|
10
|
+
id: 'basic',
|
|
11
|
+
title: 'Informações Básicas',
|
|
12
|
+
fields: [
|
|
13
|
+
{ name: 'title', label: 'Título', type: 'text', required: true },
|
|
14
|
+
{ name: 'email', label: 'E-mail', type: 'email' },
|
|
15
|
+
{ name: 'is_active', label: 'Ativo', type: 'switch' },
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
<BaseForm
|
|
21
|
+
title="Novo Item"
|
|
22
|
+
sections={sections}
|
|
23
|
+
initialData={data}
|
|
24
|
+
open={isOpen}
|
|
25
|
+
onSubmit={handleSubmit}
|
|
26
|
+
onCancel={() => setIsOpen(false)}
|
|
27
|
+
/>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Tipos de campo suportados:**
|
|
31
|
+
`text`, `email`, `password`, `number`, `textarea`, `select`, `multiselect`, `date`, `datetime-local`, `switch`, `checkbox`, `color`, `color-picker`, `icon-picker`, `user-select`, `custom`
|
|
32
|
+
|
|
33
|
+
**Grupos de campos:**
|
|
34
|
+
```tsx
|
|
35
|
+
{
|
|
36
|
+
name: 'row1',
|
|
37
|
+
type: 'group',
|
|
38
|
+
layout: 'horizontal', // ou 'vertical'
|
|
39
|
+
wrapperClassName: 'col-span-full',
|
|
40
|
+
fields: [...]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
# Padrão: Scroll em Páginas (BodyContent)
|
|
2
|
-
|
|
3
|
-
## Quando Usar Cada Abordagem
|
|
4
|
-
|
|
5
|
-
| Cenário | Componente | Classes |
|
|
6
|
-
|---------|------------|---------|
|
|
7
|
-
| **Página nova (Design System)** | `BodyContent` + `ContentContainer` | Padrão, sem classes extras |
|
|
8
|
-
| **Página legada (design próprio)** | `BodyContent` | `className="bg-transparent p-0"` |
|
|
9
|
-
| **Módulo customizado** | `div` simples | `className="h-full overflow-y-auto"` |
|
|
10
|
-
|
|
11
|
-
## Exemplos
|
|
12
|
-
|
|
13
|
-
### ✅ Página Nova (Design System Completo)
|
|
14
|
-
```tsx
|
|
15
|
-
import { BodyContent, ContentContainer } from 'forlogic-core';
|
|
16
|
-
|
|
17
|
-
<BodyContent breadcrumbs={[{ label: 'Home', href: '/' }, { label: 'Página' }]}>
|
|
18
|
-
<ContentContainer title="Título" subtitle="Descrição">
|
|
19
|
-
{/* Conteúdo */}
|
|
20
|
-
</ContentContainer>
|
|
21
|
-
</BodyContent>
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### ✅ Página Legada (Preservar Design Original)
|
|
25
|
-
```tsx
|
|
26
|
-
import { BodyContent } from 'forlogic-core';
|
|
27
|
-
|
|
28
|
-
<BodyContent className="bg-transparent p-0">
|
|
29
|
-
{/* Conteúdo original mantido sem alterações */}
|
|
30
|
-
<div className="p-6">
|
|
31
|
-
<h1>Título Original</h1>
|
|
32
|
-
</div>
|
|
33
|
-
</BodyContent>
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### ✅ Container Mínimo (Sem BodyContent)
|
|
37
|
-
```tsx
|
|
38
|
-
<div className="h-full overflow-y-auto">
|
|
39
|
-
{/* Conteúdo original */}
|
|
40
|
-
</div>
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## ❌ Erro Comum
|
|
44
|
-
```tsx
|
|
45
|
-
// ERRADO: ContentContainer em página com design próprio
|
|
46
|
-
<BodyContent>
|
|
47
|
-
<ContentContainer>
|
|
48
|
-
{/* Resultado: fundo branco, bordas, padding extra indesejados */}
|
|
49
|
-
</ContentContainer>
|
|
50
|
-
</BodyContent>
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Regra de Ouro
|
|
54
|
-
- `ContentContainer` adiciona: fundo branco, borda, sombra, padding
|
|
55
|
-
- Use apenas quando o design da página DEVE seguir esse padrão
|
|
56
|
-
- Para páginas legadas: `BodyContent className="bg-transparent p-0"`
|
|
1
|
+
# Padrão: Scroll em Páginas (BodyContent)
|
|
2
|
+
|
|
3
|
+
## Quando Usar Cada Abordagem
|
|
4
|
+
|
|
5
|
+
| Cenário | Componente | Classes |
|
|
6
|
+
|---------|------------|---------|
|
|
7
|
+
| **Página nova (Design System)** | `BodyContent` + `ContentContainer` | Padrão, sem classes extras |
|
|
8
|
+
| **Página legada (design próprio)** | `BodyContent` | `className="bg-transparent p-0"` |
|
|
9
|
+
| **Módulo customizado** | `div` simples | `className="h-full overflow-y-auto"` |
|
|
10
|
+
|
|
11
|
+
## Exemplos
|
|
12
|
+
|
|
13
|
+
### ✅ Página Nova (Design System Completo)
|
|
14
|
+
```tsx
|
|
15
|
+
import { BodyContent, ContentContainer } from 'forlogic-core';
|
|
16
|
+
|
|
17
|
+
<BodyContent breadcrumbs={[{ label: 'Home', href: '/' }, { label: 'Página' }]}>
|
|
18
|
+
<ContentContainer title="Título" subtitle="Descrição">
|
|
19
|
+
{/* Conteúdo */}
|
|
20
|
+
</ContentContainer>
|
|
21
|
+
</BodyContent>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### ✅ Página Legada (Preservar Design Original)
|
|
25
|
+
```tsx
|
|
26
|
+
import { BodyContent } from 'forlogic-core';
|
|
27
|
+
|
|
28
|
+
<BodyContent className="bg-transparent p-0">
|
|
29
|
+
{/* Conteúdo original mantido sem alterações */}
|
|
30
|
+
<div className="p-6">
|
|
31
|
+
<h1>Título Original</h1>
|
|
32
|
+
</div>
|
|
33
|
+
</BodyContent>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### ✅ Container Mínimo (Sem BodyContent)
|
|
37
|
+
```tsx
|
|
38
|
+
<div className="h-full overflow-y-auto">
|
|
39
|
+
{/* Conteúdo original */}
|
|
40
|
+
</div>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## ❌ Erro Comum
|
|
44
|
+
```tsx
|
|
45
|
+
// ERRADO: ContentContainer em página com design próprio
|
|
46
|
+
<BodyContent>
|
|
47
|
+
<ContentContainer>
|
|
48
|
+
{/* Resultado: fundo branco, bordas, padding extra indesejados */}
|
|
49
|
+
</ContentContainer>
|
|
50
|
+
</BodyContent>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Regra de Ouro
|
|
54
|
+
- `ContentContainer` adiciona: fundo branco, borda, sombra, padding
|
|
55
|
+
- Use apenas quando o design da página DEVE seguir esse padrão
|
|
56
|
+
- Para páginas legadas: `BodyContent className="bg-transparent p-0"`
|