forlogic-core 1.16.10 → 1.16.12

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 (44) hide show
  1. package/.note/memory/features/crud-defaults-batteries-included.md +14 -0
  2. package/.note/memory/patterns/alias-url-resolution.md +39 -0
  3. package/.note/memory/{rules → patterns}/doc-sync-rule.md +1 -1
  4. package/.note/memory/patterns/dynamic-supabase-config.md +4 -0
  5. package/.note/memory/patterns/environment-detection-logic.md +35 -0
  6. package/dist/auth/components/AliasRouteGuard.d.ts +25 -0
  7. package/dist/auth/services/AuthService.d.ts +1 -1
  8. package/dist/auth/services/TokenManager.d.ts +6 -0
  9. package/dist/bin/pull-docs.js +106 -28
  10. package/dist/config/index.d.ts +8 -0
  11. package/dist/crud/components/ColumnSettingsPopover.d.ts +2 -1
  12. package/dist/crud/components/CrudTable.d.ts +3 -1
  13. package/dist/crud/hooks/useColumnManager.d.ts +2 -0
  14. package/dist/crud/primitives/TreeTable.d.ts +1 -1
  15. package/dist/crud/primitives/types.d.ts +11 -0
  16. package/dist/docs/KNOWLEDGE.md +9 -7
  17. package/dist/hooks/useAliasFromUrl.d.ts +33 -0
  18. package/dist/index.css +1 -1
  19. package/dist/index.css.map +1 -1
  20. package/dist/index.d.ts +4 -0
  21. package/dist/index.esm.js +1 -1
  22. package/dist/index.js +1 -1
  23. package/dist/leadership/components/LeadershipPage.d.ts +12 -1
  24. package/dist/leadership/index.d.ts +0 -1
  25. package/dist/leadership/types.d.ts +6 -0
  26. package/dist/utils/index.d.ts +1 -1
  27. package/dist/utils/linkHelpers.d.ts +5 -0
  28. package/docs/KNOWLEDGE.md +9 -7
  29. package/package.json +2 -2
  30. package/.note/memory/architecture/documentation-strategy.md +0 -59
  31. package/.note/memory/patterns/deprecated-patterns.md +0 -14
  32. package/.note/memory/patterns/spa-navigation-pattern.md +0 -19
  33. package/.note/memory/rules/i18n-import-rule.md +0 -29
  34. package/.note/memory/rules/lib-first-rule.md +0 -42
  35. package/.note/memory/rules/no-auto-index-rule.md +0 -48
  36. package/.note/memory/rules/no-delete-policy-rule.md +0 -52
  37. package/.note/memory/rules/no-env-modification-rule.md +0 -19
  38. package/.note/memory/rules/rls-syntax-rule.md +0 -50
  39. package/.note/memory/rules/sql-naming-rule.md +0 -23
  40. package/.note/memory/rules/supabase-import-rule.md +0 -31
  41. package/.note/memory/rules/supabase-schema-rule.md +0 -20
  42. /package/.note/memory/{ui/components → components}/combo-tree.md +0 -0
  43. /package/.note/memory/{documentation/consolidated-components-registry.md → patterns/components-registry.md} +0 -0
  44. /package/.note/memory/{ui/design-system → patterns}/documentation-standard.md +0 -0
