mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-02-01 23:21:59 +01:00
implement defaultwidgets
This commit is contained in:
parent
ca3f418dc5
commit
a639fc3c8d
@ -21,6 +21,7 @@
|
|||||||
width: 50px;
|
width: 50px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
|
||||||
.widget {
|
.widget {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -46,7 +47,22 @@
|
|||||||
.widget-label {
|
.widget-label {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
margin-top: 3px;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import { ModalsRenderer } from "@/app/modals/modalsrenderer";
|
|||||||
import { TabBar } from "@/app/tab/tabbar";
|
import { TabBar } from "@/app/tab/tabbar";
|
||||||
import { TabContent } from "@/app/tab/tabcontent";
|
import { TabContent } from "@/app/tab/tabcontent";
|
||||||
import { atoms, createBlock } from "@/store/global";
|
import { atoms, createBlock } from "@/store/global";
|
||||||
import * as services from "@/store/services";
|
|
||||||
import * as util from "@/util/util";
|
import * as util from "@/util/util";
|
||||||
import * as jotai from "jotai";
|
import * as jotai from "jotai";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
@ -18,87 +17,61 @@ const iconRegex = /^[a-z0-9-]+$/;
|
|||||||
const Widgets = React.memo(() => {
|
const Widgets = React.memo(() => {
|
||||||
const settingsConfig = jotai.useAtomValue(atoms.settingsConfigAtom);
|
const settingsConfig = jotai.useAtomValue(atoms.settingsConfigAtom);
|
||||||
const newWidgetModalVisible = React.useState(false);
|
const newWidgetModalVisible = React.useState(false);
|
||||||
async function clickTerminal() {
|
const helpWidget: WidgetsConfigType = {
|
||||||
const termBlockDef: BlockDef = {
|
icon: "circle-question",
|
||||||
|
label: "help",
|
||||||
|
blockdef: {
|
||||||
meta: {
|
meta: {
|
||||||
controller: "shell",
|
view: "help",
|
||||||
view: "term",
|
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
createBlock(termBlockDef);
|
};
|
||||||
}
|
const showHelp = settingsConfig?.["widget:showhelp"] ?? true;
|
||||||
|
const showDivider = settingsConfig?.defaultwidgets?.length > 0 && settingsConfig?.widgets?.length > 0;
|
||||||
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`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="workspace-widgets">
|
<div className="workspace-widgets">
|
||||||
<div className="widget" onClick={() => clickTerminal()}>
|
{settingsConfig?.defaultwidgets?.map((data, idx) => <Widget key={`defwidget-${idx}`} widget={data} />)}
|
||||||
<div className="widget-icon">
|
{showDivider ? <div className="widget-divider" /> : null}
|
||||||
<i className="fa fa-solid fa-square-terminal fa-fw" />
|
{settingsConfig?.widgets?.map((data, idx) => <Widget key={`widget-${idx}`} widget={data} />)}
|
||||||
</div>
|
{showHelp ? (
|
||||||
<div className="widget-label">terminal</div>
|
<>
|
||||||
|
<div className="widget-spacer" />
|
||||||
|
<Widget key="help" widget={helpWidget} />
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<div
|
||||||
|
className="widget"
|
||||||
|
onClick={() => handleWidgetSelect(widget.blockdef)}
|
||||||
|
title={widget.description || widget.label}
|
||||||
|
>
|
||||||
|
<div className="widget-icon" style={{ color: widget.color }}>
|
||||||
|
<i className={getIconClass(widget.icon)}></i>
|
||||||
</div>
|
</div>
|
||||||
<div className="widget" onClick={() => clickHome()}>
|
{!util.isBlank(widget.label) ? <div className="widget-label">{widget.label}</div> : null}
|
||||||
<div className="widget-icon">
|
|
||||||
<i className="fa-sharp fa-solid fa-folder"></i>
|
|
||||||
</div>
|
|
||||||
<div className="widget-label">files</div>
|
|
||||||
</div>
|
|
||||||
{settingsConfig?.widgets?.map((data, idx) => (
|
|
||||||
<div
|
|
||||||
className="widget"
|
|
||||||
onClick={() => handleWidgetSelect(data.blockdef)}
|
|
||||||
key={`widget-${idx}`}
|
|
||||||
title={data.description || data.label}
|
|
||||||
>
|
|
||||||
<div className="widget-icon" style={{ color: data.color }}>
|
|
||||||
<i className={getIconClass(data.icon)}></i>
|
|
||||||
</div>
|
|
||||||
{!util.isBlank(data.label) ? <div className="widget-label">{data.label}</div> : null}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
3
frontend/types/gotypes.d.ts
vendored
3
frontend/types/gotypes.d.ts
vendored
@ -341,14 +341,15 @@ declare global {
|
|||||||
mimetypes: {[key: string]: MimeTypeConfigType};
|
mimetypes: {[key: string]: MimeTypeConfigType};
|
||||||
term: TerminalConfigType;
|
term: TerminalConfigType;
|
||||||
ai: AiConfigType;
|
ai: AiConfigType;
|
||||||
|
defaultwidgets: WidgetsConfigType[];
|
||||||
widgets: WidgetsConfigType[];
|
widgets: WidgetsConfigType[];
|
||||||
|
"widget:showhelp": boolean;
|
||||||
blockheader: BlockHeaderOpts;
|
blockheader: BlockHeaderOpts;
|
||||||
autoupdate: AutoUpdateOpts;
|
autoupdate: AutoUpdateOpts;
|
||||||
termthemes: {[key: string]: TermThemeType};
|
termthemes: {[key: string]: TermThemeType};
|
||||||
window: WindowSettingsType;
|
window: WindowSettingsType;
|
||||||
web: WebConfigType;
|
web: WebConfigType;
|
||||||
telemetry: TelemetrySettingsType;
|
telemetry: TelemetrySettingsType;
|
||||||
defaultmeta?: MetaType;
|
|
||||||
presets?: {[key: string]: MetaType};
|
presets?: {[key: string]: MetaType};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,19 +101,19 @@ type TelemetrySettingsType struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SettingsConfigType struct {
|
type SettingsConfigType struct {
|
||||||
MimeTypes map[string]MimeTypeConfigType `json:"mimetypes"`
|
MimeTypes map[string]MimeTypeConfigType `json:"mimetypes"`
|
||||||
Term TerminalConfigType `json:"term"`
|
Term TerminalConfigType `json:"term"`
|
||||||
Ai *AiConfigType `json:"ai"`
|
Ai *AiConfigType `json:"ai"`
|
||||||
Widgets []WidgetsConfigType `json:"widgets"`
|
DefaultWidgets []WidgetsConfigType `json:"defaultwidgets"`
|
||||||
BlockHeader BlockHeaderOpts `json:"blockheader"`
|
Widgets []WidgetsConfigType `json:"widgets"`
|
||||||
AutoUpdate *AutoUpdateOpts `json:"autoupdate"`
|
WidgetShowHelp *bool `json:"widget:showhelp"`
|
||||||
TermThemes TermThemesConfigType `json:"termthemes"`
|
BlockHeader BlockHeaderOpts `json:"blockheader"`
|
||||||
WindowSettings WindowSettingsType `json:"window"`
|
AutoUpdate *AutoUpdateOpts `json:"autoupdate"`
|
||||||
Web WebConfigType `json:"web"`
|
TermThemes TermThemesConfigType `json:"termthemes"`
|
||||||
Telemetry *TelemetrySettingsType `json:"telemetry"`
|
WindowSettings WindowSettingsType `json:"window"`
|
||||||
|
Web WebConfigType `json:"web"`
|
||||||
DefaultMeta *waveobj.MetaMapType `json:"defaultmeta,omitempty"`
|
Telemetry *TelemetrySettingsType `json:"telemetry"`
|
||||||
Presets map[string]*waveobj.MetaMapType `json:"presets,omitempty"`
|
Presets map[string]*waveobj.MetaMapType `json:"presets,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultTermDarkTheme = TermThemeType{
|
var DefaultTermDarkTheme = TermThemeType{
|
||||||
@ -279,6 +279,26 @@ func applyDefaultSettings(settings *SettingsConfigType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaultWidgets := []WidgetsConfigType{
|
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",
|
Icon: "globe",
|
||||||
Label: "web",
|
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 {
|
if settings.DefaultWidgets == nil {
|
||||||
settings.Widgets = defaultWidgets
|
settings.DefaultWidgets = defaultWidgets
|
||||||
}
|
}
|
||||||
if settings.TermThemes == nil {
|
if settings.TermThemes == nil {
|
||||||
settings.TermThemes = make(map[string]TermThemeType)
|
settings.TermThemes = make(map[string]TermThemeType)
|
||||||
|
Loading…
Reference in New Issue
Block a user