feat(12.2-04): add the fileupload field with deferred uploads on the form session key

- sessionKey.ts: one 32-byte base64url key per form mount, sent only in headers
- api/files.ts: FileRoutes over the record and child file routes, XHR upload with progress, 401 refresh and retry
- FileuploadField and FileCaptionModal per UI-SPEC section 3: dropzone, image grid, rows, per-item states, client pre-checks, reorder, protected previews
- FormView provides FORM_SESSION, counts pending changes as dirty and sends X-Session-Key on create and update
- fileupload lang keys in en and pl, admin-spa docs note, deferred smoke test, rebuilt dist
This commit is contained in:
Jakub Zych
2026-10-02 19:22:22 +02:00
parent 1ebfe691a2
commit ea33296799
22 changed files with 2338 additions and 15 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -6,8 +6,8 @@
<meta name="robots" content="noindex, nofollow" />
<meta name="summer-admin-base" content="__SUMMER_ADMIN_BASE__" />
<title>SummerCMS</title>
<script type="module" crossorigin src="./assets/index-J-FCndLr.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-CfeX_snf.css">
<script type="module" crossorigin src="./assets/index-BPPmlB5x.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-C8GNzEPt.css">
</head>
<body>
<div id="app"></div>

View File

@@ -104,6 +104,42 @@ extension:
widget_failed: This control could not be loaded. Refresh the page; if it happens again, check the plugin's assets.
partial_failed: This section could not be loaded. Refresh the page to try again.
action_failed: The action could not be completed. Please try again.
fileupload:
attachment: Attachment details
help: Add a title and description for this attachment.
title_label: Title
description_label: Description
default_prompt: Drag a file here or click to upload
default_prompt_many: Drag files here or click to upload
upload_file: Upload file
replace_file: Replace file
remove_file: Remove file
upload_error: Upload error
upload_failed: The file could not be uploaded. Try again.
retry: Retry
too_large: ":name is larger than :size. Choose a smaller file."
wrong_type: ":name is not an allowed file type. Allowed: :types."
too_many:
one: "File limit reached (:max). :count file was not added."
other: "File limit reached (:max). :count files were not added."
limits_types: "Allowed: :types"
limits_size: "up to :size"
limits_count: "Files: :current of :max"
uploading: "Uploading… :percent%"
queued: Waiting…
unsaved: Unsaved
move: "Move: :name"
moved: "Moved :name to position :position of :total."
reorder_failed: The new order could not be saved. The previous order is back.
edit_details: "Edit details: :name"
download: "Download: :name"
open_preview: "Open: :name"
preview_unavailable: No preview
load_failed: The files could not be loaded. Refresh the page to try again.
cancel_upload: "Cancel upload: :name"
details_saved: Attachment details saved
details_submit: Save details
empty: No files
messages:
list:
record_count:

View File

@@ -112,6 +112,44 @@ extension:
widget_failed: Nie udało się wczytać tej kontrolki. Odśwież stronę, a jeśli błąd wróci, sprawdź zasoby wtyczki.
partial_failed: Nie udało się wczytać tej sekcji. Odśwież stronę, aby spróbować ponownie.
action_failed: Nie udało się wykonać akcji. Spróbuj ponownie.
fileupload:
attachment: Szczegóły załącznika
help: Dodaj tytuł oraz opis załącznika.
title_label: Tytuł
description_label: Opis
default_prompt: Przeciągnij plik tutaj lub kliknij, aby przesłać
default_prompt_many: Przeciągnij pliki tutaj lub kliknij, aby przesłać
upload_file: Prześlij plik
replace_file: Zamień plik
remove_file: Usuń plik
upload_error: Błąd przesyłania
upload_failed: Nie udało się przesłać pliku. Spróbuj ponownie.
retry: Ponów
too_large: "Plik :name jest większy niż :size. Wybierz mniejszy plik."
wrong_type: "Plik :name ma niedozwolony typ. Dozwolone: :types."
too_many:
one: "Osiągnięto limit plików (:max). Nie dodano :count pliku."
few: "Osiągnięto limit plików (:max). Nie dodano :count plików."
many: "Osiągnięto limit plików (:max). Nie dodano :count plików."
other: "Osiągnięto limit plików (:max). Nie dodano :count plików."
limits_types: "Dozwolone: :types"
limits_size: "do :size"
limits_count: "Pliki: :current z :max"
uploading: "Przesyłanie… :percent%"
queued: Oczekuje…
unsaved: Niezapisany
move: "Przenieś: :name"
moved: "Przeniesiono :name na pozycję :position z :total."
reorder_failed: Nie udało się zapisać nowej kolejności. Przywrócono poprzednią.
edit_details: "Edytuj szczegóły: :name"
download: "Pobierz: :name"
open_preview: "Otwórz: :name"
preview_unavailable: Brak podglądu
load_failed: Nie udało się wczytać plików. Odśwież stronę, aby spróbować ponownie.
cancel_upload: "Anuluj przesyłanie: :name"
details_saved: Zapisano szczegóły załącznika
details_submit: Zapisz szczegóły
empty: Brak plików
messages:
list:
record_count: