Skip to content

feat(frontend): preview an operator's result when hovering it on the canvas - #9058

Merged
aglinxinyuan merged 9 commits into
apache:mainfrom
kz930:feat/9057-pinned-result-windows
Nov 5, 2026
Merged

aglinxinyuan merged 9 commits into
apache:mainfrom
kz930:feat/9057-pinned-result-windows

Conversation

@kz930

@kz930 kz930 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Resting the pointer on an operator for half a second shows a card beside it with the operator's first rows and its size, or its error, or how to keep a result the run did not keep. A pointer passing over, dragging, or a click opens nothing, and the card lingers a moment so the pointer can move into it. Any press on the canvas, including on a port to draw a link, closes the card, and so does deleting its operator. An operator with several outputs says the rows are the first output's. The preview can be turned off under Layers, and stays off while the heat-map overlay is on.

The first rows come from a request of their own, so a preview never moves the result table's page or reads its cache. While the operator runs, the card fetches again on each of its result updates until it has its rows.

pr3-1-hover-card

The PR's own changes are a64630b, 7e4e75f and 18159ea.

Any related issues, documentation, discussions?

Closes #9057. Part of #9052. Design discussed in #8842.

How was this PR tested?

A new spec for the hover card covers a table's rows and size, an error, a chart, no result, and several outputs. New cases in the workflow editor's spec cover the delay before the card opens and the moment it lingers, and the result service's spec covers fetching the first rows without moving the table. Further cases cover closing the card on a press on a port, on its operator's deletion and when the editor is destroyed, refetching while the operator runs, and the preview staying off under the heat map and the Layers toggle. The affected frontend specs pass.

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

Generated-by: Claude Code (Claude Opus 5.5)

🤖 Generated with Claude Code

@kz930

kz930 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

@carloea2 could you take a look at this when you have a chance? It stays a draft until #9054 merges, but its own change, the last commit, is ready for review.

Every external output port of an operator that keeps its result is
stored, but results were only ever read from the first port, so a
Split's second output or an If's True branch could not be shown.

A pagination request can now name the output port to read, with the
first port as the default, and the reply carries the port it read and
that port's row count. The live result updates keep following the
first port, so a client paging another port takes the count from the
reply. The result store's count per operator now comes from the first
port too; it was built from every stored port, so a terminal Split's
second output could replace its first output's count.

On the frontend, the result service gives each extra port its own
pagination service, which names its port in its requests, keeps no
page cache and takes its row count from each reply, and every port's
service takes its schema only from replies to its own requests. The
result table and its row detail can show any port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kz930
kz930 force-pushed the feat/9057-pinned-result-windows branch from 083308b to 99dfefa Compare October 20, 2026 23:26
@kz930 kz930 changed the title feat(frontend): preview an operator's result on hover, and pin it beside the operator feat(frontend): preview an operator's result when hovering it on the canvas Oct 20, 2026
kz930 and others added 2 commits October 20, 2026 16:37
Switching the table to another output port left the previous port's
rows on screen when the new port was empty, with the loading state
never ending, and a late reply for the previous port could replace the
new port's rows. A port change now starts from an empty table, a reply
for an operator or port no longer shown is dropped, and an empty page
ends the loading.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…canvas

Resting the pointer on an operator for half a second shows a card
beside it with the operator's first rows and its size, or its error,
or how to keep a result the run did not keep. A pointer passing over,
dragging, or a click opens nothing, and the card lingers a moment so
the pointer can move into it. An operator with several outputs says
the rows are the first output's. The preview can be turned off under
Layers, and stays off while the heat-map overlay is on.

The first rows come from a request of their own, so a preview never
moves the result table's page or reads its cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kz930
kz930 force-pushed the feat/9057-pinned-result-windows branch from 99dfefa to a64630b Compare October 20, 2026 23:40
@kz930

kz930 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

@carloea2 heads-up: this PR was reorganized to split the work more evenly. It now holds only the hover preview; the pinned windows moved to #9063. Its own change is still the last commit.

@github-actions

