feat(upload): include root folder option in S3 folder dropdown and support empty targetFolder (root) on backend

This commit is contained in:
Geert Rademakes 2025-08-13 17:04:20 +02:00
parent 762ae0730a
commit e4ee7230d1
3 changed files with 11 additions and 7 deletions

View File

@ -226,7 +226,8 @@ router.get('/files', async (req, res) => {
router.get('/folders', async (req, res) => { router.get('/folders', async (req, res) => {
try { try {
const folders = await s3Service.listAllFolders(''); const folders = await s3Service.listAllFolders('');
res.json({ folders }); // Include root option as empty string
res.json({ folders: [''] as string[] .concat(folders) });
} catch (error) { } catch (error) {
console.error('Error fetching S3 folders:', error); console.error('Error fetching S3 folders:', error);
res.status(500).json({ error: 'Failed to fetch S3 folders' }); res.status(500).json({ error: 'Failed to fetch S3 folders' });

View File

@ -83,8 +83,11 @@ export class S3Service {
targetFolder?: string targetFolder?: string
): Promise<UploadResult> { ): Promise<UploadResult> {
const fileExtension = originalName.split('.').pop(); const fileExtension = originalName.split('.').pop();
const safeFolder = (targetFolder || 'music').replace(/^\/+|\/+$/g, ''); const cleaned = typeof targetFolder === 'string' ? targetFolder.replace(/^\/+|\/+$/g, '') : '';
const key = `${safeFolder}/${uuidv4()}.${fileExtension}`; const safeFolder = cleaned;
const key = safeFolder
? `${safeFolder}/${uuidv4()}.${fileExtension}`
: `${uuidv4()}.${fileExtension}`;
const command = new PutObjectCommand({ const command = new PutObjectCommand({
Bucket: this.bucketName, Bucket: this.bucketName,

View File

@ -131,9 +131,9 @@ export const MusicUpload: React.FC<MusicUploadProps> = ({ onUploadComplete }) =>
const data = await res.json(); const data = await res.json();
const items = Array.isArray(data.folders) ? data.folders : []; const items = Array.isArray(data.folders) ? data.folders : [];
setFolders(items); setFolders(items);
if (items.length > 0) { if (items.length > 0 && targetFolder === 'uploads') {
// default to first folder if uploads not present // default target: root (empty) if available, else first item
const defaultChoice = items.find((f: string) => f.toLowerCase().includes('upload')) || items[0]; const defaultChoice = items.find((f: string) => f === '') || items[0];
setTargetFolder(defaultChoice.replace(/^\/+/, '')); setTargetFolder(defaultChoice.replace(/^\/+/, ''));
} }
} catch (e) { } catch (e) {
@ -154,7 +154,7 @@ export const MusicUpload: React.FC<MusicUploadProps> = ({ onUploadComplete }) =>
{folders.length > 0 ? ( {folders.length > 0 ? (
<Select value={targetFolder} onChange={(e) => setTargetFolder(e.target.value)} bg="gray.800" borderColor="gray.700"> <Select value={targetFolder} onChange={(e) => setTargetFolder(e.target.value)} bg="gray.800" borderColor="gray.700">
{folders.map((f) => ( {folders.map((f) => (
<option key={f} value={f}>{f}</option> <option key={f || 'ROOT'} value={f}>{f || '(root)'}</option>
))} ))}
</Select> </Select>
) : ( ) : (