diff --git a/frontend/app/workspace/workspace.less b/frontend/app/workspace/workspace.less
index 395662df..2d4eb16a 100644
--- a/frontend/app/workspace/workspace.less
+++ b/frontend/app/workspace/workspace.less
@@ -21,6 +21,7 @@
width: 50px;
overflow: hidden;
padding-top: 4px;
+ padding-bottom: 4px;
.widget {
display: flex;
@@ -46,7 +47,22 @@
.widget-label {
font-size: 10px;
margin-top: 3px;
+ width: 100%;
+ padding: 0 2px;
+ text-align: center;
+ white-space: nowrap;
+ overflow: hidden;
}
}
+
+ .widget-divider {
+ margin-left: 6px;
+ height: 2px;
+ background-color: var(--border-color);
+ }
+
+ .widget-spacer {
+ flex-grow: 1;
+ }
}
}
diff --git a/frontend/app/workspace/workspace.tsx b/frontend/app/workspace/workspace.tsx
index a23e9cdd..5add7b5f 100644
--- a/frontend/app/workspace/workspace.tsx
+++ b/frontend/app/workspace/workspace.tsx
@@ -5,7 +5,6 @@ import { ModalsRenderer } from "@/app/modals/modalsrenderer";
import { TabBar } from "@/app/tab/tabbar";
import { TabContent } from "@/app/tab/tabcontent";
import { atoms, createBlock } from "@/store/global";
-import * as services from "@/store/services";
import * as util from "@/util/util";
import * as jotai from "jotai";
import * as React from "react";
@@ -18,87 +17,61 @@ const iconRegex = /^[a-z0-9-]+$/;
const Widgets = React.memo(() => {
const settingsConfig = jotai.useAtomValue(atoms.settingsConfigAtom);
const newWidgetModalVisible = React.useState(false);
- async function clickTerminal() {
- const termBlockDef: BlockDef = {
+ const helpWidget: WidgetsConfigType = {
+ icon: "circle-question",
+ label: "help",
+ blockdef: {
meta: {
- controller: "shell",
- view: "term",
+ view: "help",
},
- };
- createBlock(termBlockDef);
- }
-
- async function clickHome() {
- const editDef: BlockDef = {
- meta: {
- view: "preview",
- file: "~",
- },
- };
- createBlock(editDef);
- }
- async function clickWeb() {
- const editDef: BlockDef = {
- meta: {
- view: "web",
- url: "https://waveterm.dev/",
- },
- };
- createBlock(editDef);
- }
- async function handleWidgetSelect(blockDef: BlockDef) {
- createBlock(blockDef);
- }
-
- async function handleCreateWidget(newWidget: WidgetsConfigType) {
- await services.FileService.AddWidget(newWidget);
- }
-
- async function handleRemoveWidget(idx: number) {
- await services.FileService.RemoveWidget(idx);
- }
-
- function isIconValid(icon: string): boolean {
- if (util.isBlank(icon)) {
- return false;
- }
- return icon.match(iconRegex) != null;
- }
-
- function getIconClass(icon: string): string {
- if (!isIconValid(icon)) {
- return "fa fa-solid fa-question fa-fw";
- }
- return `fa fa-solid fa-${icon} fa-fw`;
- }
-
+ },
+ };
+ const showHelp = settingsConfig?.["widget:showhelp"] ?? true;
+ const showDivider = settingsConfig?.defaultwidgets?.length > 0 && settingsConfig?.widgets?.length > 0;
return (
-
clickTerminal()}>
-
-
-
-
terminal
+ {settingsConfig?.defaultwidgets?.map((data, idx) =>
)}
+ {showDivider ?
: null}
+ {settingsConfig?.widgets?.map((data, idx) =>
)}
+ {showHelp ? (
+ <>
+
+
+ >
+ ) : null}
+
+ );
+});
+
+async function handleWidgetSelect(blockDef: BlockDef) {
+ createBlock(blockDef);
+}
+
+function isIconValid(icon: string): boolean {
+ if (util.isBlank(icon)) {
+ return false;
+ }
+ return icon.match(iconRegex) != null;
+}
+
+function getIconClass(icon: string): string {
+ if (!isIconValid(icon)) {
+ return "fa fa-solid fa-question fa-fw";
+ }
+ return `fa fa-solid fa-${icon} fa-fw`;
+}
+
+const Widget = React.memo(({ widget }: { widget: WidgetsConfigType }) => {
+ return (
+
handleWidgetSelect(widget.blockdef)}
+ title={widget.description || widget.label}
+ >
+
+
-
clickHome()}>
-
-
-
-
files
-
- {settingsConfig?.widgets?.map((data, idx) => (
-
handleWidgetSelect(data.blockdef)}
- key={`widget-${idx}`}
- title={data.description || data.label}
- >
-
-
-
- {!util.isBlank(data.label) ?
{data.label}
: null}
-
- ))}
+ {!util.isBlank(widget.label) ?
{widget.label}
: null}
);
});
diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts
index 8b03d9be..86b69cfa 100644
--- a/frontend/types/gotypes.d.ts
+++ b/frontend/types/gotypes.d.ts
@@ -341,14 +341,15 @@ declare global {
mimetypes: {[key: string]: MimeTypeConfigType};
term: TerminalConfigType;
ai: AiConfigType;
+ defaultwidgets: WidgetsConfigType[];
widgets: WidgetsConfigType[];
+ "widget:showhelp": boolean;
blockheader: BlockHeaderOpts;
autoupdate: AutoUpdateOpts;
termthemes: {[key: string]: TermThemeType};
window: WindowSettingsType;
web: WebConfigType;
telemetry: TelemetrySettingsType;
- defaultmeta?: MetaType;
presets?: {[key: string]: MetaType};
};
diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go
index e059715e..70c6e257 100644
--- a/pkg/wconfig/settingsconfig.go
+++ b/pkg/wconfig/settingsconfig.go
@@ -101,19 +101,19 @@ type TelemetrySettingsType struct {
}
type SettingsConfigType struct {
- MimeTypes map[string]MimeTypeConfigType `json:"mimetypes"`
- Term TerminalConfigType `json:"term"`
- Ai *AiConfigType `json:"ai"`
- Widgets []WidgetsConfigType `json:"widgets"`
- BlockHeader BlockHeaderOpts `json:"blockheader"`
- AutoUpdate *AutoUpdateOpts `json:"autoupdate"`
- TermThemes TermThemesConfigType `json:"termthemes"`
- WindowSettings WindowSettingsType `json:"window"`
- Web WebConfigType `json:"web"`
- Telemetry *TelemetrySettingsType `json:"telemetry"`
-
- DefaultMeta *waveobj.MetaMapType `json:"defaultmeta,omitempty"`
- Presets map[string]*waveobj.MetaMapType `json:"presets,omitempty"`
+ MimeTypes map[string]MimeTypeConfigType `json:"mimetypes"`
+ Term TerminalConfigType `json:"term"`
+ Ai *AiConfigType `json:"ai"`
+ DefaultWidgets []WidgetsConfigType `json:"defaultwidgets"`
+ Widgets []WidgetsConfigType `json:"widgets"`
+ WidgetShowHelp *bool `json:"widget:showhelp"`
+ BlockHeader BlockHeaderOpts `json:"blockheader"`
+ AutoUpdate *AutoUpdateOpts `json:"autoupdate"`
+ TermThemes TermThemesConfigType `json:"termthemes"`
+ WindowSettings WindowSettingsType `json:"window"`
+ Web WebConfigType `json:"web"`
+ Telemetry *TelemetrySettingsType `json:"telemetry"`
+ Presets map[string]*waveobj.MetaMapType `json:"presets,omitempty"`
}
var DefaultTermDarkTheme = TermThemeType{
@@ -279,6 +279,26 @@ func applyDefaultSettings(settings *SettingsConfigType) {
}
}
defaultWidgets := []WidgetsConfigType{
+ {
+ Icon: "square-terminal",
+ Label: "terminal",
+ BlockDef: wstore.BlockDef{
+ Meta: map[string]any{
+ wstore.MetaKey_View: "term",
+ wstore.MetaKey_Controller: "shell",
+ },
+ },
+ },
+ {
+ Icon: "folder",
+ Label: "files",
+ BlockDef: wstore.BlockDef{
+ Meta: map[string]any{
+ wstore.MetaKey_View: "preview",
+ wstore.MetaKey_File: "~",
+ },
+ },
+ },
{
Icon: "globe",
Label: "web",
@@ -307,18 +327,9 @@ func applyDefaultSettings(settings *SettingsConfigType) {
},
},
},
- {
- Icon: "circle-question",
- Label: "help",
- BlockDef: wstore.BlockDef{
- Meta: map[string]any{
- wstore.MetaKey_View: "help",
- },
- },
- },
}
- if settings.Widgets == nil {
- settings.Widgets = defaultWidgets
+ if settings.DefaultWidgets == nil {
+ settings.DefaultWidgets = defaultWidgets
}
if settings.TermThemes == nil {
settings.TermThemes = make(map[string]TermThemeType)