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:
@@ -4,6 +4,7 @@
|
||||
// clears that field's errors exactly like typing into it. A form without a
|
||||
// provider (settings pages) gets the defaults of the injecting control.
|
||||
import type { InjectionKey, Ref } from 'vue'
|
||||
import type { FileRoutes } from '../../api/files'
|
||||
import type { AdminRecord } from '../../api/types'
|
||||
|
||||
/** Read-only view of the form's current values. */
|
||||
@@ -21,6 +22,34 @@ export const FORM_LOCALE: InjectionKey<Readonly<Ref<string>>> = Symbol('summer.f
|
||||
*/
|
||||
export const FORM_ASSETS: InjectionKey<() => Promise<string[]>> = Symbol('summer.form.assets')
|
||||
|
||||
/**
|
||||
* The form's deferred-binding session (D-02, D-03). FormView makes one per
|
||||
* mount; a relation child modal provides its own for the fields inside it.
|
||||
* Uploads, removals and deferred relation calls go out with `key` (and
|
||||
* `childKey` in a child modal) and are committed by the form's next save.
|
||||
*/
|
||||
export interface FormSession {
|
||||
/** The record form's session key (X-Session-Key). */
|
||||
key: string
|
||||
/** The child modal's own key (X-Child-Session-Key); absent on a record form. */
|
||||
childKey?: string
|
||||
/** Id of the record the files belong to; 0 while it is not saved yet. */
|
||||
recordId: number
|
||||
/** The file routes of one fileupload field of this form. */
|
||||
routes(field: string): FileRoutes
|
||||
/**
|
||||
* Records a change held against the session (an upload, a removal, a
|
||||
* cancelled upload, a deferred relation change): the form becomes dirty.
|
||||
*/
|
||||
markDirty(): void
|
||||
/** How many such changes the form holds; 0 after a successful save. */
|
||||
pendingChanges: Readonly<Ref<number>>
|
||||
/** Goes up after every successful save, so fields can reload their files. */
|
||||
revision: Readonly<Ref<number>>
|
||||
}
|
||||
|
||||
export const FORM_SESSION: InjectionKey<FormSession> = Symbol('summer.form.session')
|
||||
|
||||
/** Event a widget element dispatches to run its action (bubbles, composed). */
|
||||
export const WIDGET_EVENT = 'summer-action'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user