Skip to content

feat(dashboard): add custom cover image for workflow cards#5704

Open
Ma77Ball wants to merge 11 commits into
apache:mainfrom
Ma77Ball:feat/workflow-card-cover-image
Open

feat(dashboard): add custom cover image for workflow cards#5704
Ma77Ball wants to merge 11 commits into
apache:mainfrom
Ma77Ball:feat/workflow-card-cover-image

Conversation

@Ma77Ball

@Ma77Ball Ma77Ball commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Workflow card cover image

  • Add a workflow_cover_image(wid, image) table (cover stored as a downscaled JPEG data URL, FK to workflow with ON DELETE CASCADE) in texera_ddl.sql plus a sql/updates/25.sql migration.
  • Add access-gated GET/PUT/DELETE /workflow/{wid}/cover endpoints on WorkflowResource: read access to fetch (404 when unset), write access to set/delete. Set validation rejects null/blank bodies and enforces a size limit plus a base64 raster MIME allowlist (PNG/JPEG/GIF/WebP; SVG and non-base64 forms rejected to limit stored-XSS surface).
  • Add WorkflowCoverService (frontend) that downscales/re-encodes the chosen file to a small JPEG data URL before upload, fetches the cover, and clears it.
  • Add hover controls on the workflow card (camera to pick an image, rollback to reset), shown only to the owner in private search; previewImage now prefers the stored cover. Controls are keyboard-accessible (aria-label, type="button", revealed on :focus-within).

HuggingFace image-upload operator

  • This branch also bundles the HuggingFace image-task work: a hugging-face-image-upload frontend component, the HuggingFace.png operator asset, and ImageTaskCodegenSpec covering the image-task codegen.

Any related issues, documentation, discussions?

Closes: #5703

How was this PR tested?

  • Backend: WorkflowResourceCoverSpec (uses the MockTexeraDB embedded-Postgres harness) covers all three cover endpoints: 404 when unset, set/get round-trip, read by a user with read access, upsert replace, data-URL/blank/null/size validation rejections, read- and write-access gating, no-persist on validation failure, and idempotent delete. Run sbt "WorkflowExecutionService/testOnly *WorkflowResourceCoverSpec".
  • Frontend (service): WorkflowCoverService spec covers GET mapping the image, 404 resolving to undefined, DELETE being issued, and setCoverFromFile PUTting the resized data URL. Run cd frontend && yarn test --include='**/workflow-cover.service.spec.ts' --watch=false.
  • Frontend (component): CardItemComponent spec covers the cover behaviors (owner-in-private-search gating, cover load on init, default-image fallback, upload success / non-image rejection / upload failure, reset success / failure). Run cd frontend && yarn test --include='**/card-item.component.spec.ts' --watch=false.
  • Manual: open the dashboard in private search as a workflow owner, hover a card, click the camera icon, pick an image, expect the card preview to update; reload in another browser and expect the same cover (synced via backend).
  • Manual: click the rollback icon, expect the card to revert to the default background and the cover to be gone after reload.

Was this PR authored or co-authored using generative AI tooling?

Co-authored with Claude Opus 4.8 in compliance with ASF

@github-actions github-actions Bot added feature engine ddl-change Changes to the TexeraDB DDL frontend Changes related to the frontend GUI labels Jun 14, 2026
@codecov-commenter

codecov-commenter commented Jun 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.28571% with 40 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.23%. Comparing base (7944c09) to head (60c5d39).

Files with missing lines Patch % Lines
...vice/user/workflow-cover/workflow-cover.service.ts 42.42% 19 Missing ⚠️
.../user/list-item/card-item/card-item.component.html 7.14% 13 Missing ⚠️
...nt/user/list-item/card-item/card-item.component.ts 76.66% 4 Missing and 3 partials ⚠️
...rce/dashboard/user/workflow/WorkflowResource.scala 97.14% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #5704      +/-   ##
============================================
- Coverage     55.25%   55.23%   -0.02%     
- Complexity     2993     3001       +8     
============================================
  Files          1117     1118       +1     
  Lines         43195    43306     +111     
  Branches       4657     4670      +13     
