mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
subblocks and parents
This commit is contained in:
parent
fa160313ea
commit
52cb0c6817
1
db/migrations-wstore/000005_blockparent.down.sql
Normal file
1
db/migrations-wstore/000005_blockparent.down.sql
Normal file
@ -0,0 +1 @@
|
||||
-- we don't need to remove parentoref
|
4
db/migrations-wstore/000005_blockparent.up.sql
Normal file
4
db/migrations-wstore/000005_blockparent.up.sql
Normal file
@ -0,0 +1,4 @@
|
||||
UPDATE db_block
|
||||
SET data = json_set(data, '$.parentoref', db_tab.oid)
|
||||
FROM db_tab
|
||||
WHERE db_block.oid IN (SELECT value FROM json_each(db_tab.data, '$.blockids'));
|
2
frontend/types/gotypes.d.ts
vendored
2
frontend/types/gotypes.d.ts
vendored
@ -7,9 +7,11 @@ declare global {
|
||||
|
||||
// waveobj.Block
|
||||
type Block = WaveObj & {
|
||||
parentoref?: string;
|
||||
blockdef: BlockDef;
|
||||
runtimeopts?: RuntimeOpts;
|
||||
stickers?: StickerType[];
|
||||
subblockids?: string[];
|
||||
};
|
||||
|
||||
// blockcontroller.BlockControllerRuntimeStatus
|
||||
|
@ -252,11 +252,13 @@ type WinSize struct {
|
||||
|
||||
type Block struct {
|
||||
OID string `json:"oid"`
|
||||
ParentORef string `json:"parentoref,omitempty"`
|
||||
Version int `json:"version"`
|
||||
BlockDef *BlockDef `json:"blockdef"`
|
||||
RuntimeOpts *RuntimeOpts `json:"runtimeopts,omitempty"`
|
||||
Stickers []*StickerType `json:"stickers,omitempty"`
|
||||
Meta MetaMapType `json:"meta"`
|
||||
SubBlockIds []string `json:"subblockids,omitempty"`
|
||||
}
|
||||
|
||||
func (*Block) GetOType() string {
|
||||
|
@ -27,7 +27,22 @@ const DefaultTimeout = 2 * time.Second
|
||||
const DefaultActivateBlockTimeout = 60 * time.Second
|
||||
|
||||
func DeleteBlock(ctx context.Context, tabId string, blockId string) error {
|
||||
err := wstore.DeleteBlock(ctx, tabId, blockId)
|
||||
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 {
|
||||
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.DeleteBlock(ctx, tabId, blockId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting block: %w", err)
|
||||
}
|
||||
@ -36,14 +51,18 @@ func DeleteBlock(ctx context.Context, tabId string, blockId string) error {
|
||||
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())
|
||||
}
|
||||
waveEvent := wps.WaveEvent{
|
||||
Event: wps.Event_BlockClose,
|
||||
Scopes: []string{
|
||||
waveobj.MakeORef(waveobj.OType_Tab, tabId).String(),
|
||||
waveobj.MakeORef(waveobj.OType_Block, blockId).String(),
|
||||
},
|
||||
Data: blockId,
|
||||
Event: wps.Event_BlockClose,
|
||||
Scopes: scopes,
|
||||
Data: blockId,
|
||||
}
|
||||
wps.Broker.Publish(waveEvent)
|
||||
}
|
||||
@ -205,6 +224,46 @@ 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")
|
||||
}
|
||||
if blockDef.Meta == nil || blockDef.Meta.GetString(waveobj.MetaKey_View, "") == "" {
|
||||
return nil, fmt.Errorf("no view provided for new block")
|
||||
}
|
||||
blockData, err := wstore.CreateSubBlock(ctx, blockId, blockDef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating sub block: %w", err)
|
||||
}
|
||||
return blockData, nil
|
||||
}
|
||||
|
||||
func CreateBlock(ctx context.Context, tabId string, blockDef *waveobj.BlockDef, rtOpts *waveobj.RuntimeOpts) (*waveobj.Block, error) {
|
||||
if blockDef == nil {
|
||||
return nil, fmt.Errorf("blockDef is nil")
|
||||
|
@ -95,6 +95,27 @@ func UpdateTabName(ctx context.Context, tabId, name string) error {
|
||||
})
|
||||
}
|
||||
|
||||
func CreateSubBlock(ctx context.Context, parentBlockId string, blockDef *waveobj.BlockDef) (*waveobj.Block, error) {
|
||||
return WithTxRtn(ctx, func(tx *TxWrap) (*waveobj.Block, error) {
|
||||
parentBlock, _ := DBGet[*waveobj.Block](tx.Context(), parentBlockId)
|
||||
if parentBlock == nil {
|
||||
return nil, fmt.Errorf("parent block not found: %q", parentBlockId)
|
||||
}
|
||||
blockId := uuid.NewString()
|
||||
blockData := &waveobj.Block{
|
||||
OID: blockId,
|
||||
ParentORef: waveobj.MakeORef(waveobj.OType_Block, parentBlockId).String(),
|
||||
BlockDef: blockDef,
|
||||
RuntimeOpts: nil,
|
||||
Meta: blockDef.Meta,
|
||||
}
|
||||
DBInsert(tx.Context(), blockData)
|
||||
parentBlock.SubBlockIds = append(parentBlock.SubBlockIds, blockId)
|
||||
DBUpdate(tx.Context(), parentBlock)
|
||||
return blockData, nil
|
||||
})
|
||||
}
|
||||
|
||||
func CreateBlock(ctx context.Context, tabId string, blockDef *waveobj.BlockDef, rtOpts *waveobj.RuntimeOpts) (*waveobj.Block, error) {
|
||||
return WithTxRtn(ctx, func(tx *TxWrap) (*waveobj.Block, error) {
|
||||
tab, _ := DBGet[*waveobj.Tab](tx.Context(), tabId)
|
||||
@ -104,6 +125,7 @@ func CreateBlock(ctx context.Context, tabId string, blockDef *waveobj.BlockDef,
|
||||
blockId := uuid.NewString()
|
||||
blockData := &waveobj.Block{
|
||||
OID: blockId,
|
||||
ParentORef: waveobj.MakeORef(waveobj.OType_Tab, tabId).String(),
|
||||
BlockDef: blockDef,
|
||||
RuntimeOpts: rtOpts,
|
||||
Meta: blockDef.Meta,
|
||||
@ -124,18 +146,32 @@ func findStringInSlice(slice []string, val string) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func DeleteSubBlock(ctx context.Context, parentBlockId string, 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)
|
||||
}
|
||||
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 {
|
||||
tab, _ := DBGet[*waveobj.Tab](tx.Context(), tabId)
|
||||
if tab == nil {
|
||||
return fmt.Errorf("tab not found: %q", tabId)
|
||||
}
|
||||
blockIdx := findStringInSlice(tab.BlockIds, blockId)
|
||||
if blockIdx == -1 {
|
||||
block, _ := DBGet[*waveobj.Block](tx.Context(), blockId)
|
||||
if block == nil {
|
||||
return nil
|
||||
}
|
||||
tab.BlockIds = append(tab.BlockIds[:blockIdx], tab.BlockIds[blockIdx+1:]...)
|
||||
DBUpdate(tx.Context(), tab)
|
||||
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)
|
||||
}
|
||||
DBDelete(tx.Context(), waveobj.OType_Block, blockId)
|
||||
return nil
|
||||
})
|
||||
@ -145,23 +181,18 @@ func DeleteBlock(ctx context.Context, tabId string, blockId string) error {
|
||||
// also deletes LayoutState
|
||||
func DeleteTab(ctx context.Context, workspaceId string, tabId string) error {
|
||||
return WithTx(ctx, func(tx *TxWrap) error {
|
||||
ws, _ := DBGet[*waveobj.Workspace](tx.Context(), workspaceId)
|
||||
if ws == nil {
|
||||
return fmt.Errorf("workspace not found: %q", workspaceId)
|
||||
}
|
||||
tab, _ := DBGet[*waveobj.Tab](tx.Context(), tabId)
|
||||
if tab == nil {
|
||||
return fmt.Errorf("tab not found: %q", tabId)
|
||||
return nil
|
||||
}
|
||||
if len(tab.BlockIds) != 0 {
|
||||
return fmt.Errorf("tab has blocks, must delete blocks first")
|
||||
}
|
||||
tabIdx := findStringInSlice(ws.TabIds, tabId)
|
||||
if tabIdx == -1 {
|
||||
return nil
|
||||
ws, _ := DBGet[*waveobj.Workspace](tx.Context(), workspaceId)
|
||||
if ws != nil {
|
||||
ws.TabIds = utilfn.RemoveElemFromSlice(ws.TabIds, tabId)
|
||||
DBUpdate(tx.Context(), ws)
|
||||
}
|
||||
ws.TabIds = append(ws.TabIds[:tabIdx], ws.TabIds[tabIdx+1:]...)
|
||||
DBUpdate(tx.Context(), ws)
|
||||
DBDelete(tx.Context(), waveobj.OType_Tab, tabId)
|
||||
DBDelete(tx.Context(), waveobj.OType_LayoutState, tab.LayoutState)
|
||||
return nil
|
||||
@ -190,6 +221,10 @@ func UpdateObjectMeta(ctx context.Context, oref waveobj.ORef, meta waveobj.MetaM
|
||||
|
||||
func MoveBlockToTab(ctx context.Context, currentTabId string, newTabId string, blockId string) error {
|
||||
return WithTx(ctx, func(tx *TxWrap) error {
|
||||
block, _ := DBGet[*waveobj.Block](tx.Context(), blockId)
|
||||
if block == nil {
|
||||
return fmt.Errorf("block not found: %q", blockId)
|
||||
}
|
||||
currentTab, _ := DBGet[*waveobj.Tab](tx.Context(), currentTabId)
|
||||
if currentTab == nil {
|
||||
return fmt.Errorf("current tab not found: %q", currentTabId)
|
||||
@ -204,6 +239,8 @@ func MoveBlockToTab(ctx context.Context, currentTabId string, newTabId string, b
|
||||
}
|
||||
currentTab.BlockIds = utilfn.RemoveElemFromSlice(currentTab.BlockIds, blockId)
|
||||
newTab.BlockIds = append(newTab.BlockIds, blockId)
|
||||
block.ParentORef = waveobj.MakeORef(waveobj.OType_Tab, newTabId).String()
|
||||
DBUpdate(tx.Context(), block)
|
||||
DBUpdate(tx.Context(), currentTab)
|
||||
DBUpdate(tx.Context(), newTab)
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user