mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
create block using a blockdef. better controller control. preview that takes a file. atom caching per block. lots of updates
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
.workspace {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.workspace-tabcontent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.workspace-widgets {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 40px;
|
||||
overflow: hidden;
|
||||
background-color: var(--panel-bg-color);
|
||||
border-left: 1px solid var(--border-color);
|
||||
|
||||
.widget {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 10px 2px 10px 0;
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 20px;
|
||||
&:hover:not(.no-hover) {
|
||||
background-color: var(--highlight-bg-color);
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 35px;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
flex-shrink: 0;
|
||||
|
||||
.tab {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
border-right: 1px solid var(--border-color);
|
||||
cursor: pointer;
|
||||
&.active {
|
||||
background-color: var(--highlight-bg-color);
|
||||
}
|
||||
}
|
||||
|
||||
.tab-add {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 40px;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
border-left: 1px solid transparent;
|
||||
&:hover {
|
||||
border-left: 1px solid white;
|
||||
background-color: var(--highlight-bg-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as jotai from "jotai";
|
||||
import { TabContent } from "@/app/tab/tab";
|
||||
import { clsx } from "clsx";
|
||||
import { atoms, addBlockIdToTab, blockDataMap } from "@/store/global";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import * as BlockService from "@/bindings/pkg/service/blockservice/BlockService";
|
||||
|
||||
import "./workspace.less";
|
||||
|
||||
function Tab({ tab }: { tab: TabData }) {
|
||||
const [activeTab, setActiveTab] = jotai.useAtom(atoms.activeTabId);
|
||||
return (
|
||||
<div className={clsx("tab", { active: activeTab === tab.tabid })} onClick={() => setActiveTab(tab.tabid)}>
|
||||
{tab.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function TabBar() {
|
||||
const [tabData, setTabData] = jotai.useAtom(atoms.tabsAtom);
|
||||
const [activeTab, setActiveTab] = jotai.useAtom(atoms.activeTabId);
|
||||
const tabs = jotai.useAtomValue(atoms.tabsAtom);
|
||||
|
||||
function handleAddTab() {
|
||||
const newTabId = uuidv4();
|
||||
const newTabName = "Tab " + (tabData.length + 1);
|
||||
setTabData([...tabData, { name: newTabName, tabid: newTabId, blockIds: [] }]);
|
||||
setActiveTab(newTabId);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="tab-bar">
|
||||
{tabs.map((tab, idx) => {
|
||||
return <Tab key={idx} tab={tab} />;
|
||||
})}
|
||||
<div className="tab-add" onClick={() => handleAddTab()}>
|
||||
<i className="fa fa-solid fa-plus fa-fw" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Widgets() {
|
||||
const activeTabId = jotai.useAtomValue(atoms.activeTabId);
|
||||
|
||||
async function createBlock(blockDef: BlockDef) {
|
||||
const rtOpts = { termsize: { rows: 25, cols: 80 } };
|
||||
const rtnBlock: BlockData = await BlockService.CreateBlock(blockDef, rtOpts);
|
||||
const newBlockAtom = jotai.atom(rtnBlock);
|
||||
blockDataMap.set(rtnBlock.blockid, newBlockAtom);
|
||||
addBlockIdToTab(activeTabId, rtnBlock.blockid);
|
||||
}
|
||||
|
||||
async function clickTerminal() {
|
||||
const termBlockDef = {
|
||||
controller: "shell",
|
||||
view: "term",
|
||||
};
|
||||
createBlock(termBlockDef);
|
||||
}
|
||||
|
||||
async function clickPreview(fileName: string) {
|
||||
const markdownDef = {
|
||||
view: "preview",
|
||||
meta: { file: fileName },
|
||||
};
|
||||
createBlock(markdownDef);
|
||||
}
|
||||
|
||||
async function clickPlot() {
|
||||
console.log("TODO plot");
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="workspace-widgets">
|
||||
<div className="widget" onClick={() => clickTerminal()}>
|
||||
<i className="fa fa-solid fa-square-terminal fa-fw" />
|
||||
</div>
|
||||
<div className="widget" onClick={() => clickPreview("README.md")}>
|
||||
<i className="fa fa-solid fa-files fa-fw" />
|
||||
</div>
|
||||
<div className="widget" onClick={() => clickPreview("go.mod")}>
|
||||
<i className="fa fa-solid fa-files fa-fw" />
|
||||
</div>
|
||||
<div className="widget" onClick={() => clickPlot()}>
|
||||
<i className="fa fa-solid fa-chart-simple fa-fw" />
|
||||
</div>
|
||||
<div className="widget no-hover">
|
||||
<i className="fa fa-solid fa-plus fa-fw" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Workspace() {
|
||||
const activeTabId = jotai.useAtomValue(atoms.activeTabId);
|
||||
return (
|
||||
<div className="workspace">
|
||||
<TabBar />
|
||||
<div className="workspace-tabcontent">
|
||||
<TabContent tabId={activeTabId} />
|
||||
<Widgets />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export { Workspace };
|
||||
Reference in New Issue
Block a user