9b135e42b7
Backend: set_permission und remove_permission feuern jetzt ein SSE-Event vom Typ 'permission' an Target-User + Owner + weitere Share-Empfaenger. Damit aktualisieren sich die Dateilisten aller Beteiligten in Echtzeit - auch beim Betroffenen, der gerade seinen Zugriff verliert. Frontend: FilesView wrapped loadFiles in safeLoadCurrentFolder(). Bei 403/404 erscheint ein Toast "Dieser Ordner wurde geloescht oder die Freigabe wurde entfernt" und nach 600ms wird zurueck zum Root navigiert. Greift beim Direktaufruf, beim Ordnerwechsel und bei durch SSE ausgeloesten Auto-Reloads. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
94 lines
2.7 KiB
JavaScript
94 lines
2.7 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import apiClient from '../api/client'
|
|
import { useAuthStore } from './auth'
|
|
|
|
export const useFilesStore = defineStore('files', () => {
|
|
const files = ref([])
|
|
const breadcrumb = ref([])
|
|
const currentParentId = ref(null)
|
|
const loading = ref(false)
|
|
|
|
async function loadFiles(parentId = null) {
|
|
loading.value = true
|
|
try {
|
|
currentParentId.value = parentId
|
|
const params = parentId ? { parent_id: parentId } : {}
|
|
const response = await apiClient.get('/files', { params })
|
|
files.value = response.data.files
|
|
breadcrumb.value = response.data.breadcrumb
|
|
} catch (err) {
|
|
// Let the caller handle access/deletion errors - just clear the list
|
|
if (err.response && (err.response.status === 403 || err.response.status === 404)) {
|
|
files.value = []
|
|
breadcrumb.value = []
|
|
}
|
|
throw err
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function createFolder(name, parentId = null) {
|
|
const response = await apiClient.post('/files/folder', {
|
|
name,
|
|
parent_id: parentId,
|
|
})
|
|
await loadFiles(parentId)
|
|
return response.data
|
|
}
|
|
|
|
async function uploadFile(file, parentId = null) {
|
|
const formData = new FormData()
|
|
formData.append('file', file)
|
|
if (parentId) formData.append('parent_id', parentId)
|
|
|
|
const response = await apiClient.post('/files/upload', formData, {
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
})
|
|
await loadFiles(parentId)
|
|
return response.data
|
|
}
|
|
|
|
async function deleteFile(fileId) {
|
|
await apiClient.delete(`/files/${fileId}`)
|
|
await loadFiles(currentParentId.value)
|
|
}
|
|
|
|
async function renameFile(fileId, newName) {
|
|
await apiClient.put(`/files/${fileId}`, { name: newName })
|
|
await loadFiles(currentParentId.value)
|
|
}
|
|
|
|
async function moveFile(fileId, newParentId) {
|
|
await apiClient.put(`/files/${fileId}`, { parent_id: newParentId })
|
|
await loadFiles(currentParentId.value)
|
|
}
|
|
|
|
async function createShareLink(fileId, options = {}) {
|
|
const response = await apiClient.post(`/files/${fileId}/share`, options)
|
|
return response.data
|
|
}
|
|
|
|
async function getShareLinks(fileId) {
|
|
const response = await apiClient.get(`/files/${fileId}/shares`)
|
|
return response.data
|
|
}
|
|
|
|
async function deleteShareLink(token) {
|
|
await apiClient.delete(`/share/${token}`)
|
|
}
|
|
|
|
function downloadUrl(fileId) {
|
|
const auth = useAuthStore()
|
|
return `/api/files/${fileId}/download?token=${encodeURIComponent(auth.accessToken || '')}`
|
|
}
|
|
|
|
return {
|
|
files, breadcrumb, currentParentId, loading,
|
|
loadFiles, createFolder, uploadFile, deleteFile,
|
|
renameFile, moveFile, createShareLink, getShareLinks,
|
|
deleteShareLink, downloadUrl,
|
|
}
|
|
})
|