@@ -0,0 +1,14 @@
1
+ # Memory: features/crud-defaults-batteries-included
2
+
3
+ Todos os CRUDs (CrudTable, createCrudPage) agora incluem por padrão:
4
+ - **Column resize** (`enableColumnResize=true`) — já era default
5
+ - **Column manager** (`enableColumnManager=true`) — botão ⋮ no header da coluna "Ações"
6
+ - **Sort** — já era suportado via `sortable` nas colunas
7
+ - **Busca** — por padrão usa a busca global do header (não a action bar). Para busca na action bar, usar `showSearch=true`
8
+ - **Storage keys** — `createCrudPage` gera automaticamente `columnManagerStorageKey` e `resizeStorageKey` a partir do `entityName`
9
+
10
+ **NÃO vem por padrão:**
11
+ - **Agrupamento** (`enableGrouping=false`) — precisa ser habilitado explicitamente com `enableGrouping={true}`
12
+ - **Busca na action bar** (`showSearch=false`) — padrão é busca no header
13
+
14
+ **Paginação:** padrão de 25 itens por página.
@@ -0,0 +1,39 @@
1
+ # Alias via URL — Resolução de Unidade por Rota
2
+
3
+ ## Padrão
4
+
5
+ O alias da unidade ativa deve **sempre** estar presente na URL como primeiro segmento de rota (`/:alias/...`). O `AliasRouteGuard` garante sincronização bidirecional entre URL e sessão.
6
+
7
+ ## Componentes
8
+
9
+ ### `useAliasFromUrl(options?)`
10
+ Hook que extrai o alias do param de rota e valida contra `companies` do `useAuth()`.
11
+
12
+ Retorna: `{ urlAlias, isAliasMismatch, isValidAlias, isMissing, matchedCompany }`
13
+
14
+ ### `AliasRouteGuard`
15
+ Wrapper de rota que sincroniza alias da URL com a sessão. Comportamento:
16
+
17
+ | Cenário | Ação |
18
+ |---------|------|
19
+ | Alias ausente na URL | Redireciona para `/{aliasAtivo}/{path}` |
20
+ | Alias diferente do ativo | Chama `switchUnit()` + loading |
21
+ | Alias correto | Renderiza children |
22
+ | Alias inválido | Redireciona para `/{aliasDefault}/{path}` |
23
+ | Troca via seletor de unidades | Atualiza URL automaticamente |
24
+
25
+ ## Uso nos Consumidores
26
+
27
+ ```tsx
28
+ <Route element={<ProtectedRoute><AliasRouteGuard><Outlet /></AliasRouteGuard></ProtectedRoute>}>
29
+ <Route path="/:alias/documents" element={<DocumentsPage />} />
30
+ <Route path="/:alias/documents/:id" element={<DocumentDetailPage />} />
31
+ </Route>
32
+ ```
33
+
34
+ ## Regras
35
+ - Guard só age após `isLoading=false && isAuthenticated=true`
36
+ - Usa `replace: true` para evitar poluir o histórico
37
+ - Se `switchUnit` falha, mantém alias atual (sem loop)
38
+ - `switchUnit` já faz `queryClient.clear()` — cache é limpo automaticamente
39
+ - Navegação inter-módulos já usa `{alias}` nas URLs (`modulesData.ts`)
@@ -29,4 +29,4 @@ lib/services/<Service>.ts → src/design-system/docs/ServicesDoc.tsx
29
29
  lib/components/layout/<comp>.tsx → src/design-system/docs/components/layout/<Comp>Doc.tsx
