mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d3eac06d7a | |||
| 5ad6a803b0 | |||
| bd366e99f3 | |||
| 4cb89e02df | |||
| c711d32f54 | |||
| 89f117b922 | |||
| 03cdc067e7 | |||
| 6c3e5b8746 | |||
| e1a931056c | |||
| 1c2c0c5efc | |||
| f6881cf380 | |||
| 345356d8d4 | |||
| 8cea209823 | |||
| a16e01f73b | |||
| 8c63be4ea0 | |||
| 35e0488f7b | |||
| c53e0a99f6 | |||
| e6df2c216d | |||
| c6a8797ddd | |||
| ac91fa8596 | |||
| 50662c2152 | |||
| 4296856cc1 | |||
| d0867477ff | |||
| 25b77c7fee | |||
| db557e0b69 | |||
| 22c5d224bd | |||
| 4f32c459a6 | |||
| a449cec33a | |||
| 5e3243564b | |||
| fcf8e4ed44 | |||
| 21d0dd076b | |||
| 6e28151dad | |||
| 12e267ad81 | |||
| 35037ac1f1 | |||
| 0649a73d84 | |||
| 50203a6934 | |||
| 8f93b3e263 | |||
| eadfb92f94 | |||
| a50db14b3e | |||
| 6308c6c4b0 | |||
| cdfc446763 | |||
| b08aaa03fb | |||
| 64244626a1 | |||
| c683d10008 | |||
| 265cc30347 | |||
| e04c5af41d | |||
| 2b0b206614 | |||
| 7c63e24525 | |||
| 8fdcf10cae | |||
| 6336f87cf2 | |||
| 39ee41921f | |||
| 2913babea7 | |||
| a787a1a934 | |||
| bf447c60ce | |||
| d923de412a | |||
| 15485d7235 | |||
| 59aef86e77 | |||
| 5353f40a20 | |||
| f86f010a34 | |||
| 73e5515e17 | |||
| 6919dbfb5f | |||
| 1f5309e097 | |||
| af7cc866d3 | |||
| 37e56acf63 | |||
| 70088afdb5 | |||
| 455790416d | |||
| eed234a131 | |||
| 5a6575a393 | |||
| 84cea373a8 | |||
| 181e14f55c | |||
| 1c23701181 | |||
| 0fe767cdf3 | |||
| 097623ab51 | |||
| 9de25e4869 | |||
| a139633375 | |||
| ccc63937b6 | |||
| dc7fc2c823 | |||
| ca5117cda0 | |||
| f41ac1d5e3 | |||
| 0024f0f3e8 | |||
| 8a3d9628ba | |||
| 7c2265f3e3 | |||
| 4f6c2ee39b | |||
| a1e4e807cc | |||
| 5c85b2b786 | |||
| 4879e90e91 | |||
| a61310afc3 | |||
| 80c781bf4c | |||
| 33400e65ff | |||
| 7b58949027 | |||
| 3be96c949d | |||
| 052645e0df |
@@ -1,26 +1,65 @@
|
||||
name: TestDriver.ai Regression Testing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
branches:
|
||||
- main
|
||||
schedule:
|
||||
- cron: "0 21 * * *" # every day at 9pm
|
||||
workflow_dispatch:
|
||||
- cron: 0 21 * * *
|
||||
workflow_dispatch: null
|
||||
|
||||
permissions:
|
||||
contents: read # To allow the action to read repository contents
|
||||
pull-requests: write # To allow the action to create/update pull request comments
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: "TestDriver"
|
||||
name: TestDriver
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dashcamio/testdriver@main
|
||||
id: testdriver
|
||||
# note that .testdriver/prerun.sh runs before this, so the app has launched already
|
||||
with:
|
||||
version: v2.10.2
|
||||
prerun: |
|
||||
rm ~/Desktop/WITH-LOVE-FROM-AMERICA.txt
|
||||
cd ~/actions-runner/_work/testdriver/testdriver/
|
||||
brew install go
|
||||
brew tap scripthaus-dev/scripthaus
|
||||
brew install scripthaus
|
||||
npm install -g yarn
|
||||
scripthaus run build-backend
|
||||
echo "Yarn"
|
||||
yarn
|
||||
echo "Rebuild"
|
||||
scripthaus run electron-rebuild
|
||||
echo "Webpack"
|
||||
scripthaus run webpack-build
|
||||
echo "Starting Electron"
|
||||
scripthaus run electron 1>/dev/null 2>&1 &
|
||||
echo "Electron Done"
|
||||
exit
|
||||
prompt: |
|
||||
2. click "Continue"
|
||||
2. focus the Wave input with the keyboard shorcut Command + I
|
||||
3. type 'ls' into the input
|
||||
4. press return
|
||||
5. validate Wave shows the result of 'ls'
|
||||
1. wait 10 seconds
|
||||
1. click "Continue"
|
||||
1. click "Create new tab"
|
||||
1. validate that overlapping text does not appear in the application
|
||||
1. focus the Wave input with the keyboard shorcut Command + I
|
||||
1. type 'ls' into the input
|
||||
1. press return
|
||||
1. validate Wave shows the result of 'ls'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: peter-evans/create-or-update-comment@v4
|
||||
if: ${{always()}}
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
## TestDriver Summary
|
||||
${{ steps.testdriver.outputs.markdown }}
|
||||
${{ steps.testdriver.outputs.summary }}
|
||||
reactions: |
|
||||
+1
|
||||
-1
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
# Wave Terminal
|
||||
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fwavetermdev%2Fwaveterm?ref=badge_shield)
|
||||
|
||||
Wave is an open-source AI-native terminal built for seamless workflows.
|
||||
|
||||
Wave isn't just another terminal emulator; it's a rethink on how terminals are built. Wave combines command line with the power of the open web to help veteran CLI users and new developers alike.
|
||||
@@ -56,3 +58,7 @@ Find more information in our [Contributions Guide](CONTRIBUTING.md), which inclu
|
||||
|
||||
- [Ways to contribute](CONTRIBUTING.md#contributing-to-wave-terminal)
|
||||
- [Contribution guidelines](CONTRIBUTING.md#before-you-start)
|
||||
|
||||
## License
|
||||
|
||||
Wave Terminal is licensed under the Apache-2.0 License. For more information on our dependencies, see [here](./acknowledgements/README.md).
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
# Open-Source Acknowledgements
|
||||
|
||||
We make use of many amazing open-source projects to build Wave Terminal. Here are the links to the latest acknowledgements for each of our components, including license disclaimers for each dependency:
|
||||
We make use of many amazing open-source projects to build Wave Terminal. We automatically generate license reports via FOSSA to comply with the license distribution requirements of our dependencies. Below is a summary of the licenses used by our product. Clicking on the image will take you to the full report on FOSSA's website.
|
||||
|
||||
- [Frontend](./disclaimers/frontend.md)
|
||||
- [Backend](./disclaimers/backend.md)
|
||||
|
||||
## Generating license disclaimers
|
||||
|
||||
The license disclaimers for the backend are generated using the [go-licenses](https://github.com/google/go-licenses) tool. We supply a template file ([`go_licenses_report.tpl`](./go_licenses_report.tpl)) to generate a pretty print of the disclaimers for each dependency. This outputs to the file [`backend.md`](./disclaimers/backend.md).
|
||||
|
||||
The license disclaimers for the frontend are generated using the [`yarn licenses` tool](https://classic.yarnpkg.com/lang/en/docs/cli/licenses/). This outputs to the file [`frontend.md`](./disclaimers/frontend.md).
|
||||
|
||||
These disclaimer files linked above will be periodically regenerated to reflect new dependencies.
|
||||
|
||||
The [`scripthaus.md` file](../scripthaus.md) contains scripts to generate the disclaimers and package them. To manually generate the disclaimers, run the following from the repository root directory:
|
||||
|
||||
```bash
|
||||
scripthaus run generate-license-disclaimers
|
||||
```
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fwavetermdev%2Fwaveterm?ref=badge_large)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,16 +0,0 @@
|
||||
# Wave Terminal Backend Acknowledgements
|
||||
|
||||
The following sets forth attribution notices for third party software that may be contained in portions of the Wave Terminal product.
|
||||
{{ range . }}
|
||||
## {{ .Name }}
|
||||
|
||||
* Name: {{ .Name }}
|
||||
* Version: {{ .Version }}
|
||||
* License: [{{ .LicenseName }}]({{ .LicenseURL }})
|
||||
|
||||
```txt
|
||||
{{ .LicenseText }}
|
||||
```
|
||||
|
||||
-----
|
||||
{{ end }}
|
||||
@@ -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",
|
||||
|
||||
+12
-7
@@ -6,7 +6,7 @@
|
||||
},
|
||||
"productName": "Wave",
|
||||
"description": "An Open-Source, AI-Native, Terminal Built for Seamless Workflows",
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.5",
|
||||
"main": "dist/emain.js",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
@@ -18,6 +18,7 @@
|
||||
"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",
|
||||
@@ -31,9 +32,10 @@
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"electron-updater": "^6.1.8",
|
||||
"framer-motion": "^10.16.16",
|
||||
"lexical": "0.14.5",
|
||||
"mobx": "6.12",
|
||||
"mobx-react": "^7.5.0",
|
||||
"monaco-editor": "^0.44.0",
|
||||
"monaco-editor": "0.48.0",
|
||||
"mustache": "^4.2.0",
|
||||
"node-fetch": "^3.2.10",
|
||||
"overlayscrollbars": "^2.6.1",
|
||||
@@ -49,8 +51,10 @@
|
||||
"tsx-control-statements": "^5.1.1",
|
||||
"uuid": "^9.0.0",
|
||||
"winston": "^3.8.2",
|
||||
"xterm": "^5.0.0",
|
||||
"xterm-addon-web-links": "^0.9.0"
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-addon-serialize": "^0.11.0",
|
||||
"xterm-addon-web-links": "^0.9.0",
|
||||
"xterm-addon-webgl": "^0.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.17.10",
|
||||
@@ -64,6 +68,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",
|
||||
@@ -78,8 +83,8 @@
|
||||
"babel-loader": "^9.1.3",
|
||||
"babel-plugin-jsx-control-statements": "^4.1.2",
|
||||
"copy-webpack-plugin": "^12.0.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"electron": "^29.0.1",
|
||||
"css-loader": "^7.1.0",
|
||||
"electron": "^30.0.1",
|
||||
"electron-builder": "^24.13.3",
|
||||
"electron-builder-squirrel-windows": "^24.13.3",
|
||||
"file-loader": "^6.2.0",
|
||||
@@ -91,7 +96,7 @@
|
||||
"prettier": "^2.8.8",
|
||||
"raw-loader": "^4.0.2",
|
||||
"react-split-it": "^2.0.0",
|
||||
"style-loader": "^3.3.1",
|
||||
"style-loader": "4.0.0",
|
||||
"typescript": "^5.0.0",
|
||||
"webpack": "^5.73.0",
|
||||
"webpack-bundle-analyzer": "^4.10.1",
|
||||
|
||||
+19
-17
@@ -42,16 +42,19 @@
|
||||
--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: #333;
|
||||
--app-maincontent-bg-color: rgb(51, 51, 51);
|
||||
--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: #fff;
|
||||
--app-icon-hover-color: rgb(255, 255, 255);
|
||||
--app-selected-mask-color: rgba(255, 255, 255, 0.06);
|
||||
|
||||
/* global status colors */
|
||||
@@ -87,7 +90,7 @@
|
||||
--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(--form-element-text-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);
|
||||
@@ -122,18 +125,18 @@
|
||||
|
||||
/* line colors */
|
||||
--line-sidebar-message-color: rgb(196, 160, 0);
|
||||
--line-background: rgba(21, 23, 21, 1);
|
||||
--line-avatar-color: #eceeec;
|
||||
--line-background: var(--app-panel-bg-color);
|
||||
--line-avatar-color: rgb(236, 238, 236);
|
||||
--line-text-color: rgb(211, 215, 207);
|
||||
--line-svg-fill-color: rgb(150, 152, 150);
|
||||
--line-svg-hover-fill-color: #eceeec;
|
||||
--line-svg-hover-fill-color: rgb(236, 238, 236);
|
||||
--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: #729fcf;
|
||||
--line-base-soft-blue-color: rgb(114, 159, 207);
|
||||
--line-active-border-color: var(--app-accent-color);
|
||||
--line-selected-bg-color: rgba(255, 255, 255, 0.05);
|
||||
--line-selected-border-left-color: #777777;
|
||||
--line-selected-border-left-color: rgb(119, 119, 119);
|
||||
--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);
|
||||
@@ -152,22 +155,21 @@
|
||||
/* 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: #ccc;
|
||||
--table-thead-bg-color: rgba(250, 250, 250, 0.02);
|
||||
--table-thead-bright-border-color: rgb(204, 204, 204);
|
||||
--table-thead-bg-color: rgb(5, 5, 5);
|
||||
--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: #222;
|
||||
--table-tr-selected-hover-bg-color: #333;
|
||||
--table-tr-selected-bg-color: rgb(34, 34, 34);
|
||||
--table-tr-selected-hover-bg-color: var(--app-maincontent-bg-color);
|
||||
|
||||
/* cmdinput colors */
|
||||
--cmdinput-textarea-bg-color: #171717;
|
||||
--cmdinput-bg-color: var(--app-text-bg-color);
|
||||
--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: 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);
|
||||
--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);
|
||||
|
||||
/* screen view color */
|
||||
--screen-view-text-caption-color: rgb(139, 145, 138);
|
||||
|
||||
+23
-21
@@ -5,20 +5,20 @@
|
||||
@import url("./term-light.css");
|
||||
|
||||
:root {
|
||||
--app-bg-color: #fefefe;
|
||||
--app-bg-color: rgb(254, 254, 254);
|
||||
--app-accent-color: rgb(75, 166, 57);
|
||||
--app-accent-bg-color: rgba(75, 166, 57, 0.2);
|
||||
--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-text-color: rgb(0, 0, 0);
|
||||
--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: #e0e0e0;
|
||||
--app-panel-bg-color-dev: #e0e0e0;
|
||||
--app-icon-color: rgb(80, 80, 80);
|
||||
--app-icon-hover-color: rgb(100, 100, 100);
|
||||
--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-selected-mask-color: rgba(0, 0, 0, 0.06);
|
||||
|
||||
--input-bg-color: #eeeeee;
|
||||
--input-bg-color: rgb(238, 238, 238);
|
||||
|
||||
/* tab color */
|
||||
--tab-white: rgb(0, 0, 0, 0.6);
|
||||
@@ -30,19 +30,19 @@
|
||||
--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: #dddddd;
|
||||
--table-tr-selected-hover-bg-color: #cccccc;
|
||||
--table-tr-selected-bg-color: rgb(221, 221, 221);
|
||||
--table-tr-selected-hover-bg-color: rgb(204, 204, 204);
|
||||
|
||||
/* 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-color);
|
||||
--form-element-primary-text-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: 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: #b7b7b7;
|
||||
--form-element-placeholder-color: #b7b7b7;
|
||||
--form-element-disabled-text-color: rgb(183, 183, 183);
|
||||
--form-element-placeholder-color: rgb(183, 183, 183);
|
||||
|
||||
--markdown-bg-color: rgb(0, 0, 0, 0.1);
|
||||
|
||||
@@ -50,8 +50,6 @@
|
||||
--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);
|
||||
@@ -59,20 +57,24 @@
|
||||
--scrollbar-thumb-hover-color: rgba(0, 0, 0, 0.4);
|
||||
--scrollbar-thumb-active-color: rgba(0, 0, 0, 0.5);
|
||||
|
||||
/* table colors */
|
||||
--table-thead-bg-color: rgb(253, 253, 253);
|
||||
--table-tr-selected-bg-color: rgb(216, 216, 216);
|
||||
|
||||
/* 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: #f0f0f0;
|
||||
--logo-button-hover-bg-color: rgb(240, 240, 240);
|
||||
|
||||
--xterm-viewport-border-color: rgba(0, 0, 0, 0.3);
|
||||
|
||||
--datepicker-cell-hover-bg-color: #f0f0f0;
|
||||
--datepicker-cell-hover-bg-color: rgb(240, 240, 240);
|
||||
--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: #f5f5f5;
|
||||
--datepicker-year-header-border-color: #dcdcdc;
|
||||
--datepicker-year-header-bg-color: rgb(245, 245, 245);
|
||||
--datepicker-year-header-border-color: rgb(220, 220, 220);
|
||||
|
||||
/* toggle colors */
|
||||
--toggle-thumb-color: var(--app-bg-color);
|
||||
|
||||
+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.7
|
||||
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.7
|
||||
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.7
|
||||
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)
|
||||
|
||||
+64
-43
@@ -4,10 +4,10 @@
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import * as mobx from "mobx";
|
||||
import cn from "classnames";
|
||||
|
||||
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 { isBlank } from "@/util/util";
|
||||
import { WorkspaceView } from "./workspace/workspaceview";
|
||||
@@ -22,15 +22,15 @@ import { DisconnectedModal, ClientStopModal } from "@/modals";
|
||||
import { ModalsProvider } from "@/modals/provider";
|
||||
import { Button } from "@/elements";
|
||||
import { ErrorBoundary } from "@/common/error/errorboundary";
|
||||
import cn from "classnames";
|
||||
import "./app.less";
|
||||
import { TermStyleList } from "@/elements";
|
||||
|
||||
dayjs.extend(localizedFormat);
|
||||
import "./app.less";
|
||||
|
||||
@mobxReact.observer
|
||||
class App extends React.Component<{}, {}> {
|
||||
dcWait: OV<boolean> = mobx.observable.box(false, { name: "dcWait" });
|
||||
mainContentRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||
termThemesLoaded: OV<boolean> = mobx.observable.box(false, { name: "termThemesLoaded" });
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
@@ -80,6 +80,13 @@ class App extends React.Component<{}, {}> {
|
||||
rightSidebarModel.saveState(width, false);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleTermThemesRendered() {
|
||||
mobx.action(() => {
|
||||
this.termThemesLoaded.set(true);
|
||||
})();
|
||||
}
|
||||
|
||||
render() {
|
||||
const remotesModel = GlobalModel.remotesModel;
|
||||
const disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get();
|
||||
@@ -90,7 +97,8 @@ class App extends React.Component<{}, {}> {
|
||||
|
||||
// Previously, this is done in sidebar.tsx but it causes flicker when clientData is null cos screen-view shifts around.
|
||||
// Doing it here fixes the flicker cos app is not rendered until clientData is populated.
|
||||
if (clientData == null) {
|
||||
// wait for termThemes as well (this actually means that the "connect" packet has been received)
|
||||
if (clientData == null || GlobalModel.termThemes.get() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -118,52 +126,65 @@ class App extends React.Component<{}, {}> {
|
||||
if (dcWait) {
|
||||
setTimeout(() => this.updateDcWait(false), 0);
|
||||
}
|
||||
|
||||
// used to force a full reload of the application
|
||||
const renderVersion = GlobalModel.renderVersion.get();
|
||||
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 mainClassName = cn(
|
||||
"platform-" + platform,
|
||||
{
|
||||
"mainsidebar-collapsed": mainSidebarCollapsed,
|
||||
"rightsidebar-collapsed": rightSidebarCollapsed,
|
||||
},
|
||||
lightDarkClass
|
||||
);
|
||||
return (
|
||||
<div
|
||||
key={"version-" + renderVersion}
|
||||
id="main"
|
||||
className={cn(
|
||||
"platform-" + platform,
|
||||
{ "mainsidebar-collapsed": mainSidebarCollapsed, "rightsidebar-collapsed": rightSidebarCollapsed },
|
||||
lightDarkClass
|
||||
)}
|
||||
onContextMenu={this.handleContextMenu}
|
||||
>
|
||||
<If condition={mainSidebarCollapsed}>
|
||||
<div key="logo-button" className="logo-button-container">
|
||||
<div className="logo-button-spacer" />
|
||||
<div className="logo-button" onClick={this.openMainSidebar}>
|
||||
<img src="public/logos/wave-logo.png" alt="logo" />
|
||||
<>
|
||||
<TermStyleList onRendered={this.handleTermThemesRendered} />
|
||||
<div
|
||||
key={`version- + ${renderVersion}`}
|
||||
id="main"
|
||||
className={mainClassName}
|
||||
onContextMenu={this.handleContextMenu}
|
||||
>
|
||||
<If condition={this.termThemesLoaded.get()}>
|
||||
<If condition={mainSidebarCollapsed}>
|
||||
<div key="logo-button" className="logo-button-container">
|
||||
<div className="logo-button-spacer" />
|
||||
<div className="logo-button" onClick={this.openMainSidebar}>
|
||||
<img src="public/logos/wave-logo.png" alt="logo" />
|
||||
</div>
|
||||
</div>
|
||||
</If>
|
||||
<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>
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<div ref={this.mainContentRef} className="main-content">
|
||||
<MainSideBar parentRef={this.mainContentRef} />
|
||||
<ErrorBoundary>
|
||||
<PluginsView />
|
||||
<WorkspaceView />
|
||||
<HistoryView />
|
||||
<BookmarksView />
|
||||
<ConnectionsView model={remotesModel} />
|
||||
<ClientSettingsView model={remotesModel} />
|
||||
</ErrorBoundary>
|
||||
<RightSideBar parentRef={this.mainContentRef} />
|
||||
</div>
|
||||
</div>
|
||||
</If>
|
||||
<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-regular fa-lightbulb"></i>
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<div ref={this.mainContentRef} className="main-content">
|
||||
<MainSideBar parentRef={this.mainContentRef} />
|
||||
<ErrorBoundary>
|
||||
<PluginsView />
|
||||
<WorkspaceView />
|
||||
<HistoryView />
|
||||
<BookmarksView />
|
||||
<ConnectionsView model={remotesModel} />
|
||||
<ClientSettingsView model={remotesModel} />
|
||||
</ErrorBoundary>
|
||||
<RightSideBar parentRef={this.mainContentRef} />
|
||||
<ModalsProvider />
|
||||
</If>
|
||||
</div>
|
||||
<ModalsProvider />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,10 @@ export const TabIcons = [
|
||||
"heart",
|
||||
"file",
|
||||
];
|
||||
export const DefaultSudoPwStore = "on";
|
||||
export const DefaultSudoPwTimeoutMs = 5 * 60 * 1000;
|
||||
|
||||
export const MaxWebSocketSendSize = 64 * 1024 - 100;
|
||||
|
||||
// @ts-ignore
|
||||
export const VERSION = __WAVETERM_VERSION__;
|
||||
@@ -64,3 +68,7 @@ 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";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
.clientsettings-view {
|
||||
.content {
|
||||
padding: 14px 18px 0 30px;
|
||||
padding: 14px 18px 14px 30px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.wave-dropdown {
|
||||
|
||||
@@ -6,13 +6,15 @@ 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, getApi } from "@/models";
|
||||
import { GlobalModel, GlobalCommandRunner, RemotesModel } 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 "./clientsettings.less";
|
||||
import { MainView } from "../common/elements/mainview";
|
||||
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
|
||||
|
||||
class ClientSettingsKeybindings extends React.Component<{}, {}> {
|
||||
componentDidMount() {
|
||||
@@ -69,7 +71,19 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
return;
|
||||
}
|
||||
const prtn = GlobalCommandRunner.setTheme(themeSource, false);
|
||||
getApi().setNativeThemeSource(themeSource);
|
||||
GlobalModel.getElectronApi().setNativeThemeSource(themeSource);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeTermTheme(theme: string): void {
|
||||
// For root terminal theme, the key is root, otherwise it's either
|
||||
// sessionId or screenId.
|
||||
const currTheme = GlobalModel.getTermThemeSettings()["root"];
|
||||
if (currTheme == theme) {
|
||||
return;
|
||||
}
|
||||
const prtn = GlobalCommandRunner.setRootTermTheme(theme, false);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@@ -93,7 +107,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
prtn = GlobalCommandRunner.releaseCheckAutoOff(false);
|
||||
}
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
getApi().changeAutoUpdate(val);
|
||||
GlobalModel.getElectronApi().changeAutoUpdate(val);
|
||||
}
|
||||
|
||||
getFontSizes(): DropdownItem[] {
|
||||
@@ -144,6 +158,12 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
inlineUpdateOpenAITimeout(newTimeout: string): void {
|
||||
const prtn = GlobalCommandRunner.setClientOpenAISettings({ timeout: newTimeout });
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
setErrorMessage(msg: string): void {
|
||||
mobx.action(() => {
|
||||
@@ -178,6 +198,35 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
GlobalModel.clientSettingsViewModel.closeView();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
getSudoPwStoreOptions(): DropdownItem[] {
|
||||
const sudoCacheSources: DropdownItem[] = [];
|
||||
sudoCacheSources.push({ label: "On", value: "on" });
|
||||
sudoCacheSources.push({ label: "Off", value: "off" });
|
||||
sudoCacheSources.push({ label: "On Without Timeout", value: "notimeout" });
|
||||
return sudoCacheSources;
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeSudoPwStoreConfig(store: string) {
|
||||
const prtn = GlobalCommandRunner.setSudoPwStore(store);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeSudoPwTimeoutConfig(timeout: string) {
|
||||
if (Number(timeout) != 0) {
|
||||
const prtn = GlobalCommandRunner.setSudoPwTimeout(timeout);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeSudoPwClearOnSleepConfig(clearOnSleep: boolean) {
|
||||
const prtn = GlobalCommandRunner.setSudoPwClearOnSleep(clearOnSleep);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
render() {
|
||||
const isHidden = GlobalModel.activeMainView.get() != "clientsettings";
|
||||
if (isHidden) {
|
||||
@@ -190,12 +239,25 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
const maxTokensStr = String(
|
||||
openAIOpts.maxtokens == null || openAIOpts.maxtokens == 0 ? 1000 : openAIOpts.maxtokens
|
||||
);
|
||||
const aiTimeoutStr = String(
|
||||
openAIOpts.timeout == null || openAIOpts.timeout == 0 ? 10 : openAIOpts.timeout / 1000
|
||||
);
|
||||
const curFontSize = GlobalModel.getTermFontSize();
|
||||
const curFontFamily = GlobalModel.getTermFontFamily();
|
||||
const curTheme = GlobalModel.getThemeSource();
|
||||
const termThemes = getTermThemes(GlobalModel.termThemes.get(), "Wave Default");
|
||||
const currTermTheme = GlobalModel.getTermThemeSettings()["root"] ?? termThemes[0].label;
|
||||
const curSudoPwStore = GlobalModel.getSudoPwStore();
|
||||
const curSudoPwTimeout = String(GlobalModel.getSudoPwTimeout());
|
||||
const curSudoPwClearOnSleep = GlobalModel.getSudoPwClearOnSleep();
|
||||
|
||||
return (
|
||||
<MainView className="clientsettings-view" title="Client Settings" onClose={this.handleClose}>
|
||||
<MainView
|
||||
className="clientsettings-view"
|
||||
title="Client Settings"
|
||||
onClose={this.handleClose}
|
||||
scrollable={true}
|
||||
>
|
||||
<If condition={!isHidden}>
|
||||
<ClientSettingsKeybindings></ClientSettingsKeybindings>
|
||||
</If>
|
||||
@@ -233,6 +295,19 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
/>
|
||||
</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>
|
||||
@@ -314,6 +389,19 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">AI Timeout (seconds)</div>
|
||||
<div className="settings-input">
|
||||
<InlineSettingsTextEdit
|
||||
placeholder=""
|
||||
text={aiTimeoutStr}
|
||||
value={aiTimeoutStr}
|
||||
onChange={this.inlineUpdateOpenAITimeout}
|
||||
maxLength={10}
|
||||
showIcon={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Global Hotkey</div>
|
||||
<div className="settings-input">
|
||||
@@ -325,6 +413,40 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Remember Sudo Password</div>
|
||||
<div className="settings-input">
|
||||
<Dropdown
|
||||
className="hotkey-dropdown"
|
||||
options={this.getSudoPwStoreOptions()}
|
||||
defaultValue={curSudoPwStore}
|
||||
onChange={this.handleChangeSudoPwStoreConfig}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Sudo Timeout (Minutes)</div>
|
||||
<div className="settings-input">
|
||||
<InlineSettingsTextEdit
|
||||
placeholder=""
|
||||
text={curSudoPwTimeout}
|
||||
value={curSudoPwTimeout}
|
||||
onChange={this.handleChangeSudoPwTimeoutConfig}
|
||||
maxLength={6}
|
||||
showIcon={true}
|
||||
isNumber={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Clear Sudo Password on Sleep</div>
|
||||
<div className="settings-input">
|
||||
<Toggle
|
||||
checked={curSudoPwClearOnSleep}
|
||||
onChange={this.handleChangeSudoPwClearOnSleepConfig}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<SettingsError errorMessage={this.errorMessage} />
|
||||
</div>
|
||||
</MainView>
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.danger {
|
||||
background: var(--app-error-color);
|
||||
}
|
||||
|
||||
&.primary.outlined {
|
||||
background: none;
|
||||
border: 1px solid var(--form-element-primary-color);
|
||||
@@ -36,6 +40,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.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 {
|
||||
@@ -43,6 +78,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.ghost.danger {
|
||||
background: none;
|
||||
i {
|
||||
fill: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
color: var(--form-element-text-color);
|
||||
background: var(--form-element-secondary-color);
|
||||
@@ -56,6 +98,11 @@
|
||||
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?: () => void;
|
||||
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
disabled?: boolean;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
@@ -14,6 +14,7 @@ interface ButtonProps {
|
||||
autoFocus?: boolean;
|
||||
className?: string;
|
||||
termInline?: boolean;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
class Button extends React.Component<ButtonProps> {
|
||||
@@ -23,14 +24,14 @@ class Button extends React.Component<ButtonProps> {
|
||||
};
|
||||
|
||||
@boundMethod
|
||||
handleClick() {
|
||||
handleClick(e) {
|
||||
if (this.props.onClick && !this.props.disabled) {
|
||||
this.props.onClick();
|
||||
this.props.onClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { leftIcon, rightIcon, children, disabled, style, autoFocus, termInline, className } = this.props;
|
||||
const { leftIcon, rightIcon, children, disabled, style, autoFocus, termInline, className, title } = this.props;
|
||||
|
||||
return (
|
||||
<button
|
||||
@@ -39,6 +40,7 @@ class Button extends React.Component<ButtonProps> {
|
||||
disabled={disabled}
|
||||
style={style}
|
||||
autoFocus={autoFocus}
|
||||
title={title}
|
||||
>
|
||||
{leftIcon && <span className="icon-left">{leftIcon}</span>}
|
||||
{children}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.copy-button {
|
||||
padding: 5px 5px;
|
||||
|
||||
.fa-check {
|
||||
color: var(--app-success-color);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
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 };
|
||||
@@ -312,7 +312,6 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
};
|
||||
|
||||
const handleArrowNavigation = (key: string, currentPart: string) => {
|
||||
console.log("Arrow key pressed: ", key);
|
||||
const currentIndex = formatParts.indexOf(currentPart);
|
||||
let targetInput;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user