diff --git a/apps/sim/app/api/table/route.ts b/apps/sim/app/api/table/route.ts index 3f40a58ec..b1ae916f3 100644 --- a/apps/sim/app/api/table/route.ts +++ b/apps/sim/app/api/table/route.ts @@ -7,7 +7,7 @@ import { z } from 'zod' import { checkHybridAuth } from '@/lib/auth/hybrid' import { generateRequestId } from '@/lib/core/utils/request' import { TABLE_LIMITS, validateTableName, validateTableSchema } from '@/lib/table' -import type { TableSchema } from '@/lib/table/validation/validation' +import type { TableSchema } from '@/lib/table/validation/schema' import type { TableColumnData, TableSchemaData } from './utils' const logger = createLogger('TableAPI') diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/filter-builder.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/filter-builder.tsx index 133b830b2..42e1969d1 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/filter-builder.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/filter-builder.tsx @@ -3,8 +3,8 @@ import { useCallback, useMemo, useState } from 'react' import { ArrowDownAZ, ArrowUpAZ, Plus, X } from 'lucide-react' import { Button, Combobox, Input } from '@/components/emcn' -import type { FilterCondition } from '@/lib/table/filters/filter-constants' -import { useFilterBuilder } from '@/lib/table/filters/use-filter-builder' +import type { FilterCondition } from '@/lib/table/filters/constants' +import { useFilterBuilder } from '@/lib/table/filters/use-builder' /** * Represents a sort configuration. diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-format/filter-format.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-format/filter-format.tsx index 0ae54a0c9..6fff0803e 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-format/filter-format.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-format/filter-format.tsx @@ -4,12 +4,9 @@ import { useEffect, useMemo, useRef, useState } from 'react' import { Plus, X } from 'lucide-react' import { Button, Combobox, type ComboboxOption, Input } from '@/components/emcn' import { cn } from '@/lib/core/utils/cn' -import { - conditionsToJsonString, - jsonStringToConditions, -} from '@/lib/table/filters/filter-builder-utils' -import type { FilterCondition } from '@/lib/table/filters/filter-constants' -import { useFilterBuilder } from '@/lib/table/filters/use-filter-builder' +import { conditionsToJsonString, jsonStringToConditions } from '@/lib/table/filters/builder-utils' +import type { FilterCondition } from '@/lib/table/filters/constants' +import { useFilterBuilder } from '@/lib/table/filters/use-builder' import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text' import { SubBlockInputController } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sub-block-input-controller' import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value' diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sort-format/sort-format.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sort-format/sort-format.tsx index 50bba388b..937e20617 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sort-format/sort-format.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sort-format/sort-format.tsx @@ -2,14 +2,13 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { Plus, X } from 'lucide-react' +import { nanoid } from 'nanoid' import { Button, Combobox, type ComboboxOption } from '@/components/emcn' import { - generateId, jsonStringToSortConditions, - SORT_DIRECTIONS, - type SortCondition, sortConditionsToJsonString, -} from '@/lib/table/filters/filter-builder-utils' +} from '@/lib/table/filters/builder-utils' +import { SORT_DIRECTIONS, type SortCondition } from '@/lib/table/filters/constants' import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value' interface SortFormatProps { @@ -30,7 +29,7 @@ interface SortFormatProps { * Creates a new sort condition with default values */ const createDefaultCondition = (columns: ComboboxOption[]): SortCondition => ({ - id: generateId(), + id: nanoid(), column: columns[0]?.value || '', direction: 'asc', }) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx index 11593e32c..efda1c05d 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx @@ -3,7 +3,7 @@ import { AlertTriangle, Wand2 } from 'lucide-react' import { Label, Tooltip } from '@/components/emcn/components' import { Button } from '@/components/ui/button' import { cn } from '@/lib/core/utils/cn' -import type { FilterCondition, SortCondition } from '@/lib/table/filters/filter-builder-utils' +import type { FilterCondition, SortCondition } from '@/lib/table/filters/constants' import type { FieldDiffStatus } from '@/lib/workflows/diff/types' import { CheckboxList, diff --git a/apps/sim/blocks/blocks/table.ts b/apps/sim/blocks/blocks/table.ts index 92442390f..7b494b0e1 100644 --- a/apps/sim/blocks/blocks/table.ts +++ b/apps/sim/blocks/blocks/table.ts @@ -1,5 +1,5 @@ import { TableIcon } from '@/components/icons' -import { conditionsToFilter, sortConditionsToSort } from '@/lib/table/filters/filter-builder-utils' +import { conditionsToFilter, sortConditionsToSort } from '@/lib/table/filters/builder-utils' import type { BlockConfig } from '@/blocks/types' import type { TableQueryResponse } from '@/tools/table/types' diff --git a/apps/sim/lib/table/filters/filter-builder-utils.ts b/apps/sim/lib/table/filters/builder-utils.ts similarity index 92% rename from apps/sim/lib/table/filters/filter-builder-utils.ts rename to apps/sim/lib/table/filters/builder-utils.ts index ca1664ae2..011cddfde 100644 --- a/apps/sim/lib/table/filters/filter-builder-utils.ts +++ b/apps/sim/lib/table/filters/builder-utils.ts @@ -1,24 +1,11 @@ /** * Shared utilities for filter builder UI components. * - * @module lib/table/filters/filter-builder-utils + * @module lib/table/filters/builder-utils */ -// Re-export shared constants and types for backward compatibility -export { - COMPARISON_OPERATORS, - type FilterCondition, - generateConditionId as generateId, - LOGICAL_OPERATORS, - SORT_DIRECTIONS, - type SortCondition, -} from './filter-constants' - -// Import for internal use -import { type FilterCondition, generateConditionId, type SortCondition } from './filter-constants' - -// Use internal alias for generateConditionId -const generateId = generateConditionId +import { nanoid } from 'nanoid' +import type { FilterCondition, SortCondition } from './constants' type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue } @@ -141,7 +128,7 @@ function parseFilterGroup(group: Record): FilterCondition[] { for (const [op, opValue] of Object.entries(value)) { if (op.startsWith('$')) { conditions.push({ - id: generateId(), + id: nanoid(), logicalOperator: 'and', column, operator: op.substring(1), @@ -151,7 +138,7 @@ function parseFilterGroup(group: Record): FilterCondition[] { } } else { conditions.push({ - id: generateId(), + id: nanoid(), logicalOperator: 'and', column, operator: 'eq', @@ -234,7 +221,7 @@ export function sortToConditions(sort: Record | null): SortCondi if (!sort) return [] return Object.entries(sort).map(([column, direction]) => ({ - id: generateId(), + id: nanoid(), column, direction: direction === 'desc' ? 'desc' : 'asc', })) diff --git a/apps/sim/lib/table/filters/filter-constants.ts b/apps/sim/lib/table/filters/constants.ts similarity index 84% rename from apps/sim/lib/table/filters/filter-constants.ts rename to apps/sim/lib/table/filters/constants.ts index fe634dc11..7e7715c7b 100644 --- a/apps/sim/lib/table/filters/filter-constants.ts +++ b/apps/sim/lib/table/filters/constants.ts @@ -1,7 +1,7 @@ /** * Shared constants and types for table filtering and sorting. * - * @module lib/table/filters/filter-constants + * @module lib/table/filters/constants * */ @@ -68,13 +68,3 @@ export interface SortCondition { /** Sort direction */ direction: 'asc' | 'desc' } - -/** - * Generates a unique ID for filter or sort conditions. - * Used as React keys for list items in builder UI. - * - * @returns Random alphanumeric string - */ -export function generateConditionId(): string { - return Math.random().toString(36).substring(2, 9) -} diff --git a/apps/sim/lib/table/filters/index.ts b/apps/sim/lib/table/filters/index.ts index e29e7a5ea..023315b36 100644 --- a/apps/sim/lib/table/filters/index.ts +++ b/apps/sim/lib/table/filters/index.ts @@ -4,6 +4,6 @@ * @module lib/table/filters */ -export * from './filter-builder-utils' -export * from './filter-constants' -export * from './use-filter-builder' +export * from './builder-utils' +export * from './constants' +export * from './use-builder' diff --git a/apps/sim/lib/table/filters/use-filter-builder.ts b/apps/sim/lib/table/filters/use-builder.ts similarity index 78% rename from apps/sim/lib/table/filters/use-filter-builder.ts rename to apps/sim/lib/table/filters/use-builder.ts index 37af180f7..8a4961f4b 100644 --- a/apps/sim/lib/table/filters/use-filter-builder.ts +++ b/apps/sim/lib/table/filters/use-builder.ts @@ -3,59 +3,37 @@ * * Provides reusable filter condition management logic shared between * the table data viewer's FilterBuilder and workflow block's FilterFormat. - * - * @module lib/table/filters/use-filter-builder */ import { useCallback, useMemo } from 'react' +import { nanoid } from 'nanoid' import { COMPARISON_OPERATORS, type FilterCondition, - generateConditionId, LOGICAL_OPERATORS, SORT_DIRECTIONS, type SortCondition, -} from './filter-constants' +} from './constants' -/** - * Column option for dropdowns. - */ export interface ColumnOption { value: string label: string } -/** - * Props for the useFilterBuilder hook. - */ export interface UseFilterBuilderProps { - /** Available columns for filtering */ columns: ColumnOption[] - /** Current filter conditions */ conditions: FilterCondition[] - /** Setter function for updating conditions */ setConditions: (conditions: FilterCondition[]) => void - /** Whether the builder is read-only */ isReadOnly?: boolean } -/** - * Return type for the useFilterBuilder hook. - */ export interface UseFilterBuilderReturn { - /** Memoized comparison operator options */ comparisonOptions: ColumnOption[] - /** Memoized logical operator options */ logicalOptions: ColumnOption[] - /** Memoized sort direction options */ sortDirectionOptions: ColumnOption[] - /** Adds a new filter condition */ addCondition: () => void - /** Removes a filter condition by ID */ removeCondition: (id: string) => void - /** Updates a specific field of a condition */ updateCondition: (id: string, field: keyof FilterCondition, value: string) => void - /** Creates a default condition (for external use) */ createDefaultCondition: () => FilterCondition } @@ -97,7 +75,6 @@ export function useFilterBuilder({ setConditions, isReadOnly = false, }: UseFilterBuilderProps): UseFilterBuilderReturn { - // Memoized options for dropdowns const comparisonOptions = useMemo( () => COMPARISON_OPERATORS.map((op) => ({ value: op.value, label: op.label })), [] @@ -113,12 +90,9 @@ export function useFilterBuilder({ [] ) - /** - * Creates a new filter condition with default values. - */ const createDefaultCondition = useCallback((): FilterCondition => { return { - id: generateConditionId(), + id: nanoid(), logicalOperator: 'and', column: columns[0]?.value || '', operator: 'eq', @@ -126,17 +100,11 @@ export function useFilterBuilder({ } }, [columns]) - /** - * Adds a new filter condition. - */ const addCondition = useCallback(() => { if (isReadOnly) return setConditions([...conditions, createDefaultCondition()]) }, [isReadOnly, conditions, setConditions, createDefaultCondition]) - /** - * Removes a filter condition by ID. - */ const removeCondition = useCallback( (id: string) => { if (isReadOnly) return @@ -145,9 +113,6 @@ export function useFilterBuilder({ [isReadOnly, conditions, setConditions] ) - /** - * Updates a specific field of a condition. - */ const updateCondition = useCallback( (id: string, field: keyof FilterCondition, value: string) => { if (isReadOnly) return @@ -167,31 +132,17 @@ export function useFilterBuilder({ } } -/** - * Props for sort configuration management. - */ export interface UseSortBuilderProps { - /** Available columns for sorting */ columns: ColumnOption[] - /** Current sort condition */ sortCondition: SortCondition | null - /** Setter function for updating sort */ setSortCondition: (sort: SortCondition | null) => void } -/** - * Return type for the useSortBuilder hook. - */ export interface UseSortBuilderReturn { - /** Memoized sort direction options */ sortDirectionOptions: ColumnOption[] - /** Adds a sort configuration */ addSort: () => void - /** Removes the sort configuration */ removeSort: () => void - /** Updates the sort column */ updateSortColumn: (column: string) => void - /** Updates the sort direction */ updateSortDirection: (direction: 'asc' | 'desc') => void } @@ -221,7 +172,7 @@ export function useSortBuilder({ const addSort = useCallback(() => { setSortCondition({ - id: generateConditionId(), + id: nanoid(), column: columns[0]?.value || '', direction: 'asc', }) diff --git a/apps/sim/lib/table/validation/validation-helpers.ts b/apps/sim/lib/table/validation/helpers.ts similarity index 98% rename from apps/sim/lib/table/validation/validation-helpers.ts rename to apps/sim/lib/table/validation/helpers.ts index dd2e36996..60cf994e8 100644 --- a/apps/sim/lib/table/validation/validation-helpers.ts +++ b/apps/sim/lib/table/validation/helpers.ts @@ -4,20 +4,20 @@ * These helpers consolidate common validation patterns (size, schema, uniqueness) * into reusable functions that return formatted error responses. * - * @module lib/table/validation/validation-helpers + * @module lib/table/validation/helpers */ import { db } from '@sim/db' import { userTableRows } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { NextResponse } from 'next/server' -import type { TableSchema } from './validation' +import type { TableSchema } from './schema' import { getUniqueColumns, validateRowAgainstSchema, validateRowSize, validateUniqueConstraints, -} from './validation' +} from './schema' /** * Row data type for validation functions. diff --git a/apps/sim/lib/table/validation/index.ts b/apps/sim/lib/table/validation/index.ts index 6347176d4..ed6128e55 100644 --- a/apps/sim/lib/table/validation/index.ts +++ b/apps/sim/lib/table/validation/index.ts @@ -4,5 +4,5 @@ * @module lib/table/validation */ -export * from './validation' -export * from './validation-helpers' +export * from './helpers' +export * from './schema' diff --git a/apps/sim/lib/table/validation/validation.ts b/apps/sim/lib/table/validation/schema.ts similarity index 99% rename from apps/sim/lib/table/validation/validation.ts rename to apps/sim/lib/table/validation/schema.ts index f8bd6b8fd..71412eebf 100644 --- a/apps/sim/lib/table/validation/validation.ts +++ b/apps/sim/lib/table/validation/schema.ts @@ -1,7 +1,7 @@ /** * Validation utilities for table schemas and row data. * - * @module lib/table/validation/validation + * @module lib/table/validation/schema */ import type { ColumnType } from '../constants'