feat(quick-261009-dkv): Teilen mit Personen und Gruppen - Durchstich, Oberflaeche

- Teilen-Dialog (Suche mit Verzoegerung, Ergebnisliste als Combobox, Berechtigung
  je Zeile aendern, entfernen) auf dem Modul-Dialog, Fehler mit Meldung der Nextcloud
- Menueeintrag Teilen (nur bei Buchstabe R), Freigabe-Kennzeichen in Liste und Raster
  (ausgehend als Knopf, eingehend als Markierung)
- Web-Client, reine Hilfen (Berechtigungsauswahl, Passwort erzeugen), Fehlertexte
  und Meldungen de/en; sharingDisabled traegt scope=groups fuer den Gruppentext

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-09 10:52:35 +02:00
parent 207d37b8d6
commit bf893afc61
19 changed files with 1640 additions and 12 deletions
+110
View File
@@ -209,6 +209,8 @@ export interface NcEntry {
permissions: string;
hasPreview: boolean;
favorite: boolean;
/** Freigabearten des Eintrags (0 Person, 1 Gruppe, 3 Link ...); leer = nicht geteilt. */
shareTypes: number[];
}
export interface NcQuota {
@@ -315,3 +317,111 @@ export function checkZip(dir: string, names: readonly string[]): Promise<{ ok: t
json: { dir, names, check: true },
});
}
// --- Teilen (quick-261009-dkv) -------------------------------------------------------------------
export type NcShareKind = 'user' | 'group' | 'link';
/** `custom`: eine Berechtigung, die sich nicht auf Ansehen/Bearbeiten/Hochladen abbilden laesst. */
export type NcShareAccess = 'view' | 'edit' | 'upload' | 'custom';
export interface NcShare {
id: string;
kind: NcShareKind;
path: string;
name: string;
itemType: 'file' | 'folder';
mime: string | null;
itemWritable: boolean;
permissions: number;
access: NcShareAccess;
shareWith: string | null;
shareWithName: string | null;
ownerId: string | null;
ownerName: string | null;
canEdit: boolean;
canDelete: boolean;
/** `YYYY-MM-DD` oder null. */
expiration: string | null;
label: string;
/** Nur bei eigenen Links; Tessera ruft sie nie auf. */
url: string | null;
hasPassword: boolean;
target: string;
sharedAt: string | null;
pending?: boolean;
}
export interface NcSharee {
kind: 'user' | 'group';
id: string;
label: string;
detail: string | null;
}
/** Freigaberegeln der Nextcloud fuer den angemeldeten Benutzer (frisch gelesen). */
export interface NcSharePolicy {
enabled: boolean;
groupsEnabled: boolean;
links: {
enabled: boolean;
passwordRequired: boolean;
passwordSuggested: boolean;
expiryDefaultDays: number | null;
expiryEnforced: boolean;
uploadAllowed: boolean;
multipleLinks: boolean;
};
internalExpiry: { defaultDays: number | null; enforced: boolean };
minSearchLength: number;
passwordMinLength: number | null;
}
export interface NcShareList {
path: string;
shares: NcShare[];
/** Freigaben anderer Arten (E-Mail, Server ...), nur als Zahl. */
hidden: number;
truncated: boolean;
}
export interface CreateShareInput {
path: string;
kind: 'user' | 'group';
shareWith: string;
access: 'view' | 'edit' | 'upload';
}
export interface UpdateShareInput {
access?: 'view' | 'edit' | 'upload';
}
export function getSharePolicy(): Promise<NcSharePolicy> {
return request<NcSharePolicy>('/shares/policy');
}
/** Freigaben eines Eintrags; der Pfad geht nur in der Query. */
export function listSharesForPath(path: string): Promise<NcShareList> {
return request<NcShareList>(`/shares/by-path?path=${encodeURIComponent(path)}`);
}
/** Personen und Gruppen, die die Nextcloud zum Suchbegriff kennt. */
export function searchSharees(
term: string,
itemType: 'file' | 'folder',
): Promise<{ sharees: NcSharee[] }> {
return request<{ sharees: NcSharee[] }>(
`/sharees?term=${encodeURIComponent(term)}&itemType=${encodeURIComponent(itemType)}`,
);
}
export function createShare(input: CreateShareInput): Promise<NcShare> {
return request<NcShare>('/shares', { method: 'POST', json: input });
}
export function updateShare(id: string, input: UpdateShareInput): Promise<NcShare> {
return request<NcShare>(`/shares/${encodeURIComponent(id)}`, { method: 'PUT', json: input });
}
export function deleteShare(id: string): Promise<{ deleted: true }> {
return request<{ deleted: true }>(`/shares/${encodeURIComponent(id)}`, { method: 'DELETE' });
}