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>
This commit is contained in:
parent
9369c851a0
commit
9b135e42b7
|
|
@ -665,6 +665,11 @@ def set_permission(file_id):
|
|||
|
||||
db.session.commit()
|
||||
|
||||
# SSE: notify target user (they just got/updated access) + owner + other
|
||||
# share recipients so everyone's file list refreshes.
|
||||
notify_file_change(f.owner_id, f.id, 'permission',
|
||||
shared_with=[target.id, *_share_recipients(f)])
|
||||
|
||||
# Notify user via email
|
||||
if is_new:
|
||||
try:
|
||||
|
|
@ -692,8 +697,13 @@ def remove_permission(file_id, perm_id):
|
|||
if not is_owner and perm.granted_by != user.id:
|
||||
return jsonify({'error': 'Du kannst nur selbst erstellte Freigaben entfernen'}), 403
|
||||
|
||||
target_user_id = perm.user_id
|
||||
db.session.delete(perm)
|
||||
db.session.commit()
|
||||
|
||||
notify_file_change(f.owner_id, f.id, 'permission',
|
||||
shared_with=[target_user_id, *_share_recipients(f)])
|
||||
|
||||
return jsonify({'message': 'Berechtigung entfernt'}), 200
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,13 @@ export const useFilesStore = defineStore('files', () => {
|
|||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -764,8 +764,26 @@ async function doDelete() {
|
|||
}
|
||||
}
|
||||
|
||||
async function safeLoadCurrentFolder() {
|
||||
try {
|
||||
await filesStore.loadFiles(currentParentId())
|
||||
} catch (err) {
|
||||
const status = err.response?.status
|
||||
if (status === 403 || status === 404) {
|
||||
toast.add({
|
||||
severity: 'warn',
|
||||
summary: 'Kein Zugriff',
|
||||
detail: 'Dieser Ordner wurde geloescht oder die Freigabe wurde entfernt.',
|
||||
life: 5000,
|
||||
})
|
||||
// Redirect to root after short delay so user sees the toast
|
||||
setTimeout(() => router.push('/files'), 600)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => route.params.folderId, () => {
|
||||
filesStore.loadFiles(currentParentId())
|
||||
safeLoadCurrentFolder()
|
||||
})
|
||||
|
||||
// Live updates: subscribe to server-sent events so that lock changes /
|
||||
|
|
@ -778,12 +796,12 @@ function scheduleReload() {
|
|||
if (reloadDebounce) return
|
||||
reloadDebounce = setTimeout(() => {
|
||||
reloadDebounce = null
|
||||
filesStore.loadFiles(currentParentId())
|
||||
safeLoadCurrentFolder()
|
||||
}, 300)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
filesStore.loadFiles(currentParentId())
|
||||
safeLoadCurrentFolder()
|
||||
|
||||
if (auth.accessToken) {
|
||||
const url = `/api/sync/events?token=${encodeURIComponent(auth.accessToken)}`
|
||||
|
|
|
|||
Loading…
Reference in New Issue