Files
minmal-file-cloud-email-pim…/frontend/src/stores/files.js
T
Stefan Hacker 9b135e42b7 feat: Freigaben-Aenderung live + "Ordner nicht mehr verfuegbar"-Handling
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>
2026-04-12 12:00:15 +02:00

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,
}
})