eugenegujing opened a new issue, #6845:
URL: https://github.com/apache/texera/issues/6845
### What happened?
Using the **Import Workflow** button in the workspace toolbar
(`menu.component.ts` → `onClickImportWorkflow`) to import a workflow JSON into
the currently open workflow **A** produces two wrong effects at once:
1. A brand-new workflow **B** appears in the user's workflow list, with
content identical to the imported file.
2. The currently open workflow **A** also has its content replaced by the
imported file (its original operators/links are lost).
So a single import both silently overwrites the current workflow **and**
forks a duplicate copy into the list.
**Expected:** Importing into the current workspace should replace **only the
content** of the current workflow A in place (A keeps its own `wid` and its own
name), and must **not** create any additional workflow in the list.
#### Root cause
Two independent defects in the same code path compound each other:
- **Lost identity → duplicate insert.** `onClickImportWorkflow` builds the
`Workflow` object with `wid: undefined` (`menu.component.ts:615`).
`reloadWorkflow` immediately calls `setWorkflowMetadata(workflow)`
(`workflow-action.service.ts:628`), so the in-memory `metadata.wid` is wiped to
`undefined`. The registered auto-persist (`workspace.component.ts:213`
`registerAutoPersistWorkflow`) then fires and calls
`persistWorkflow(getWorkflow())` with a null `wid`. On the backend,
`WorkflowResource.persistWorkflow` treats a null/non-existent `wid` as a
brand-new workflow and **inserts** it (`WorkflowResource.scala:445-460`) → this
is workflow B, and the URL is redirected to B's new wid.
- **Shared model not reset → original mutated.** `reloadWorkflow` explicitly
documents that it resets the workflow **but not** the shared-editing (Yjs)
model, and that callers must quit the shared session (`destroySharedModel`)
first (`workflow-action.service.ts:614-619`). The normal open path
`loadWorkflowWithId` honors this by calling `setNewSharedModel(wid, user)`
before `reloadWorkflow` (`workspace.component.ts:257-261`). The import path
calls **neither** — it invokes `reloadWorkflow(workflow, true)` directly while
the shared model is still bound to workflow A's room. The
`deleteOperatorsAndLinks` / `addOperatorsAndLinks` calls
(`workflow-action.service.ts:631,666`) therefore mutate A's live shared
document → A's content is replaced by the imported content.
Note: the Dashboard-page upload (`user-workflow.component.ts:452`
`handleFileUploads` → `createWorkflow`) is a *different, intended* "create a
new workflow from file" entry point. The workspace-toolbar import is meant to
be in-place, so the duplicate creation there is a bug, not a duplicate feature.
#### Proposed fix
Preserve the current workflow's identity when building the imported
`Workflow` in `onClickImportWorkflow` — keep the current `wid` (and keep A's
existing name; only the content is replaced):
```ts
const current = this.workflowActionService.getWorkflowMetadata();
const workflow: Workflow = {
content: workflowContent,
name: current.name, // keep A's name; only replace content
wid: current.wid, // keep A's identity → auto-persist updates
instead of inserting
description: current.description,
creationTime: current.creationTime,
lastModifiedTime: current.lastModifiedTime,
readonly: false,
isPublished: current.isPublished,
};
```
With the `wid` preserved, auto-persist calls `persistWorkflow(wid = A)` →
backend takes the `update A` branch (`WorkflowResource.scala:445-447`), no B is
inserted, and the URL stays on A. Because the shared model is already bound to
A, the in-place content replacement is now the correct behavior for "import
into current workflow." A brand-new unsaved workspace (wid already `undefined`)
still results in exactly one workflow.
### How to reproduce?
1. Log in and open an existing workflow **A** (URL `/workspace/<wid_A>`), so
A has a real `wid`.
2. In the workspace toolbar, click **Import Workflow** and select a workflow
JSON (e.g. the attached `Test_Run_Sample_Pipeline2.json`, 7 operators).
3. Observe the canvas now shows the imported content.
4. Wait for auto-persist (~debounce), then open the workflows list.
Observed: the list contains both the original A (now overwritten with the
imported content) **and** a new workflow B identical to the import; the URL has
switched to B's wid.
Expected: A's content is replaced in place, A keeps its name and wid, and no
new workflow B is created.
### Version/Branch
1.3.0-incubating-SNAPSHOT (main)
### Commit Hash (Optional)
42027e8c38d248a60cab32871887bc754ef311b5
### What browsers are you seeing the problem on?
Chrome
### Relevant log output
_No response (frontend behavioral bug; see root-cause analysis above)._
--
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]