github-actions Bot commented Oct 21, 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: @yangzhang75, @aglinxinyuan, @PG1204
    You can notify them by mentioning @yangzhang75, @aglinxinyuan, @PG1204 in a comment.

@github-actions github-actions Bot added feature engine frontend Changes related to the frontend GUI labels Oct 21, 2026
@codecov-commenter

codecov-commenter commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.95434% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.84%. Comparing base (94914a0) to head (8f43951).

Files with missing lines Patch % Lines
...onent/workflow-editor/workflow-editor.component.ts 78.37% 4 Missing and 4 partials ⚠️
...esult-preview/operator-result-preview.component.ts 89.06% 0 Missing and 7 partials ⚠️
...c/app/workspace/component/menu/menu.component.html 50.00% 2 Missing ⚠️
...ervice/workflow-graph/model/joint-graph-wrapper.ts 60.00% 2 Missing ⚠️
...src/app/workspace/component/menu/menu.component.ts 66.66% 1 Missing ⚠️
...result-table-frame/result-table-frame.component.ts 94.73% 0 Missing and 1 partial ⚠️
...ult-preview/operator-result-preview.component.html 97.22% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #9058      +/-   ##
============================================
+ Coverage     91.82%   91.84%   +0.01%     
- Complexity     5066     5068       +2     
============================================
  Files          1273     1275       +2     
  Lines         55338    55540     +202     
  Branches       7001     7037      +36     
============================================
+ Hits          50814    51010     +196     
+ Misses         2802     2791      -11     
- Partials       1722     1739      +17     
Flag Coverage Δ *Carryforward flag
access-control-service 77.44% <ø> (ø) Carriedforward from 94914a0
agent-service 99.16% <ø> (ø) Carriedforward from 94914a0
amber 85.96% <100.00%> (+0.01%) ⬆️
computing-unit-managing-service 61.84% <ø> (ø) Carriedforward from 94914a0
config-service 87.50% <ø> (ø) Carriedforward from 94914a0
file-service 82.29% <ø> (ø) Carriedforward from 94914a0
frontend 96.51% <88.94%> (-0.01%) ⬇️
notebook-migration-service 83.77% <ø> (ø) Carriedforward from 94914a0
pyamber 98.48% <ø> (ø) Carriedforward from 94914a0
workflow-compiling-service 72.61% <ø> (ø) Carriedforward from 94914a0

*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.

@carloea2 carloea2 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.

Reviewed the hover-preview change after #9054. The 171 workflow-editor, operator-result-preview and workflow-result service tests pass. Focused prettier-eslint and ESLint checks pass. The existing result panel remains available here; the result-access problem is in #9060.

kz930 and others added 3 commits October 26, 2026 14:27
Resolve the conflicts with apache#8766: a page with no rows takes its columns
from the stored schema, and the reply still carries the port's total
count and is dropped when it belongs to another operator or port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

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

Compared against main 94914a0 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 392 0.239 24,711/36,826/36,826 us 🔴 +10.5% / 🔴 +201.2%
🔴 bs=100 sw=10 sl=64 798 0.487 117,964/177,693/177,693 us 🔴 +18.7% / 🔴 +103.9%
⚪ bs=1000 sw=10 sl=64 957 0.584 1,036,490/1,096,739/1,096,739 us ⚪ within ±5% / 🔴 +34.1%
Baseline details

