feat: Bestehende Benutzerfreigaben per Stift-Button bearbeiten
Neben der Muelltonne jetzt ein Stift-Icon im Share-Dialog: Klick macht die Zeile zur Inline-Edit-Zeile mit Permission- Dropdown + Weiterteilen-Checkbox + Speichern/Abbrechen-Buttons. Speichern ruft POST /permissions mit user_id auf - Backend erkennt die bestehende Freigabe und aktualisiert sie, statt loeschen + neu anlegen zu muessen. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9b135e42b7
commit
04bc3f80ec
|
|
@ -187,13 +187,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="filePermissions.length" class="existing-shares">
|
<div v-if="filePermissions.length" class="existing-shares">
|
||||||
<div v-for="perm in filePermissions" :key="perm.id" class="share-perm-item">
|
<template v-for="perm in filePermissions" :key="perm.id">
|
||||||
<i class="pi pi-user"></i>
|
<div v-if="editingPermId !== perm.id" class="share-perm-item">
|
||||||
<span>{{ perm.username }}</span>
|
<i class="pi pi-user"></i>
|
||||||
<Tag :value="permLabel(perm.permission)" size="small" />
|
<span>{{ perm.username }}</span>
|
||||||
<Tag v-if="perm.can_reshare" value="darf weiterteilen" severity="info" size="small" />
|
<Tag :value="permLabel(perm.permission)" size="small" />
|
||||||
<Button icon="pi pi-trash" text size="small" severity="danger" @click="removeUserShare(perm.id)" />
|
<Tag v-if="perm.can_reshare" value="darf weiterteilen" severity="info" size="small" />
|
||||||
</div>
|
<Button icon="pi pi-pencil" text size="small" @click="startEditPerm(perm)" title="Bearbeiten" />
|
||||||
|
<Button icon="pi pi-trash" text size="small" severity="danger" @click="removeUserShare(perm.id)" title="Entfernen" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="share-perm-item editing">
|
||||||
|
<i class="pi pi-user"></i>
|
||||||
|
<span>{{ perm.username }}</span>
|
||||||
|
<Select v-model="editPermValue" :options="availableUserPermOptions" optionLabel="label" optionValue="value" />
|
||||||
|
<label class="reshare-check">
|
||||||
|
<input type="checkbox" v-model="editPermReshare" /> darf weiterteilen
|
||||||
|
</label>
|
||||||
|
<Button icon="pi pi-check" text size="small" severity="success" @click="saveEditPerm(perm)" title="Speichern" />
|
||||||
|
<Button icon="pi pi-times" text size="small" @click="cancelEditPerm" title="Abbrechen" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -295,6 +308,9 @@ const shareUserQuery = ref('')
|
||||||
const selectedShareUser = ref(null)
|
const selectedShareUser = ref(null)
|
||||||
const shareUserPermission = ref('read')
|
const shareUserPermission = ref('read')
|
||||||
const shareUserReshare = ref(false)
|
const shareUserReshare = ref(false)
|
||||||
|
const editingPermId = ref(null)
|
||||||
|
const editPermValue = ref('read')
|
||||||
|
const editPermReshare = ref(false)
|
||||||
const userSearchResults = ref([])
|
const userSearchResults = ref([])
|
||||||
const userPermOptions = [{ label: 'Lesen', value: 'read' }, { label: 'Schreiben', value: 'write' }, { label: 'Admin', value: 'admin' }]
|
const userPermOptions = [{ label: 'Lesen', value: 'read' }, { label: 'Schreiben', value: 'write' }, { label: 'Admin', value: 'admin' }]
|
||||||
const linkPermOptions = [
|
const linkPermOptions = [
|
||||||
|
|
@ -684,6 +700,34 @@ async function removeUserShare(permId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startEditPerm(perm) {
|
||||||
|
editingPermId.value = perm.id
|
||||||
|
editPermValue.value = perm.permission
|
||||||
|
editPermReshare.value = !!perm.can_reshare
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelEditPerm() {
|
||||||
|
editingPermId.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveEditPerm(perm) {
|
||||||
|
if (!shareFile.value) return
|
||||||
|
try {
|
||||||
|
await apiClient.post(`/files/${shareFile.value.id}/permissions`, {
|
||||||
|
user_id: perm.user_id,
|
||||||
|
permission: editPermValue.value,
|
||||||
|
can_reshare: editPermReshare.value,
|
||||||
|
})
|
||||||
|
const res = await apiClient.get(`/files/${shareFile.value.id}/permissions`)
|
||||||
|
filePermissions.value = res.data
|
||||||
|
editingPermId.value = null
|
||||||
|
toast.add({ severity: 'success', summary: 'Berechtigung aktualisiert', life: 2500 })
|
||||||
|
await filesStore.loadFiles(currentParentId())
|
||||||
|
} catch (err) {
|
||||||
|
toast.add({ severity: 'error', summary: 'Fehler', detail: err.response?.data?.error || err.message, life: 5000 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function createShare() {
|
async function createShare() {
|
||||||
console.log('createShare called, shareFile:', shareFile.value?.id, 'permission:', shareLinkPermission.value)
|
console.log('createShare called, shareFile:', shareFile.value?.id, 'permission:', shareLinkPermission.value)
|
||||||
if (!shareFile.value) {
|
if (!shareFile.value) {
|
||||||
|
|
@ -886,7 +930,8 @@ onUnmounted(() => {
|
||||||
.user-result { padding: 0.5rem 0.75rem; cursor: pointer; display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; }
|
.user-result { padding: 0.5rem 0.75rem; cursor: pointer; display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; }
|
||||||
.user-result:hover, .user-result.selected { background: var(--p-primary-50); }
|
.user-result:hover, .user-result.selected { background: var(--p-primary-50); }
|
||||||
.existing-shares { margin-top: 0.5rem; }
|
.existing-shares { margin-top: 0.5rem; }
|
||||||
.share-perm-item { display: flex; align-items: center; gap: 0.5rem; padding: 0.375rem 0; font-size: 0.875rem; }
|
.share-perm-item { display: flex; align-items: center; gap: 0.5rem; padding: 0.375rem 0; font-size: 0.875rem; flex-wrap: wrap; }
|
||||||
|
.share-perm-item.editing { background: var(--p-surface-50); padding: 0.5rem; border-radius: 4px; }
|
||||||
.share-link-item {
|
.share-link-item {
|
||||||
display: flex; justify-content: space-between; align-items: center;
|
display: flex; justify-content: space-between; align-items: center;
|
||||||
padding: 0.5rem 0; border-bottom: 1px solid var(--p-surface-100);
|
padding: 0.5rem 0; border-bottom: 1px solid var(--p-surface-100);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue