diff --git a/cmd/wsh/cmd/wshcmd-deleteblock.go b/cmd/wsh/cmd/wshcmd-deleteblock.go new file mode 100644 index 000000000..b8c4315d9 --- /dev/null +++ b/cmd/wsh/cmd/wshcmd-deleteblock.go @@ -0,0 +1,54 @@ +// Copyright 2024, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/wavetermdev/thenextwave/pkg/wshrpc" +) + +var deleteBlockCmd = &cobra.Command{ + Use: "deleteblock", + Short: "delete a block", + Args: cobra.ExactArgs(1), + Run: deleteBlockRun, +} + +func init() { + rootCmd.AddCommand(deleteBlockCmd) +} + +func deleteBlockRun(cmd *cobra.Command, args []string) { + oref := args[0] + if oref == "" { + fmt.Println("oref is required") + return + } + err := validateEasyORef(oref) + if err != nil { + fmt.Printf("%v\n", err) + return + } + setTermRawMode() + fullORef, err := resolveSimpleId(oref) + if err != nil { + fmt.Printf("error resolving oref: %v\r\n", err) + return + } + if fullORef.OType != "block" { + fmt.Printf("oref is not a block\r\n") + return + } + deleteBlockData := &wshrpc.CommandDeleteBlockData{ + BlockId: fullORef.OID, + } + _, err = RpcClient.SendRpcRequest(wshrpc.Command_DeleteBlock, deleteBlockData, 2000) + if err != nil { + fmt.Printf("error deleting block: %v\r\n", err) + return + } + fmt.Print("block deleted\r\n") +} diff --git a/frontend/app/store/wshserver.ts b/frontend/app/store/wshserver.ts index db28730be..221173246 100644 --- a/frontend/app/store/wshserver.ts +++ b/frontend/app/store/wshserver.ts @@ -22,6 +22,11 @@ class WshServerType { return WOS.wshServerRpcHelper_call("createblock", data, opts); } + // command "deleteblock" [call] + DeleteBlockCommand(data: CommandDeleteBlockData, opts?: WshRpcCommandOpts): Promise { + return WOS.wshServerRpcHelper_call("deleteblock", data, opts); + } + // command "file:append" [call] AppendFileCommand(data: CommandAppendFileData, opts?: WshRpcCommandOpts): Promise { return WOS.wshServerRpcHelper_call("file:append", data, opts); diff --git a/frontend/app/view/directorypreview.less b/frontend/app/view/directorypreview.less index 484ee9aa5..9d7301839 100644 --- a/frontend/app/view/directorypreview.less +++ b/frontend/app/view/directorypreview.less @@ -10,7 +10,7 @@ border-radius: 3px; display: flex; flex-direction: column; - font-family: Inter; + font: var(--base-font); .dir-table-head { .dir-table-head-row { display: flex; diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 263c17e79..fb8152be2 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -95,6 +95,11 @@ declare global { rtopts: RuntimeOpts; }; + // wshrpc.CommandDeleteBlockData + type CommandDeleteBlockData = { + blockid: string; + }; + // wshrpc.CommandGetMetaData type CommandGetMetaData = { oref: ORef; diff --git a/pkg/wshrpc/wshclient/wshclient.go b/pkg/wshrpc/wshclient/wshclient.go index 6c4e5830c..ace45d172 100644 --- a/pkg/wshrpc/wshclient/wshclient.go +++ b/pkg/wshrpc/wshclient/wshclient.go @@ -29,6 +29,12 @@ func CreateBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandCreateBlockData, o return resp, err } +// command "deleteblock", wshserver.DeleteBlockCommand +func DeleteBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandDeleteBlockData, opts *wshrpc.WshRpcCommandOpts) error { + _, err := sendRpcRequestCallHelper[any](w, "deleteblock", data, opts) + return err +} + // command "file:append", wshserver.AppendFileCommand func AppendFileCommand(w *wshutil.WshRpc, data wshrpc.CommandAppendFileData, opts *wshrpc.WshRpcCommandOpts) error { _, err := sendRpcRequestCallHelper[any](w, "file:append", data, opts) diff --git a/pkg/wshrpc/wshrpctypes.go b/pkg/wshrpc/wshrpctypes.go index 6a19ebf9b..008af941d 100644 --- a/pkg/wshrpc/wshrpctypes.go +++ b/pkg/wshrpc/wshrpctypes.go @@ -25,6 +25,7 @@ const ( Command_AppendIJson = "file:appendijson" Command_ResolveIds = "resolveids" Command_CreateBlock = "createblock" + Command_DeleteBlock = "deleteblock" ) type MetaDataType = map[string]any @@ -133,3 +134,7 @@ type CommandAppendIJsonData struct { FileName string `json:"filename"` Data ijson.Command `json:"data"` } + +type CommandDeleteBlockData struct { + BlockId string `json:"blockid" wshcontext:"BlockId"` +} diff --git a/pkg/wshrpc/wshserver/wshserver.go b/pkg/wshrpc/wshserver/wshserver.go index a5140e68c..80ae49858 100644 --- a/pkg/wshrpc/wshserver/wshserver.go +++ b/pkg/wshrpc/wshserver/wshserver.go @@ -44,6 +44,7 @@ var WshServerCommandToDeclMap = map[string]*WshServerMethodDecl{ wshrpc.Command_BlockInput: GetWshServerMethod(wshrpc.Command_BlockInput, wshutil.RpcType_Call, "BlockInputCommand", WshServerImpl.BlockInputCommand), wshrpc.Command_AppendFile: GetWshServerMethod(wshrpc.Command_AppendFile, wshutil.RpcType_Call, "AppendFileCommand", WshServerImpl.AppendFileCommand), wshrpc.Command_AppendIJson: GetWshServerMethod(wshrpc.Command_AppendIJson, wshutil.RpcType_Call, "AppendIJsonCommand", WshServerImpl.AppendIJsonCommand), + wshrpc.Command_DeleteBlock: GetWshServerMethod(wshrpc.Command_DeleteBlock, wshutil.RpcType_Call, "DeleteBlockCommand", WshServerImpl.DeleteBlockCommand), "streamtest": RespStreamTest_MethodDecl, } @@ -294,3 +295,37 @@ func (ws *WshServer) AppendIJsonCommand(ctx context.Context, data wshrpc.Command }) return nil } + +func (ws *WshServer) DeleteBlockCommand(ctx context.Context, data wshrpc.CommandDeleteBlockData) error { + ctx = wstore.ContextWithUpdates(ctx) + tabId, err := wstore.DBFindTabForBlockId(ctx, data.BlockId) + if err != nil { + return fmt.Errorf("error finding tab for block: %w", err) + } + if tabId == "" { + return fmt.Errorf("no tab found for block") + } + windowId, err := wstore.DBFindWindowForTabId(ctx, tabId) + if err != nil { + return fmt.Errorf("error finding window for tab: %w", err) + } + if windowId == "" { + return fmt.Errorf("no window found for tab") + } + err = wstore.DeleteBlock(ctx, tabId, data.BlockId) + if err != nil { + return fmt.Errorf("error deleting block: %w", err) + } + eventbus.SendEventToWindow(windowId, eventbus.WSEventType{ + EventType: eventbus.WSEvent_LayoutAction, + Data: &eventbus.WSLayoutActionData{ + ActionType: "delete", + TabId: tabId, + BlockId: data.BlockId, + }, + }) + blockcontroller.StopBlockController(data.BlockId) + updates := wstore.ContextGetUpdatesRtn(ctx) + sendWStoreUpdatesToEventBus(updates) + return nil +} diff --git a/pkg/wstore/wstore_dbops.go b/pkg/wstore/wstore_dbops.go index d2916ee0c..edd909ed5 100644 --- a/pkg/wstore/wstore_dbops.go +++ b/pkg/wstore/wstore_dbops.go @@ -267,3 +267,13 @@ func DBFindWindowForTabId(ctx context.Context, tabId string) (string, error) { return tx.GetString(query, tabId), nil }) } + +func DBFindTabForBlockId(ctx context.Context, blockId string) (string, error) { + return WithTxRtn(ctx, func(tx *TxWrap) (string, error) { + query := ` + SELECT t.oid + FROM db_tab t, json_each(data->'blockids') je + WHERE je.value = ?;` + return tx.GetString(query, blockId), nil + }) +}