Initial release: DictIA v0.8.14-alpha (fork de Speakr, AGPL-3.0)
This commit is contained in:
173
static/js/modules/composables/folders.js
Normal file
173
static/js/modules/composables/folders.js
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* Folders Management Composable
|
||||
* Handles folder operations for recordings
|
||||
*/
|
||||
|
||||
const { computed, ref } = Vue;
|
||||
|
||||
export function useFolders({
|
||||
recordings,
|
||||
availableFolders,
|
||||
selectedRecording,
|
||||
showToast,
|
||||
setGlobalError
|
||||
}) {
|
||||
// Computed / Helpers
|
||||
const getRecordingFolder = (recording) => {
|
||||
if (!recording || !recording.folder_id) return null;
|
||||
// Try to get from recording.folder first, then lookup
|
||||
if (recording.folder) return recording.folder;
|
||||
return availableFolders.value?.find(f => f.id === recording.folder_id) || null;
|
||||
};
|
||||
|
||||
const getFolderById = (folderId) => {
|
||||
if (!folderId || !availableFolders.value) return null;
|
||||
// Use == for loose equality to handle string/number type mismatch (e.g., from localStorage)
|
||||
return availableFolders.value.find(f => f.id == folderId) || null;
|
||||
};
|
||||
|
||||
const getFolderColor = (folderId) => {
|
||||
const folder = getFolderById(folderId);
|
||||
return folder?.color || '#10B981';
|
||||
};
|
||||
|
||||
const getFolderName = (folderId) => {
|
||||
const folder = getFolderById(folderId);
|
||||
return folder?.name || 'Folder';
|
||||
};
|
||||
|
||||
const getAvailableFoldersForRecording = () => {
|
||||
if (!availableFolders.value) return [];
|
||||
return availableFolders.value;
|
||||
};
|
||||
|
||||
// Methods
|
||||
const assignFolderToRecording = async (recordingId, folderId) => {
|
||||
try {
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
||||
|
||||
const response = await fetch(`/api/recordings/${recordingId}/folder`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
body: JSON.stringify({ folder_id: folderId || null })
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || 'Failed to update folder');
|
||||
}
|
||||
|
||||
const updatedRecording = await response.json();
|
||||
|
||||
// Update local recording data
|
||||
const recordingInList = recordings.value.find(r => r.id === recordingId);
|
||||
if (recordingInList) {
|
||||
recordingInList.folder_id = updatedRecording.folder_id;
|
||||
recordingInList.folder = updatedRecording.folder;
|
||||
}
|
||||
|
||||
// Update selectedRecording if it matches
|
||||
if (selectedRecording.value && selectedRecording.value.id === recordingId) {
|
||||
selectedRecording.value.folder_id = updatedRecording.folder_id;
|
||||
selectedRecording.value.folder = updatedRecording.folder;
|
||||
}
|
||||
|
||||
// Update folder recording counts
|
||||
if (availableFolders.value) {
|
||||
availableFolders.value.forEach(f => {
|
||||
const count = recordings.value.filter(r => r.folder_id === f.id).length;
|
||||
f.recording_count = count;
|
||||
});
|
||||
}
|
||||
|
||||
if (folderId) {
|
||||
const folder = availableFolders.value?.find(f => f.id === folderId);
|
||||
showToast(`Moved to folder "${folder?.name || 'Unknown'}"`, 'fa-folder', 2000, 'success');
|
||||
} else {
|
||||
showToast('Removed from folder', 'fa-folder-minus', 2000, 'success');
|
||||
}
|
||||
|
||||
return updatedRecording;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error updating folder:', error);
|
||||
setGlobalError(`Failed to update folder: ${error.message}`);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const removeRecordingFromFolder = async (recordingId) => {
|
||||
return assignFolderToRecording(recordingId, null);
|
||||
};
|
||||
|
||||
const bulkAssignFolder = async (recordingIds, folderId) => {
|
||||
try {
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
||||
|
||||
const response = await fetch('/api/recordings/bulk/folder', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
body: JSON.stringify({
|
||||
recording_ids: recordingIds,
|
||||
folder_id: folderId || null
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || 'Failed to update folders');
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// Update local recording data
|
||||
recordingIds.forEach(id => {
|
||||
const recording = recordings.value.find(r => r.id === id);
|
||||
if (recording) {
|
||||
recording.folder_id = folderId || null;
|
||||
recording.folder = folderId ? availableFolders.value?.find(f => f.id === folderId) : null;
|
||||
}
|
||||
});
|
||||
|
||||
// Update folder recording counts
|
||||
if (availableFolders.value) {
|
||||
availableFolders.value.forEach(f => {
|
||||
const count = recordings.value.filter(r => r.folder_id === f.id).length;
|
||||
f.recording_count = count;
|
||||
});
|
||||
}
|
||||
|
||||
if (folderId) {
|
||||
const folder = availableFolders.value?.find(f => f.id === folderId);
|
||||
showToast(`${result.updated_count} recording(s) moved to "${folder?.name || 'Unknown'}"`, 'fa-folder', 2000, 'success');
|
||||
} else {
|
||||
showToast(`${result.updated_count} recording(s) removed from folder`, 'fa-folder-minus', 2000, 'success');
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error bulk updating folders:', error);
|
||||
setGlobalError(`Failed to update folders: ${error.message}`);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
// Methods
|
||||
getRecordingFolder,
|
||||
getFolderById,
|
||||
getFolderColor,
|
||||
getFolderName,
|
||||
getAvailableFoldersForRecording,
|
||||
assignFolderToRecording,
|
||||
removeRecordingFromFolder,
|
||||
bulkAssignFolder
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user