mengw15 commented on code in PR #8456:
URL: https://github.com/apache/texera/pull/8456#discussion_r3998694193
##########
frontend/src/app/workspace/component/menu/menu.component.ts:
##########
@@ -617,15 +628,99 @@ export class MenuComponent implements OnInit, OnDestroy {
}
public onClickExportWorkflow(): void {
- const workflowContent: WorkflowContent =
this.workflowActionService.getWorkflowContent();
- const workflowContentJson = JSON.stringify(workflowContent, null, 2);
+ // The same shape the dashboard download produces (see exportedWorkflow):
the content plus the
+ // landing view as a sibling key, so a file exported here uploads as a
form-default workflow too.
+ const exported = exportedWorkflow(
+ this.workflowActionService.getWorkflowContent(),
+ this.workflowActionService.getWorkflowMetadata().defaultView
+ );
+ const workflowContentJson = JSON.stringify(exported, null, 2);
const fileName = this.currentWorkflowName + ".json";
// Through the injectable wrapper (as the dashboard downloads already do),
so a spec stubs it
// with TestBed instead of module-mocking the CommonJS file-saver package,
which the unit-test
// builder cannot hoist reliably.
this.fileSaverService.saveAs(new Blob([workflowContentJson], { type:
"text/plain;charset=utf-8" }), fileName);
}
+ /**
+ * Open the Form View -- a full page load, not a route: the two views share
root-level
+ * singletons (graph, Yjs shared model), and routing left the old
collaboration client
+ * alive (you appeared as your own coeditor). A fresh document is the clean
handover.
+ */
+ public onClickOpenFormView(): void {
+ const wid = this.workflowActionService.getWorkflowMetadata().wid;
+ if (wid === undefined || this.handingOverToFormView) {
+ return;
+ }
+ // A reader has nothing to save, and every save of theirs is a guaranteed
403 that would keep
+ // them here with an error: straight over, as the form's own switch does
for a reader.
+ if (!this.writeAccess) {
+ this.openFormViewPage(wid);
+ return;
+ }
+ // Save first, and hand over only once the save has completed. The
full-page load that
+ // follows unloads this document, and a request still in flight at that
moment is aborted, so
+ // navigating right after firing the save could lose the very edit the
switch is meant to carry
+ // across; the workspace's beforeunload save runs into the same unload and
is no safety net. A
+ // save that fails keeps the user here with the error shown, rather than
leaving with changes
+ // that were never stored. The form's own switch (openRegularCanvas) does
the same.
+ //
+ // Two more things the hand-over must not lose. An autosave already in
flight when the switch
+ // is clicked: WorkflowPersistService sends saves one at a time and in
order, so ours lands after
+ // it and completes after it. And an edit made while our save is out (the
page stays editable
+ // until the load): workflowChanged marks a graph edit, persistWorkflow a
rename or a
+ // description edit (those save through the menu itself, not the
autosave), and the drain below
+ // saves once more before handing over rather than letting the full-page
load abort that edit's
+ // own save.
+ this.handingOverToFormView = true;
+ this.isSaving = true;
+ this.saveThenOpenFormView(wid);
+ }
+
+ private saveThenOpenFormView(wid: number): void {
+ // The snapshot below carries everything reported up to now.
+ this.editedSinceSwitchSnapshot = false;
+ this.workflowPersistService
+ .persistWorkflow(this.workflowActionService.getWorkflow())
+ .pipe(untilDestroyed(this))
+ .subscribe({
+ next: (updatedWorkflow: Workflow) => {
+ // An edit since the snapshot makes this response stale: applying it
would put the old
+ // name back just before the save below re-reads the workflow. That
save's own response
+ // is the one applied.
+ if (!this.editedSinceSwitchSnapshot) {
+ this.workflowActionService.setWorkflowMetadata(updatedWorkflow);
Review Comment:
On the stale-response guard: this went beyond the reader fix that was asked
for, and the follow-up above is right that it covers only one of the three
places a response is applied (`menu.component.ts:778`,
`workspace.component.ts:217`). Completing it here keeps growing this PR; the
rule it wants — don't apply a response a newer local edit has overtaken —
belongs in `WorkflowPersistService`, now the one place every save goes through,
and the race predates this PR (a canvas rename during an in-flight autosave
loses the same way today). Consider dropping this back to the reader
early-return that was asked for, and filing the staleness rule as its own item,
so this PR stays "entry points".
--
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]