mengw15 commented on code in PR #8441:
URL: https://github.com/apache/texera/pull/8441#discussion_r3960964082
##########
frontend/src/app/workspace/component/workflow-form/workflow-form.component.ts:
##########
@@ -376,11 +450,61 @@ export class WorkflowFormComponent implements OnInit,
OnDestroy {
this.parameters = this.formBindingService.resolveFields();
this.instructionTitle = config.instruction?.title ?? "";
this.instructionBody = config.instruction?.body ?? "";
+ this.refreshShownResults();
// A reader always sees the instruction as rendered markdown.
void this.renderInstruction();
this.buildForm();
}
+ /**
+ * Decide which operators' result cards to show. The engine materializes a
result for every terminal
+ * operator (no enabled downstream) as well as every view-result operator,
so a terminal's result is
+ * always available; the form shows terminals by default and layers the
author's chosen view-result
+ * steps on top. This is a pure display filter that reads the graph and
never writes it, so a normal
+ * canvas user's result-viewing is unaffected. A step that is neither viewed
nor terminal (or was
+ * deleted) drops out rather than rendering a stale card.
+ */
+ private refreshShownResults(): void {
+ const graph = this.workflowActionService.getTexeraGraph();
+ const viewed = graph.getOperatorsToViewResult();
+ // A result exists for an operator that is view-result (the eye) or
terminal (no enabled
+ // downstream); the engine materializes both (WorkflowCompiler stores
terminal operators plus
+ // opsToViewResult). A view-result id is always a live operator; a
terminal id comes from
+ // terminalOperatorIds (live, enabled operators only), so both branches
reference real steps.
+ const terminals = new Set(this.terminalOperatorIds());
+ const availableOnCanvas = (id: string): boolean => viewed.has(id) ||
terminals.has(id);
+ const chosen = this.formBindingService.getConfig().resultOperatorIds;
+ // The terminal (final) operator's result always shows -- the engine
always materializes it, so it
+ // cannot be turned off. resultOperatorIds adds extra intermediate
(view-result) steps on top. The
+ // downstream hasNonEmptyResult filter drops steps that produced no data.
+ this.shownResultIds = [...new Set([...terminals,
...chosen])].filter(availableOnCanvas);
+ }
+
+ /** The workflow's terminal operators: enabled operators with no enabled
downstream link. Matches the
+ * backend's storage rule (WorkflowCompiler treats out-degree-0 operators
of the enabled plan as
+ * terminal and always materializes them), so a disabled link or operator
does not mislead this. */
+ private terminalOperatorIds(): string[] {
+ const graph = this.workflowActionService.getTexeraGraph();
+ const hasEnabledDownstream = new Set(graph.getAllEnabledLinks().map(link
=> link.source.operatorID));
+ return graph
+ .getAllOperators()
+ .filter(op => !(op.isDisabled ?? false) &&
!hasEnabledDownstream.has(op.operatorID))
+ .map(op => op.operatorID);
+ }
+
+ /** Terminal = a live, enabled operator with no enabled downstream link. */
+ private isTerminalOperator(operatorID: string): boolean {
Review Comment:
These two (`isTerminalOperator` / `hasEnabledDownstream`) have no callers —
`refreshShownResults` uses the batch `terminalOperatorIds()`, and nothing else
(tests included) reaches them. Worth dropping them rather than keeping a second
copy of the terminal rule that can drift from the one in use.
##########
frontend/src/app/workspace/component/workflow-form/workflow-form.component.ts:
##########
@@ -376,11 +450,61 @@ export class WorkflowFormComponent implements OnInit,
OnDestroy {
this.parameters = this.formBindingService.resolveFields();
this.instructionTitle = config.instruction?.title ?? "";
this.instructionBody = config.instruction?.body ?? "";
+ this.refreshShownResults();
// A reader always sees the instruction as rendered markdown.
void this.renderInstruction();
this.buildForm();
}
+ /**
+ * Decide which operators' result cards to show. The engine materializes a
result for every terminal
+ * operator (no enabled downstream) as well as every view-result operator,
so a terminal's result is
+ * always available; the form shows terminals by default and layers the
author's chosen view-result
+ * steps on top. This is a pure display filter that reads the graph and
never writes it, so a normal
+ * canvas user's result-viewing is unaffected. A step that is neither viewed
nor terminal (or was
+ * deleted) drops out rather than rendering a stale card.
+ */
+ private refreshShownResults(): void {
+ const graph = this.workflowActionService.getTexeraGraph();
+ const viewed = graph.getOperatorsToViewResult();
+ // A result exists for an operator that is view-result (the eye) or
terminal (no enabled
+ // downstream); the engine materializes both (WorkflowCompiler stores
terminal operators plus
+ // opsToViewResult). A view-result id is always a live operator; a
terminal id comes from
+ // terminalOperatorIds (live, enabled operators only), so both branches
reference real steps.
+ const terminals = new Set(this.terminalOperatorIds());
Review Comment:
One note on the triggers, not blocking: terminal-ness is derived from links,
but none of the three refresh triggers fires on a link edit — a co-editor
wiring a downstream link onto a shown terminal leaves its card up until the
next trigger. That said, the lingering card is semantically sound — the last
run's result still exists and that is what the card shows — and the next run
corrects the set. So fine to leave as is (or fold into #8439); flagging mainly
so the trigger gap is a known choice rather than an accident.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]