diff --git a/cmd/wsh/cmd/wshcmd-editor.go b/cmd/wsh/cmd/wshcmd-editor.go index 0a32af9fd..16a346591 100644 --- a/cmd/wsh/cmd/wshcmd-editor.go +++ b/cmd/wsh/cmd/wshcmd-editor.go @@ -65,11 +65,11 @@ func editorRun(cmd *cobra.Command, args []string) { return } doneCh := make(chan bool) - RpcClient.EventListener.On("blockclose", func(event *wps.WaveEvent) { + RpcClient.EventListener.On(wps.Event_BlockClose, func(event *wps.WaveEvent) { if event.HasScope(blockRef.String()) { close(doneCh) } }) - wshclient.EventSubCommand(RpcClient, wps.SubscriptionRequest{Event: "blockclose", Scopes: []string{blockRef.String()}}, nil) + wshclient.EventSubCommand(RpcClient, wps.SubscriptionRequest{Event: wps.Event_BlockClose, Scopes: []string{blockRef.String()}}, nil) <-doneCh } diff --git a/db/migrations-wstore/000005_blockparent.up.sql b/db/migrations-wstore/000005_blockparent.up.sql index 940d62b32..a75ca157f 100644 --- a/db/migrations-wstore/000005_blockparent.up.sql +++ b/db/migrations-wstore/000005_blockparent.up.sql @@ -1,4 +1,4 @@ UPDATE db_block -SET data = json_set(data, '$.parentoref', db_tab.oid) +SET data = json_set(data, '$.parentoref', 'tab:' || db_tab.oid) FROM db_tab WHERE db_block.oid IN (SELECT value FROM json_each(db_tab.data, '$.blockids')); diff --git a/pkg/service/objectservice/objectservice.go b/pkg/service/objectservice/objectservice.go index 2584d142d..08338da1f 100644 --- a/pkg/service/objectservice/objectservice.go +++ b/pkg/service/objectservice/objectservice.go @@ -201,7 +201,7 @@ func (svc *ObjectService) DeleteBlock(uiContext waveobj.UIContext, blockId strin ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout) defer cancelFn() ctx = waveobj.ContextWithUpdates(ctx) - err := wcore.DeleteBlock(ctx, uiContext.ActiveTabId, blockId) + err := wcore.DeleteBlock(ctx, blockId) if err != nil { return nil, fmt.Errorf("error deleting block: %w", err) } diff --git a/pkg/vdom/vdomclient/vdomclient.go b/pkg/vdom/vdomclient/vdomclient.go index 740802c1d..1d950d244 100644 --- a/pkg/vdom/vdomclient/vdomclient.go +++ b/pkg/vdom/vdomclient/vdomclient.go @@ -131,7 +131,7 @@ func (c *Client) CreateVDomContext() error { if err != nil { return err } - wshclient.EventSubCommand(c.RpcClient, wps.SubscriptionRequest{Event: "blockclose", Scopes: []string{ + wshclient.EventSubCommand(c.RpcClient, wps.SubscriptionRequest{Event: wps.Event_BlockClose, Scopes: []string{ waveobj.MakeORef("block", c.RpcContext.BlockId).String(), }}, nil) c.RpcClient.EventListener.On("blockclose", func(event *wps.WaveEvent) { diff --git a/pkg/waveobj/waveobj.go b/pkg/waveobj/waveobj.go index ba5931316..13111b54a 100644 --- a/pkg/waveobj/waveobj.go +++ b/pkg/waveobj/waveobj.go @@ -94,6 +94,14 @@ func ParseORef(orefStr string) (ORef, error) { return ORef{OType: otype, OID: oid}, nil } +func ParseORefNoErr(orefStr string) *ORef { + oref, err := ParseORef(orefStr) + if err != nil { + return nil + } + return &oref +} + type WaveObj interface { GetOType() string // should not depend on object state (should work with nil value) } diff --git a/pkg/wcore/wcore.go b/pkg/wcore/wcore.go index 3e9e1bb4a..784a735d8 100644 --- a/pkg/wcore/wcore.go +++ b/pkg/wcore/wcore.go @@ -26,7 +26,7 @@ import ( const DefaultTimeout = 2 * time.Second const DefaultActivateBlockTimeout = 60 * time.Second -func DeleteBlock(ctx context.Context, tabId string, blockId string) error { +func DeleteBlock(ctx context.Context, blockId string) error { block, err := wstore.DBMustGet[*waveobj.Block](ctx, blockId) if err != nil { return fmt.Errorf("error getting block: %w", err) @@ -36,33 +36,28 @@ func DeleteBlock(ctx context.Context, tabId string, blockId string) error { } if len(block.SubBlockIds) > 0 { for _, subBlockId := range block.SubBlockIds { - err := DeleteSubBlock(ctx, blockId, subBlockId) + err := DeleteBlock(ctx, subBlockId) if err != nil { return fmt.Errorf("error deleting subblock %s: %w", subBlockId, err) } } } - err = wstore.DeleteBlock(ctx, tabId, blockId) + err = wstore.DeleteBlock(ctx, blockId) if err != nil { return fmt.Errorf("error deleting block: %w", err) } go blockcontroller.StopBlockController(blockId) - sendBlockCloseEvent(tabId, blockId) + sendBlockCloseEvent(blockId) return nil } -// tabid is optional -func sendBlockCloseEvent(tabId string, blockId string) { - scopes := []string{ - waveobj.MakeORef(waveobj.OType_Block, blockId).String(), - } - if tabId != "" { - scopes = append(scopes, waveobj.MakeORef(waveobj.OType_Tab, tabId).String()) - } +func sendBlockCloseEvent(blockId string) { waveEvent := wps.WaveEvent{ - Event: wps.Event_BlockClose, - Scopes: scopes, - Data: blockId, + Event: wps.Event_BlockClose, + Scopes: []string{ + waveobj.MakeORef(waveobj.OType_Block, blockId).String(), + }, + Data: blockId, } wps.Broker.Publish(waveEvent) } @@ -77,7 +72,7 @@ func DeleteTab(ctx context.Context, workspaceId string, tabId string) error { } // close blocks (sends events + stops block controllers) for _, blockId := range tabData.BlockIds { - err := DeleteBlock(ctx, tabId, blockId) + err := DeleteBlock(ctx, blockId) if err != nil { return fmt.Errorf("error deleting block %s: %w", blockId, err) } @@ -224,32 +219,6 @@ func CreateClient(ctx context.Context) (*waveobj.Client, error) { return client, nil } -func DeleteSubBlock(ctx context.Context, parentBlockId string, blockId string) error { - block, err := wstore.DBMustGet[*waveobj.Block](ctx, blockId) - if err != nil { - return fmt.Errorf("error getting block: %w", err) - } - if block == nil { - return nil - } - if len(block.SubBlockIds) > 0 { - // recursively delete sub-blocks - for _, subBlockId := range block.SubBlockIds { - err := DeleteSubBlock(ctx, blockId, subBlockId) - if err != nil { - return fmt.Errorf("error deleting subblock %s: %w", subBlockId, err) - } - } - } - err = wstore.DeleteSubBlock(ctx, parentBlockId, blockId) - if err != nil { - return fmt.Errorf("error deleting block: %w", err) - } - go blockcontroller.StopBlockController(blockId) - sendBlockCloseEvent("", blockId) - return nil -} - func CreateSubBlock(ctx context.Context, blockId string, blockDef *waveobj.BlockDef) (*waveobj.Block, error) { if blockDef == nil { return nil, fmt.Errorf("blockDef is nil") diff --git a/pkg/wshrpc/wshserver/wshserver.go b/pkg/wshrpc/wshserver/wshserver.go index d9afe7889..094b07eed 100644 --- a/pkg/wshrpc/wshserver/wshserver.go +++ b/pkg/wshrpc/wshserver/wshserver.go @@ -392,7 +392,7 @@ func (ws *WshServer) DeleteBlockCommand(ctx context.Context, data wshrpc.Command if windowId == "" { return fmt.Errorf("no window found for tab") } - err = wcore.DeleteBlock(ctx, tabId, data.BlockId) + err = wcore.DeleteBlock(ctx, data.BlockId) if err != nil { return fmt.Errorf("error deleting block: %w", err) } diff --git a/pkg/wstore/wstore.go b/pkg/wstore/wstore.go index 450e7d587..0872ec45b 100644 --- a/pkg/wstore/wstore.go +++ b/pkg/wstore/wstore.go @@ -146,31 +146,33 @@ func findStringInSlice(slice []string, val string) int { return -1 } -func DeleteSubBlock(ctx context.Context, parentBlockId string, blockId string) error { +func DeleteBlock(ctx context.Context, blockId string) error { return WithTx(ctx, func(tx *TxWrap) error { - parentBlock, _ := DBGet[*waveobj.Block](tx.Context(), parentBlockId) - if parentBlock != nil { - parentBlock.SubBlockIds = utilfn.RemoveElemFromSlice(parentBlock.SubBlockIds, blockId) - DBUpdate(tx.Context(), parentBlock) + block, err := DBGet[*waveobj.Block](tx.Context(), blockId) + if err != nil { + return fmt.Errorf("error getting block: %w", err) } - DBDelete(tx.Context(), waveobj.OType_Block, blockId) - return nil - }) -} - -func DeleteBlock(ctx context.Context, tabId string, blockId string) error { - return WithTx(ctx, func(tx *TxWrap) error { - block, _ := DBGet[*waveobj.Block](tx.Context(), blockId) if block == nil { return nil } if len(block.SubBlockIds) > 0 { return fmt.Errorf("block has subblocks, must delete subblocks first") } - tab, _ := DBGet[*waveobj.Tab](tx.Context(), tabId) - if tab != nil { - tab.BlockIds = utilfn.RemoveElemFromSlice(tab.BlockIds, blockId) - DBUpdate(tx.Context(), tab) + parentORef := waveobj.ParseORefNoErr(block.ParentORef) + if parentORef != nil { + if parentORef.OType == waveobj.OType_Tab { + tab, _ := DBGet[*waveobj.Tab](tx.Context(), parentORef.OID) + if tab != nil { + tab.BlockIds = utilfn.RemoveElemFromSlice(tab.BlockIds, blockId) + DBUpdate(tx.Context(), tab) + } + } else if parentORef.OType == waveobj.OType_Block { + parentBlock, _ := DBGet[*waveobj.Block](tx.Context(), parentORef.OID) + if parentBlock != nil { + parentBlock.SubBlockIds = utilfn.RemoveElemFromSlice(parentBlock.SubBlockIds, blockId) + DBUpdate(tx.Context(), parentBlock) + } + } } DBDelete(tx.Context(), waveobj.OType_Block, blockId) return nil