Skip to content

Commit 14c93f6

Browse files
authored
feat(files): allow image uploads in workspace files (#4419)
* feat(files): allow image uploads in workspace files * fix(files): include images in workspace type filter * fix(files): match all image mime types in image filter
1 parent f76a10c commit 14c93f6

2 files changed

Lines changed: 40 additions & 6 deletions

File tree

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
SUPPORTED_AUDIO_EXTENSIONS,
4444
SUPPORTED_CODE_EXTENSIONS,
4545
SUPPORTED_DOCUMENT_EXTENSIONS,
46+
SUPPORTED_IMAGE_EXTENSIONS,
4647
SUPPORTED_VIDEO_EXTENSIONS,
4748
} from '@/lib/uploads/utils/validation'
4849
import type {
@@ -89,6 +90,7 @@ const SUPPORTED_EXTENSIONS = [
8990
...SUPPORTED_CODE_EXTENSIONS,
9091
...SUPPORTED_AUDIO_EXTENSIONS,
9192
...SUPPORTED_VIDEO_EXTENSIONS,
93+
...SUPPORTED_IMAGE_EXTENSIONS,
9294
] as const
9395

9496
const ACCEPT_ATTR = SUPPORTED_EXTENSIONS.map((ext) => `.${ext}`).join(',')
@@ -125,6 +127,7 @@ function formatFileType(mimeType: string | null, filename: string): string {
125127

126128
if (mimeType?.startsWith('audio/')) return 'Audio'
127129
if (mimeType?.startsWith('video/')) return 'Video'
130+
if (mimeType?.startsWith('image/')) return 'Image'
128131

129132
const ext = getFileExtension(filename)
130133
if (ext) return ext.toUpperCase()
@@ -246,6 +249,7 @@ export function Files() {
246249
if (typeFilter.includes('document') && isSupportedExtension(ext)) return true
247250
if (typeFilter.includes('audio') && isAudioFileType(f.type)) return true
248251
if (typeFilter.includes('video') && isVideoFileType(f.type)) return true
252+
if (typeFilter.includes('image') && f.type?.startsWith('image/')) return true
249253
return false
250254
})
251255
}
@@ -926,9 +930,14 @@ export function Files() {
926930
typeFilter.length === 0
927931
? 'All'
928932
: typeFilter.length === 1
929-
? (({ document: 'Documents', audio: 'Audio', video: 'Video' } as Record<string, string>)[
930-
typeFilter[0]
931-
] ?? typeFilter[0])
933+
? ((
934+
{
935+
document: 'Documents',
936+
image: 'Images',
937+
audio: 'Audio',
938+
video: 'Video',
939+
} as Record<string, string>
940+
)[typeFilter[0]] ?? typeFilter[0])
932941
: `${typeFilter.length} selected`
933942

934943
const sizeDisplayLabel =
@@ -954,6 +963,7 @@ export function Files() {
954963
<Combobox
955964
options={[
956965
{ value: 'document', label: 'Documents' },
966+
{ value: 'image', label: 'Images' },
957967
{ value: 'audio', label: 'Audio' },
958968
{ value: 'video', label: 'Video' },
959969
]}
@@ -1036,6 +1046,7 @@ export function Files() {
10361046
if (typeFilter.length > 0) {
10371047
const typeLabels: Record<string, string> = {
10381048
document: 'Documents',
1049+
image: 'Images',
10391050
audio: 'Audio',
10401051
video: 'Video',
10411052
}

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,31 @@ export const SUPPORTED_AUDIO_EXTENSIONS = [
9595

9696
export const SUPPORTED_VIDEO_EXTENSIONS = ['mp4', 'mov', 'avi', 'mkv', 'webm'] as const
9797

98+
export const SUPPORTED_IMAGE_EXTENSIONS = [
99+
'png',
100+
'jpg',
101+
'jpeg',
102+
'gif',
103+
'webp',
104+
'svg',
105+
'bmp',
106+
'tif',
107+
'tiff',
108+
'heic',
109+
'heif',
110+
'avif',
111+
'ico',
112+
] as const
113+
98114
export type SupportedDocumentExtension = (typeof SUPPORTED_DOCUMENT_EXTENSIONS)[number]
99115
export type SupportedAudioExtension = (typeof SUPPORTED_AUDIO_EXTENSIONS)[number]
100116
export type SupportedVideoExtension = (typeof SUPPORTED_VIDEO_EXTENSIONS)[number]
117+
export type SupportedImageExtension = (typeof SUPPORTED_IMAGE_EXTENSIONS)[number]
101118
export type SupportedMediaExtension =
102119
| SupportedDocumentExtension
103120
| SupportedAudioExtension
104121
| SupportedVideoExtension
122+
| SupportedImageExtension
105123

106124
export const SUPPORTED_MIME_TYPES: Record<SupportedDocumentExtension, string[]> = {
107125
pdf: ['application/pdf', 'application/x-pdf'],
@@ -180,14 +198,19 @@ const SUPPORTED_IMAGE_MIME_TYPES = [
180198
'image/gif',
181199
'image/webp',
182200
'image/svg+xml',
201+
'image/bmp',
202+
'image/tiff',
203+
'image/heic',
204+
'image/heif',
205+
'image/avif',
206+
'image/x-icon',
207+
'image/vnd.microsoft.icon',
183208
]
184209

185-
const SUPPORTED_IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg']
186-
187210
export const CHAT_ACCEPT_ATTRIBUTE = [
188211
ACCEPT_ATTRIBUTE,
189212
...SUPPORTED_IMAGE_MIME_TYPES,
190-
...SUPPORTED_IMAGE_EXTENSIONS,
213+
...SUPPORTED_IMAGE_EXTENSIONS.map((ext) => `.${ext}`),
191214
].join(',')
192215

193216
export interface FileValidationError {

0 commit comments

Comments
 (0)