Must delete all blocks individually first. Also deletes LayoutState. recursive: if true, will recursively close parent window, workspace, if they are empty. Returns new active tab id, error.
(ctx context.Context, workspaceId string, tabId string, recursive bool)
| 295 | // recursive: if true, will recursively close parent window, workspace, if they are empty. |
| 296 | // Returns new active tab id, error. |
| 297 | func DeleteTab(ctx context.Context, workspaceId string, tabId string, recursive bool) (string, error) { |
| 298 | ws, _ := wstore.DBGet[*waveobj.Workspace](ctx, workspaceId) |
| 299 | if ws == nil { |
| 300 | return "", fmt.Errorf("workspace not found: %q", workspaceId) |
| 301 | } |
| 302 | |
| 303 | // ensure tab is in workspace |
| 304 | tabIdx := utilfn.FindStringInSlice(ws.TabIds, tabId) |
| 305 | if tabIdx == -1 { |
| 306 | return "", fmt.Errorf("tab %s not found in workspace %s", tabId, workspaceId) |
| 307 | } |
| 308 | ws.TabIds = append(ws.TabIds[:tabIdx], ws.TabIds[tabIdx+1:]...) |
| 309 | |
| 310 | // close blocks (sends events + stops block controllers) |
| 311 | tab, _ := wstore.DBGet[*waveobj.Tab](ctx, tabId) |
| 312 | if tab != nil { |
| 313 | for _, blockId := range tab.BlockIds { |
| 314 | err := DeleteBlock(ctx, blockId, false) |
| 315 | if err != nil { |
| 316 | return "", fmt.Errorf("error deleting block %s: %w", blockId, err) |
| 317 | } |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | // if the tab is active, determine new active tab |
| 322 | newActiveTabId := ws.ActiveTabId |
| 323 | if ws.ActiveTabId == tabId { |
| 324 | if len(ws.TabIds) > 0 { |
| 325 | newActiveTabId = ws.TabIds[max(0, min(tabIdx-1, len(ws.TabIds)-1))] |
| 326 | } else { |
| 327 | newActiveTabId = "" |
| 328 | } |
| 329 | } |
| 330 | ws.ActiveTabId = newActiveTabId |
| 331 | |
| 332 | wstore.DBUpdate(ctx, ws) |
| 333 | wstore.DBDelete(ctx, waveobj.OType_Tab, tabId) |
| 334 | if tab != nil { |
| 335 | wstore.DBDelete(ctx, waveobj.OType_LayoutState, tab.LayoutState) |
| 336 | } |
| 337 | |
| 338 | // if no tabs remaining, close window |
| 339 | if recursive && newActiveTabId == "" { |
| 340 | log.Printf("no tabs remaining in workspace %s, closing window\n", workspaceId) |
| 341 | windowId, err := wstore.DBFindWindowForWorkspaceId(ctx, workspaceId) |
| 342 | if err != nil { |
| 343 | return newActiveTabId, fmt.Errorf("unable to find window for workspace id %v: %w", workspaceId, err) |
| 344 | } |
| 345 | err = CloseWindow(ctx, windowId, false) |
| 346 | if err != nil { |
| 347 | return newActiveTabId, err |
| 348 | } |
| 349 | } |
| 350 | return newActiveTabId, nil |
| 351 | } |
| 352 | |
| 353 | func SetActiveTab(ctx context.Context, workspaceId string, tabId string) error { |
| 354 | if tabId != "" && workspaceId != "" { |
no test coverage detected