feat: Ordneruebersicht in der Galerie -- und der Proxy haelt keine Bilder mehr fest
ORDNERUEBERSICHT. Eine Spalte neben der Galerie mit allen Ordnern, auf allen Ebenen, mit Anzahl und Groesse; ein Klick filtert. Neu dafuer: - GET /api/dash/folders -- die Ordner werden in JavaScript zusammengezaehlt und nicht in SQL: fuer eine Baumansicht braucht es JEDE Ebene, und das waere in SQLite eine rekursive Abfrage, die niemand mehr liest. - GET /api/dash/media?folder=... als EIGENER Filter neben der Suche. Die Suche findet mit LIKE %...% auch "alt/vehicles/adder.webp"; ein Ordner, der Dinge zeigt, die nicht darin liegen, ist keiner. Hier ist der Anfang verankert. - Die LIKE-Sonderzeichen werden maskiert: ein Ordner "fotos_alt" wuerde sonst auch "fotosXalt" treffen, weil _ in LIKE ein beliebiges Zeichen ist. Die Zahlen sind kumulativ -- "vehicles" enthaelt, was in "vehicles/showroom" liegt. Alles andere ueberrascht in einer Baumansicht. Nachgemessen ueber drei Ebenen: vehicles (24) > showroom (2) > tief (1), Filter und Zaehlung stimmen, und nach dem Aufraeumen steht wieder vehicles (22). Flache Liste mit Einrueckung statt aufklappbarem Baum: bei einer Handvoll Ordner ist ein Aufklappmechanismus mehr Bedienung als Nutzen -- und was man nicht aufklappen muss, kann man auch nicht zugeklappt uebersehen. Dazu: der NPM-Zwischenspeicher ist zu. Der Schnipsel steht im Feld "Custom Nginx Configuration"; NPM setzt ihn innerhalb des server-Blocks ein, eine location ist dort also gueltig. Nachgemessen: cache-control kommt wieder von uns, und ein ueberschriebenes Bild ist sofort das neue. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+14
-2
@@ -137,6 +137,16 @@ export type NewToken = {
|
||||
token: string
|
||||
}
|
||||
|
||||
/** Ein Ordner mit KUMULATIVEN Zahlen: "vehicles" enthält, was in
|
||||
* "vehicles/showroom" liegt. `tiefe` ist die Einrückung im Baum. */
|
||||
export type FolderRow = { folder: string; files: number; bytes: number; tiefe: number }
|
||||
|
||||
export type Folders = {
|
||||
items: FolderRow[]
|
||||
gesamt: { files: number; bytes: number }
|
||||
wurzel: { files: number; bytes: number }
|
||||
}
|
||||
|
||||
export type ThumbLauf = {
|
||||
erzeugt: number
|
||||
vorhanden: number
|
||||
@@ -160,10 +170,12 @@ export const api = {
|
||||
changePassword: (current: string, next: string) =>
|
||||
post<{ ok: true }>('/api/dash/auth/password', { current, next }),
|
||||
|
||||
media: (query: string, limit: number, offset: number) =>
|
||||
media: (query: string, folder: string, limit: number, offset: number) =>
|
||||
get<MediaPage>(
|
||||
`/api/dash/media?query=${encodeURIComponent(query)}&limit=${limit}&offset=${offset}`,
|
||||
`/api/dash/media?query=${encodeURIComponent(query)}` +
|
||||
`&folder=${encodeURIComponent(folder)}&limit=${limit}&offset=${offset}`,
|
||||
),
|
||||
folders: () => get<Folders>('/api/dash/folders'),
|
||||
deleteMedia: (id: number) => del<{ deleted: string }>(`/api/dash/media/${id}`),
|
||||
deleteMediaBulk: (ids: number[]) =>
|
||||
post<{ deleted: string[]; count: number }>('/api/dash/media/delete', { ids }),
|
||||
|
||||
Reference in New Issue
Block a user