fix(frontend): make a result cell's download work off the canvas - #8539
yangzhang75 wants to merge 2 commits into
Conversation
Automated Reviewer SuggestionsBased on the
|
Backport auto-label reportThis
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8539 +/- ##
============================================
- Coverage 92.94% 92.91% -0.04%
Complexity 4883 4883
============================================
Files 1232 1235 +3
Lines 51628 51981 +353
Branches 6354 6393 +39
============================================
+ Hits 47988 48297 +309
- Misses 2076 2108 +32
- Partials 1564 1576 +12
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
39e828d to
0698dc6
Compare
0698dc6 to
3910c41
Compare
An export scopes itself to the operators selected on the canvas unless the caller asked for all of them. That is the right scope for the two callers that read the canvas: the top menu asks for everything, the context menu exports the selection. The third caller is the download button on a result cell, and a cell belongs to one operator, whoever happens to be selected. The same cell is also mounted on the Form View, where the selection holds the step the user is configuring and holds nothing at all until they click one. There the export found an empty scope, so `performExport` returned before sending anything and the dialog closed: a download button that did nothing, with no request, no error and no message. The dialog's own checks read the same empty selection, so a restricted operator went unreported there too -- with a scope of nothing, there was nothing to report. A caller that knows which operators it is exporting now says so, and both the dialog and the service prefer that over the selection. The cell names the one operator whose results it is showing. Nothing changes for the menu or the context menu, which name none and keep the old scope. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3910c41 to
74e6d31
Compare
|
/request-review: @kunwp1 |
|
Dropping the backport labels (they were auto-added from the The reproduction in #8538 goes through the Form View — its step 2 opens |
kunwp1
left a comment
There was a problem hiding this comment.
I left some comments! Overall looks good! Some comments are not directly related to this PR but I want you to fix them because it's a simple fix.
… older gaps Review on apache#8539. The dialog already resolves which operators an export covers, because it reports on them: what a blocking dataset blocks, what kind of output is on offer. The export then derived that scope a second time, from an exportAll flag and the canvas selection. Two answers to one question, agreeing today only because the two implementations happen to line up. The dialog now hands over the scope it resolved, so what is exported is what the dialog said it would export. `exportAll` and both unreachable default parameter values are gone with it, the parameter is `operatorIds`, and the three-way scope expression in the service collapses to using what it was given. Which list the dialog resolves, for each way of opening it, is now the dialog's own spec rather than the service's. Four fixes to older code, each asked for in the same review: * A result cell's export carried the string "getWorkflowMetadata" as the workflow name: the accessor was read without being called, so `.name` was the function's own name. Every export from a cell has been labelled that. * The download button rendered whether or not result export is switched on for the deployment. Every action behind it returns without sending a request when it is off, so it is not rendered now, the way the top menu and the context menu already treat the same switch. * `sourceTriggered` arrives absent from a result cell, which sends no trigger of its own, so it read as undefined through a field typed string. * The dialog built the whole-workflow scope by mapping over every operator; the graph already offers `getAllOperatorIDs()`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVvP3ttj22f9LB4p9u2anY
| private sanitizer: DomSanitizer, | ||
| private workflowStatusService: WorkflowStatusService, | ||
| private guiConfigService: GuiConfigService | ||
| public guiConfigService: GuiConfigService |
What changes were proposed in this PR?
The download button on a result cell did nothing when pressed from the Form View: the dialog opened, Export closed it, and no file arrived — no request, no error, no message.
An export scopes itself to the operators selected on the canvas unless the caller asked for all of them. That is the right scope for the two callers that read the canvas: the top menu asks for everything, the context menu exports the selection. The third caller is the download button on a result cell, and a cell belongs to one operator, whoever happens to be selected. The same cell is also mounted on the Form View, where the selection holds the step the user is configuring and holds nothing at all until they click one. There the export found an empty scope, so
performExportreturned at itsoperatorIds.length === 0check before sending anything. The dialog's own checks read the same empty selection, so a restricted operator went unreported there too.A caller that knows which operators it is exporting now says so, and both the dialog and the service prefer that over the selection:
workflow-result-export.service.ts: a trailing optionalrequestedOperatorIdsonexportWorkflowExecutionResult, threaded toperformExport. Precedence isexportAll(whole workflow) > caller-named > canvas selection.result-exportation.component.ts: readsoperatorIdsoff the modal data;getOperatorIdsToCheck()returns it when present, andonClickExportResultforwards it.result-table-frame.component.ts: the cell's dialog names the operator whose results the frame is showing.Nothing changes for the menu or the context menu, which name no operators and keep the old scope. Ten lines of logic in three files.
Any related issues, documentation, discussions?
Closes #8538, which has a recording of the before state.
One thing that PR does not change:
export-execution-result-enabledstill defaults tofalseingui.conf, andperformExportreturns on that switch before it reaches any of this. A deployment with the switch off sees no change from this PR; every deployment that has it on gets a working cell download. Whether that default should flip is a separate question and is noted at the end of the issue.How was this PR tested?
exportAllwin; the dialog names none by default, checks the named operator, and hands it to the export; the frame names its operator, and names none when it has none.result-table-frame.component.tsthat this PR does not touch.ng test --watch=false: 223 files, 6065 passed, 1 skipped (pre-existing), 0 failed.ng build --configuration=production(AOT): clean.eslintandprettier --checkon all six files: clean.main: a Form View workflow whose result column holds binary files. With the fix, the cell download sendsPOST /api/executions/result/export/localand returns the bytes (4096 bytes, HDF5 magic89 48 44 46, byte-exact) while the canvas selection is empty. With the three production hunks reverted on the same stack, the same click sends no request and produces no file within two minutes.After the fix: downloading a result file from the Form View
Screen.Recording.2026-09-16.at.7.05.42.PM.mov
Was this PR authored or co-authored using generative AI tooling?
Yes. Generated-by: Claude Code (Claude Opus 5, Anthropic). Co-authored with Claude; the author reviewed the change before submission.
🤖 Generated with Claude Code