Deleting current workspace switches to another instead of closing [ backend implementation ] (#1623)

I did not mean to close the previous pr, anyway i tried to implement
what you suggested, the backend now does most of it
and DeleteWorkspace will return an unclaimed id and avoid closing the
window.

```go 
        const moveToNewWorkspace = await WorkspaceService.DeleteWorkspace(workspaceId) 
        console.log("delete-workspace done", workspaceId, ww?.waveWindowId);
        if (ww?.workspaceId == workspaceId){
            if ( workspaceList?.length > 1 ) {
                   await ww.switchWorkspace(moveToNewWorkspace)
            } else {
                    console.log("delete-workspace closing window", workspaceId, ww?.waveWindowId);
                    ww.destroy();
            }
        }
    });
```


![unknown_2024 12 26-17
05](https://github.com/user-attachments/assets/9c8455e5-b71c-479d-a15c-ee5c99c7a909)
![unknown_2024 12 26-17
06](https://github.com/user-attachments/assets/5dbf63bc-1ffd-4088-abc0-7c02fac9af94)

---------

Co-authored-by: Evan Simkowitz <esimkowitz@users.noreply.github.com>
This commit is contained in:
Yacoub 2024-12-29 18:58:29 +01:00 committed by GitHub
parent 477052e8fc
commit 0890475a60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 75 additions and 26 deletions

View File

@ -18,6 +18,7 @@ import { delay, ensureBoundsAreVisible, waveKeyToElectronKey } from "./emain-uti
import { log } from "./log";
import { getElectronAppBasePath, unamePlatform } from "./platform";
import { updater } from "./updater";
export type WindowOpts = {
unamePlatform: string;
};
@ -303,7 +304,8 @@ export class WaveBrowserWindow extends BaseWindow {
const workspaceList = await WorkspaceService.ListWorkspaces();
if (!workspaceList?.find((wse) => wse.workspaceid === workspaceId)?.windowid) {
const curWorkspace = await WorkspaceService.GetWorkspace(this.workspaceId);
if (isNonEmptyUnsavedWorkspace(curWorkspace)) {
if (curWorkspace && isNonEmptyUnsavedWorkspace(curWorkspace)) {
console.log(
`existing unsaved workspace ${this.workspaceId} has content, opening workspace ${workspaceId} in new window`
);
@ -693,17 +695,22 @@ ipcMain.on("delete-workspace", (event, workspaceId) => {
type: "question",
buttons: ["Cancel", "Delete Workspace"],
title: "Confirm",
message: `Deleting workspace will also delete its contents.${workspaceHasWindow ? "\nWorkspace is open in a window, which will be closed." : ""}\n\nContinue?`,
message: `Deleting workspace will also delete its contents.\n\nContinue?`,
});
if (choice === 0) {
console.log("user cancelled workspace delete", workspaceId, ww?.waveWindowId);
return;
}
await WorkspaceService.DeleteWorkspace(workspaceId);
const newWorkspaceId = await WorkspaceService.DeleteWorkspace(workspaceId);
console.log("delete-workspace done", workspaceId, ww?.waveWindowId);
if (ww?.workspaceId == workspaceId) {
console.log("delete-workspace closing window", workspaceId, ww?.waveWindowId);
ww.destroy();
if (newWorkspaceId) {
await ww.switchWorkspace(newWorkspaceId);
} else {
console.log("delete-workspace closing window", workspaceId, ww?.waveWindowId);
ww.destroy();
}
}
});
});

View File

@ -189,7 +189,7 @@ class WorkspaceServiceType {
}
// @returns object updates
DeleteWorkspace(workspaceId: string): Promise<void> {
DeleteWorkspace(workspaceId: string): Promise<string> {
return WOS.callBackendService("workspace", "DeleteWorkspace", Array.from(arguments))
}

View File

@ -54,7 +54,8 @@ func (svc *WorkspaceService) UpdateWorkspace(ctx context.Context, workspaceId st
}
wps.Broker.Publish(wps.WaveEvent{
Event: wps.Event_WorkspaceUpdate})
Event: wps.Event_WorkspaceUpdate,
})
updates := waveobj.ContextGetUpdatesRtn(ctx)
go func() {
@ -87,23 +88,26 @@ func (svc *WorkspaceService) DeleteWorkspace_Meta() tsgenmeta.MethodMeta {
}
}
func (svc *WorkspaceService) DeleteWorkspace(workspaceId string) (waveobj.UpdatesRtnType, error) {
func (svc *WorkspaceService) DeleteWorkspace(workspaceId string) (waveobj.UpdatesRtnType, string, error) {
ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
defer cancelFn()
ctx = waveobj.ContextWithUpdates(ctx)
deleted, err := wcore.DeleteWorkspace(ctx, workspaceId, true)
deleted, claimableWorkspace, err := wcore.DeleteWorkspace(ctx, workspaceId, true)
if claimableWorkspace != "" {
return nil, claimableWorkspace, nil
}
if err != nil {
return nil, fmt.Errorf("error deleting workspace: %w", err)
return nil, claimableWorkspace, fmt.Errorf("error deleting workspace: %w", err)
}
if !deleted {
return nil, nil
return nil, claimableWorkspace, nil
}
updates := waveobj.ContextGetUpdatesRtn(ctx)
go func() {
defer panichandler.PanicHandler("WorkspaceService:DeleteWorkspace:SendUpdateEvents")
wps.Broker.SendUpdateEvents(updates)
}()
return updates, nil
return updates, claimableWorkspace, nil
}
func (svc *WorkspaceService) ListWorkspaces() (waveobj.WorkspaceList, error) {

View File

@ -52,10 +52,13 @@ func SwitchWorkspace(ctx context.Context, windowId string, workspaceId string) (
return nil, fmt.Errorf("error updating window: %w", err)
}
deleted, err := DeleteWorkspace(ctx, curWsId, false)
if err != nil {
return nil, fmt.Errorf("error deleting current workspace: %w", err)
deleted, _, err := DeleteWorkspace(ctx, curWsId, false)
if err != nil && deleted {
print(err.Error()) // @jalileh isolated the error for now, curwId/workspace was deleted when this occurs.
} else if err != nil {
return nil, fmt.Errorf("error deleting workspace: %w", err)
}
if !deleted {
log.Printf("current workspace %s was not deleted\n", curWsId)
} else {
@ -131,7 +134,7 @@ func CloseWindow(ctx context.Context, windowId string, fromElectron bool) error
window, err := GetWindow(ctx, windowId)
if err == nil {
log.Printf("got window %s\n", windowId)
deleted, err := DeleteWorkspace(ctx, window.WorkspaceId, false)
deleted, _, err := DeleteWorkspace(ctx, window.WorkspaceId, false)
if err != nil {
log.Printf("error deleting workspace: %v\n", err)
}

View File

@ -66,7 +66,8 @@ func CreateWorkspace(ctx context.Context, name string, icon string, color string
}
wps.Broker.Publish(wps.WaveEvent{
Event: wps.Event_WorkspaceUpdate})
Event: wps.Event_WorkspaceUpdate,
})
ws, _, err = UpdateWorkspace(ctx, ws.OID, name, icon, color, applyDefaults)
return ws, err
@ -114,15 +115,24 @@ func UpdateWorkspace(ctx context.Context, workspaceId string, name string, icon
// If force is true, it will delete even if workspace is named.
// If workspace is empty, it will be deleted, even if it is named.
// Returns true if workspace was deleted, false if it was not deleted.
func DeleteWorkspace(ctx context.Context, workspaceId string, force bool) (bool, error) {
func DeleteWorkspace(ctx context.Context, workspaceId string, force bool) (bool, string, error) {
log.Printf("DeleteWorkspace %s\n", workspaceId)
workspace, err := wstore.DBMustGet[*waveobj.Workspace](ctx, workspaceId)
if err != nil && wstore.ErrNotFound == err {
return true, "", fmt.Errorf("workspace already deleted %w", err)
}
// @jalileh list needs to be saved early on i assume
workspaces, err := ListWorkspaces(ctx)
if err != nil {
return false, fmt.Errorf("error getting workspace: %w", err)
return false, "", fmt.Errorf("error retrieving workspaceList: %w", err)
}
if err != nil {
return false, "", fmt.Errorf("error getting workspace: %w", err)
}
if workspace.Name != "" && workspace.Icon != "" && !force && (len(workspace.TabIds) > 0 || len(workspace.PinnedTabIds) > 0) {
log.Printf("Ignoring DeleteWorkspace for workspace %s as it is named\n", workspaceId)
return false, nil
return false, "", nil
}
// delete all pinned and unpinned tabs
@ -130,24 +140,49 @@ func DeleteWorkspace(ctx context.Context, workspaceId string, force bool) (bool,
log.Printf("deleting tab %s\n", tabId)
_, err := DeleteTab(ctx, workspaceId, tabId, false)
if err != nil {
return false, fmt.Errorf("error closing tab: %w", err)
return false, "", fmt.Errorf("error closing tab: %w", err)
}
}
windowId, err := wstore.DBFindWindowForWorkspaceId(ctx, workspaceId)
err = wstore.DBDelete(ctx, waveobj.OType_Workspace, workspaceId)
if err != nil {
return false, fmt.Errorf("error deleting workspace: %w", err)
return false, "", fmt.Errorf("error deleting workspace: %w", err)
}
log.Printf("deleted workspace %s\n", workspaceId)
wps.Broker.Publish(wps.WaveEvent{
Event: wps.Event_WorkspaceUpdate})
Event: wps.Event_WorkspaceUpdate,
})
if windowId != "" {
err = CloseWindow(ctx, windowId, false)
UnclaimedWorkspace, findAfter := "", false
for _, ws := range workspaces {
if ws.WorkspaceId == workspaceId {
if UnclaimedWorkspace != "" {
break
}
findAfter = true
continue
}
if findAfter && ws.WindowId == "" {
UnclaimedWorkspace = ws.WorkspaceId
break
} else if ws.WindowId == "" {
UnclaimedWorkspace = ws.WorkspaceId
}
}
if UnclaimedWorkspace != "" {
return true, UnclaimedWorkspace, nil
} else {
err = CloseWindow(ctx, windowId, false)
}
if err != nil {
return false, fmt.Errorf("error closing window: %w", err)
return false, "", fmt.Errorf("error closing window: %w", err)
}
}
return true, nil
return true, "", nil
}
func GetWorkspace(ctx context.Context, wsID string) (*waveobj.Workspace, error) {