Repository navigation
feat(dashboard): preview images in plugin file configuration - #10596
ZXLyyds100 wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="dashboard/src/components/shared/ConfigImagePreview.vue" line_range="69" />
<code_context>
+ objectUrl = URL.createObjectURL(response.data)
+ imageUrl.value = objectUrl
+ }
+ } catch {
+ // Unsupported, missing, or oversized images must not block file management.
+ } finally {
</code_context>
<issue_to_address>
**Preview failures go unnoticed**
When the preview API fails because of a transient service, storage, or network error, the catch suppresses every request failure, so a backend or storage outage is rendered as the same unavailable icon as an unsupported image, with no log or operator-visible indication that previews are failing.
Keep unsupported-image failures quiet but log or otherwise surface unexpected preview request failures.
</issue_to_address>
### Comment 2
<location path="dashboard/src/components/shared/FileConfigItem.vue" line_range="29" />
<code_context>
<template #prepend>
- <v-icon size="18">mdi-file</v-icon>
+ <div class="file-thumbnail mr-3">
+ <v-lazy v-if="dialog && item.status !== 'missing' && /\.(png|jpe?g|webp|gif|bmp|tiff?|ico)$/i.test(item.path)"
+ :key="`${pluginName}:${configKey}:${item.path}:${previewRevision}`" min-height="48" width="56">
+ <ConfigImagePreview :plugin-name="pluginName" :config-key="configKey" :path="item.path" />
</code_context>
<issue_to_address>
**Supported images show generic icons**
When a supported image uses an extension omitted from the frontend allowlist, such as `.jfif`, `.jpe`, or `.dib`, the extension check prevents `ConfigImagePreview` from calling the endpoint, so users see a generic file icon instead of a preview even though the backend accepts the image.
Include all supported image extensions in the frontend allowlist or avoid filtering previews by filename extension.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 2 findings to address first, and the new authenticated endpoint returns image content from plugin storage; if its field-directory or symlink checks fail, a user with plugin scope could retrieve images outside the selected field. Reverting removes the endpoint, but cannot undo images already accessed.
Blocking findings: dashboard/src/components/shared/ConfigImagePreview.vue:69, dashboard/src/components/shared/FileConfigItem.vue:29
|
你好,这个可以点进去一项看图片吗? |
|
@mjy1113451 你好,可以的。在「插件 → 已安装 → 插件配置(齿轮)→ 管理文件」里,点击每项左侧的图片缩略图,就会弹出较大的图片预览;可以用 Esc 或右上角关闭按钮退出,键盘聚焦缩略图后按 Enter 也可以打开。 刚在当前提交 PR 已附有放大预览截图和10 秒操作录像,可以直接看效果。 补充说明:这里是经过安全处理的图片预览(最长边 1024 像素,动图显示首帧),不是原始文件下载;点击入口是缩略图,而非文件名。 |
|
Updated on 2026-10-22 in Fresh local results: 4,848 Python tests passed / 11 skipped / 72 warnings, Existing visual evidence keeps its original revisions. Hosted workflows still Historical delivery reportUpdated on 2026-10-20 in Fresh local acceptance: 4720 Python tests passed / 11 platform-or-optional The pushed ref, resulting PR file list and PR body were read back and verified. Previous synchronization report — 2026-10-18Synchronized master in Revalidation exposed a pre-existing restart-test hang, independently reproduced on clean master Full local suite: 4702 passed / 11 skipped; dashboard Node: 78 passed; browser: 31 assertions, with all 29 object URLs reclaimed. Types, locales, API generation, builds, Ruff and normal hooks passed. Fresh screenshots, 10.6-second recording, skip details and provenance are also linked in the updated PR description. Hosted GitHub Actions still require maintainer authorization; these local results and the automated Sourcery check are not hosted CI success or human approval. |
Closes #10595.
The plugin file-configuration manager lists uploaded images by name only. This
adds thumbnails and a larger preview within the existing manager, without
changing plugin configuration or upload/delete semantics.
Modifications / 改动点
Reuse plugin authentication for a field-scoped image-preview endpoint. Resolve
and reject path/symlink escapes; bound input to 10 MiB and 20 million pixels;
return a metadata-free PNG thumbnail (maximum edge 1024). Animated images
preview their first frame. Original files are not modified.
Lazy-load previews through the authenticated API client and object URLs, never
login tokens in image URLs. Cancel requests and revoke URLs when closing,
removing or switching files. Refresh previews after same-name uploads.
Preserve management of non-image, missing, corrupt and oversized files. Add
accessible preview buttons, keyboard operation and translations for all four
existing locales.
Update Chinese/English WebUI and plugin-configuration instructions, OpenAPI,
the generated client and public API/scope documentation. No navigation
entry was renamed or moved.
This is NOT a breaking change. / 这不是一个破坏性变更。
Screenshots or Test Results / 运行截图或测试结果
Current acceptance after master sync — 2026-10-22
Current head:
802a79718b383f0de58ad01545a2c93c99429a85. Normally merged master1b10813c70949071fa11153cc4ec8c51421d13d0, preserving PR history.The only merge conflict was the generated SDK's type import. Resolved it with
the official API generator, retaining both this image-preview API and master's
log-export API. The resulting PR still contains the original 20 feature files;
no workflow, dependency, permission-gate or production-restart change was added.
pytest -q --cov=.): 4,848 passed, 11 skipped,72 warnings. The focused dashboard API suite: 205 passed (included in
the full count, not additive).
and production dashboard build passed. Existing dependency, asset/font and
async-cleanup warnings remain; this is not a warning-free run.
These are this run's tools, not the historical CI-version claims below.
fresh synthetic data root; the task-owned process was then stopped. An earlier
attempt waited for a remote dashboard download, so it was not counted as a
successful start. No IM provider or paid model was invoked.
No fresh browser capture, locale check or documentation build is claimed for
this synchronization. Existing screenshots/recordings and earlier lifecycle,
locale and documentation results retain their actual historical revisions.
The private smoke log is not published because it can include synthetic
initialization credentials. Local success and Sourcery are not human review
or upstream Actions approval/success.
Historical acceptance after master sync — 2026-10-20
Head at that checkpoint:
63f30db299fe9d9d75ba8aa6b8813b51e264d440. Normally merged masterf2404c191716a64daaa422be7f3c567cace50d39without rewriting the PR history.The only conflict was the restart-test fixture: master now supplies its own
module-local threading mock and bounded wait. Kept that upstream test
byte-for-byte, removing the superseded fixture workaround from this PR.
The resulting diff is the original 20 feature files; no production restart,
workflow, dependency, or permission-gate changes are introduced.
4720 passed, 11 skipped. No tests were deselected or newly skipped.
dashboard Node tests: 78 passed.
final typecheck, four-locale checks, production dashboard build, and
English/Chinese documentation build passed. Dashboard uses CI's
Node 24.13.0 / pnpm 10.28.2.
and one requires optional
edge_tts. Dependency deprecation warnings andexisting build-size warnings remain.
temporary parent and verified the dynamic-plugin data-root convention.
The final complete CI-script run passed with no production or test-source
changes to hide those setup failures.
The preview implementation and its regression tests are byte-identical to
the preceding head. The only changed feature-file blobs are the two WebUI
guides, which retain master's current navigation/settings instructions plus
the preview instructions. Existing real screenshots/recordings below keep
their explicit historical revisions; no fresh browser run or new capture
is claimed for this test-fixture-only conflict resolution. The current
documentation path is Extensions → Plugins → Extension Config → Manage Files.
Hosted workflow authorization and human review remain separate from these
local results; neither is implied by local tests or a bot check.
Historical acceptance after master sync — 2026-10-18
Head at that checkpoint:
ae728172062566bd251be143a40d9ecd79ffbdb5. Synchronized master8774e53, resolving the generatedSDK conflict by regeneration and preserving both preview and trace endpoints.
The original 20 feature files remain in scope, plus one test-only lifecycle
fixture adjustment; production restart logic is unchanged.
345 passed; lifecycle: 26 passed; dashboard Node tests: 78 passed.
production dashboard build and docs build passed with CI's Node/pnpm versions.
8774e53checkout reproduces a hang in the restart test.Its global Thread mock also blocks the executor used by new trace cleanup.
The fixture now mocks
asyncio.to_threadand asserts the cleanup call.The full suite was rerun without deselecting that test or adding a skip.
Fresh real screenshots and a 10.6-second
interaction recording use recreated synthetic files and the real backend.
edge_ttsimport. Hosted Actions still await maintainer authorization; localsuccess and Sourcery success are not human approval or hosted CI success.
2026-10-18 evidence and source provenance ·
2026-10-18 interaction recording
2026-10-18 synchronized-head screenshots
The historical before/after captures and counts below remain tied to their
explicit original revisions; they have not been relabeled as current captures.
Actual dashboard screenshots using the same synthetic fixture files in an
isolated data root. Before: unmodified
de898afbackend and production build.After:
e80a91ebackend and production build. These are not mockups.10-second actual browser recording
· Evidence and reproducible fixture
Larger preview and mobile screenshots
Verification steps
From the repository's development environment:
in the existing API test module. Includes JWT/API-key scope, path/field/symlink
isolation, invalid/missing images, limits, formats, orientation, metadata,
first-frame behavior and source-file preservation.
production build, API-generation consistency, docs build, full Ruff checks and
normal changed-file commit hooks passed. Final build uses CI's
Node 24.13.0 / pnpm 10.28.2.
desktop/mobile bounds, same-name overwrite/restore, unconfigured images,
add/delete, field isolation, repeated open/close and cancellation of delayed
real requests, actual image-extension aliases, sanitized failure logging and
expected-error suppression. Instrumented 29 URLs created / 29 revoked / 0 live.
updated docs. Evidence is on a separate fork branch, not in the product diff.
Manual reproduction: use a plugin
filesetting accepting images, upload alandscape/portrait image and a non-image file, open Manage Files, click a
thumbnail, and close it with Escape or its close button. Repeat on mobile,
overwrite an image with the same filename, and reopen the manager.
Original pre-sync validation boundaries: the four Python skips also occur on the base. No live
IM platform or paid-model execution is claimed. The deliberate invalid PNG gets
the expected 415/fallback; baseline Vuetify list warnings remain. Repository-wide
pre-commit --all-filesrewrites two unrelated baseline files through pyupgrade;those incidental changes were reverted and are excluded. Normal commit hooks
on this PR pass without any bypass.
Automated review follow-up
Both Sourcery findings were addressed in
e80a91e: log unexpected failureswithout Axios credentials, distinguish storage failures (503) from decoder
failures (415), and support
.jfif/.jpe/.dib/.apngaliases including real DIBdecoding. The supplemental review before/after evidence
reproduces the old frontend's zero alias thumbnails/zero 500 warnings and
verifies the corrected behavior. Browser 500/network/415/wrong-MIME scenarios
are explicitly controlled fault injection, not real deployment outage claims.
Sourcery's automated review does not replace a human reviewer.
Checklist / 检查清单
in [Feature] 增加插件配置的管理文件的已上传图片可视图化 #10595 and the issue reporter invited implementation. This is not a claim
of maintainer design approval.
updated. Navigation is unchanged, so no old-to-new entry mapping is needed.
Disclosure: investigation, implementation, tests, self-review and evidence were
produced with OpenAI Codex assistance. No independent human review, maintainer
approval or completed upstream CI is implied.
Summary by Sourcery
Enable secure image previews in the plugin file configuration manager without changing upload or deletion semantics.
New Features:
Enhancements:
Documentation:
Tests: