mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
145 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e4d3bfd90a | |||
| 9073b9b31e | |||
| cf28bb53ca | |||
| e59f70d26b | |||
| deb9e23d53 | |||
| 3a9aa5813f | |||
| c3aa027cc8 | |||
| 7bdf332ce0 | |||
| 9483b43afa | |||
| 3fc4eb40cc | |||
| b142940a4c | |||
| 3e4a22e7b8 | |||
| b4928780d2 | |||
| a5e092e6c5 | |||
| 8f93b3e263 | |||
| 6a7ee12c10 | |||
| f5af7ad283 | |||
| eadfb92f94 | |||
| a50db14b3e | |||
| 6308c6c4b0 | |||
| cdfc446763 | |||
| b08aaa03fb | |||
| 64244626a1 | |||
| c683d10008 | |||
| b115d04876 | |||
| 265cc30347 | |||
| 5f755e6574 | |||
| e04c5af41d | |||
| 2b0b206614 | |||
| 7c63e24525 | |||
| 0b74f4afcf | |||
| 77706bf21e | |||
| 6bd5931056 | |||
| e5ee4e4069 | |||
| f05cb30dca | |||
| 260b29167d | |||
| e543538bae | |||
| bd7a83ba0e | |||
| 5d1c92d643 | |||
| c6f187d65d | |||
| b476ab31c6 | |||
| 20b25a9272 | |||
| 35cf4b6a3b | |||
| ff50e89156 | |||
| 024f46bf7b | |||
| 73164e0152 | |||
| 0d40d6fff3 | |||
| 86cbba1f79 | |||
| 8fdcf10cae | |||
| 6336f87cf2 | |||
| bdf17f0133 | |||
| f5f0791b32 | |||
| 899347e90f | |||
| fbc5e1606b | |||
| 39ee41921f | |||
| fde2ce97d2 | |||
| 93845c405d | |||
| 2913babea7 | |||
| a787a1a934 | |||
| bf447c60ce | |||
| f2b322c7d7 | |||
| c1bd5f5765 | |||
| b97c7e186d | |||
| 0442fc84d4 | |||
| 27efae3ad5 | |||
| 4d8c2cd242 | |||
| a560499b58 | |||
| e8b489bcd9 | |||
| 31c12c4705 | |||
| 787bcbc9d8 | |||
| 985304c9aa | |||
| 13cbfdeb6e | |||
| 53290b47e1 | |||
| 4bdd092d33 | |||
| fb2b3dfc6a | |||
| fa27964d49 | |||
| 95132011e4 | |||
| dae4210b72 | |||
| e394ba70a6 | |||
| 483b2eff6f | |||
| 2f4a6fa6e2 | |||
| 4af1b19ffd | |||
| 8b1d930cd6 | |||
| a4e8648968 | |||
| 429ea37419 | |||
| a8f3e356f6 | |||
| 85235aaad8 | |||
| 619cfe4931 | |||
| 11f1c3bb70 | |||
| 8d140c9920 | |||
| 205a9d1e2e | |||
| d3139d51cf | |||
| 5c931de40c | |||
| 497a96bfc2 | |||
| 427447c592 | |||
| 1fe5d425da | |||
| a395043a1c | |||
| ff9f9b43b6 | |||
| 98ba0b46ac | |||
| fb3253d018 | |||
| 8d91d156aa | |||
| b7eec15853 | |||
| 38ff6183a2 | |||
| 1b1e6edaee | |||
| f4aeb92d32 | |||
| b780d5b244 | |||
| d81a6ed480 | |||
| d8393ae50b | |||
| 79deb01ea4 | |||
| 12f9a50686 | |||
| 239933be3e | |||
| 4692cf698b | |||
| 907e87c217 | |||
| f97bb699a1 | |||
| 077545ed93 | |||
| 60d0f0e976 | |||
| cd4671e5bb | |||
| d8a714dd4a | |||
| e0fa1b2560 | |||
| 2dffcc9237 | |||
| 70090b8684 | |||
| 3f8952caf4 | |||
| 15a2486e94 | |||
| 38aa7016b8 | |||
| cff353ca94 | |||
| 5b440ace65 | |||
| 87de0dbc44 | |||
| 74839b8e1b | |||
| 8a24953a88 | |||
| a95854514a | |||
| 229fcf8cd4 | |||
| 83542ddab8 | |||
| b520242f04 | |||
| bc73ed1b6c | |||
| c4647945a4 | |||
| 3db40b1c63 | |||
| f6d7c37915 | |||
| a41e866b1f | |||
| a772715ae4 | |||
| d32e2aae05 | |||
| 3f9d52a7e4 | |||
| a239a8d70e | |||
| a1bddd971f | |||
| 722318f57d | |||
| 3b633328a1 |
@@ -107,12 +107,12 @@
|
||||
{
|
||||
"command": "app:openConnectionsView",
|
||||
"keys": [],
|
||||
"commandStr": "/mainview connections"
|
||||
"commandStr": ["/mainview connections"]
|
||||
},
|
||||
{
|
||||
"command": "app:openSettingsView",
|
||||
"keys": [],
|
||||
"commandStr": "/mainview clientsettings"
|
||||
"commandStr": ["/mainview clientsettings"]
|
||||
},
|
||||
{
|
||||
"command": "app:newTab",
|
||||
@@ -149,48 +149,39 @@
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-1",
|
||||
"keys": ["Cmd:1"],
|
||||
"commandStr":"/screen 1"
|
||||
"keys": ["Cmd:1"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-2",
|
||||
"keys": ["Cmd:2"],
|
||||
"commandStr":"/screen 2"
|
||||
"keys": ["Cmd:2"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-3",
|
||||
"keys": ["Cmd:3"],
|
||||
"commandStr":"/screen 3"
|
||||
"keys": ["Cmd:3"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-4",
|
||||
"keys": ["Cmd:4"],
|
||||
"commandStr":"/screen 4"
|
||||
"keys": ["Cmd:4"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-5",
|
||||
"keys": ["Cmd:5"],
|
||||
"commandStr":"/screen 5"
|
||||
"keys": ["Cmd:5"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-6",
|
||||
"keys": ["Cmd:6"],
|
||||
"commandStr":"/screen 6"
|
||||
"keys": ["Cmd:6"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-7",
|
||||
"keys": ["Cmd:7"],
|
||||
"commandStr":"/screen 7"
|
||||
"keys": ["Cmd:7"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-8",
|
||||
"keys": ["Cmd:8"],
|
||||
"commandStr":"/screen 8"
|
||||
"keys": ["Cmd:8"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTab-9",
|
||||
"keys": ["Cmd:9"],
|
||||
"commandStr":"/screen 9"
|
||||
"keys": ["Cmd:9"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectTabLeft",
|
||||
@@ -202,48 +193,39 @@
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-1",
|
||||
"keys": ["Cmd:Ctrl:1"],
|
||||
"commandStr": "/session 1"
|
||||
"keys": ["Cmd:Ctrl:1"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-2",
|
||||
"keys": ["Cmd:Ctrl:2"],
|
||||
"commandStr": "/session 2"
|
||||
"keys": ["Cmd:Ctrl:2"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-3",
|
||||
"keys": ["Cmd:Ctrl:3"],
|
||||
"commandStr": "/session 3"
|
||||
"keys": ["Cmd:Ctrl:3"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-4",
|
||||
"keys": ["Cmd:Ctrl:4"],
|
||||
"commandStr": "/session 4"
|
||||
"keys": ["Cmd:Ctrl:4"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-5",
|
||||
"keys": ["Cmd:Ctrl:5"],
|
||||
"commandStr": "/session 5"
|
||||
"keys": ["Cmd:Ctrl:5"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-6",
|
||||
"keys": ["Cmd:Ctrl:6"],
|
||||
"commandStr": "/session 6"
|
||||
"keys": ["Cmd:Ctrl:6"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-7",
|
||||
"keys": ["Cmd:Ctrl:7"],
|
||||
"commandStr": "/session 7"
|
||||
"keys": ["Cmd:Ctrl:7"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-8",
|
||||
"keys": ["Cmd:Ctrl:8"],
|
||||
"commandStr": "/session 8"
|
||||
"keys": ["Cmd:Ctrl:8"]
|
||||
},
|
||||
{
|
||||
"command": "app:selectWorkspace-9",
|
||||
"keys": ["Cmd:Ctrl:9"],
|
||||
"commandStr": "/session 9"
|
||||
"keys": ["Cmd:Ctrl:9"]
|
||||
},
|
||||
{
|
||||
"command": "app:toggleSidebar",
|
||||
@@ -256,7 +238,7 @@
|
||||
{
|
||||
"command": "app:openBookmarksView",
|
||||
"keys": ["Cmd:b"],
|
||||
"commandStr": "/bookmarks:show"
|
||||
"commandStr": ["/bookmarks:show"]
|
||||
},
|
||||
{
|
||||
"command": "bookmarks:edit",
|
||||
@@ -301,7 +283,7 @@
|
||||
{
|
||||
"command": "cmdinput:openHistory",
|
||||
"keys": ["Ctrl:r"],
|
||||
"commandStr": "/history"
|
||||
"commandStr": ["/history"]
|
||||
},
|
||||
{
|
||||
"command": "cmdinput:openAIChat",
|
||||
|
||||
+6
-2
@@ -24,6 +24,7 @@
|
||||
"@table-nav/react": "^0.0.7",
|
||||
"@tanstack/match-sorter-utils": "^8.8.4",
|
||||
"@tanstack/react-table": "^8.10.3",
|
||||
"@withfig/autocomplete": "^2.652.3",
|
||||
"autobind-decorator": "^2.4.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"classnames": "^2.3.1",
|
||||
@@ -43,10 +44,10 @@
|
||||
"papaparse": "^5.4.1",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-frame-component": "^5.2.6",
|
||||
"react-markdown": "^9.0.0",
|
||||
"remark": "^15.0.1",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"shell-quote": "^1.8.1",
|
||||
"sprintf-js": "^1.1.2",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"tsx-control-statements": "^5.1.1",
|
||||
@@ -69,6 +70,7 @@
|
||||
"@babel/preset-env": "^7.18.2",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"@babel/preset-typescript": "^7.17.12",
|
||||
"@electron/rebuild": "^3.6.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@types/classnames": "^2.3.1",
|
||||
"@types/electron": "^1.6.10",
|
||||
@@ -76,10 +78,12 @@
|
||||
"@types/papaparse": "^5.3.10",
|
||||
"@types/react": "^18.0.12",
|
||||
"@types/semver": "^7.5.6",
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"@types/sprintf-js": "^1.1.3",
|
||||
"@types/throttle-debounce": "^5.0.1",
|
||||
"@types/uuid": "^9.0.7",
|
||||
"@types/webpack-env": "^1.18.3",
|
||||
"@withfig/autocomplete-types": "^1.30.0",
|
||||
"babel-loader": "^9.1.3",
|
||||
"babel-plugin-jsx-control-statements": "^4.1.2",
|
||||
"copy-webpack-plugin": "^12.0.0",
|
||||
@@ -108,4 +112,4 @@
|
||||
"scripts": {
|
||||
"postinstall": "electron-builder install-app-deps"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
--app-accent-color: rgb(75, 166, 57);
|
||||
--app-accent-bg-color: rgba(75, 166, 57, 0.2);
|
||||
--app-text-color: rgb(0, 0, 0);
|
||||
--app-text-primary-color: rgb(0, 0, 0, 0.9);
|
||||
--app-text-secondary-color: rgb(0, 0, 0, 0.7);
|
||||
--app-text-primary-color: rgb(23, 23, 23);
|
||||
--app-text-secondary-color: rgb(76, 76, 76);
|
||||
--app-border-color: rgb(139 145 138);
|
||||
--app-panel-bg-color: rgb(224, 224, 224);
|
||||
--app-panel-bg-color-dev: rgb(224, 224, 224);
|
||||
|
||||
@@ -68,3 +68,4 @@ export const ErrorCode_InvalidCwd = "ERRCWD";
|
||||
export const InputAuxView_History = "history";
|
||||
export const InputAuxView_Info = "info";
|
||||
export const InputAuxView_AIChat = "aichat";
|
||||
export const InputAuxView_Suggestions = "suggestions";
|
||||
|
||||
@@ -11,9 +11,9 @@ import { Toggle, InlineSettingsTextEdit, SettingsError, Dropdown } from "@/commo
|
||||
import { commandRtnHandler, isBlank } from "@/util/util";
|
||||
import { getTermThemes } from "@/util/themeutil";
|
||||
import * as appconst from "@/app/appconst";
|
||||
import { MainView } from "@/common/elements/mainview";
|
||||
|
||||
import "./clientsettings.less";
|
||||
import { MainView } from "../common/elements/mainview";
|
||||
|
||||
class ClientSettingsKeybindings extends React.Component<{}, {}> {
|
||||
componentDidMount() {
|
||||
@@ -110,6 +110,19 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
GlobalModel.getElectronApi().changeAutoUpdate(val);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeAutocompleteEnabled(val: boolean): void {
|
||||
const prtn: Promise<CommandRtnType> = GlobalCommandRunner.setAutocompleteEnabled(val);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeAutocompleteDebuggingEnabled(val: boolean): void {
|
||||
mobx.action(() => {
|
||||
GlobalModel.autocompleteModel.loggingEnabled = val;
|
||||
})();
|
||||
}
|
||||
|
||||
getFontSizes(): DropdownItem[] {
|
||||
const availableFontSizes: DropdownItem[] = [];
|
||||
for (let s = appconst.MinFontSize; s <= appconst.MaxFontSize; s++) {
|
||||
@@ -354,6 +367,24 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Command Autocomplete</div>
|
||||
<div className="settings-input">
|
||||
<Toggle
|
||||
checked={cdata.clientopts.autocompleteenabled ?? false}
|
||||
onChange={this.handleChangeAutocompleteEnabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Command Autocomplete Debugging</div>
|
||||
<div className="settings-input">
|
||||
<Toggle
|
||||
checked={GlobalModel.autocompleteModel.loggingEnabled}
|
||||
onChange={this.handleChangeAutocompleteDebuggingEnabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<SettingsError errorMessage={this.errorMessage} />
|
||||
</div>
|
||||
</MainView>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
width: 100%;
|
||||
border: 2px solid var(--form-element-border-color);
|
||||
border-radius: 6px;
|
||||
line-height: 22px;
|
||||
line-height: 20px;
|
||||
background: var(--form-element-bg-color);
|
||||
|
||||
&.no-label {
|
||||
@@ -63,11 +63,14 @@
|
||||
display: flex;
|
||||
min-width: 120px;
|
||||
padding: 5px 8px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
align-self: stretch;
|
||||
border-radius: 6px;
|
||||
|
||||
i {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
&-highlighted,
|
||||
&:hover {
|
||||
background: rgba(241, 246, 243, 0.08);
|
||||
|
||||
@@ -163,7 +163,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
if (isOpen) {
|
||||
const option = options[highlightedIndex];
|
||||
if (option) {
|
||||
this.handleSelect(option.value, undefined);
|
||||
this.handleSelect(option, undefined);
|
||||
}
|
||||
} else {
|
||||
this.toggleDropdown();
|
||||
@@ -185,18 +185,19 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
handleKeyDown(event: React.KeyboardEvent) {}
|
||||
|
||||
@boundMethod
|
||||
handleSelect(value: string, event?: React.MouseEvent | React.KeyboardEvent) {
|
||||
handleSelect({ value, noop }: DropdownItem, event?: React.MouseEvent | React.KeyboardEvent) {
|
||||
const { onChange } = this.props;
|
||||
if (event) {
|
||||
event.stopPropagation(); // This stops the event from bubbling up to the wrapper
|
||||
}
|
||||
|
||||
if (!("value" in this.props)) {
|
||||
this.setState({ internalValue: value });
|
||||
}
|
||||
onChange(value);
|
||||
this.setState({ isOpen: false, isTouched: true });
|
||||
this.unregisterKeybindings();
|
||||
|
||||
if (!("value" in this.props) && !noop) {
|
||||
this.setState({ internalValue: value });
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
@@ -245,10 +246,11 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
className={cn("wave-dropdown-item unselectable", {
|
||||
"wave-dropdown-item-highlighted": index === highlightedIndex,
|
||||
})}
|
||||
onClick={(e) => this.handleSelect(option.value, e)}
|
||||
onClick={(e) => this.handleSelect(option, e)}
|
||||
onMouseEnter={() => this.setState({ highlightedIndex: index })}
|
||||
onMouseLeave={() => this.setState({ highlightedIndex: -1 })}
|
||||
>
|
||||
{option.icon && <span className="wave-dropdown-item-icon">{option.icon}</span>}
|
||||
{option.label}
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -131,7 +131,7 @@ class InlineSettingsTextEdit extends React.Component<
|
||||
</div>
|
||||
<div className="control">
|
||||
<div
|
||||
onClick={this.cancelChange}
|
||||
onMouseDown={this.cancelChange}
|
||||
title="Cancel (Esc)"
|
||||
className="button is-prompt-danger is-outlined is-small"
|
||||
>
|
||||
@@ -142,7 +142,7 @@ class InlineSettingsTextEdit extends React.Component<
|
||||
</div>
|
||||
<div className="control">
|
||||
<div
|
||||
onClick={this.confirmChange}
|
||||
onMouseDown={this.confirmChange}
|
||||
title="Confirm (Enter)"
|
||||
className="button is-wave-green is-outlined is-small"
|
||||
>
|
||||
|
||||
@@ -58,4 +58,8 @@
|
||||
.term-prompt-python {
|
||||
color: var(--term-magenta);
|
||||
}
|
||||
|
||||
.term-prompt-k8s {
|
||||
color: var(--term-magenta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ class Prompt extends React.Component<
|
||||
let branchElem = null;
|
||||
let pythonElem = null;
|
||||
let condaElem = null;
|
||||
let k8sElem = null;
|
||||
if (!isBlank(festate["PROMPTVAR_GITBRANCH"])) {
|
||||
const branchName = festate["PROMPTVAR_GITBRANCH"];
|
||||
branchElem = (
|
||||
@@ -171,9 +172,19 @@ class Prompt extends React.Component<
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (!isBlank(festate["K8SCONTEXT"])) {
|
||||
const k8sContext = festate["K8SCONTEXT"];
|
||||
const k8sNs = festate["K8SNAMESPACE"];
|
||||
k8sElem = (
|
||||
<span title="k8s context:namespace" className="term-prompt-k8s">
|
||||
k8s:({k8sContext}
|
||||
{isBlank(k8sNs) ? "" : ":" + k8sNs}){" "}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<span className={termClassNames}>
|
||||
{remoteElem} {cwdElem} {branchElem} {condaElem} {pythonElem}
|
||||
{remoteElem} {cwdElem} {branchElem} {condaElem} {pythonElem} {k8sElem}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -226,12 +226,13 @@
|
||||
}
|
||||
|
||||
.ts,
|
||||
.termopts {
|
||||
.termopts,
|
||||
.renderer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.renderer-icon {
|
||||
margin-right: 0.2em;
|
||||
.renderer .renderer-icon {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.metapart-mono {
|
||||
|
||||
@@ -291,10 +291,10 @@ class LineHeader extends React.Component<{ screen: LineContainerType; line: Line
|
||||
</div>
|
||||
<If condition={!isBlank(renderer) && renderer != "terminal"}>
|
||||
<div className="meta-divider">|</div>
|
||||
<div className="renderer-icon">
|
||||
<div className="renderer">
|
||||
<i className="fa-sharp fa-solid fa-fill renderer-icon" />
|
||||
{renderer}
|
||||
</div>
|
||||
<div className="renderer-name">{renderer}</div>
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,70 +1,72 @@
|
||||
.cmd-aichat {
|
||||
padding-bottom: 0 !important;
|
||||
.auxview-content {
|
||||
flex-flow: column nowrap;
|
||||
|
||||
.chat-window {
|
||||
display: flex;
|
||||
overflow-y: auto;
|
||||
margin-bottom: 5px;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.chat-window {
|
||||
overflow-y: auto;
|
||||
margin-bottom: 5px;
|
||||
// This is the filler that will push the chat messages to the bottom until the chat window is full
|
||||
.filler {
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.chat-input {
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
flex: 1 0 auto;
|
||||
|
||||
.chat-textarea {
|
||||
color: var(--app-text-primary-color);
|
||||
background-color: var(--cmdinput-textarea-bg);
|
||||
resize: none;
|
||||
width: 100%;
|
||||
border: transparent;
|
||||
outline: none;
|
||||
overflow: auto;
|
||||
overflow-wrap: anywhere;
|
||||
font-family: var(--termfontfamily);
|
||||
font-weight: normal;
|
||||
line-height: var(--termlineheight);
|
||||
}
|
||||
}
|
||||
|
||||
.chat-msg {
|
||||
margin-top: calc(var(--termpad) * 2);
|
||||
margin-bottom: calc(var(--termpad) * 2);
|
||||
|
||||
.chat-msg-header {
|
||||
display: flex;
|
||||
margin-bottom: 2px;
|
||||
|
||||
i {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.chat-username {
|
||||
font-weight: bold;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-msg-assistant {
|
||||
color: var(--app-text-color);
|
||||
}
|
||||
|
||||
.chat-msg-user {
|
||||
.msg-text {
|
||||
font-family: var(--markdown-font);
|
||||
font-size: 14px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-msg-error {
|
||||
color: var(--cmdinput-text-error);
|
||||
font-family: var(--markdown-font);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-input {
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
flex: 0 0 auto;
|
||||
|
||||
.chat-textarea {
|
||||
color: var(--app-text-primary-color);
|
||||
background-color: var(--cmdinput-textarea-bg);
|
||||
resize: none;
|
||||
width: 100%;
|
||||
border: transparent;
|
||||
outline: none;
|
||||
overflow: auto;
|
||||
overflow-wrap: anywhere;
|
||||
font-family: var(--termfontfamily);
|
||||
font-weight: normal;
|
||||
line-height: var(--termlineheight);
|
||||
}
|
||||
}
|
||||
|
||||
.chat-msg {
|
||||
margin-top: calc(var(--termpad) * 2);
|
||||
margin-bottom: calc(var(--termpad) * 2);
|
||||
|
||||
.chat-msg-header {
|
||||
display: flex;
|
||||
margin-bottom: 2px;
|
||||
|
||||
i {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.chat-username {
|
||||
font-weight: bold;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-msg-assistant {
|
||||
color: var(--app-text-color);
|
||||
}
|
||||
|
||||
.chat-msg-user {
|
||||
.msg-text {
|
||||
font-family: var(--markdown-font);
|
||||
font-size: 14px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-msg-error {
|
||||
color: var(--cmdinput-text-error);
|
||||
font-family: var(--markdown-font);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { boundMethod } from "autobind-decorator";
|
||||
import { If, For } from "tsx-control-statements/components";
|
||||
import { Markdown } from "@/elements";
|
||||
import { AuxiliaryCmdView } from "./auxview";
|
||||
import * as appconst from "@/app/appconst";
|
||||
|
||||
import "./aichat.less";
|
||||
|
||||
@@ -56,18 +57,13 @@ class AIChat extends React.Component<{}, {}> {
|
||||
chatListKeyCount: number = 0;
|
||||
chatWindowScrollRef: React.RefObject<HTMLDivElement>;
|
||||
textAreaRef: React.RefObject<HTMLTextAreaElement>;
|
||||
isFocused: OV<boolean>;
|
||||
termFontSize: number = 14;
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.chatWindowScrollRef = React.createRef();
|
||||
this.textAreaRef = React.createRef();
|
||||
this.isFocused = mobx.observable.box(false, {
|
||||
name: "aichat-isfocused",
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const inputModel = GlobalModel.inputModel;
|
||||
if (this.chatWindowScrollRef?.current != null) {
|
||||
@@ -92,7 +88,7 @@ class AIChat extends React.Component<{}, {}> {
|
||||
}
|
||||
|
||||
submitChatMessage(messageStr: string) {
|
||||
const curLine = GlobalModel.inputModel.getCurLine();
|
||||
const curLine = GlobalModel.inputModel.curLine;
|
||||
const prtn = GlobalModel.submitChatInfoCommand(messageStr, curLine, false);
|
||||
prtn.then((rtn) => {
|
||||
if (!rtn.success) {
|
||||
@@ -109,13 +105,14 @@ class AIChat extends React.Component<{}, {}> {
|
||||
|
||||
onTextAreaFocused(e: any) {
|
||||
mobx.action(() => {
|
||||
this.isFocused.set(true);
|
||||
GlobalModel.inputModel.setAuxViewFocus(true);
|
||||
})();
|
||||
this.onTextAreaChange(e);
|
||||
}
|
||||
|
||||
onTextAreaBlur(e: any) {
|
||||
mobx.action(() => {
|
||||
this.isFocused.set(false);
|
||||
GlobalModel.inputModel.setAuxViewFocus(false);
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -237,17 +234,7 @@ class AIChat extends React.Component<{}, {}> {
|
||||
render() {
|
||||
const chatMessageItems = GlobalModel.inputModel.AICmdInfoChatItems.slice();
|
||||
const chitem: OpenAICmdInfoChatMessageType = null;
|
||||
const renderKeybindings = mobx
|
||||
.computed(() => {
|
||||
return (
|
||||
this.isFocused.get() ||
|
||||
GlobalModel.inputModel.hasFocus() ||
|
||||
(GlobalModel.getActiveScreen().getFocusType() == "input" &&
|
||||
GlobalModel.activeMainView.get() == "session")
|
||||
);
|
||||
})
|
||||
.get();
|
||||
|
||||
const renderKeybindings = GlobalModel.inputModel.shouldRenderAuxViewKeybindings(appconst.InputAuxView_AIChat);
|
||||
return (
|
||||
<AuxiliaryCmdView
|
||||
title="Wave AI"
|
||||
@@ -259,6 +246,7 @@ class AIChat extends React.Component<{}, {}> {
|
||||
<AIChatKeybindings AIChatObject={this}></AIChatKeybindings>
|
||||
</If>
|
||||
<div className="chat-window" ref={this.chatWindowScrollRef}>
|
||||
<div className="filler"></div>
|
||||
<For each="chitem" index="idx" of={chatMessageItems}>
|
||||
{this.renderChatMessage(chitem)}
|
||||
</For>
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
// For the additonal views, we want less padding on the top and bottom than we want for the base-cmdinput div
|
||||
.auxview {
|
||||
padding: var(--termpad) calc(var(--termpad) * 2) var(--termpad) calc(var(--termpad) * 3 - 1px);
|
||||
overflow: auto;
|
||||
flex-shrink: 1;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
|
||||
--auxview-titlebar-height: 18px;
|
||||
|
||||
.auxview-titlebar {
|
||||
position: absolute;
|
||||
z-index: 22;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: var(--app-panel-bg-color);
|
||||
color: var(--term-blue);
|
||||
padding: 6px 10px 6px 10px;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid var(--app-border-color);
|
||||
@@ -23,6 +20,7 @@
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
line-height: var(--auxview-titlebar-height);
|
||||
overflow: hidden;
|
||||
|
||||
.title-string {
|
||||
font-weight: bold;
|
||||
@@ -46,6 +44,9 @@
|
||||
|
||||
.auxview-content {
|
||||
display: flex;
|
||||
padding-top: calc(var(--auxview-titlebar-height) + 6px);
|
||||
flex-flow: column nowrap;
|
||||
flex: 1 1 auto;
|
||||
padding: var(--termpad) calc(var(--termpad) * 2) var(--termpad) calc(var(--termpad) * 3 - 1px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,26 +3,28 @@
|
||||
|
||||
import * as React from "react";
|
||||
import cn from "classnames";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import { Choose, If, Otherwise, When } from "tsx-control-statements/components";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import "./auxview.less";
|
||||
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
|
||||
|
||||
export class AuxiliaryCmdView extends React.Component<
|
||||
{
|
||||
title: string;
|
||||
className?: string;
|
||||
iconClass?: string;
|
||||
titleBarContents?: React.ReactElement[];
|
||||
children?: React.ReactNode;
|
||||
onClose?: React.MouseEventHandler<HTMLDivElement>;
|
||||
},
|
||||
{}
|
||||
> {
|
||||
render() {
|
||||
const { title, className, iconClass, titleBarContents, children, onClose } = this.props;
|
||||
interface AuxiliaryCmdViewProps {
|
||||
title: string;
|
||||
className?: string;
|
||||
iconClass?: string;
|
||||
titleBarContents?: React.ReactElement[];
|
||||
children?: React.ReactNode;
|
||||
onClose?: React.MouseEventHandler<HTMLDivElement>;
|
||||
scrollable?: boolean;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn("auxview", className)}>
|
||||
export const AuxiliaryCmdView: React.FC<AuxiliaryCmdViewProps> = observer((props) => {
|
||||
const { title, className, iconClass, titleBarContents, children, onClose } = props;
|
||||
|
||||
return (
|
||||
<div className={cn("auxview", className)}>
|
||||
<If condition={title || onClose || titleBarContents || iconClass}>
|
||||
<div className="auxview-titlebar">
|
||||
<If condition={iconClass != null}>
|
||||
<div className="title-icon">
|
||||
@@ -41,10 +43,22 @@ export class AuxiliaryCmdView extends React.Component<
|
||||
</div>
|
||||
</If>
|
||||
</div>
|
||||
<If condition={children != null}>
|
||||
<div className="auxview-content">{children}</div>
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
</If>
|
||||
<If condition={children != null}>
|
||||
<Choose>
|
||||
<When condition={props.scrollable}>
|
||||
<OverlayScrollbarsComponent
|
||||
className="auxview-content"
|
||||
options={{ scrollbars: { autoHide: "leave" } }}
|
||||
>
|
||||
{children}
|
||||
</OverlayScrollbarsComponent>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<div className="auxview-content">{children}</div>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -14,19 +14,15 @@
|
||||
// TODO: use a generic selector for this
|
||||
&.has-aichat,
|
||||
&.has-history,
|
||||
&.has-info {
|
||||
&.has-info,
|
||||
&.has-suggestions {
|
||||
.base-cmdinput {
|
||||
border-top: 1px solid var(--app-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.has-info {
|
||||
padding-top: var(--termpad);
|
||||
}
|
||||
|
||||
&.has-history,
|
||||
&.has-aichat {
|
||||
padding-top: var(--termpad);
|
||||
height: max(300px, 70%);
|
||||
}
|
||||
|
||||
@@ -109,9 +105,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
color: var(--app-text-primary-color);
|
||||
background-color: var(--app-bg-color);
|
||||
.textarea,
|
||||
.textarea-ghost {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: var(--termpad) 0;
|
||||
resize: none;
|
||||
overflow: auto;
|
||||
@@ -119,10 +117,21 @@
|
||||
font-family: var(--termfontfamily);
|
||||
line-height: var(--termlineheight);
|
||||
font-size: var(--termfontsize);
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
color: var(--app-text-primary-color);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.textarea-ghost {
|
||||
color: var(--app-text-secondary-color);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
input.history-input {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
|
||||
@@ -19,6 +19,7 @@ import { CenteredIcon, RotateIcon } from "@/common/icons/icons";
|
||||
import { AIChat } from "./aichat";
|
||||
import * as util from "@/util/util";
|
||||
import * as appconst from "@/app/appconst";
|
||||
import { AutocompleteSuggestionView } from "./suggestionview";
|
||||
|
||||
import "./cmdinput.less";
|
||||
|
||||
@@ -181,6 +182,7 @@ class CmdInput extends React.Component<{}, {}> {
|
||||
hidePrompt = true;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={this.cmdInputRef} className={cn("cmd-input", hasOpenView, { active: focusVal })}>
|
||||
<Choose>
|
||||
@@ -195,6 +197,9 @@ class CmdInput extends React.Component<{}, {}> {
|
||||
<When condition={openView === appconst.InputAuxView_Info}>
|
||||
<InfoMsg key="infomsg" />
|
||||
</When>
|
||||
<When condition={openView === appconst.InputAuxView_Suggestions}>
|
||||
<AutocompleteSuggestionView />
|
||||
</When>
|
||||
</Choose>
|
||||
<If condition={remote && remote.status != "connected"}>
|
||||
<div className="remote-status-warning">
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
.history-clickable-opt {
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: var(--app-text-primary-color);
|
||||
@@ -21,6 +20,7 @@
|
||||
|
||||
.history-items {
|
||||
color: var(--app-text-color);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.history-item {
|
||||
|
||||
@@ -174,7 +174,7 @@ class HistoryInfo extends React.Component<{}, {}> {
|
||||
handleItemClick(hitem: HistoryItem) {
|
||||
const inputModel = GlobalModel.inputModel;
|
||||
const selItem = inputModel.getHistorySelectedItem();
|
||||
inputModel.setAuxViewFocus(false);
|
||||
inputModel.setAuxViewFocus(!inputModel.getAuxViewFocus());
|
||||
if (this.lastClickHNum == hitem.historynum && selItem != null && selItem.historynum == hitem.historynum) {
|
||||
inputModel.grabSelectedHistoryItem();
|
||||
return;
|
||||
@@ -225,7 +225,7 @@ class HistoryInfo extends React.Component<{}, {}> {
|
||||
render() {
|
||||
const inputModel = GlobalModel.inputModel;
|
||||
const selItem = inputModel.getHistorySelectedItem();
|
||||
const hitems = inputModel.getFilteredHistoryItems().slice().reverse();
|
||||
const hitems = inputModel.filteredHistoryItems.slice().reverse();
|
||||
const opts = inputModel.historyQueryOpts.get();
|
||||
let hitem: HistoryItem = null;
|
||||
let snames: Record<string, string> = {};
|
||||
@@ -239,10 +239,11 @@ class HistoryInfo extends React.Component<{}, {}> {
|
||||
return (
|
||||
<AuxiliaryCmdView
|
||||
title="History"
|
||||
className="cmd-history hide-scrollbar"
|
||||
className="cmd-history"
|
||||
onClose={this.handleClose}
|
||||
titleBarContents={this.getTitleBarContents()}
|
||||
iconClass="fa-sharp fa-solid fa-clock-rotate-left"
|
||||
scrollable={true}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user