diff --git a/frontend/app/store/tabrpcclient.ts b/frontend/app/store/tabrpcclient.ts index 3e7ad7fd76..d6bfef56e1 100644 --- a/frontend/app/store/tabrpcclient.ts +++ b/frontend/app/store/tabrpcclient.ts @@ -2,11 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 import { WaveAIModel } from "@/app/aipanel/waveai-model"; -import { getApi } from "@/app/store/global"; +import { getApi, getBlockComponentModel, getConnStatusAtom, globalStore, WOS } from "@/app/store/global"; +import type { TermViewModel } from "@/app/view/term/term-model"; import { WorkspaceLayoutModel } from "@/app/workspace/workspace-layout-model"; import { getLayoutModelForStaticTab } from "@/layout/index"; import { base64ToArrayBuffer } from "@/util/util"; import { RpcResponseHelper, WshClient } from "./wshclient"; +import { RpcApi } from "./wshclientapi"; export class TabClient extends WshClient { constructor(routeId: string) { @@ -103,4 +105,73 @@ export class TabClient extends WshClient { layoutModel.focusNode(node.id); } + + async handle_getfocusedblockdata(rh: RpcResponseHelper): Promise { + const layoutModel = getLayoutModelForStaticTab(); + if (!layoutModel) { + throw new Error("Layout model not found"); + } + + const focusedNode = globalStore.get(layoutModel.focusedNode); + const blockId = focusedNode?.data?.blockId; + + if (!blockId) { + return null; + } + + const blockAtom = WOS.getWaveObjectAtom(WOS.makeORef("block", blockId)); + const blockData = globalStore.get(blockAtom); + + if (!blockData) { + return null; + } + + const viewType = blockData.meta?.view ?? ""; + const controller = blockData.meta?.controller ?? ""; + const connName = blockData.meta?.connection ?? ""; + + const result: FocusedBlockData = { + blockid: blockId, + viewtype: viewType, + controller: controller, + connname: connName, + blockmeta: blockData.meta ?? {}, + }; + + if (viewType === "term" && controller === "shell") { + const jobStatus = await RpcApi.BlockJobStatusCommand(this, blockId); + if (jobStatus) { + result.termjobstatus = jobStatus; + } + } + + if (connName) { + const connStatusAtom = getConnStatusAtom(connName); + const connStatus = globalStore.get(connStatusAtom); + if (connStatus) { + result.connstatus = connStatus; + } + } + + if (viewType === "term") { + try { + const bcm = getBlockComponentModel(blockId); + if (bcm?.viewModel) { + const termViewModel = bcm.viewModel as TermViewModel; + if (termViewModel.termRef?.current?.shellIntegrationStatusAtom) { + const shellIntegrationStatus = globalStore.get(termViewModel.termRef.current.shellIntegrationStatusAtom); + result.termshellintegrationstatus = shellIntegrationStatus || ""; + } + if (termViewModel.termRef?.current?.lastCommandAtom) { + const lastCommand = globalStore.get(termViewModel.termRef.current.lastCommandAtom); + result.termlastcommand = lastCommand || ""; + } + } + } catch (e) { + console.log("error getting term-specific data", e); + } + } + + return result; + } } diff --git a/frontend/app/store/wshclientapi.ts b/frontend/app/store/wshclientapi.ts index 72ffd8618d..302ebfa87c 100644 --- a/frontend/app/store/wshclientapi.ts +++ b/frontend/app/store/wshclientapi.ts @@ -332,6 +332,11 @@ class RpcApiType { return client.wshRpcCall("getbuilderstatus", data, opts); } + // command "getfocusedblockdata" [call] + GetFocusedBlockDataCommand(client: WshClient, opts?: RpcOpts): Promise { + return client.wshRpcCall("getfocusedblockdata", null, opts); + } + // command "getfullconfig" [call] GetFullConfigCommand(client: WshClient, opts?: RpcOpts): Promise { return client.wshRpcCall("getfullconfig", null, opts); diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 8a30f5e9be..2ac8bbe675 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -909,6 +909,19 @@ declare global { append?: boolean; }; + // wshrpc.FocusedBlockData + type FocusedBlockData = { + blockid: string; + viewtype: string; + controller: string; + connname: string; + blockmeta: MetaType; + termjobstatus?: BlockJobStatusData; + connstatus?: ConnStatus; + termshellintegrationstatus?: string; + termlastcommand?: string; + }; + // wconfig.FullConfigType type FullConfigType = { settings: SettingsType; diff --git a/pkg/wshrpc/wshclient/wshclient.go b/pkg/wshrpc/wshclient/wshclient.go index 533fb01c24..a6f09cee81 100644 --- a/pkg/wshrpc/wshclient/wshclient.go +++ b/pkg/wshrpc/wshclient/wshclient.go @@ -404,6 +404,12 @@ func GetBuilderStatusCommand(w *wshutil.WshRpc, data string, opts *wshrpc.RpcOpt return resp, err } +// command "getfocusedblockdata", wshserver.GetFocusedBlockDataCommand +func GetFocusedBlockDataCommand(w *wshutil.WshRpc, opts *wshrpc.RpcOpts) (*wshrpc.FocusedBlockData, error) { + resp, err := sendRpcRequestCallHelper[*wshrpc.FocusedBlockData](w, "getfocusedblockdata", nil, opts) + return resp, err +} + // command "getfullconfig", wshserver.GetFullConfigCommand func GetFullConfigCommand(w *wshutil.WshRpc, opts *wshrpc.RpcOpts) (wconfig.FullConfigType, error) { resp, err := sendRpcRequestCallHelper[wconfig.FullConfigType](w, "getfullconfig", nil, opts) diff --git a/pkg/wshrpc/wshrpctypes.go b/pkg/wshrpc/wshrpctypes.go index 00cad208f0..ba8422272a 100644 --- a/pkg/wshrpc/wshrpctypes.go +++ b/pkg/wshrpc/wshrpctypes.go @@ -153,6 +153,7 @@ type WshRpcInterface interface { // block focus SetBlockFocusCommand(ctx context.Context, blockId string) error + GetFocusedBlockDataCommand(ctx context.Context) (*FocusedBlockData, error) // rtinfo GetRTInfoCommand(ctx context.Context, data CommandGetRTInfoData) (*waveobj.ObjRTInfo, error) @@ -876,3 +877,15 @@ type BlockJobStatusData struct { CmdExitCode *int `json:"cmdexitcode,omitempty"` CmdExitSignal string `json:"cmdexitsignal,omitempty"` } + +type FocusedBlockData struct { + BlockId string `json:"blockid"` + ViewType string `json:"viewtype"` + Controller string `json:"controller"` + ConnName string `json:"connname"` + BlockMeta waveobj.MetaMapType `json:"blockmeta"` + TermJobStatus *BlockJobStatusData `json:"termjobstatus,omitempty"` + ConnStatus *ConnStatus `json:"connstatus,omitempty"` + TermShellIntegrationStatus string `json:"termshellintegrationstatus,omitempty"` + TermLastCommand string `json:"termlastcommand,omitempty"` +}