============================================
+ Hits          23866    23921      +55     
- Misses        17930    17982      +52     
- Partials       1399     1403       +4     
Flag Coverage Δ *Carryforward flag
access-control-service 70.00% <ø> (ø)
agent-service 34.36% <ø> (ø) Carriedforward from 7944c09
amber 57.88% <97.14%> (+0.06%) ⬆️
computing-unit-managing-service 0.00% <ø> (ø)
config-service 51.56% <ø> (ø)
file-service 59.02% <ø> (ø)
frontend 48.71% <49.35%> (-0.06%) ⬇️
notebook-migration-service 78.57% <ø> (ø)
pyamber 90.20% <ø> (ø) Carriedforward from 7944c09
python 90.76% <ø> (ø) Carriedforward from 7944c09
workflow-compiling-service 55.14% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 2 better · 🔴 5 worse · ⚪ 8 noise (<±5%) · 0 without baseline

Compared against main 7944c09 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 380 0.232 25,834/42,442/42,442 us 🔴 +20.7% / 🔴 +172.5%
🟢 bs=100 sw=10 sl=64 810 0.494 122,425/140,173/140,173 us 🟢 -5.4% / 🔴 +27.9%
bs=1000 sw=10 sl=64 925 0.565 1,081,833/1,127,587/1,127,587 us ⚪ within ±5% / 🔴 +7.3%
Baseline details

Latest main 7944c09 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 380 tuples/sec 417 tuples/sec 758.88 tuples/sec -8.9% -49.9%
bs=10 sw=10 sl=64 MB/s 0.232 MB/s 0.254 MB/s 0.463 MB/s -8.7% -49.9%
bs=10 sw=10 sl=64 p50 25,834 us 23,024 us 12,965 us +12.2% +99.3%
bs=10 sw=10 sl=64 p95 42,442 us 35,153 us 15,578 us +20.7% +172.5%
bs=10 sw=10 sl=64 p99 42,442 us 35,153 us 18,378 us +20.7% +130.9%
bs=100 sw=10 sl=64 throughput 810 tuples/sec 823 tuples/sec 968.9 tuples/sec -1.6% -16.4%
bs=100 sw=10 sl=64 MB/s 0.494 MB/s 0.502 MB/s 0.591 MB/s -1.6% -16.5%
bs=100 sw=10 sl=64 p50 122,425 us 119,548 us 102,767 us +2.4% +19.1%
bs=100 sw=10 sl=64 p95 140,173 us 148,140 us 109,629 us -5.4% +27.9%
bs=100 sw=10 sl=64 p99 140,173 us 148,140 us 118,129 us -5.4% +18.7%
bs=1000 sw=10 sl=64 throughput 925 tuples/sec 920 tuples/sec 997.01 tuples/sec +0.5% -7.2%
bs=1000 sw=10 sl=64 MB/s 0.565 MB/s 0.561 MB/s 0.609 MB/s +0.7% -7.2%
bs=1000 sw=10 sl=64 p50 1,081,833 us 1,083,953 us 1,009,306 us -0.2% +7.2%
bs=1000 sw=10 sl=64 p95 1,127,587 us 1,133,734 us 1,051,088 us -0.5% +7.3%
bs=1000 sw=10 sl=64 p99 1,127,587 us 1,133,734 us 1,082,535 us -0.5% +4.2%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,525.89,200,128000,380,0.232,25834.07,42441.74,42441.74
1,100,10,64,20,2468.85,2000,1280000,810,0.494,122424.88,140172.86,140172.86
2,1000,10,64,20,21620.29,20000,12800000,925,0.565,1081833.32,1127587.30,1127587.30

@Ma77Ball Ma77Ball marked this pull request as ready for review June 14, 2026 12:04
@Ma77Ball

Ma77Ball commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

