mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 406afe4a4f |
@@ -1,8 +1,7 @@
|
||||
[
|
||||
{
|
||||
"command": "system:toggleDeveloperTools",
|
||||
"keys": ["Cmd:Option:i"],
|
||||
"info": "Opens the chrome developer tool menu"
|
||||
"keys": ["Cmd:Option:i"]
|
||||
},
|
||||
{
|
||||
"command": "system:hideWindow",
|
||||
@@ -16,62 +15,10 @@
|
||||
"command": "generic:confirm",
|
||||
"keys": ["Enter"]
|
||||
},
|
||||
{
|
||||
"command": "generic:expandTextInput",
|
||||
"keys": ["Shift:Enter", "Ctrl:Enter"]
|
||||
},
|
||||
{
|
||||
"command": "generic:deleteItem",
|
||||
"keys": ["Backspace", "Delete"]
|
||||
},
|
||||
{
|
||||
"command": "generic:space",
|
||||
"keys": ["Space"]
|
||||
},
|
||||
{
|
||||
"command": "generic:tab",
|
||||
"keys": ["Tab"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-0",
|
||||
"keys": ["0"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-1",
|
||||
"keys": ["1"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-2",
|
||||
"keys": ["2"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-3",
|
||||
"keys": ["3"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-4",
|
||||
"keys": ["4"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-5",
|
||||
"keys": ["5"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-6",
|
||||
"keys": ["6"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-7",
|
||||
"keys": ["7"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-8",
|
||||
"keys": ["8"]
|
||||
},
|
||||
{
|
||||
"command": "generic:numpad-9",
|
||||
"keys": ["9"]
|
||||
},
|
||||
{
|
||||
"command": "generic:selectAbove",
|
||||
"keys": ["ArrowUp"]
|
||||
@@ -80,14 +27,6 @@
|
||||
"command": "generic:selectBelow",
|
||||
"keys": ["ArrowDown"]
|
||||
},
|
||||
{
|
||||
"command": "generic:selectLeft",
|
||||
"keys": ["ArrowLeft"]
|
||||
},
|
||||
{
|
||||
"command": "generic:selectRight",
|
||||
"keys": ["ArrowRight"]
|
||||
},
|
||||
{
|
||||
"command": "generic:selectPageAbove",
|
||||
"keys": ["PageUp"]
|
||||
@@ -128,8 +67,7 @@
|
||||
},
|
||||
{
|
||||
"command": "app:restartCommand",
|
||||
"keys": ["Cmd:r"],
|
||||
"info": "Restarts the command running in the current selected line"
|
||||
"keys": ["Cmd:r"]
|
||||
},
|
||||
{
|
||||
"command": "app:restartLastCommand",
|
||||
|
||||
+12
-20
@@ -6,7 +6,7 @@
|
||||
},
|
||||
"productName": "Wave",
|
||||
"description": "An Open-Source, AI-Native, Terminal Built for Seamless Workflows",
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.1",
|
||||
"main": "dist/emain.js",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
@@ -18,13 +18,12 @@
|
||||
"appId": "dev.commandline.waveterm"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lexical/react": "^0.14.3",
|
||||
"@monaco-editor/react": "^4.5.1",
|
||||
"@table-nav/core": "^0.0.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",
|
||||
"@types/semver": "^7.5.6",
|
||||
"autobind-decorator": "^2.4.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"classnames": "^2.3.1",
|
||||
@@ -33,14 +32,11 @@
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"electron-updater": "^6.1.8",
|
||||
"framer-motion": "^10.16.16",
|
||||
"lexical": "^0.14.3",
|
||||
"mobx": "6.12",
|
||||
"mobx-react": "^7.5.0",
|
||||
"monaco-editor": "^0.44.0",
|
||||
"mustache": "^4.2.0",
|
||||
"node-fetch": "^3.2.10",
|
||||
"overlayscrollbars": "^2.6.1",
|
||||
"overlayscrollbars-react": "^0.5.5",
|
||||
"papaparse": "^5.4.1",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
@@ -49,13 +45,11 @@
|
||||
"remark-gfm": "^4.0.0",
|
||||
"sprintf-js": "^1.1.2",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"tsx-control-statements": "^5.1.1",
|
||||
"tsx-control-statements": "^4.1.1",
|
||||
"uuid": "^9.0.0",
|
||||
"winston": "^3.8.2",
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-addon-serialize": "^0.11.0",
|
||||
"xterm-addon-web-links": "^0.9.0",
|
||||
"xterm-addon-webgl": "^0.16.0"
|
||||
"xterm": "^5.0.0",
|
||||
"xterm-addon-web-links": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.17.10",
|
||||
@@ -72,26 +66,24 @@
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@types/classnames": "^2.3.1",
|
||||
"@types/electron": "^1.6.10",
|
||||
"@types/node": "^20.11.0",
|
||||
"@types/node": "20.11.0",
|
||||
"@types/papaparse": "^5.3.10",
|
||||
"@types/react": "^18.0.12",
|
||||
"@types/semver": "^7.5.6",
|
||||
"@types/sprintf-js": "^1.1.3",
|
||||
"@types/throttle-debounce": "^5.0.1",
|
||||
"@types/uuid": "^9.0.7",
|
||||
"@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",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"electron": "^29.0.1",
|
||||
"electron": "29.0.1",
|
||||
"electron-builder": "^24.13.3",
|
||||
"electron-builder-squirrel-windows": "^24.13.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"http-server": "^14.1.1",
|
||||
"less": "^4.1.2",
|
||||
"less-loader": "^12.0.0",
|
||||
"less-loader": "^11.0.0",
|
||||
"lodash-webpack-plugin": "^0.11.6",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
"prettier": "^2.8.8",
|
||||
@@ -102,11 +94,11 @@
|
||||
"webpack": "^5.73.0",
|
||||
"webpack-bundle-analyzer": "^4.10.1",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^5.0.4",
|
||||
"webpack-dev-server": "^4.9.1",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"yaml": "^2.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "electron-builder install-app-deps"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<link rel="stylesheet" href="public/fontawesome/css/sharp-regular.min.css" />
|
||||
<link rel="stylesheet" href="dist-dev/waveterm.css" />
|
||||
|
||||
<link rel="stylesheet" id="theme-stylesheet" href="public/themes/themequery.css" />
|
||||
<link rel="stylesheet" id="theme-stylesheet" href="public/themes/default.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="measure"></div>
|
||||
|
||||
+6
-6
@@ -5,14 +5,14 @@
|
||||
<base href="../" />
|
||||
<script charset="UTF-8" src="dist/waveterm.js"></script>
|
||||
<link rel="stylesheet" href="public/bulma-0.9.4.min.css" />
|
||||
<link rel="stylesheet" href="public/fontawesome/css/fontawesome.min.css" />
|
||||
<link rel="stylesheet" href="public/fontawesome/css/brands.min.css" />
|
||||
<link rel="stylesheet" href="public/fontawesome/css/solid.min.css" />
|
||||
<link rel="stylesheet" href="public/fontawesome/css/sharp-solid.min.css" />
|
||||
<link rel="stylesheet" href="public/fontawesome/css/sharp-regular.min.css" />
|
||||
<link rel="stylesheet" href="public/fontawesome/css/fontawesome.min.css">
|
||||
<link rel="stylesheet" href="public/fontawesome/css/brands.min.css">
|
||||
<link rel="stylesheet" href="public/fontawesome/css/solid.min.css">
|
||||
<link rel="stylesheet" href="public/fontawesome/css/sharp-solid.min.css">
|
||||
<link rel="stylesheet" href="public/fontawesome/css/sharp-regular.min.css">
|
||||
<link rel="stylesheet" href="dist/waveterm.css" />
|
||||
|
||||
<link rel="stylesheet" id="theme-stylesheet" href="public/themes/themequery.css" />
|
||||
<link rel="stylesheet" id="theme-stylesheet" href="public/themes/default.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="measure"></div>
|
||||
|
||||
+16
-27
@@ -42,19 +42,16 @@
|
||||
--app-bg-color: black;
|
||||
--app-accent-color: rgb(88, 193, 66);
|
||||
--app-accent-bg-color: rgba(88, 193, 66, 0.25);
|
||||
--app-accent-bg-darker-color: rgba(88, 193, 66, 0.5);
|
||||
--app-text-color: rgb(211, 215, 207);
|
||||
--app-text-primary-color: rgb(255, 255, 255);
|
||||
--app-text-secondary-color: rgb(195, 200, 194);
|
||||
--app-text-disabled-color: rgb(173, 173, 173);
|
||||
--app-text-bg-color: rgb(23, 23, 23);
|
||||
--app-text-bg-disabled-color: rgb(51, 51, 51);
|
||||
--app-border-color: rgb(51, 51, 51);
|
||||
--app-maincontent-bg-color: rgb(51, 51, 51);
|
||||
--app-maincontent-bg-color: #333;
|
||||
--app-panel-bg-color: rgba(21, 23, 21, 1);
|
||||
--app-panel-bg-color-dev: rgb(21, 23, 48);
|
||||
--app-icon-color: rgb(139, 145, 138);
|
||||
--app-icon-hover-color: rgb(255, 255, 255);
|
||||
--app-icon-hover-color: #fff;
|
||||
--app-selected-mask-color: rgba(255, 255, 255, 0.06);
|
||||
|
||||
/* global status colors */
|
||||
@@ -70,7 +67,6 @@
|
||||
--scrollbar-background-color: var(--app-bg-color);
|
||||
--scrollbar-thumb-color: rgba(255, 255, 255, 0.3);
|
||||
--scrollbar-thumb-hover-color: rgba(255, 255, 255, 0.5);
|
||||
--scrollbar-thumb-active-color: rgba(255, 255, 255, 0.6);
|
||||
|
||||
/* code color */
|
||||
--pre-bg-color: rgb(0, 0, 0);
|
||||
@@ -90,7 +86,6 @@
|
||||
--form-element-border-color: rgba(241, 246, 243, 0.15);
|
||||
--form-element-bg-color: var(--app-bg-color);
|
||||
--form-element-text-color: var(--app-text-primary-color);
|
||||
--form-element-primary-text-color: var(--app-text-primary-color);
|
||||
--form-element-label-color: var(--app-text-secondary-color);
|
||||
--form-element-primary-color: var(--app-accent-color);
|
||||
--form-element-secondary-color: rgba(255, 255, 255, 0.2);
|
||||
@@ -117,7 +112,7 @@
|
||||
--hotkey-text-color: var(--app-text-secondary-color);
|
||||
|
||||
/* sidebar colors */
|
||||
--sidebar-highlight-color: var(--app-accent-bg-color);
|
||||
--sidebar-highlight-color: rgba(241, 246, 243, 0.08);
|
||||
--sidebar-font-size: 15px;
|
||||
--sidebar-line-height: 1.5;
|
||||
--sidebar-font-weight: normal;
|
||||
@@ -125,18 +120,18 @@
|
||||
|
||||
/* line colors */
|
||||
--line-sidebar-message-color: rgb(196, 160, 0);
|
||||
--line-background: var(--app-panel-bg-color);
|
||||
--line-avatar-color: rgb(236, 238, 236);
|
||||
--line-background: rgba(21, 23, 21, 1);
|
||||
--line-avatar-color: #eceeec;
|
||||
--line-text-color: rgb(211, 215, 207);
|
||||
--line-svg-fill-color: rgb(150, 152, 150);
|
||||
--line-svg-hover-fill-color: rgb(236, 238, 236);
|
||||
--line-svg-hover-fill-color: #eceeec;
|
||||
--line-separator-color: rgb(126, 126, 126);
|
||||
--line-error-color: var(--app-error-color);
|
||||
--line-warning-color: var(--app-warning-color);
|
||||
--line-base-soft-blue-color: rgb(114, 159, 207);
|
||||
--line-base-soft-blue-color: #729fcf;
|
||||
--line-active-border-color: var(--app-accent-color);
|
||||
--line-selected-bg-color: rgba(255, 255, 255, 0.05);
|
||||
--line-selected-border-left-color: rgb(119, 119, 119);
|
||||
--line-selected-border-left-color: #777777;
|
||||
--line-selected-error-border-color: rgba(204, 0, 0, 0.8);
|
||||
--line-selected-error-bg-color: rgb(19, 4, 3);
|
||||
--line-error-bg-color: rgba(200, 0, 0, 0.1);
|
||||
@@ -155,21 +150,22 @@
|
||||
/* table colors */
|
||||
--table-border-color: rgba(241, 246, 243, 0.15);
|
||||
--table-thead-border-top-color: rgba(250, 250, 250, 0.1);
|
||||
--table-thead-bright-border-color: rgb(204, 204, 204);
|
||||
--table-thead-bright-border-color: #ccc;
|
||||
--table-thead-bg-color: rgba(250, 250, 250, 0.02);
|
||||
--table-tr-border-bottom-color: rgba(241, 246, 243, 0.15);
|
||||
--table-tr-hover-bg-color: rgba(255, 255, 255, 0.06);
|
||||
--table-tr-selected-bg-color: rgb(34, 34, 34);
|
||||
--table-tr-selected-hover-bg-color: var(--app-maincontent-bg-color);
|
||||
--table-tr-selected-bg-color: #222;
|
||||
--table-tr-selected-hover-bg-color: #333;
|
||||
|
||||
/* cmdinput colors */
|
||||
--cmdinput-bg-color: var(--app-text-bg-color);
|
||||
--cmdinput-textarea-bg-color: #171717;
|
||||
--cmdinput-text-error-color: var(--term-red);
|
||||
--cmdinput-history-item-error-color: var(--term-bright-red);
|
||||
--cmdinput-history-item-selected-error-color: var(--term-bright-red);
|
||||
--cmdinput-button-bg-color: var(--tab-green);
|
||||
--cmdinput-disabled-bg-color: var(--app-text-bg-disabled-color);
|
||||
--cmdinput-history-bg-color: var(--app-bg-color);
|
||||
--cmdinput-button-bg-color: rgb(88, 193, 66);
|
||||
--cmdinput-comment-button-bg-color: rgb(57, 113, 255);
|
||||
--cmdinput-disabled-icon-color: rgb(76, 81, 75, 1);
|
||||
--cmdinput-history-bg-color: rgb(21, 23, 21, 1);
|
||||
|
||||
/* screen view color */
|
||||
--screen-view-text-caption-color: rgb(139, 145, 138);
|
||||
@@ -190,11 +186,4 @@
|
||||
--datepicker-header-fade-color: rgba(255, 255, 255, 0.4);
|
||||
--datepicker-year-header-bg-color: rgba(255, 255, 255, 0.2); /* Light grey background */
|
||||
--datepicker-year-header-border-color: rgba(241, 246, 243, 0.15); /* Light grey border */
|
||||
|
||||
/* OverlayScrollbars styling */
|
||||
.os-scrollbar {
|
||||
--os-handle-bg: var(--scrollbar-thumb-color);
|
||||
--os-handle-bg-hover: var(--scrollbar-thumb-hover-color);
|
||||
--os-handle-bg-active: var(--scrollbar-thumb-active-color);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-22
@@ -1,48 +1,53 @@
|
||||
/* Copyright 2024, Command Line Inc.
|
||||
SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
@import url("./term-default.css");
|
||||
@import url("./term-light.css");
|
||||
@import "./default.css";
|
||||
@import "./term-default.css";
|
||||
@import "./term-light.css";
|
||||
|
||||
:root {
|
||||
--app-bg-color: rgb(254, 254, 254);
|
||||
--app-bg-color: #fefefe;
|
||||
--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(23, 23, 23);
|
||||
--app-text-secondary-color: rgb(76, 76, 76);
|
||||
--app-text-color: #000;
|
||||
--app-text-primary-color: rgb(0, 0, 0, 0.9);
|
||||
--app-text-secondary-color: rgb(0, 0, 0, 0.7);
|
||||
--app-border-color: rgb(139 145 138);
|
||||
--app-panel-bg-color: rgb(224, 224, 224);
|
||||
--app-panel-bg-color-dev: rgb(224, 224, 224);
|
||||
--app-icon-color: rgb(110, 110, 110);
|
||||
--app-icon-hover-color: rgb(80, 80, 80);
|
||||
--app-panel-bg-color: #e0e0e0;
|
||||
--app-panel-bg-color-dev: #e0e0e0;
|
||||
--app-icon-color: rgb(80, 80, 80);
|
||||
--app-icon-hover-color: rgb(100, 100, 100);
|
||||
--app-selected-mask-color: rgba(0, 0, 0, 0.06);
|
||||
|
||||
--input-bg-color: rgb(238, 238, 238);
|
||||
--input-bg-color: #eeeeee;
|
||||
|
||||
/* tab color */
|
||||
--tab-white: rgb(0, 0, 0, 0.6);
|
||||
--tab-mint: rgb(70, 235, 156);
|
||||
|
||||
/* button colors */
|
||||
--button-text-color: rgb(50, 50, 50); /* Dark gray for light theme */
|
||||
--button-primary-color: #fefefe;
|
||||
--button-secondary-bg-color: rgba(200, 200, 200, 0.3); /* Semi-transparent light gray */
|
||||
|
||||
/* table colors */
|
||||
--table-thead-border-top-color: rgba(0, 0, 0, 0.2);
|
||||
--table-thead-border-bottom-color: rgba(0, 0, 0, 0.3);
|
||||
--table-thead-bg-color: rgba(250, 250, 250, 0.15);
|
||||
--table-tr-border-bottom-color: rgba(0, 0, 0, 0.15);
|
||||
--table-tr-hover-bg-color: rgba(0, 0, 0, 0.15);
|
||||
--table-tr-selected-bg-color: rgb(221, 221, 221);
|
||||
--table-tr-selected-hover-bg-color: rgb(204, 204, 204);
|
||||
--table-tr-selected-bg-color: #dddddd;
|
||||
--table-tr-selected-hover-bg-color: #cccccc;
|
||||
|
||||
/* form colors */
|
||||
--form-element-border-color: rgba(0, 0, 0, 0.3);
|
||||
--form-element-bg-color: var(--app-bg-color);
|
||||
--form-element-text-color: var(--app-text-primary-color);
|
||||
--form-element-primary-text-color: var(--app-text-primary-color);
|
||||
--form-element-text-color: var(--app-text-color);
|
||||
--form-element-label-color: rgba(0, 0, 0, 0.6);
|
||||
--form-element-secondary-color: rgba(0, 0, 0, 0.09);
|
||||
--form-element-icon-color: rgb(0, 0, 0, 0.6);
|
||||
--form-element-disabled-text-color: rgb(183, 183, 183);
|
||||
--form-element-placeholder-color: rgb(183, 183, 183);
|
||||
--form-element-disabled-text-color: #b7b7b7;
|
||||
--form-element-placeholder-color: #b7b7b7;
|
||||
|
||||
--markdown-bg-color: rgb(0, 0, 0, 0.1);
|
||||
|
||||
@@ -50,27 +55,28 @@
|
||||
--modal-header-bottom-border-color: rgba(0, 0, 0, 0.3);
|
||||
|
||||
/* cmd input */
|
||||
--cmdinput-textarea-bg-color: rgba(0, 0, 0, 0.1);
|
||||
--cmdinput-textarea-border-color: var(--form-element-border-color);
|
||||
|
||||
/* scroll colors */
|
||||
--scrollbar-background-color: var(--app-bg-color);
|
||||
--scrollbar-thumb-color: rgba(0, 0, 0, 0.2);
|
||||
--scrollbar-thumb-hover-color: rgba(0, 0, 0, 0.4);
|
||||
--scrollbar-thumb-active-color: rgba(0, 0, 0, 0.5);
|
||||
|
||||
/* line color */
|
||||
--line-actions-bg-color: rgba(0, 0, 0, 0.1);
|
||||
--line-actions-inactive-color: rgba(0, 0, 0, 0.3);
|
||||
--line-actions-active-color: rgba(0, 0, 0, 1);
|
||||
|
||||
--logo-button-hover-bg-color: rgb(240, 240, 240);
|
||||
--logo-button-hover-bg-color: #f0f0f0;
|
||||
|
||||
--xterm-viewport-border-color: rgba(0, 0, 0, 0.3);
|
||||
|
||||
--datepicker-cell-hover-bg-color: rgb(240, 240, 240);
|
||||
--datepicker-cell-hover-bg-color: #f0f0f0;
|
||||
--datepicker-cell-other-text-color: rgba(0, 0, 0, 0.3);
|
||||
--datepicker-header-fade-color: rgba(0, 0, 0, 0.4);
|
||||
--datepicker-year-header-bg-color: rgb(245, 245, 245);
|
||||
--datepicker-year-header-border-color: rgb(220, 220, 220);
|
||||
--datepicker-year-header-bg-color: #f5f5f5;
|
||||
--datepicker-year-header-border-color: #dcdcdc;
|
||||
|
||||
/* toggle colors */
|
||||
--toggle-thumb-color: var(--app-bg-color);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
@import url("./default.css") screen;
|
||||
|
||||
@import url("./light.css") screen and (prefers-color-scheme: light);
|
||||
+3
-3
@@ -44,7 +44,7 @@ rm -rf bin/
|
||||
rm -rf build/
|
||||
node_modules/.bin/webpack --env prod
|
||||
WAVESRV_VERSION=$(node -e 'console.log(require("./version.js"))')
|
||||
WAVESHELL_VERSION=v0.6
|
||||
WAVESHELL_VERSION=v0.5
|
||||
GO_LDFLAGS="-s -w -X main.BuildTime=$(date +'%Y%m%d%H%M')"
|
||||
function buildWaveShell {
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=$1 GOARCH=$2 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-$WAVESHELL_VERSION-$1.$2 main-waveshell.go)
|
||||
@@ -69,7 +69,7 @@ rm -rf bin/
|
||||
rm -rf build/
|
||||
node_modules/.bin/webpack --env prod
|
||||
WAVESRV_VERSION=$(node -e 'console.log(require("./version.js"))')
|
||||
WAVESHELL_VERSION=v0.6
|
||||
WAVESHELL_VERSION=v0.5
|
||||
GO_LDFLAGS="-s -w -X main.BuildTime=$(date +'%Y%m%d%H%M')"
|
||||
function buildWaveShell {
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=$1 GOARCH=$2 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-$WAVESHELL_VERSION-$1.$2 main-waveshell.go)
|
||||
@@ -96,7 +96,7 @@ CGO_ENABLED=1 go build -tags "osusergo,netgo,sqlite_omit_load_extension" -ldflag
|
||||
```bash
|
||||
# @scripthaus command fullbuild-waveshell
|
||||
set -e
|
||||
WAVESHELL_VERSION=v0.6
|
||||
WAVESHELL_VERSION=v0.5
|
||||
GO_LDFLAGS="-s -w -X main.BuildTime=$(date +'%Y%m%d%H%M')"
|
||||
function buildWaveShell {
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=$1 GOARCH=$2 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-$WAVESHELL_VERSION-$1.$2 main-waveshell.go)
|
||||
|
||||
+39
-77
@@ -251,13 +251,6 @@ input[type="checkbox"] {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-centered-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
a.a-block {
|
||||
display: block;
|
||||
}
|
||||
@@ -793,75 +786,6 @@ a.a-block {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.conn-dropdown {
|
||||
width: 412px;
|
||||
|
||||
.lefticon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 16px;
|
||||
transform: translateY(-50%);
|
||||
|
||||
.globe-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
fill: var(--app-text-secondary-color);
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
position: absolute;
|
||||
left: 7px;
|
||||
top: 8px;
|
||||
circle {
|
||||
stroke: var(--app-bg-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wave-dropdown-display {
|
||||
bottom: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-colors,
|
||||
.tab-icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.tab-color-sep,
|
||||
.tab-icon-sep {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tab-color-icon,
|
||||
.tab-icon-icon {
|
||||
width: 1.1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tab-color-name,
|
||||
.tab-icon-name {
|
||||
display: inline-block;
|
||||
margin-left: 1em;
|
||||
min-width: 70px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tab-color-select,
|
||||
.tab-icon-select {
|
||||
cursor: pointer;
|
||||
margin: 3px;
|
||||
&:hover {
|
||||
outline: 2px solid white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settings-field {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -923,7 +847,7 @@ a.a-block {
|
||||
}
|
||||
}
|
||||
|
||||
input:not(.wave-input) {
|
||||
input {
|
||||
padding: 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
@@ -934,6 +858,44 @@ a.a-block {
|
||||
}
|
||||
}
|
||||
|
||||
.tab-colors,
|
||||
.tab-icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.tab-color-sep,
|
||||
.tab-icon-sep {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tab-color-icon,
|
||||
.tab-icon-icon {
|
||||
width: 1.1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tab-color-name,
|
||||
.tab-icon-name {
|
||||
display: inline-block;
|
||||
margin-left: 1em;
|
||||
min-width: 70px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tab-color-select,
|
||||
.tab-icon-select {
|
||||
cursor: pointer;
|
||||
margin: 3px;
|
||||
&:hover {
|
||||
outline: 2px solid white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-text {
|
||||
margin-left: 20px;
|
||||
|
||||
|
||||
+6
-6
@@ -8,7 +8,7 @@ import { boundMethod } from "autobind-decorator";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import dayjs from "dayjs";
|
||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||
import { GlobalModel } from "@/models";
|
||||
import { GlobalCommandRunner, GlobalModel } from "@/models";
|
||||
import { isBlank } from "@/util/util";
|
||||
import { WorkspaceView } from "./workspace/workspaceview";
|
||||
import { PluginsView } from "./pluginsview/pluginsview";
|
||||
@@ -101,7 +101,7 @@ class App extends React.Component<{}, {}> {
|
||||
return (
|
||||
<div id="main" className={"platform-" + platform} onContextMenu={this.handleContextMenu}>
|
||||
<div ref={this.mainContentRef} className="main-content">
|
||||
<MainSideBar parentRef={this.mainContentRef} />
|
||||
<MainSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||
<div className="session-view" />
|
||||
</div>
|
||||
<If condition={dcWait}>
|
||||
@@ -123,7 +123,7 @@ class App extends React.Component<{}, {}> {
|
||||
const mainSidebarCollapsed = GlobalModel.mainSidebarModel.getCollapsed();
|
||||
const rightSidebarCollapsed = GlobalModel.rightSidebarModel.getCollapsed();
|
||||
const activeMainView = GlobalModel.activeMainView.get();
|
||||
const lightDarkClass = GlobalModel.isDarkTheme.get() ? "is-dark" : "is-light";
|
||||
const lightDarkClass = GlobalModel.isThemeDark() ? "is-dark" : "is-light";
|
||||
return (
|
||||
<div
|
||||
key={"version-" + renderVersion}
|
||||
@@ -146,12 +146,12 @@ class App extends React.Component<{}, {}> {
|
||||
<If condition={GlobalModel.isDev && rightSidebarCollapsed && activeMainView == "session"}>
|
||||
<div className="right-sidebar-triggers">
|
||||
<Button className="secondary ghost right-sidebar-trigger" onClick={this.openRightSidebar}>
|
||||
<i className="fa-sharp fa-solid fa-sidebar-flip"></i>
|
||||
<i className="fa-sharp fa-regular fa-lightbulb"></i>
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<div ref={this.mainContentRef} className="main-content">
|
||||
<MainSideBar parentRef={this.mainContentRef} />
|
||||
<MainSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||
<ErrorBoundary>
|
||||
<PluginsView />
|
||||
<WorkspaceView />
|
||||
@@ -160,7 +160,7 @@ class App extends React.Component<{}, {}> {
|
||||
<ConnectionsView model={remotesModel} />
|
||||
<ClientSettingsView model={remotesModel} />
|
||||
</ErrorBoundary>
|
||||
<RightSideBar parentRef={this.mainContentRef} />
|
||||
<RightSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||
</div>
|
||||
<ModalsProvider />
|
||||
</div>
|
||||
|
||||
@@ -64,8 +64,3 @@ export enum StatusIndicatorLevel {
|
||||
|
||||
// matches packet.go
|
||||
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";
|
||||
|
||||
@@ -6,14 +6,13 @@ import * as mobxReact from "mobx-react";
|
||||
import * as mobx from "mobx";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "@/models";
|
||||
import { GlobalModel, GlobalCommandRunner, RemotesModel, getApi } from "@/models";
|
||||
import { Toggle, InlineSettingsTextEdit, SettingsError, Dropdown } from "@/common/elements";
|
||||
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() {
|
||||
@@ -65,25 +64,11 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeThemeSource(themeSource: NativeThemeSource): void {
|
||||
if (GlobalModel.getThemeSource() == themeSource) {
|
||||
handleChangeTheme(theme: string): void {
|
||||
if (GlobalModel.getTheme() == theme) {
|
||||
return;
|
||||
}
|
||||
const prtn = GlobalCommandRunner.setTheme(themeSource, false);
|
||||
GlobalModel.getElectronApi().setNativeThemeSource(themeSource);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeTermTheme(theme: string): void {
|
||||
// For global terminal theme, the key is global, otherwise it's either
|
||||
// sessionId or screenId.
|
||||
const currTheme = GlobalModel.getTermTheme()["global"];
|
||||
if (currTheme == theme) {
|
||||
return;
|
||||
}
|
||||
|
||||
const prtn = GlobalCommandRunner.setGlobalTermTheme(theme, false);
|
||||
const prtn = GlobalCommandRunner.setTheme(theme, false);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@@ -107,13 +92,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
prtn = GlobalCommandRunner.releaseCheckAutoOff(false);
|
||||
}
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
GlobalModel.getElectronApi().changeAutoUpdate(val);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeAutocompleteEnabled(val: boolean): void {
|
||||
const prtn: Promise<CommandRtnType> = GlobalCommandRunner.setAutocompleteEnabled(val);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
getApi().changeAutoUpdate(val);
|
||||
}
|
||||
|
||||
getFontSizes(): DropdownItem[] {
|
||||
@@ -132,12 +111,11 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
return availableFontFamilies;
|
||||
}
|
||||
|
||||
getThemeSources(): DropdownItem[] {
|
||||
const themeSources: DropdownItem[] = [];
|
||||
themeSources.push({ label: "Dark", value: "dark" });
|
||||
themeSources.push({ label: "Light", value: "light" });
|
||||
themeSources.push({ label: "System", value: "system" });
|
||||
return themeSources;
|
||||
getThemes(): DropdownItem[] {
|
||||
const themes: DropdownItem[] = [];
|
||||
themes.push({ label: "Dark", value: "dark" });
|
||||
themes.push({ label: "Light", value: "light" });
|
||||
return themes;
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
@@ -212,9 +190,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
);
|
||||
const curFontSize = GlobalModel.getTermFontSize();
|
||||
const curFontFamily = GlobalModel.getTermFontFamily();
|
||||
const curTheme = GlobalModel.getThemeSource();
|
||||
const termThemes = getTermThemes(GlobalModel.termThemes, "Wave Default");
|
||||
const currTermTheme = GlobalModel.getTermTheme()["global"] ?? termThemes[0].label;
|
||||
const curTheme = GlobalModel.getTheme();
|
||||
|
||||
return (
|
||||
<MainView className="clientsettings-view" title="Client Settings" onClose={this.handleClose}>
|
||||
@@ -249,25 +225,12 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
<div className="settings-input">
|
||||
<Dropdown
|
||||
className="theme-dropdown"
|
||||
options={this.getThemeSources()}
|
||||
options={this.getThemes()}
|
||||
defaultValue={curTheme}
|
||||
onChange={this.handleChangeThemeSource}
|
||||
onChange={this.handleChangeTheme}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<If condition={termThemes.length > 0}>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Terminal Theme</div>
|
||||
<div className="settings-input">
|
||||
<Dropdown
|
||||
className="terminal-theme-dropdown"
|
||||
options={termThemes}
|
||||
defaultValue={currTermTheme}
|
||||
onChange={this.handleChangeTermTheme}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</If>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Client ID</div>
|
||||
<div className="settings-input">{cdata.clientid}</div>
|
||||
@@ -318,7 +281,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
text={isBlank(openAIOpts.baseurl) ? "openai default" : openAIOpts.baseurl}
|
||||
value={openAIOpts.baseurl ?? ""}
|
||||
onChange={this.inlineUpdateOpenAIBaseURL}
|
||||
maxLength={200}
|
||||
maxLength={10}
|
||||
showIcon={true}
|
||||
/>
|
||||
</div>
|
||||
@@ -360,15 +323,6 @@ 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>
|
||||
<SettingsError errorMessage={this.errorMessage} />
|
||||
</div>
|
||||
</MainView>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
border-radius: 6px;
|
||||
height: auto;
|
||||
line-height: 1.5;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
|
||||
@@ -20,17 +21,13 @@
|
||||
}
|
||||
|
||||
&.primary {
|
||||
color: var(--form-element-primary-text-color);
|
||||
color: var(--form-element-text-color);
|
||||
background: var(--form-element-primary-color);
|
||||
i {
|
||||
fill: var(--form-element-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.danger {
|
||||
background: var(--app-error-color);
|
||||
}
|
||||
|
||||
&.primary.outlined {
|
||||
background: none;
|
||||
border: 1px solid var(--form-element-primary-color);
|
||||
@@ -40,37 +37,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.greyoutlined {
|
||||
background: none;
|
||||
border: 1px solid var(--app-text-secondary-color);
|
||||
|
||||
i {
|
||||
fill: var(--app-text-secondary-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.outlined,
|
||||
&.primary.greyoutlined {
|
||||
&.hover-danger:hover {
|
||||
color: var(--form-element-primary-text-color);
|
||||
border: 1px solid var(--app-error-color);
|
||||
background: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.outlined.danger {
|
||||
background: none;
|
||||
border: 1px solid var(--app-error-color);
|
||||
|
||||
i {
|
||||
fill: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.greytext {
|
||||
color: var(--app-text-secondary-color);
|
||||
}
|
||||
|
||||
&.primary.ghost {
|
||||
background: none;
|
||||
i {
|
||||
@@ -78,13 +44,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.ghost.danger {
|
||||
background: none;
|
||||
i {
|
||||
fill: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
color: var(--form-element-text-color);
|
||||
background: var(--form-element-secondary-color);
|
||||
@@ -98,11 +57,6 @@
|
||||
border: 1px solid var(--form-element-text-color);
|
||||
}
|
||||
|
||||
&.secondary.outlined.danger {
|
||||
background: none;
|
||||
border: 1px solid var(--app-error-color);
|
||||
}
|
||||
|
||||
&.secondary.ghost {
|
||||
background: none;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import "./button.less";
|
||||
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode;
|
||||
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
onClick?: () => void;
|
||||
disabled?: boolean;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
@@ -14,7 +14,6 @@ interface ButtonProps {
|
||||
autoFocus?: boolean;
|
||||
className?: string;
|
||||
termInline?: boolean;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
class Button extends React.Component<ButtonProps> {
|
||||
@@ -24,14 +23,14 @@ class Button extends React.Component<ButtonProps> {
|
||||
};
|
||||
|
||||
@boundMethod
|
||||
handleClick(e) {
|
||||
handleClick() {
|
||||
if (this.props.onClick && !this.props.disabled) {
|
||||
this.props.onClick(e);
|
||||
this.props.onClick();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { leftIcon, rightIcon, children, disabled, style, autoFocus, termInline, className, title } = this.props;
|
||||
const { leftIcon, rightIcon, children, disabled, style, autoFocus, termInline, className } = this.props;
|
||||
|
||||
return (
|
||||
<button
|
||||
@@ -40,7 +39,6 @@ class Button extends React.Component<ButtonProps> {
|
||||
disabled={disabled}
|
||||
style={style}
|
||||
autoFocus={autoFocus}
|
||||
title={title}
|
||||
>
|
||||
{leftIcon && <span className="icon-left">{leftIcon}</span>}
|
||||
{children}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
.copy-button {
|
||||
padding: 5px 5px;
|
||||
|
||||
.fa-check {
|
||||
color: var(--app-success-color);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { Button } from "./button";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import * as mobx from "mobx";
|
||||
|
||||
import "./copybutton.less";
|
||||
|
||||
type CopyButtonProps = {
|
||||
title: string;
|
||||
onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
};
|
||||
|
||||
@mobxReact.observer
|
||||
class CopyButton extends React.Component<CopyButtonProps, {}> {
|
||||
isCopied: OV<boolean> = mobx.observable.box(false, { name: "isCopied" });
|
||||
|
||||
@boundMethod
|
||||
handleOnClick(e: React.MouseEvent<HTMLButtonElement>) {
|
||||
if (this.isCopied.get()) {
|
||||
return;
|
||||
}
|
||||
mobx.action(() => {
|
||||
this.isCopied.set(true);
|
||||
})();
|
||||
setTimeout(() => {
|
||||
mobx.action(() => {
|
||||
this.isCopied.set(false);
|
||||
})();
|
||||
}, 2000);
|
||||
if (this.props.onClick) {
|
||||
this.props.onClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { title, onClick } = this.props;
|
||||
const isCopied = this.isCopied.get();
|
||||
return (
|
||||
<Button onClick={this.handleOnClick} className="copy-button secondary ghost" title={title}>
|
||||
{isCopied ? (
|
||||
<i className="fa-sharp fa-solid fa-check"></i>
|
||||
) : (
|
||||
<i className="fa-sharp fa-solid fa-copy"></i>
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { CopyButton };
|
||||
@@ -22,7 +22,6 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--form-element-bg-color);
|
||||
|
||||
input {
|
||||
outline: none !important;
|
||||
@@ -30,7 +29,6 @@
|
||||
height: 100%;
|
||||
padding: 0 !important;
|
||||
cursor: default !important;
|
||||
background-color: inherit !important;
|
||||
}
|
||||
|
||||
.fa-calendar {
|
||||
@@ -101,7 +99,6 @@
|
||||
background-color: var(--datepicker-cell-hover-bg-color);
|
||||
}
|
||||
&.selected {
|
||||
color: var(--form-element-primary-text-color);
|
||||
background-color: var(--form-element-primary-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -160,7 +157,6 @@
|
||||
}
|
||||
|
||||
&.selected {
|
||||
color: var(--form-element-primary-text-color);
|
||||
background-color: var(--form-element-primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import React, { useState, useEffect, useRef, createRef } from "react";
|
||||
import * as mobx from "mobx";
|
||||
import ReactDOM from "react-dom";
|
||||
import dayjs from "dayjs";
|
||||
import cn from "classnames";
|
||||
import cs from "classnames";
|
||||
import { Button } from "@/elements";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import { GlobalModel } from "@/models";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import "./datepicker.less";
|
||||
|
||||
@@ -39,10 +36,6 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
MM: selDate.format("MM"),
|
||||
DD: selDate.format("DD"),
|
||||
});
|
||||
const curUuid = uuidv4();
|
||||
const keybindsRegistered = mobx.observable.box(false, {
|
||||
name: "datepicker-keybinds-registered",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
inputRefs.current = {
|
||||
@@ -90,6 +83,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
const newDate = dayjs(date);
|
||||
setSelDate(newDate); // Update selDate with the new dayjs object
|
||||
onSelectDate && onSelectDate(date); // Call parent's onSelectDate
|
||||
setIsOpen(false); // Close the picker
|
||||
};
|
||||
|
||||
const changeMonth = (delta: number) => {
|
||||
@@ -102,7 +96,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
return (
|
||||
<div className="day-picker-header">
|
||||
<div
|
||||
className={cn({ fade: showYearAccordion })}
|
||||
className={cs({ fade: showYearAccordion })}
|
||||
onClick={() => {
|
||||
if (!showYearAccordion) {
|
||||
setExpandedYear(selDate.year()); // Set expandedYear when opening accordion
|
||||
@@ -111,7 +105,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
}}
|
||||
>
|
||||
{selDate.format("MMMM YYYY")}
|
||||
<span className={cn("dropdown-arrow", { fade: showYearAccordion })}></span>
|
||||
<span className={cs("dropdown-arrow", { fade: showYearAccordion })}></span>
|
||||
</div>
|
||||
<If condition={!showYearAccordion}>
|
||||
<div className="arrows">
|
||||
@@ -182,9 +176,9 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
}
|
||||
|
||||
// Next month's filler days
|
||||
let overFlowIndex = 1;
|
||||
while (days.length < 42) {
|
||||
const dayDate = endDay.add(overFlowIndex++, "day");
|
||||
const fillerDayCount = days.length - daysInPreviousMonth - endDay.date();
|
||||
const dayDate = endDay.add(fillerDayCount + 1, "day");
|
||||
days.push(
|
||||
<div
|
||||
key={`next-month-day-${dayDate.format("YYYY-MM-DD")}`}
|
||||
@@ -250,14 +244,14 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
</div>
|
||||
<If condition={expandedYear === year}>
|
||||
<div
|
||||
className={cn("month-container", {
|
||||
className={cs("month-container", {
|
||||
expanded: expandedYear === year,
|
||||
})}
|
||||
>
|
||||
{Array.from({ length: 12 }, (_, i) => i + 1).map((month) => (
|
||||
<div
|
||||
key={month}
|
||||
className={cn("month", {
|
||||
className={cs("month", {
|
||||
selected: year === currentYear && month === selDate.month() + 1,
|
||||
})}
|
||||
onClick={() => handleMonthYearSelect(month, year)}
|
||||
@@ -279,11 +273,6 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
setShowYearAccordion(false);
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
setIsOpen(false);
|
||||
setShowYearAccordion(false);
|
||||
};
|
||||
|
||||
const dayPickerModal = isOpen
|
||||
? ReactDOM.createPortal(
|
||||
<div ref={modalRef} className="day-picker-modal" style={calculatePosition()}>
|
||||
@@ -300,7 +289,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
)
|
||||
: null;
|
||||
|
||||
const handleDatePartChange = (part: string, value: string) => {
|
||||
const handleDatePartChange = (part, value) => {
|
||||
const newDateParts = { ...dateParts, [part]: value };
|
||||
setDateParts(newDateParts);
|
||||
|
||||
@@ -311,13 +300,13 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
}
|
||||
};
|
||||
|
||||
const handleArrowNavigation = (key: string, currentPart: string) => {
|
||||
const handleArrowNavigation = (event, currentPart) => {
|
||||
const currentIndex = formatParts.indexOf(currentPart);
|
||||
let targetInput;
|
||||
|
||||
if (key == "ArrowLeft" && currentIndex > 0) {
|
||||
if (event.key === "ArrowLeft" && currentIndex > 0) {
|
||||
targetInput = inputRefs.current[formatParts[currentIndex - 1]].current;
|
||||
} else if (key == "ArrowRight" && currentIndex < formatParts.length - 1) {
|
||||
} else if (event.key === "ArrowRight" && currentIndex < formatParts.length - 1) {
|
||||
targetInput = inputRefs.current[formatParts[currentIndex + 1]].current;
|
||||
}
|
||||
|
||||
@@ -326,86 +315,51 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = (event, currentPart: string) => {};
|
||||
const handleKeyDown = (event, currentPart) => {
|
||||
const key = event.key;
|
||||
|
||||
const handleFocus = (event, part: string) => {
|
||||
event.target.select();
|
||||
registerKeybindings(event, part);
|
||||
};
|
||||
|
||||
const registerKeybindings = (event: any, part: string) => {
|
||||
if (keybindsRegistered.get() == true) {
|
||||
if (key === "ArrowLeft" || key === "ArrowRight") {
|
||||
// Handle arrow navigation without selecting text
|
||||
handleArrowNavigation(event, currentPart);
|
||||
return;
|
||||
}
|
||||
mobx.action(() => {
|
||||
keybindsRegistered.set(true);
|
||||
})();
|
||||
const keybindManager = GlobalModel.keybindManager;
|
||||
const domain = "datepicker-" + curUuid + "-" + part;
|
||||
keybindManager.registerKeybinding("control", domain, "generic:selectLeft", (_) => {
|
||||
handleArrowNavigation("ArrowLeft", part);
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:selectRight", (_) => {
|
||||
handleArrowNavigation("ArrowRight", part);
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:space", (_) => {
|
||||
toggleModal();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:confirm", (_) => {
|
||||
toggleModal();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:cancel", (_) => {
|
||||
closeModal();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:tab", (_) => {
|
||||
handleArrowNavigation("ArrowRight", part);
|
||||
return true;
|
||||
});
|
||||
for (let numpadKey = 0; numpadKey <= 9; numpadKey++) {
|
||||
keybindManager.registerKeybinding("control", domain, "generic:numpad-" + numpadKey.toString(), (_) => {
|
||||
const currentPart = part;
|
||||
const maxLength = currentPart === "YYYY" ? 4 : 2;
|
||||
const newValue = event.target.value.length < maxLength ? event.target.value + numpadKey : numpadKey;
|
||||
let selectionTimeoutId = null;
|
||||
handleDatePartChange(currentPart, newValue);
|
||||
|
||||
// Clear any existing timeout
|
||||
if (selectionTimeoutId !== null) {
|
||||
clearTimeout(selectionTimeoutId);
|
||||
}
|
||||
if (key === " ") {
|
||||
// Handle spacebar press to toggle the modal
|
||||
toggleModal();
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-focus and select the input after state update
|
||||
selectionTimeoutId = setTimeout(() => {
|
||||
event.target.focus();
|
||||
event.target.select();
|
||||
}, 0);
|
||||
return true;
|
||||
});
|
||||
if (key.match(/[0-9]/)) {
|
||||
// Handle numeric keys
|
||||
event.preventDefault();
|
||||
const maxLength = currentPart === "YYYY" ? 4 : 2;
|
||||
const newValue = event.target.value.length < maxLength ? event.target.value + key : key;
|
||||
let selectionTimeoutId = null;
|
||||
handleDatePartChange(currentPart, newValue);
|
||||
|
||||
// Clear any existing timeout
|
||||
if (selectionTimeoutId !== null) {
|
||||
clearTimeout(selectionTimeoutId);
|
||||
}
|
||||
|
||||
// Re-focus and select the input after state update
|
||||
selectionTimeoutId = setTimeout(() => {
|
||||
event.target.focus();
|
||||
event.target.select();
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = (event, part: string) => {
|
||||
unregisterKeybindings(part);
|
||||
};
|
||||
|
||||
const unregisterKeybindings = (part: string) => {
|
||||
mobx.action(() => {
|
||||
keybindsRegistered.set(false);
|
||||
})();
|
||||
const domain = "datepicker-" + curUuid + "-" + part;
|
||||
GlobalModel.keybindManager.unregisterDomain(domain);
|
||||
const handleFocus = (event) => {
|
||||
event.target.select();
|
||||
};
|
||||
|
||||
// Prevent use from selecting text in the input
|
||||
const handleMouseDown = (event, part: string) => {
|
||||
const handleMouseDown = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
handleFocus(event, part);
|
||||
handleFocus(event);
|
||||
};
|
||||
|
||||
const handleIconKeyDown = (event) => {
|
||||
@@ -459,9 +413,8 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
value={dateParts[part]}
|
||||
onChange={(e) => handleDatePartChange(part, e.target.value)}
|
||||
onKeyDown={(e) => handleKeyDown(e, part)}
|
||||
onMouseDown={(e) => handleMouseDown(e, part)}
|
||||
onFocus={(e) => handleFocus(e, part)}
|
||||
onBlur={(e) => handleBlur(e, part)}
|
||||
onMouseDown={handleMouseDown}
|
||||
onFocus={handleFocus}
|
||||
maxLength={part === "YYYY" ? 4 : 2}
|
||||
className="date-input"
|
||||
placeholder={part}
|
||||
|
||||
@@ -7,8 +7,6 @@ import { boundMethod } from "autobind-decorator";
|
||||
import cn from "classnames";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import ReactDOM from "react-dom";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { GlobalModel } from "@/models";
|
||||
|
||||
import "./dropdown.less";
|
||||
|
||||
@@ -41,7 +39,6 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
wrapperRef: React.RefObject<HTMLDivElement>;
|
||||
menuRef: React.RefObject<HTMLDivElement>;
|
||||
timeoutId: any;
|
||||
curUuid: string;
|
||||
|
||||
constructor(props: DropdownProps) {
|
||||
super(props);
|
||||
@@ -53,7 +50,6 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
};
|
||||
this.wrapperRef = React.createRef();
|
||||
this.menuRef = React.createRef();
|
||||
this.curUuid = uuidv4();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -100,90 +96,56 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
|
||||
@boundMethod
|
||||
handleClick() {
|
||||
if (!this.state.isOpen || !this.state.isTouched) {
|
||||
this.registerKeybindings();
|
||||
}
|
||||
this.toggleDropdown();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleFocus() {
|
||||
this.setState({ isTouched: true });
|
||||
this.registerKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
registerKeybindings() {
|
||||
let keybindManager = GlobalModel.keybindManager;
|
||||
let domain = "dropdown-" + this.curUuid;
|
||||
keybindManager.registerKeybinding("control", domain, "generic:confirm", (waveEvent) => {
|
||||
this.handleConfirm();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:space", (waveEvent) => {
|
||||
this.handleConfirm();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:cancel", (waveEvent) => {
|
||||
this.setState({ isOpen: false });
|
||||
this.unregisterKeybindings();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:selectAbove", (waveEvent) => {
|
||||
const { isOpen } = this.state;
|
||||
const { options } = this.props;
|
||||
if (isOpen) {
|
||||
this.setState((prevState) => ({
|
||||
highlightedIndex:
|
||||
prevState.highlightedIndex > 0 ? prevState.highlightedIndex - 1 : options.length - 1,
|
||||
}));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:selectBelow", (waveEvent) => {
|
||||
const { isOpen } = this.state;
|
||||
const { options } = this.props;
|
||||
if (isOpen) {
|
||||
this.setState((prevState) => ({
|
||||
highlightedIndex:
|
||||
prevState.highlightedIndex < options.length - 1 ? prevState.highlightedIndex + 1 : 0,
|
||||
}));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:tab", (waveEvent) => {
|
||||
this.setState({ isOpen: false });
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
handleConfirm() {
|
||||
handleKeyDown(event: React.KeyboardEvent) {
|
||||
const { options } = this.props;
|
||||
const { isOpen, highlightedIndex } = this.state;
|
||||
if (isOpen) {
|
||||
const option = options[highlightedIndex];
|
||||
if (option) {
|
||||
this.handleSelect(option.value, undefined);
|
||||
}
|
||||
} else {
|
||||
this.toggleDropdown();
|
||||
|
||||
switch (event.key) {
|
||||
case "Enter":
|
||||
case " ":
|
||||
if (isOpen) {
|
||||
const option = options[highlightedIndex];
|
||||
if (option) {
|
||||
this.handleSelect(option.value, undefined);
|
||||
}
|
||||
} else {
|
||||
this.toggleDropdown();
|
||||
}
|
||||
break;
|
||||
case "Escape":
|
||||
this.setState({ isOpen: false });
|
||||
break;
|
||||
case "ArrowUp":
|
||||
if (isOpen) {
|
||||
this.setState((prevState) => ({
|
||||
highlightedIndex:
|
||||
prevState.highlightedIndex > 0 ? prevState.highlightedIndex - 1 : options.length - 1,
|
||||
}));
|
||||
}
|
||||
break;
|
||||
case "ArrowDown":
|
||||
if (isOpen) {
|
||||
this.setState((prevState) => ({
|
||||
highlightedIndex:
|
||||
prevState.highlightedIndex < options.length - 1 ? prevState.highlightedIndex + 1 : 0,
|
||||
}));
|
||||
}
|
||||
break;
|
||||
case "Tab":
|
||||
this.setState({ isOpen: false });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleBlur() {
|
||||
this.unregisterKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
unregisterKeybindings() {
|
||||
let domain = "dropdown-" + this.curUuid;
|
||||
GlobalModel.keybindManager.unregisterDomain(domain);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleKeyDown(event: React.KeyboardEvent) {}
|
||||
|
||||
@boundMethod
|
||||
handleSelect(value: string, event?: React.MouseEvent | React.KeyboardEvent) {
|
||||
const { onChange } = this.props;
|
||||
@@ -196,7 +158,6 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
}
|
||||
onChange(value);
|
||||
this.setState({ isOpen: false, isTouched: true });
|
||||
this.unregisterKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
@@ -267,8 +228,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
tabIndex={0}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onClick={this.handleClick}
|
||||
onFocus={this.handleFocus.bind(this)}
|
||||
onBlur={this.handleBlur.bind(this)}
|
||||
onFocus={this.handleFocus}
|
||||
>
|
||||
{decoration?.startDecoration && <>{decoration.startDecoration}</>}
|
||||
<If condition={label}>
|
||||
|
||||
@@ -18,4 +18,3 @@ export { Toggle } from "./toggle";
|
||||
export { Tooltip } from "./tooltip";
|
||||
export { TabIcon } from "./tabicon";
|
||||
export { DatePicker } from "./datepicker";
|
||||
export { CopyButton } from "./copybutton";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user