waveterm/frontend/app/workspace/workspace.tsx

117 lines
3.6 KiB
TypeScript
Raw Normal View History

// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { ErrorBoundary } from "@/app/element/errorboundary";
import { CenteredDiv } from "@/app/element/quickelems";
import { ModalsRenderer } from "@/app/modals/modalsrenderer";
2024-06-18 06:50:33 +02:00
import { TabBar } from "@/app/tab/tabbar";
import { TabContent } from "@/app/tab/tabcontent";
import { atoms, createBlock, isDev } from "@/store/global";
import { isBlank, makeIconClass } from "@/util/util";
import { useAtomValue } from "jotai";
import { memo } from "react";
2024-11-16 06:26:16 +01:00
import { NotificationPopover } from "../notification/notificationpopover";
import "./workspace.scss";
2024-06-22 00:15:38 +02:00
const iconRegex = /^[a-z0-9-]+$/;
2024-08-28 03:49:49 +02:00
function keyLen(obj: Object): number {
if (obj == null) {
return 0;
}
return Object.keys(obj).length;
}
function sortByDisplayOrder(wmap: { [key: string]: WidgetConfigType }): WidgetConfigType[] {
if (wmap == null) {
return [];
}
const wlist = Object.values(wmap);
wlist.sort((a, b) => {
2024-11-09 00:46:44 +01:00
return (a["display:order"] ?? 0) - (b["display:order"] ?? 0);
2024-08-28 03:49:49 +02:00
});
return wlist;
}
const Widgets = memo(() => {
const fullConfig = useAtomValue(atoms.fullConfigAtom);
2024-08-28 03:49:49 +02:00
const helpWidget: WidgetConfigType = {
2024-08-20 02:21:44 +02:00
icon: "circle-question",
label: "help",
blockdef: {
meta: {
2024-08-20 02:21:44 +02:00
view: "help",
},
2024-08-20 02:21:44 +02:00
},
};
const tipsWidget: WidgetConfigType = {
icon: "lightbulb",
label: "tips",
blockdef: {
meta: {
view: "tips",
},
},
};
2024-08-28 03:49:49 +02:00
const showHelp = fullConfig?.settings?.["widget:showhelp"] ?? true;
const widgets = sortByDisplayOrder(fullConfig?.widgets);
2024-08-20 02:21:44 +02:00
return (
<div className="workspace-widgets">
2024-08-28 03:49:49 +02:00
{widgets?.map((data, idx) => <Widget key={`widget-${idx}`} widget={data} />)}
2024-08-20 02:21:44 +02:00
{showHelp ? (
<>
<div className="widget-spacer" />
2024-09-19 23:49:57 +02:00
<Widget key="tips" widget={tipsWidget} />
2024-08-20 02:21:44 +02:00
<Widget key="help" widget={helpWidget} />
</>
) : null}
{isDev() ? <NotificationPopover /> : null}
2024-08-20 02:21:44 +02:00
</div>
);
});
2024-08-20 02:21:44 +02:00
async function handleWidgetSelect(blockDef: BlockDef) {
createBlock(blockDef);
}
const Widget = memo(({ widget }: { widget: WidgetConfigType }) => {
return (
2024-08-20 02:21:44 +02:00
<div
className="widget"
onClick={() => handleWidgetSelect(widget.blockdef)}
title={widget.description || widget.label}
>
<div className="widget-icon" style={{ color: widget.color }}>
<i className={makeIconClass(widget.icon, true, { defaultIcon: "browser" })}></i>
</div>
{!isBlank(widget.label) ? <div className="widget-label">{widget.label}</div> : null}
</div>
);
2024-06-26 18:31:43 +02:00
});
const WorkspaceElem = memo(() => {
2024-10-17 23:34:02 +02:00
const tabId = useAtomValue(atoms.staticTabId);
const ws = useAtomValue(atoms.workspace);
return (
<div className="workspace">
2024-06-26 18:31:43 +02:00
<TabBar key={ws.oid} workspace={ws} />
<div className="workspace-tabcontent">
2024-10-17 23:34:02 +02:00
<ErrorBoundary key={tabId}>
{tabId == "" ? (
<CenteredDiv>No Active Tab</CenteredDiv>
) : (
<>
2024-10-17 23:34:02 +02:00
<TabContent key={tabId} tabId={tabId} />
<Widgets />
<ModalsRenderer />
</>
)}
</ErrorBoundary>
</div>
</div>
);
2024-06-26 18:31:43 +02:00
});
export { WorkspaceElem as Workspace };