30
30
  ```
31
31
 
32
- Consultar `.note/memory/documentation/consolidated-components-registry.md` para componentes agrupados sob uma única doc.
32
+ Consultar `.note/memory/patterns/components-registry.md` para componentes agrupados sob uma única doc.
@@ -0,0 +1,4 @@
1
+ # Memory: patterns/dynamic-supabase-config
2
+ Updated: 2026-03-24
3
+
4
+ As credenciais do Supabase vêm exclusivamente do `.env` (auto-populado pelo Lovable ao trocar banco). O Vite injeta automaticamente variáveis `VITE_*` em `import.meta.env` — não há bloco `define` manual nem extração de `client.ts`. O `vite.config.ts` usa `loadEnv()` apenas para ler o project ID no contexto Node (CSP headers). O `SupabaseSingleton` lê `import.meta.env.VITE_SUPABASE_URL` e `VITE_SUPABASE_PUBLISHABLE_KEY` em runtime no browser.
@@ -0,0 +1,35 @@
1
+ # Memory: patterns/environment-detection-logic
2
+ Updated: 2026-03-24
3
+
4
+ O sistema separa duas preocupações independentes de ambiente:
5
+
6
+ ## 1. Método de autenticação (`shouldUseDevTokens()` / `isLovablePreview()`)
7
+ Detecta se o app roda em contexto de desenvolvimento (preview Lovable via iframe, `*.lovable.dev`, localhost ou `import.meta.env.DEV`). Quando true, usa a edge function `dev-tokens` do Supabase conectado para autenticar. Quando false (app publicado), usa OAuth padrão do Qualiex.
8
+
9
+ ## 2. Qual API usar (`getEnvironmentConfig()` / `isDevSupabaseProject()`)
10
+ Compara o project ID do Supabase conectado com `PROD_PROJECT_ID` (`ccjfvpnndclajkleyqkc`). Se igual → config PROD (API prod, OAuth prod). Se diferente → config DEV (API dev, OAuth dev).
11
+
12
+ ## Fonte de verdade do Project ID
13
+ O project ID vem do `.env` (auto-populado pelo Lovable ao trocar banco), que o Vite injeta automaticamente em `import.meta.env.VITE_SUPABASE_PROJECT_ID`. **Não** é extraído de `src/integrations/supabase/client.ts`. O `vite.config.ts` usa `loadEnv()` apenas no contexto Node para configurar CSP headers.
14
+
15
+ ## Tabela de regras
16
+
17
+ | Cenário | API | Auth |
18
+ |------------------------------|------|------------|
19
+ | Preview + Prod Supabase | Prod | dev-tokens |
20
+ | Preview + Dev Supabase | Dev | dev-tokens |
21
+ | Publicado + Prod Supabase | Prod | OAuth |
22
+ | Publicado + Dev Supabase | Dev | OAuth |
23
+
24
+ ## Guard de troca de projeto (`TokenManager.checkProjectMismatch()`)
25
+ Ao inicializar (`AuthService.initialize()`), o sistema compara `import.meta.env.VITE_SUPABASE_PROJECT_ID` com o valor armazenado em `localStorage('supabase_project_id')`. Se diferente, limpa todos os tokens stale automaticamente antes de qualquer chamada a `validate-token`, evitando 401 desnecessários. Após a limpeza, armazena o novo project ID. Isso garante transição limpa ao trocar de banco Supabase sem erros ou blank screen.
26
+
27
+ ## Funções (lib/config/index.ts)
28
+ - `isLovablePreview()` — detecta contexto de preview/localhost
29
+ - `shouldUseDevTokens()` — wrapper semântico sobre `isLovablePreview()`
30
+ - `isDevEnvironment` — alias deprecated, mantido para compatibilidade
31
+ - `getEnvironmentConfig()` — retorna config PROD ou DEV baseado no project ID
32
+ - `isDevSupabaseProject()` — true se project ID ≠ PROD_PROJECT_ID
33
+
34
+ ## Funções (lib/auth/services/TokenManager.ts)
35
+ - `checkProjectMismatch()` — detecta troca de projeto Supabase e limpa tokens stale
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ export interface AliasRouteGuardProps {
3
+ children: React.ReactNode;
4
+ /** Nome do param de rota (default: "alias") */
5
+ paramName?: string;
6
+ }
7
+ /**
8
+ * Guard de rota que sincroniza o alias da URL com a sessão de autenticação.
9
+ *
10
+ * Comportamento:
11
+ * - **Alias ausente na URL** → Redireciona para `/{aliasAtivo}/{restoDoPath}` (replace)
12
+ * - **Alias presente mas diferente do ativo** → Chama `switchUnit()` + loading
13
+ * - **Alias presente e correto** → Renderiza children
14
+ * - **Alias inválido (não existe em companies)** → Redireciona para `/{aliasDefault}/{restoDoPath}`
15
+ * - **Troca via seletor de unidades** → Atualiza URL automaticamente
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * <Route element={<AliasRouteGuard><Outlet /></AliasRouteGuard>}>
20
+ * <Route path="/:alias/documents" element={<DocumentsPage />} />
21
+ * <Route path="/:alias/documents/:id" element={<DocumentDetailPage />} />
22
+ * </Route>
23
+ * ```
24
+ */
25
+ export declare function AliasRouteGuard({ children, paramName }: AliasRouteGuardProps): import("react/jsx-runtime").JSX.Element;
@@ -20,7 +20,7 @@ export declare class AuthService {
20
20
  /**
21
21
  * Logout do usuário
22
22
  */
23
- static logout(): void;
23
+ static logout(): Promise<void>;
24
24
  /**
25
25
  * Decodifica um token JWT usando TokenService robusto
26
26
  */
@@ -16,6 +16,12 @@ export declare const TokenManager: {
16
16
  generateOAuthState: () => string;
17
17
  generateOAuthNonce: () => string;
18
18
  hasAllTokens: () => boolean;
19
+ /**
20
+ * Detecta troca de projeto Supabase e limpa tokens stale automaticamente.
21
+ * Deve ser chamado ANTES de qualquer validação de token.
22
+ * Retorna true se houve troca (tokens foram limpos).
23
+ */
24
+ checkProjectMismatch: () => boolean;
19
25
  setSupabaseToken: (token: string) => void;
20
26
  areAllTokensValid: () => boolean;
21
27
  clearExpiredTokens: () => boolean;
@@ -29,26 +29,73 @@ function copyFile(src, dest) {
29
29
  fs.copyFileSync(src, dest);
30
30
  return true;
31
31
  }
32
- function copyDirRecursive(src, dest) {
33
- if (!fs.existsSync(src)) {
34
- return 0;
35
- }
36
- let count = 0;
37
- if (!fs.existsSync(dest)) {
38
- fs.mkdirSync(dest, { recursive: true });
39
- }
40
- const entries = fs.readdirSync(src, { withFileTypes: true });
41
- for (const entry of entries) {
42
- const srcPath = path.join(src, entry.name);
43
- const destPath = path.join(dest, entry.name);
44
- if (entry.isDirectory()) {
45
- count += copyDirRecursive(srcPath, destPath);
46
- } else {
47
- fs.copyFileSync(srcPath, destPath);
48
- count++;
32
+ const README_MARKER = "<!-- managed by lib-update -->";
33
+ function generateProjectReadme(readmePath, projectName, coreVersion) {
34
+ const template = `${README_MARKER}
35
+ # ${projectName}
36
+
37
+ > Projeto baseado em [forlogic-core](https://www.npmjs.com/package/forlogic-core) v${coreVersion}
38
+
39
+ ## Setup
40
+
41
+ \`\`\`bash
42
+ # Instalar depend\xEAncias
43
+ npm install
44
+
45
+ # Rodar em desenvolvimento
46
+ npm run dev
47
+
48
+ # Build de produ\xE7\xE3o
49
+ npm run build
50
+ \`\`\`
51
+
52
+ ## Scripts Dispon\xEDveis
53
+
54
+ | Comando | Descri\xE7\xE3o |
55
+ |---------|-----------|
56
+ | \`npm run dev\` | Servidor de desenvolvimento (Vite) |
57
+ | \`npm run build\` | Build de produ\xE7\xE3o |
58
+ | \`npm run preview\` | Preview do build |
59
+ | \`npx lib-update\` | Sincronizar regras e docs do forlogic-core |
60
+
61
+ ## Documenta\xE7\xE3o
62
+
63
+ - \u{1F4D6} **Regras do projeto**: \`docs/KNOWLEDGE.md\`
64
+ - \u{1F916} **Mem\xF3rias da IA**: \`.note/memory/\`
65
+ - \u{1F3A8} **Design System**: Rota \`/ds\` no app (projeto Admin)
66
+ - \u{1F4E6} **forlogic-core**: [README no npm](https://www.npmjs.com/package/forlogic-core)
67
+
68
+ ## Conven\xE7\xF5es
69
+
70
+ - Schema Supabase: \`common\` (nunca \`public\`)
71
+ - Soft delete obrigat\xF3rio (coluna \`deleted_at\`)
72
+ - Sempre usar componentes do \`forlogic-core\` antes de criar novos
73
+ - RLS policies: nunca \`FOR DELETE\`
74
+
75
+ ---
76
+ *Gerado automaticamente por \`lib-update\`. \xDAltima sync: forlogic-core v${coreVersion}*
77
+ ${README_MARKER}`;
78
+ if (fs.existsSync(readmePath)) {
79
+ const existing = fs.readFileSync(readmePath, "utf-8");
80
+ if (existing.includes(README_MARKER)) {
81
+ const markerRegex = new RegExp(
82
+ `${README_MARKER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${README_MARKER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`,
83
+ "m"
84
+ );
85
+ const updated2 = existing.replace(markerRegex, template);
86
+ fs.writeFileSync(readmePath, updated2, "utf-8");
87
+ return true;
49
88
  }
89
+ const updated = template + "\n\n" + existing;
90
+ fs.writeFileSync(readmePath, updated, "utf-8");
91
+ return true;
92
+ }
93
+ const destDir = path.dirname(readmePath);
94
+ if (!fs.existsSync(destDir)) {
95
+ fs.mkdirSync(destDir, { recursive: true });
50
96
  }
51
- return count;
97
+ fs.writeFileSync(readmePath, template, "utf-8");
98
+ return true;
52
99
  }
53
100
  async function syncDocs() {
54
101
  console.log("\u{1F4E5} Sincronizando regras e conven\xE7\xF5es do forlogic-core...\n");
@@ -79,15 +126,46 @@ async function syncDocs() {
79
126
  errorCount++;
80
127
  }
81
128
  }
82
- const rulesSrc = path.join(pkgPath, ".note", "memory", "rules");
83
- const rulesDest = path.join(projectRoot, ".note", "memory", "rules");
84
- if (fs.existsSync(rulesSrc)) {
85
- const filesCopied = copyDirRecursive(rulesSrc, rulesDest);
86
- console.log(`\u2705 .note/memory/rules/ (${filesCopied} arquivos)`);
129
+ const obsoleteFiles = [
130
+ "docs/DESIGN_SYSTEM.md",
131
+ "docs/COMPONENTS.md",
132
+ "docs/PATTERNS.md",
133
+ ".note/memory/rules/supabase-schema-rule.md",
134
+ ".note/memory/rules/supabase-import-rule.md",
135
+ ".note/memory/rules/lib-first-rule.md",
136
+ ".note/memory/rules/no-auto-index-rule.md",
137
+ ".note/memory/rules/no-delete-policy-rule.md",
138
+ ".note/memory/rules/no-env-modification-rule.md",
139
+ ".note/memory/rules/rls-syntax-rule.md",
140
+ ".note/memory/rules/sql-naming-rule.md",
141
+ ".note/memory/rules/i18n-import-rule.md",
142
+ ".note/memory/patterns/deprecated-patterns.md",
143
+ ".note/memory/patterns/spa-navigation-pattern.md",
144
+ ".note/memory/architecture/documentation-strategy.md",
145
+ // Pastas reestruturadas (v2 — padronização 3 pastas)
146
+ ".note/memory/rules/doc-sync-rule.md",
147
+ ".note/memory/ui/components/combo-tree.md",
148
+ ".note/memory/ui/design-system/documentation-standard.md",
149
+ ".note/memory/documentation/consolidated-components-registry.md"
150
+ ];
151
+ let cleanedCount = 0;
152
+ for (const relPath of obsoleteFiles) {
153
+ const fullPath = path.join(projectRoot, relPath);
154
+ if (fs.existsSync(fullPath)) {
155
+ fs.unlinkSync(fullPath);
156
+ console.log(`\u{1F5D1}\uFE0F ${relPath} (removido \u2014 obsoleto)`);
157
+ cleanedCount++;
158
+ }
159
+ }
160
+ if (cleanedCount > 0) {
161
+ successCount++;
162
+ }
163
+ const projectReadmePath = path.join(projectRoot, "README.md");
164
+ const projectName = path.basename(projectRoot);
165
+ const readmeGenerated = generateProjectReadme(projectReadmePath, projectName, pkgJson.version);
166
+ if (readmeGenerated) {
167
+ console.log(`\u2705 README.md (gerado/atualizado)`);
87
168
  successCount++;
88
- } else {
89
- console.warn("\u26A0\uFE0F .note/memory/rules/ \u2014 n\xE3o encontrado no pacote");
90
- errorCount++;
91
169
  }
92
170
  console.log("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
93
171
  console.log(`\u{1F389} Sincroniza\xE7\xE3o conclu\xEDda!`);
@@ -98,8 +176,8 @@ async function syncDocs() {
98
176
  console.log("");
99
177
  if (successCount > 0) {
100
178
  console.log("\u{1F4A1} Arquivos sincronizados:");
101
- console.log(" docs/KNOWLEDGE.md \u2014 Regras cr\xEDticas + mapa de m\xF3dulos");
102
- console.log(" .note/memory/rules/ \u2014 Regras de schema, RLS, \xEDndices, .env");
179
+ console.log(" docs/KNOWLEDGE.md \u2014 Regras cr\xEDticas + mapa de m\xF3dulos (fonte \xFAnica de verdade)");
180
+ console.log(" README.md \u2014 Template com setup, scripts e links");
103
181
  console.log("");
104
182
  console.log("\u{1F4D6} Documenta\xE7\xE3o de componentes, props e padr\xF5es s\xE3o lidos");
105
183
  console.log(" diretamente do forlogic-core via cross-project.\n");
@@ -19,6 +19,14 @@ export declare const CRUD_CONFIG: {
19
19
  export declare const SEARCH_CONFIG: {
20
20
  readonly debounceDelay: 500;
21
21
  };
22
+ export declare const isLovablePreview: () => boolean;
23
+ /**
24
+ * Determines auth method: true → use dev-tokens edge function, false → use OAuth.
25
+ * This is independent of which API environment (prod/dev) is used — that's decided
26
+ * by getEnvironmentConfig() based on the Supabase project ID.
27
+ */
28
+ export declare const shouldUseDevTokens: () => boolean;
29
+ /** @deprecated Use `isLovablePreview()` or `shouldUseDevTokens()` instead */
22
30
  export declare const isDevEnvironment: () => boolean;
23
31
  export { isDevSupabaseProject } from './environments';
24
32
  export declare const getQualiexApiUrl: () => string;
@@ -5,6 +5,7 @@ export interface ColumnSettingsPopoverProps<T> {
5
5
  isColumnHidden: (key: string) => boolean;
6
6
  toggleColumn: (key: string) => void;
7
7
  showAllColumns: () => void;
8
+ resetColumns?: () => void;
8
9
  reorderColumns: (fromIndex: number, toIndex: number) => void;
9
10
  /** @deprecated Use groupByColumns + addGroupByColumn + removeGroupByColumn */
10
11
  groupByColumn?: string | null;
@@ -14,4 +15,4 @@ export interface ColumnSettingsPopoverProps<T> {
14
15
  addGroupByColumn?: (key: string) => void;
15
16
  removeGroupByColumn?: (key: string) => void;
16
17
  }
17
- export declare function ColumnSettingsPopover<T extends BaseEntity>({ columns, columnOrder, isColumnHidden, toggleColumn, showAllColumns, reorderColumns, groupByColumn, setGroupByColumn, groupByColumns, addGroupByColumn, removeGroupByColumn, }: ColumnSettingsPopoverProps<T>): import("react/jsx-runtime").JSX.Element;
18
+ export declare function ColumnSettingsPopover<T extends BaseEntity>({ columns, columnOrder, isColumnHidden, toggleColumn, showAllColumns, reorderColumns, groupByColumn, setGroupByColumn, groupByColumns, addGroupByColumn, removeGroupByColumn, resetColumns, }: ColumnSettingsPopoverProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -40,6 +40,8 @@ export interface CrudTableProps<T extends BaseEntity & {
40
40
  resizeStorageKey?: string;
41
41
  enableColumnManager?: boolean;
42
42
  columnManagerStorageKey?: string;
43
+ /** Habilita agrupamento de colunas (GroupDropZone + opções de grupo no ColumnSettings). Default: false */
44
+ enableGrouping?: boolean;
43
45
  }
44
- export declare const CrudTable: <T extends BaseEntity>({ manager, columns, onEdit, onView, onToggleStatus, onDelete, renderActions, customRowActions, enableBulkActions, rowActionsVariant, onNew, newButtonLabel, showNewButton, customActions, hideActionBar, showActionBar, showSearch, searchValue, onSearchChange, searchPlaceholder, bulkActions, onBulkDelete, filters, viewMode, onViewModeChange, showViewToggle, enableColumnResize, resizeStorageKey, enableColumnManager, columnManagerStorageKey, }: CrudTableProps<T>) => import("react/jsx-runtime").JSX.Element;
46
+ export declare const CrudTable: <T extends BaseEntity>({ manager, columns, onEdit, onView, onToggleStatus, onDelete, renderActions, customRowActions, enableBulkActions, rowActionsVariant, onNew, newButtonLabel, showNewButton, customActions, hideActionBar, showActionBar, showSearch, searchValue, onSearchChange, searchPlaceholder, bulkActions, onBulkDelete, filters, viewMode, onViewModeChange, showViewToggle, enableColumnResize, resizeStorageKey, enableColumnManager, columnManagerStorageKey, enableGrouping, }: CrudTableProps<T>) => import("react/jsx-runtime").JSX.Element;
45
47
  export default CrudTable;
@@ -20,6 +20,8 @@ export interface UseColumnManagerReturn<T> {
20
20
  toggleColumn: (key: string) => void;
21
21
  /** Show all columns */
22
22
  showAllColumns: () => void;
23
+ /** Reset columns to default order and visibility */
24
+ resetColumns: () => void;
23
25
  /** Current column order (keys) */
24
26
  columnOrder: string[];
25
27
  /** Reorder columns */
@@ -1,2 +1,2 @@
1
1
  import type { TreeNode, TreeTableProps } from './types';
2
- export declare function TreeTable<T extends TreeNode>({ data, columns, nameKey, nameHeader, iconComponent, expandedIds, onToggleExpand, onRowClick, renderActions, actionsHeader, rowActionsVariant, isLoading, emptyMessage, className, }: TreeTableProps<T>): import("react/jsx-runtime").JSX.Element;
2
+ export declare function TreeTable<T extends TreeNode>({ data, columns, nameKey, nameHeader, iconComponent, expandedIds, onToggleExpand, onRowClick, renderActions, actionsHeader, rowActionsVariant, isLoading, emptyMessage, className, enableSelection, selectedIds: selectedIdsArray, onSelectItem, onSelectAll, isAllSelected, enableRowDrag, onMoveNode, onMoveNodes, }: TreeTableProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -98,6 +98,17 @@ export interface TreeTableProps<T extends TreeNode = TreeNode> {
98
98
  isLoading?: boolean;
99
99
  emptyMessage?: string;
100
100
  className?: string;
101
+ enableSelection?: boolean;
102
+ selectedIds?: string[];
103
+ onSelectItem?: (id: string) => void;
104
+ onSelectAll?: () => void;
105
+ isAllSelected?: boolean;
106
+ /** Habilita drag-and-drop de linhas para reordenar a hierarquia */
107
+ enableRowDrag?: boolean;
108
+ /** Callback ao mover um nó: targetId=null significa tornar raiz */
109
+ onMoveNode?: (draggedId: string, targetId: string | null) => void;
110
+ /** Callback ao mover múltiplos nós (seleção em lote): targetId=null significa tornar raiz */
111
+ onMoveNodes?: (draggedIds: string[], targetId: string | null) => void;
101
112
  }
102
113
  export interface FilterBarProps {
103
114
  searchValue?: string;
@@ -98,10 +98,12 @@ supabase.from('tabela').select('*');
98
98
 
99
99
  ## 6. Fontes de Contexto
100
100
 
101
- | Fonte | Caminho |
102
- |-------|---------|
103
- | Memory rules | `.note/memory/rules/` |
104
- | Memory patterns | `.note/memory/patterns/` |
105
- | Memory components | `.note/memory/components/` |
106
- | Código-fonte da lib | Cross-project → projeto **Admin** (forlogic-core) |
107
- | Design System (visual) | Rota `/ds` no app do projeto **Admin** |
101
+ | Fonte | Caminho | Conteúdo |
102
+ |-------|---------|----------|
103
+ | Memory components | `.note/memory/components/` | Props, variantes e exemplos de componentes |
104
+ | Memory patterns | `.note/memory/patterns/` | Layouts, setup, convenções, regras do projeto |
105
+ | Memory features | `.note/memory/features/` | Contexto de features específicas do projeto |
106
+ | Código-fonte da lib | Cross-project → projeto **Admin** (forlogic-core) | Props, tipos, implementação |
107
+ | Design System (visual) | Rota `/ds` no app do projeto **Admin** | Documentação interativa |
108
+
109
+ > ℹ️ `.note/memory/` usa 3 pastas padronizadas: `components/`, `patterns/`, `features/`. `KNOWLEDGE.md` é a fonte única de verdade para regras e convenções.
@@ -0,0 +1,33 @@
1
+ export interface UseAliasFromUrlOptions {
2
+ /** Nome do param de rota (default: "alias") */
3
+ paramName?: string;
4
+ }
5
+ export interface UseAliasFromUrlReturn {
6
+ /** Alias extraído da URL (ou null se ausente) */
7
+ urlAlias: string | null;
8
+ /** true se há alias na URL e é diferente do alias ativo */
9
+ isAliasMismatch: boolean;
10
+ /** true se o alias da URL existe nas companies do usuário */
11
+ isValidAlias: boolean;
12
+ /** true se não há alias na URL */
13
+ isMissing: boolean;
14
+ /** Company correspondente ao alias da URL (ou null) */
15
+ matchedCompany: {
16
+ id: string;
17
+ alias: string;
18
+ name: string;
19
+ } | null;
20
+ }
21
+ /**
22
+ * Hook para extrair e validar o alias da URL contra as companies do usuário.
23
+ *
24
+ * Lê o param `:alias` do React Router e verifica se é um alias válido
25
+ * (presente na lista de companies do token de autenticação).
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * // Rota: /:alias/documents
30
+ * const { urlAlias, isAliasMismatch, isValidAlias, isMissing } = useAliasFromUrl();
31
+ * ```
32
+ */
33
+ export declare function useAliasFromUrl(options?: UseAliasFromUrlOptions): UseAliasFromUrlReturn;