Latest main 94914a0 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 392 tuples/sec 412 tuples/sec 1,019 tuples/sec -4.9% -61.5%
bs=10 sw=10 sl=64 MB/s 0.239 MB/s 0.251 MB/s 0.622 MB/s -4.8% -61.6%
bs=10 sw=10 sl=64 p50 24,711 us 22,355 us 10,144 us +10.5% +143.6%
bs=10 sw=10 sl=64 p95 36,826 us 38,954 us 12,225 us -5.5% +201.2%
bs=10 sw=10 sl=64 p99 36,826 us 38,954 us 15,527 us -5.5% +137.2%
bs=100 sw=10 sl=64 throughput 798 tuples/sec 866 tuples/sec 1,371 tuples/sec -7.9% -41.8%
bs=100 sw=10 sl=64 MB/s 0.487 MB/s 0.528 MB/s 0.837 MB/s -7.8% -41.8%
bs=100 sw=10 sl=64 p50 117,964 us 113,433 us 79,910 us +4.0% +47.6%
bs=100 sw=10 sl=64 p95 177,693 us 149,665 us 87,155 us +18.7% +103.9%
bs=100 sw=10 sl=64 p99 177,693 us 149,665 us 106,643 us +18.7% +66.6%
bs=1000 sw=10 sl=64 throughput 957 tuples/sec 983 tuples/sec 1,415 tuples/sec -2.6% -32.4%
bs=1000 sw=10 sl=64 MB/s 0.584 MB/s 0.6 MB/s 0.864 MB/s -2.7% -32.4%
bs=1000 sw=10 sl=64 p50 1,036,490 us 1,017,468 us 780,407 us +1.9% +32.8%
bs=1000 sw=10 sl=64 p95 1,096,739 us 1,099,821 us 817,814 us -0.3% +34.1%
bs=1000 sw=10 sl=64 p99 1,096,739 us 1,099,821 us 848,683 us -0.3% +29.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,510.31,200,128000,392,0.239,24711.39,36826.47,36826.47
1,100,10,64,20,2506.72,2000,1280000,798,0.487,117963.73,177692.80,177692.80
2,1000,10,64,20,20898.94,20000,12800000,957,0.584,1036489.50,1096738.66,1096738.66

@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.

Left some minor comments below.

@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.

Nice work. The stale-reply handling in loadRows and the request-id matching look right.

kz930 and others added 2 commits October 31, 2026 22:39
…nd keep it fresh

Pressing an output port to drag a link now closes the card: a native
capture listener on the paper replaces element/blank:pointerdown, which
JointJS never emits for a magnet. Deleting the card's operator closes it
and cancels a pending one, and ngOnDestroy clears both card timers.

The card fetches its rows again on its operator's result updates until
it shows a full preview, keeping the rows on show while it does.

selectPage's default column limit is ALL_COLUMNS, as peekFirstRows'
is: Number.MAX_SAFE_INTEGER fails the server's Int parse, so the row
details modal's request was never answered.

The heat-map test now waits out the preview delay, and a new test
covers the Layers > Result preview toggle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The row details modal's column limit is a separate fix, as the review
asked, so selectPage goes back to what it was before 7e4e75f.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot removed the engine label Nov 1, 2026
@kz930
kz930 marked this pull request as ready for review November 2, 2026 20:23

@carloea2 carloea2 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.

Rechecked the addressed threads and preview behavior. No further blocker found; CI is green.

@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.

LGTM!

@aglinxinyuan
aglinxinyuan added this pull request to the merge queue Nov 5, 2026
renovate-bot pushed a commit to renovate-bot/apache-_-texera that referenced this pull request Nov 5, 2026
…mit (apache#9242)

### What changes were proposed in this PR?

`selectPage` defaulted its column limit to `Number.MAX_SAFE_INTEGER`,
which the server cannot read as an Int, so a request that left it out
was never answered and was recorded as a compilation error. The Row
Details modal and report generation both leave it out. The default is
now `ALL_COLUMNS`, which is Int.MaxValue, and the page cache is keyed by
the same value.

### Any related issues, documentation, discussions?

Closes apache#9241. Found in the review of apache#9058, which uses the same value
for its hover preview.

### How was this PR tested?

A new `workflow-result.service.spec.ts` case checks that a page asked
for without a column limit sends `ALL_COLUMNS`, and the existing cache
case still passes on the default. In the running app, Row Details shows
the clicked row and no error is recorded.

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

Generated-by: Claude Code (Claude Opus 5.5)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Merged via the queue into apache:main with commit b8b308e Nov 5, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature frontend Changes related to the frontend GUI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Preview an operator's result when hovering it on the canvas

4 participants