Skip to content

Commit a7b732b

Browse files
waleedlatif1claude
andcommitted
refactor(files): extract shared DataTable, isolate client-safe constants
- Move SUPPORTED_CODE_EXTENSIONS to validation-constants.ts so client components no longer transitively import Node's `path` module - Extract shared DataTable component used by both CsvPreview and XlsxPreview, eliminating duplicated table markup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a284499 commit a7b732b

File tree

6 files changed

+104
-108
lines changed

6 files changed

+104
-108
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { memo } from 'react'
2+
3+
interface DataTableProps {
4+
headers: string[]
5+
rows: string[][]
6+
}
7+
8+
export const DataTable = memo(function DataTable({ headers, rows }: DataTableProps) {
9+
return (
10+
<div className='overflow-x-auto rounded-md border border-[var(--border)]'>
11+
<table className='w-full border-collapse text-[13px]'>
12+
<thead className='bg-[var(--surface-2)]'>
13+
<tr>
14+
{headers.map((header, i) => (
15+
<th
16+
key={i}
17+
className='whitespace-nowrap px-3 py-2 text-left font-semibold text-[12px] text-[var(--text-primary)]'
18+
>
19+
{String(header ?? '')}
20+
</th>
21+
))}
22+
</tr>
23+
</thead>
24+
<tbody>
25+
{rows.map((row, ri) => (
26+
<tr key={ri} className='border-[var(--border)] border-t'>
27+
{headers.map((_, ci) => (
28+
<td
29+
key={ci}
30+
className='whitespace-nowrap px-3 py-2 text-[var(--text-secondary)]'
31+
>
32+
{String(row[ci] ?? '')}
33+
</td>
34+
))}
35+
</tr>
36+
))}
37+
</tbody>
38+
</table>
39+
</div>
40+
)
41+
})

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import { Skeleton } from '@/components/emcn'
77
import { cn } from '@/lib/core/utils/cn'
88
import type { WorkspaceFileRecord } from '@/lib/uploads/contexts/workspace'
99
import { getFileExtension } from '@/lib/uploads/utils/file-utils'
10-
import { SUPPORTED_CODE_EXTENSIONS } from '@/lib/uploads/utils/validation'
10+
import { SUPPORTED_CODE_EXTENSIONS } from '@/lib/uploads/utils/validation-constants'
1111
import {
1212
useUpdateWorkspaceFileContent,
1313
useWorkspaceFileBinary,
1414
useWorkspaceFileContent,
1515
} from '@/hooks/queries/workspace-files'
1616
import { useAutosave } from '@/hooks/use-autosave'
1717
import { useStreamingText } from '@/hooks/use-streaming-text'
18+
import { DataTable } from './data-table'
1819
import { PreviewPanel, resolvePreviewType } from './preview-panel'
1920

