Skip to content

[Bug] Render Video editable loading / error states natively in Studio#3486

Merged
markus-moser merged 23 commits into
2025.4from
3407-fix-video-editable-rendering
Jun 24, 2026
Merged

[Bug] Render Video editable loading / error states natively in Studio#3486
markus-moser merged 23 commits into
2025.4from
3407-fix-video-editable-rendering

Conversation

@markus-moser

@markus-moser markus-moser commented May 5, 2026

Copy link
Copy Markdown
Contributor

Changes in this pull request

Resolves #3407

Renders the Video editable's in-progress and error states with Studio-native UI instead of the classic-UI markup:

  • in-progress: a Spin overlay over the placeholder; polls the thumbnail status every 5s and reloads the editor once conversion finishes
  • error: an edit button so users can pick a different asset / thumbnail config

Companion PRs

The Video editable's in-progress and error placeholders were rendered
by pimcore/pimcore as classic-UI markup with hardcoded references to
/bundles/pimcoreadmin/img/video-loading.gif and
filetype-not-supported.svg, plus inline editmode-iframe styling.
These leaked into Studio's chrome (see screenshots in #3407) and the
error state offered no edit affordance, leaving users unable to
recover from a broken thumbnail config.

Companion changes in pimcore/pimcore (12.3 + 2026.1) reduce those
methods to minimal marker divs in Studio context. This change makes
studio-ui-bundle render the actual UI on top:

- detects .pimcore_editable_video_progress and
  .pimcore_editable_video_error markers in the editable container
- renders a Spin overlay (with a dashed border matching the empty
  placeholder) over the in-progress marker
- renders the same edit IconButton that's used on a rendered video
  over the error marker, so users can click through to the modal
  and pick a different asset / thumbnail config
- polls a new studio-backend-bundle endpoint
  (/assets/{id}/video/thumbnail/{thumbnailName}/status) every 5s
  while in-progress and triggers an editor reload when the status
  flips to finished or error

The thumbnail config name is now part of VideoEditableDefinition.config
and threaded into the VideoEditable component as the thumbnailName prop.

Resolves #3407
@sonarqubecloud

sonarqubecloud Bot commented May 5, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
1 New Critical Issues (required ≤ 0)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

markus-moser and others added 21 commits June 9, 2026 13:58
… guard reload

- extract renderEditButtonOverlay() shared by the error and rendered-video states
- extract captureMarker() helper, removing 3x duplicated querySelector/setState blocks
- centralize marker class names in MARKER_CLASS
- guard triggerSaveAndReload() with a ref so it fires once per mount
- narrow container with isNil (covers undefined)
… translations

- show the data-message provided by the error marker inside the error overlay
  (it was previously preserved by the core PRs but never consumed)
- only poll the thumbnail status for named thumbnail configurations, the
  editable config may also contain an inline configuration object
- stop polling while the browser tab is unfocused
- add the video.preview-in-progress translation to all remaining languages
The studio-backend video thumbnail status endpoint is now part of the committed
OpenAPI schema, so the asset API slice is generated with the
assetVideoThumbnailStatus query + VideoThumbnailStatus type. Drop the manual
injectEndpoints() hand-injection (and its hand-written types) from the enhanced
slice — the endpoint now comes straight from asset-api-slice.gen.ts.
Resolve assets/build/api/docs.jsonopenapi.json: take the latest 2025.4 schema
(which does not yet include the video thumbnail status endpoint) and re-add the
asset_video_thumbnail_status path + VideoThumbnailStatus schema on top, so the
generated asset slice keeps the endpoint. Build artifacts taken from 2025.4 (CI
regenerates them).
When the thumbnail finishes converting, the document state is unchanged (same
asset reference) — there is nothing to save, the editable just needs to
re-render. triggerSaveAndReload() runs an autosave, which the edit-lock gate
holds until the first user edit; for a poll-triggered save with no prior edit
that never resolves and the editor hangs on the reload overlay.

Add a reload-only path (DocumentApi.reloadIframe -> iframeRef.reload()) and use
it from the video editable. Avoids the autosave/edit-lock gate entirely and no
longer requires save permission for the auto-refresh.
reloadIframe now flushes pending edits first when the document is modified
(save-and-reload, as before — the edit-lock gate is already resolved in that
case), and only does a plain reload when there is nothing to save. Keeps the
original save-and-reload behavior where edits exist while still avoiding the
edit-lock autosave gate hang for the no-edit case (e.g. opening a document whose
video is already assigned and still converting).
…refresh

The video editable's auto-refresh chose save-vs-reload from the redux `modified`
flag, which is set via a deferred startTransition. A "finished" poll landing in the
brief window right after a keystroke saw modified=false and took the reload-only
path, discarding the just-typed (still unsaved) value.

Record edited documents synchronously in triggerValueChange instead. Any document
the user has touched is then always flushed via save-and-reload (which persists the
live editable values and whose edit-lock gate is/will-be resolved, so it cannot
hang), while never-edited documents keep the reload-only path. The flag is cleared
after a save-and-reload and on unregister so a freshly reloaded, untouched document
correctly reverts to reload-only.
Resolve conflict in video-editable.tsx: keep the renderEditButtonOverlay
refactor (ours) and adopt the InheritanceOverlay -> EditableOverlay rename
from 2025.4. Generated public/build artifacts taken from this branch; CI
regenerates them on push.
…ock gate

The gate is armed once on EditorContainer mount, not per iframe reload. The
delete still stands (the reloaded document is a clean baseline, so a later
refresh can take the cheap reload-only path), but the prior rationale was wrong.
't("video.edit")' had no translation key in any language (pre-existing), so the
tooltip showed the raw key. Reuse the generic 'edit' key, which is translated in
all 7 languages.
@sonarqubecloud

Copy link
Copy Markdown

@markus-moser markus-moser added this to the 2025.4.6 milestone Jun 24, 2026
@markus-moser markus-moser marked this pull request as ready for review June 24, 2026 12:57
@markus-moser markus-moser merged commit 05ea49c into 2025.4 Jun 24, 2026
1 check passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 24, 2026
@markus-moser markus-moser deleted the 3407-fix-video-editable-rendering branch June 24, 2026 12:58
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant