diff --git a/apps/sim/app/workspace/[workspaceId]/tables/components/create-table-modal.tsx b/apps/sim/app/workspace/[workspaceId]/tables/components/create-modal.tsx similarity index 98% rename from apps/sim/app/workspace/[workspaceId]/tables/components/create-table-modal.tsx rename to apps/sim/app/workspace/[workspaceId]/tables/components/create-modal.tsx index 08cc4921b..80b435116 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/components/create-table-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/components/create-modal.tsx @@ -21,9 +21,9 @@ import { import type { ColumnDefinition } from '@/lib/table' import { useCreateTable } from '@/hooks/queries/use-tables' -const logger = createLogger('CreateTableModal') +const logger = createLogger('CreateModal') -interface CreateTableModalProps { +interface CreateModalProps { isOpen: boolean onClose: () => void } @@ -44,7 +44,7 @@ function createEmptyColumn(): ColumnWithId { return { id: nanoid(), name: '', type: 'string', required: true, unique: false } } -export function CreateTableModal({ isOpen, onClose }: CreateTableModalProps) { +export function CreateModal({ isOpen, onClose }: CreateModalProps) { const params = useParams() const workspaceId = params.workspaceId as string diff --git a/apps/sim/app/workspace/[workspaceId]/tables/components/empty-state.tsx b/apps/sim/app/workspace/[workspaceId]/tables/components/empty-state.tsx new file mode 100644 index 000000000..285e505b0 --- /dev/null +++ b/apps/sim/app/workspace/[workspaceId]/tables/components/empty-state.tsx @@ -0,0 +1,20 @@ +interface EmptyStateProps { + hasSearchQuery: boolean +} + +export function EmptyState({ hasSearchQuery }: EmptyStateProps) { + return ( +
+
+

+ {hasSearchQuery ? 'No tables found' : 'No tables yet'} +

+

+ {hasSearchQuery + ? 'Try adjusting your search query' + : 'Create your first table to store structured data for your workflows'} +

+
+
+ ) +} diff --git a/apps/sim/app/workspace/[workspaceId]/tables/components/error-state.tsx b/apps/sim/app/workspace/[workspaceId]/tables/components/error-state.tsx new file mode 100644 index 000000000..39e6fa687 --- /dev/null +++ b/apps/sim/app/workspace/[workspaceId]/tables/components/error-state.tsx @@ -0,0 +1,16 @@ +interface ErrorStateProps { + error: unknown +} + +export function ErrorState({ error }: ErrorStateProps) { + return ( +
+
+

Error loading tables

+

+ {error instanceof Error ? error.message : 'An error occurred'} +

+
+
+ ) +} diff --git a/apps/sim/app/workspace/[workspaceId]/tables/components/index.ts b/apps/sim/app/workspace/[workspaceId]/tables/components/index.ts index 0a495b879..4a8726484 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/components/index.ts +++ b/apps/sim/app/workspace/[workspaceId]/tables/components/index.ts @@ -1,2 +1,6 @@ -export * from './create-table-modal' +export * from './create-modal' +export * from './empty-state' +export * from './error-state' +export * from './loading-state' export * from './table-card' +export * from './tables-view' diff --git a/apps/sim/app/workspace/[workspaceId]/tables/components/loading-state.tsx b/apps/sim/app/workspace/[workspaceId]/tables/components/loading-state.tsx new file mode 100644 index 000000000..1a292cd2e --- /dev/null +++ b/apps/sim/app/workspace/[workspaceId]/tables/components/loading-state.tsx @@ -0,0 +1,31 @@ +export function LoadingState() { + return ( + <> + {Array.from({ length: 8 }).map((_, i) => ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))} + + ) +} diff --git a/apps/sim/app/workspace/[workspaceId]/tables/components/table-card.tsx b/apps/sim/app/workspace/[workspaceId]/tables/components/table-card.tsx index 2d7929c63..06bb31e97 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/components/table-card.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/components/table-card.tsx @@ -26,8 +26,8 @@ import { } from '@/components/emcn' import type { TableDefinition } from '@/lib/table' import { useDeleteTable } from '@/hooks/queries/use-tables' -import { getTypeBadgeVariant } from '../[tableId]/table-data-viewer/utils' -import { formatAbsoluteDate, formatRelativeTime } from './utils' +import { getTypeBadgeVariant } from '../[tableId]/lib/utils' +import { formatAbsoluteDate, formatRelativeTime } from '../lib/utils' const logger = createLogger('TableCard') diff --git a/apps/sim/app/workspace/[workspaceId]/tables/tables.tsx b/apps/sim/app/workspace/[workspaceId]/tables/components/tables-view.tsx similarity index 57% rename from apps/sim/app/workspace/[workspaceId]/tables/tables.tsx rename to apps/sim/app/workspace/[workspaceId]/tables/components/tables-view.tsx index 92fdae6a8..5feb201ca 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/tables.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/components/tables-view.tsx @@ -8,10 +8,13 @@ import { Input } from '@/components/ui/input' import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider' import { useTablesList } from '@/hooks/queries/use-tables' import { useDebounce } from '@/hooks/use-debounce' -import { CreateTableModal } from './components/create-table-modal' -import { TableCard } from './components/table-card' +import { CreateModal } from './create-modal' +import { EmptyState } from './empty-state' +import { ErrorState } from './error-state' +import { LoadingState } from './loading-state' +import { TableCard } from './table-card' -export function Tables() { +export function TablesView() { const params = useParams() const workspaceId = params.workspaceId as string const userPermissions = useUserPermissionsContext() @@ -84,7 +87,7 @@ export function Tables() { {/* Content */}
{isLoading ? ( - + ) : error ? ( ) : filteredTables.length === 0 ? ( @@ -99,69 +102,7 @@ export function Tables() {
- setIsCreateModalOpen(false)} /> + setIsCreateModalOpen(false)} /> ) } - -function LoadingSkeletons() { - return ( - <> - {Array.from({ length: 8 }).map((_, i) => ( -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ))} - - ) -} - -function ErrorState({ error }: { error: unknown }) { - return ( -
-
-

Error loading tables

-

- {error instanceof Error ? error.message : 'An error occurred'} -

-
-
- ) -} - -function EmptyState({ hasSearchQuery }: { hasSearchQuery: boolean }) { - return ( -
-
-

- {hasSearchQuery ? 'No tables found' : 'No tables yet'} -

-

- {hasSearchQuery - ? 'Try adjusting your search query' - : 'Create your first table to store structured data for your workflows'} -

-
-
- ) -} diff --git a/apps/sim/app/workspace/[workspaceId]/tables/lib/index.ts b/apps/sim/app/workspace/[workspaceId]/tables/lib/index.ts new file mode 100644 index 000000000..9c56149ef --- /dev/null +++ b/apps/sim/app/workspace/[workspaceId]/tables/lib/index.ts @@ -0,0 +1 @@ +export * from './utils' diff --git a/apps/sim/app/workspace/[workspaceId]/tables/components/utils.ts b/apps/sim/app/workspace/[workspaceId]/tables/lib/utils.ts similarity index 88% rename from apps/sim/app/workspace/[workspaceId]/tables/components/utils.ts rename to apps/sim/app/workspace/[workspaceId]/tables/lib/utils.ts index 71b3f50a5..e635a1c63 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/components/utils.ts +++ b/apps/sim/app/workspace/[workspaceId]/tables/lib/utils.ts @@ -1,3 +1,6 @@ +/** + * Formats a date as relative time (e.g., "5m ago", "2d ago") + */ export function formatRelativeTime(dateValue: string | Date): string { const dateString = typeof dateValue === 'string' ? dateValue : dateValue.toISOString() const date = new Date(dateString) @@ -13,6 +16,9 @@ export function formatRelativeTime(dateValue: string | Date): string { return `${Math.floor(diffInSeconds / 31536000)}y ago` } +/** + * Formats a date as absolute date string (e.g., "Jan 15, 2024, 10:30 AM") + */ export function formatAbsoluteDate(dateValue: string | Date): string { const dateString = typeof dateValue === 'string' ? dateValue : dateValue.toISOString() const date = new Date(dateString) diff --git a/apps/sim/app/workspace/[workspaceId]/tables/page.tsx b/apps/sim/app/workspace/[workspaceId]/tables/page.tsx index 90feff581..c6200a37a 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/page.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/page.tsx @@ -1,7 +1,7 @@ import { redirect } from 'next/navigation' import { getSession } from '@/lib/auth' import { verifyWorkspaceMembership } from '@/app/api/workflows/utils' -import { Tables } from './tables' +import { TablesView } from './components' interface TablesPageProps { params: Promise<{ @@ -22,5 +22,5 @@ export default async function TablesPage({ params }: TablesPageProps) { redirect('/') } - return + return }