/request-review @xuang7 @aglinxinyuan

@github-actions github-actions Bot requested a review from xuang7 June 14, 2026 12:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for optional, per-workflow custom cover images on the dashboard workflow cards, persisted on the backend so the cover syncs across sessions/browsers for users with access.

Changes:

  • Adds a new workflow_cover_image table plus Liquibase migration entry.
  • Adds GET/PUT/DELETE /workflow/{wid}/cover endpoints with access gating and basic validation.
  • Adds a frontend WorkflowCoverService (downscale + JPEG re-encode) and workflow-card UI controls (upload/reset) with unit tests.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
sql/updates/25.sql Adds migration to create workflow_cover_image.
sql/texera_ddl.sql Adds workflow_cover_image to the base schema DDL.
sql/changelog.xml Registers Liquibase changeSet 25.
amber/src/main/scala/.../WorkflowResource.scala Implements cover CRUD endpoints and validation.
amber/src/test/scala/.../WorkflowResourceCoverSpec.scala Adds backend regression tests for cover endpoints and authorization/validation.
frontend/src/app/dashboard/service/user/workflow-cover/workflow-cover.service.ts Adds frontend service to fetch/set/clear cover images and resize uploads.
frontend/src/app/dashboard/service/user/workflow-cover/workflow-cover.service.spec.ts Adds unit tests for the new cover service.
frontend/src/app/dashboard/component/.../card-item.component.ts Loads cover on init; adds upload/reset handlers and edit gating.
frontend/src/app/dashboard/component/.../card-item.component.html Adds cover controls (camera/reset) and hidden file input.
frontend/src/app/dashboard/component/.../card-item.component.scss Styles hover-revealed cover controls.
frontend/src/app/dashboard/component/.../card-item.component.spec.ts Adds component tests for cover behaviors and gating.
common/workflow-operator/src/test/.../ImageTaskCodegenSpec.scala Adds HuggingFace image codegen tests (appears unrelated to the dashboard cover feature).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Ma77Ball

Copy link
Copy Markdown
Contributor Author

/request-review @aglinxinyuan

@github-actions github-actions Bot requested a review from aglinxinyuan June 21, 2026 07:03
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @xuang7, @aicam, @kunwp1
    You can notify them by mentioning @xuang7, @aicam, @kunwp1 in a comment.

@Ma77Ball

Copy link
Copy Markdown
Contributor Author

@xuang7 and @aglinxinyuan, please review the changes and let me know if they look good.

@aglinxinyuan aglinxinyuan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of things before this goes in:

  • Per-card cover fetch (N+1) — flagged inline on card-item.component.ts. This is the main one.
  • PR description vs. diff — the description says the branch also bundles a hugging-face-image-upload component and the HuggingFace.png asset, but the diff only contains ImageTaskCodegenSpec.scala (the other two appear to already be on main). Could you either split that unrelated HF test into its own PR, or at minimum update the description so it matches the 12 files actually changed?

The rest are inline nits — non-blocking.

@aglinxinyuan

Copy link
Copy Markdown
Contributor

Please resolve the conflicts, and we can merge.

@Ma77Ball Ma77Ball force-pushed the feat/workflow-card-cover-image branch from 912a58f to 1880e39 Compare June 27, 2026 03:06
@github-actions github-actions Bot added dependencies Pull requests that update a dependency file pyamber ci changes related to CI docs Changes related to documentations dev common platform Non-amber Scala service paths amber-integration labels Jun 27, 2026
@Ma77Ball Ma77Ball force-pushed the feat/workflow-card-cover-image branch from 1880e39 to 00480c7 Compare June 27, 2026 03:59
@github-actions github-actions Bot removed dependencies Pull requests that update a dependency file pyamber ci changes related to CI docs Changes related to documentations dev common platform Non-amber Scala service paths amber-integration labels Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ddl-change Changes to the TexeraDB DDL engine feature frontend Changes related to the frontend GUI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow setting a custom cover image on workflow dashboard cards

4 participants