2021
const logger = createLogger('FileViewer')
@@ -1058,39 +1059,11 @@ const XlsxPreview = memo(function XlsxPreview({
10581059
</div>
10591060
)}
10601061
<div className='flex-1 overflow-auto p-6'>
1061-
<div className='overflow-x-auto rounded-md border border-[var(--border)]'>
1062-
<table className='w-full border-collapse text-[13px]'>
1063-
<thead className='bg-[var(--surface-2)]'>
1064-
<tr>
1065-
{currentSheet.headers.map((header, i) => (
1066-
<th
1067-
key={i}
1068-
className='whitespace-nowrap px-3 py-2 text-left font-semibold text-[12px] text-[var(--text-primary)]'
1069-
>
1070-
{String(header ?? '')}
1071-
</th>
1072-
))}
1073-
</tr>
1074-
</thead>
1075-
<tbody>
1076-
{currentSheet.rows.map((row, ri) => (
1077-
<tr key={ri} className='border-[var(--border)] border-t'>
1078-
{currentSheet.headers.map((_, ci) => (
1079-
<td
1080-
key={ci}
1081-
className='whitespace-nowrap px-3 py-2 text-[var(--text-secondary)]'
1082-
>
1083-
{String(row[ci] ?? '')}
1084-
</td>
1085-
))}
1086-
</tr>
1087-
))}
1088-
</tbody>
1089-
</table>
1090-
</div>
1062+
<DataTable headers={currentSheet.headers} rows={currentSheet.rows} />
10911063
{currentSheet.truncated && (
10921064
<p className='mt-3 text-center text-[12px] text-[var(--text-muted)]'>
1093-
Showing first {XLSX_MAX_ROWS.toLocaleString()} rows. Download the file to view all data.
1065+
Showing first {XLSX_MAX_ROWS.toLocaleString()} rows. Download the file to view all
1066+
data.
10941067
</p>
10951068
)}
10961069
</div>

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import remarkGfm from 'remark-gfm'
1010
import { Checkbox } from '@/components/emcn'
1111
import { cn } from '@/lib/core/utils/cn'
1212
import { getFileExtension } from '@/lib/uploads/utils/file-utils'
13+
import { DataTable } from './data-table'
1314
import { useAutoScroll } from '@/hooks/use-auto-scroll'
1415
import { useStreamingReveal } from '@/hooks/use-streaming-reveal'
1516

@@ -486,33 +487,7 @@ const CsvPreview = memo(function CsvPreview({ content }: { content: string }) {
486487

487488
return (
488489
<div className='h-full overflow-auto p-6'>
489-
<div className='overflow-x-auto rounded-md border border-[var(--border)]'>
490-
<table className='w-full border-collapse text-[13px]'>
491-
<thead className='bg-[var(--surface-2)]'>
492-
<tr>
493-
{headers.map((header, i) => (
494-
<th
495-
key={i}
496-
className='whitespace-nowrap px-3 py-2 text-left font-semibold text-[12px] text-[var(--text-primary)]'
497-
>
498-
{header}
499-
</th>
500-
))}
501-
</tr>
502-
</thead>
503-
<tbody>
504-
{rows.map((row, ri) => (
505-
<tr key={ri} className='border-[var(--border)] border-t'>
506-
{headers.map((_, ci) => (
507-
<td key={ci} className='whitespace-nowrap px-3 py-2 text-[var(--text-secondary)]'>
508-
{row[ci] ?? ''}
509-
</td>
510-
))}
511-
</tr>
512-
))}
513-
</tbody>
514-
</table>
515-
</div>
490+
<DataTable headers={headers} rows={rows} />
516491
</div>
517492
)
518493
})

apps/sim/app/workspace/[workspaceId]/files/files.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ import {
3636
isAudioFileType,
3737
isVideoFileType,
3838
} from '@/lib/uploads/utils/file-utils'
39+
import { SUPPORTED_CODE_EXTENSIONS } from '@/lib/uploads/utils/validation-constants'
3940
import {
4041
isSupportedExtension,
4142
SUPPORTED_AUDIO_EXTENSIONS,
42-
SUPPORTED_CODE_EXTENSIONS,
4343
SUPPORTED_DOCUMENT_EXTENSIONS,
4444
SUPPORTED_VIDEO_EXTENSIONS,
4545
} from '@/lib/uploads/utils/validation'
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Extension constants that are safe to import from client components.
3+
* Separated from validation.ts which imports Node's `path` module.
4+
*/
5+
6+
export const SUPPORTED_CODE_EXTENSIONS = [
7+
'mdx',
8+
'xml',
9+
'css',
10+
'scss',
11+
'less',
12+
'js',
13+
'jsx',
14+
'ts',
15+
'tsx',
16+
'py',
17+
'rb',
18+
'go',
19+
'rs',
20+
'java',
21+
'kt',
22+
'swift',
23+
'c',
24+
'cpp',
25+
'h',
26+
'hpp',
27+
'cs',
28+
'php',
29+
'sh',
30+
'bash',
31+
'zsh',
32+
'fish',
33+
'sql',
34+
'graphql',
35+
'gql',
36+
'toml',
37+
'ini',
38+
'conf',
39+
'cfg',
40+
'env',
41+
'log',
42+
'diff',
43+
'patch',
44+
'dockerfile',
45+
'makefile',
46+
'gitignore',
47+
'editorconfig',
48+
'prettierrc',
49+
'eslintrc',
50+
] as const
51+
52+
export type SupportedCodeExtension = (typeof SUPPORTED_CODE_EXTENSIONS)[number]

apps/sim/lib/uploads/utils/validation.ts

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import path from 'path'
22

3+
export { SUPPORTED_CODE_EXTENSIONS } from '@/lib/uploads/utils/validation-constants'
4+
export type { SupportedCodeExtension } from '@/lib/uploads/utils/validation-constants'
5+
36
/**
47
* Checks whether a string is a valid file extension (lowercase alphanumeric only).
58
* Rejects extensions containing spaces, punctuation, or other non-alphanumeric characters
@@ -29,54 +32,6 @@ export const SUPPORTED_DOCUMENT_EXTENSIONS = [
2932
'yml',
3033
] as const
3134

32-
export const SUPPORTED_CODE_EXTENSIONS = [
33-
'mdx',
34-
'xml',
35-
'css',
36-
'scss',
37-
'less',
38-
'js',
39-
'jsx',
40-
'ts',
41-
'tsx',
42-
'py',
43-
'rb',
44-
'go',
45-
'rs',
46-
'java',
47-
'kt',
48-
'swift',
49-
'c',
50-
'cpp',
51-
'h',
52-
'hpp',
53-
'cs',
54-
'php',
55-
'sh',
56-
'bash',
57-
'zsh',
58-
'fish',
59-
'sql',
60-
'graphql',
61-
'gql',
62-
'toml',
63-
'ini',
64-
'conf',
65-
'cfg',
66-
'env',
67-
'log',
68-
'diff',
69-
'patch',
70-
'dockerfile',
71-
'makefile',
72-
'gitignore',
73-
'editorconfig',
74-
'prettierrc',
75-
'eslintrc',
76-
] as const
77-
78-
export type SupportedCodeExtension = (typeof SUPPORTED_CODE_EXTENSIONS)[number]
79-
8035
export const SUPPORTED_AUDIO_EXTENSIONS = [
8136
'mp3',
8237
'm4a',

0 commit comments

Comments
 (0)