mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cdeef49ec1 | |||
| 7e128c791b | |||
| 09c4a42557 | |||
| 75d1a435ae | |||
| 426f9546e5 | |||
| d410e5d07f | |||
| e66f34c9b5 | |||
| 58e971276e | |||
| 2d08037782 | |||
| 226699732d | |||
| 03b1e410e7 | |||
| 38c784bf8e | |||
| 40af311e5b | |||
| 112fda912f | |||
| f2eb383cc3 | |||
| 8d71f5538c | |||
| 7a37fdb942 | |||
| 80f7162691 | |||
| a639d72e30 | |||
| ce252d479b | |||
| d8d19ea035 | |||
| 21ab82e2e2 | |||
| 781ebe8154 | |||
| ad225ed28a | |||
| 633cb8fbd0 | |||
| 4ccd62f12a | |||
| b733724c7d | |||
| 4ff5dcf1e0 | |||
| f9d0e63d0c | |||
| ea9cb37de1 | |||
| 8200a312b9 | |||
| 3b65e9941a | |||
| 535fd0d7d9 | |||
| 96980b2f83 | |||
| b6c880c6ff | |||
| 1feffc8a11 | |||
| f442236679 | |||
| 414937911e | |||
| 5d39815dea | |||
| 96f636c2da | |||
| 112d002c2a | |||
| 4adcf6d92e | |||
| e79dcaf910 | |||
| e6186cd694 | |||
| 58551d6a2a | |||
| 2b8adfe40e | |||
| ce4b6d413c | |||
| 8a938744f7 | |||
| 87bf3f7a65 | |||
| 800fda2e14 | |||
| 3c30eb4e08 | |||
| 32a825aea1 | |||
| 0ece51e690 | |||
| 724a68393a | |||
| 6791d874e3 | |||
| a3187a1235 | |||
| 9ebd5bda8f | |||
| c8485ad80c | |||
| dbde4b58df | |||
| 7280bbf9d9 | |||
| 08762fdfc3 | |||
| 0c756838e0 | |||
| 7310481383 | |||
| 23b6bb29e7 | |||
| fc79da776c | |||
| 24499cb0b5 | |||
| b9e12b2623 | |||
| 86a86bc756 | |||
| 1c9c470fec | |||
| 75c3c42750 | |||
| ebf356417d | |||
| 4ef8dd5a98 | |||
| 0fbc800685 | |||
| 5a147dc887 | |||
| b250cc2042 | |||
| e95934e2df | |||
| 98b373d401 | |||
| 64203e7823 | |||
| 7d8f811228 | |||
| ebdc1ff524 | |||
| 3f57ee8c46 | |||
| d9c7b61c91 | |||
| 0017946bbb | |||
| e15558690f | |||
| bf03ff2591 | |||
| ad0f11c097 |
@@ -0,0 +1,81 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '36 5 * * 5'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners
|
||||
# Consider using larger runners for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'go', 'javascript-typescript' ]
|
||||
# CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
|
||||
# Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
@@ -5,7 +5,7 @@ If you're developing on Linux please use the [Linux Build Instructions](./build-
|
||||
|
||||
## Running the Development Version of Wave
|
||||
|
||||
If you install the production version of Wave, you'll see a semi-transparent sidebar, and the data for Wave is stored in the directory ~/prompt. The development version has a red/brown sidebar and stores its data in ~/prompt-dev. This allows the production and development versions to be run simultaneously with no conflicts. If the dev database is corrupted by development bugs, or the schema changes in development it will not affect the production copy.
|
||||
If you install the production version of Wave, you'll see a semi-transparent sidebar, and the data for Wave is stored in the directory ~/.waveterm. The development version has a blue sidebar and stores its data in ~/.waveterm-dev. This allows the production and development versions to be run simultaneously with no conflicts. If the dev database is corrupted by development bugs, or the schema changes in development it will not affect the production copy.
|
||||
|
||||
## Prereqs and Tools
|
||||
|
||||
|
||||
@@ -25,6 +25,11 @@ Wave Terminal works with MacOS and Linux (preliminary).
|
||||
|
||||
Install Wave Terminal from: [www.waveterm.dev/download](https://www.waveterm.dev/download)
|
||||
|
||||
Also available as a homebrew cask for MacOS:
|
||||
```
|
||||
brew install --cask wave
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
* Homepage — https://www.waveterm.dev
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# assumes we have Wave-darwin-x64-[version].zip and Wave-darwin-arm64-[version].zip in current directory
|
||||
VERSION=0.5.0
|
||||
VERSION=0.5.2
|
||||
rm -rf temp
|
||||
mkdir temp
|
||||
mkdir temp/x64
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
||||
Generated
-11314
File diff suppressed because it is too large
Load Diff
+11
-9
@@ -2,7 +2,7 @@
|
||||
"name": "waveterm",
|
||||
"author": "Command Line Inc",
|
||||
"productName": "Wave",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.2",
|
||||
"main": "dist/emain.js",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -11,12 +11,14 @@
|
||||
"@table-nav/react": "^0.0.7",
|
||||
"@tanstack/match-sorter-utils": "^8.8.4",
|
||||
"@tanstack/react-table": "^8.10.3",
|
||||
"@types/semver": "^7.5.6",
|
||||
"autobind-decorator": "^2.4.0",
|
||||
"classnames": "^2.3.1",
|
||||
"dayjs": "^1.11.3",
|
||||
"dompurify": "^3.0.2",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"mobx": "^6.6.0",
|
||||
"framer-motion": "^10.16.16",
|
||||
"mobx": "6.12",
|
||||
"mobx-react": "^7.5.0",
|
||||
"monaco-editor": "^0.44.0",
|
||||
"mustache": "^4.2.0",
|
||||
@@ -43,9 +45,9 @@
|
||||
"@babel/plugin-proposal-private-methods": "^7.18.6",
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||
"@babel/plugin-transform-react-jsx": "^7.17.12",
|
||||
"@babel/plugin-transform-runtime": "^7.18.2",
|
||||
"@babel/plugin-transform-runtime": "^7.23.4",
|
||||
"@babel/preset-env": "^7.18.2",
|
||||
"@babel/preset-react": "^7.17.12",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"@babel/preset-typescript": "^7.17.12",
|
||||
"@electron-forge/cli": "^6.0.0-beta.70",
|
||||
"@electron-forge/maker-deb": "^6.0.0-beta.70",
|
||||
@@ -53,22 +55,22 @@
|
||||
"@electron-forge/maker-snap": "^6.4.2",
|
||||
"@electron-forge/maker-squirrel": "^6.0.0-beta.70",
|
||||
"@electron-forge/maker-zip": "^6.0.0-beta.70",
|
||||
"@electron/rebuild": "^3.3.0",
|
||||
"@electron/rebuild": "^3.4.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@types/classnames": "^2.3.1",
|
||||
"@types/electron": "^1.6.10",
|
||||
"@types/node": "^20.4.0",
|
||||
"@types/node": "20.10.3",
|
||||
"@types/papaparse": "^5.3.10",
|
||||
"@types/react": "^18.0.12",
|
||||
"@types/sprintf-js": "^1.1.3",
|
||||
"@types/throttle-debounce": "^5.0.1",
|
||||
"@types/uuid": "9.0.6",
|
||||
"@types/uuid": "9.0.7",
|
||||
"@types/webpack-env": "^1.18.3",
|
||||
"babel-loader": "^9.1.3",
|
||||
"babel-plugin-jsx-control-statements": "^4.1.2",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"electron": "27.0.3",
|
||||
"electron": "27.1.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"http-server": "^14.1.1",
|
||||
"less": "^4.1.2",
|
||||
@@ -81,7 +83,7 @@
|
||||
"style-loader": "^3.3.1",
|
||||
"typescript": "^4.7.3",
|
||||
"webpack": "^5.73.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0",
|
||||
"webpack-bundle-analyzer": "^4.10.1",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^4.9.1",
|
||||
"webpack-merge": "^5.8.0"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
+18
-25
@@ -27,13 +27,13 @@ node_modules/.bin/electron-rebuild
|
||||
```bash
|
||||
# @scripthaus command electron
|
||||
# @scripthaus cd :playbook
|
||||
WAVETERM_DEV=1 PCLOUD_ENDPOINT="https://ot2e112zx5.execute-api.us-west-2.amazonaws.com/dev" node_modules/.bin/electron dist-dev/emain.js
|
||||
WAVETERM_DEV=1 PCLOUD_ENDPOINT="https://ot2e112zx5.execute-api.us-west-2.amazonaws.com/dev" PCLOUD_WS_ENDPOINT="wss://5lfzlg5crl.execute-api.us-west-2.amazonaws.com/dev/" node_modules/.bin/electron dist-dev/emain.js
|
||||
```
|
||||
|
||||
```bash
|
||||
# @scripthaus command typecheck
|
||||
# @scripthaus cd :playbook
|
||||
node_modules/.bin/tsc --jsx preserve --noEmit --esModuleInterop --target ES5 --experimentalDecorators --downlevelIteration src/index.ts src/types/custom.d.ts
|
||||
node_modules/.bin/tsc --noEmit
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -44,11 +44,11 @@ rm -rf bin/
|
||||
rm -rf build/
|
||||
node_modules/.bin/webpack --env prod
|
||||
GO_LDFLAGS="-s -w -X main.BuildTime=$(date +'%Y%m%d%H%M')"
|
||||
(cd waveshell; GOOS=darwin GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.amd64 main-waveshell.go)
|
||||
(cd waveshell; GOOS=darwin GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.arm64 main-waveshell.go)
|
||||
(cd waveshell; GOOS=linux GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.amd64 main-waveshell.go)
|
||||
(cd waveshell; GOOS=linux GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.arm64 main-waveshell.go)
|
||||
(cd wavesrv; CGO_ENABLED=1 go build -ldflags="$GO_LDFLAGS" -o ../bin/wavesrv ./cmd)
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.amd64 main-waveshell.go)
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.arm64 main-waveshell.go)
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.amd64 main-waveshell.go)
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.arm64 main-waveshell.go)
|
||||
(cd wavesrv; CGO_ENABLED=1 go build -tags "osusergo,netgo,sqlite_omit_load_extension" -ldflags "-X main.BuildTime=$(date +'%Y%m%d%H%M')" -o ../bin/wavesrv ./cmd)
|
||||
node_modules/.bin/electron-forge make
|
||||
```
|
||||
|
||||
@@ -60,11 +60,12 @@ rm -rf bin/
|
||||
rm -rf build/
|
||||
node_modules/.bin/webpack --env prod
|
||||
GO_LDFLAGS="-s -w -X main.BuildTime=$(date +'%Y%m%d%H%M')"
|
||||
(cd waveshell; GOOS=darwin GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.amd64 main-waveshell.go)
|
||||
(cd waveshell; GOOS=darwin GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.arm64 main-waveshell.go)
|
||||
(cd waveshell; GOOS=linux GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.amd64 main-waveshell.go)
|
||||
(cd waveshell; GOOS=linux GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.arm64 main-waveshell.go)
|
||||
(cd wavesrv; CGO_ENABLED=1 go build -ldflags="$GO_LDFLAGS" -o ../bin/wavesrv ./cmd)
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.amd64 main-waveshell.go)
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.arm64 main-waveshell.go)
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.amd64 main-waveshell.go)
|
||||
(cd waveshell; CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.arm64 main-waveshell.go)
|
||||
# adds -extldflags=-static, *only* on linux (macos does not support fully static binaries) to avoid a glibc dependency
|
||||
(cd wavesrv; CGO_ENABLED=1 go build -tags "osusergo,netgo,sqlite_omit_load_extension" -ldflags "-linkmode 'external' -extldflags=-static $GO_LDFLAGS" -o ../bin/wavesrv ./cmd)
|
||||
node_modules/.bin/electron-forge make
|
||||
```
|
||||
|
||||
@@ -77,14 +78,7 @@ open out/Wave-darwin-x64/Wave.app
|
||||
```bash
|
||||
# @scripthaus command build-wavesrv
|
||||
cd wavesrv
|
||||
CGO_ENABLED=1 go build -ldflags "-X main.BuildTime=$(date +'%Y%m%d%H%M')" -o ../bin/wavesrv ./cmd
|
||||
```
|
||||
|
||||
```bash
|
||||
# @scripthaus command build-waveshell
|
||||
cd waveshell
|
||||
GO_LDFLAGS="-s -w -X main.BuildTime=$(date +'%Y%m%d%H%M')"
|
||||
go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.amd64 main-waveshell.go
|
||||
CGO_ENABLED=1 go build -tags "osusergo,netgo,sqlite_omit_load_extension" -ldflags "-X main.BuildTime=$(date +'%Y%m%d%H%M')" -o ../bin/wavesrv ./cmd
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -92,11 +86,10 @@ go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.amd64 main-w
|
||||
set -e
|
||||
cd waveshell
|
||||
GO_LDFLAGS="-s -w -X main.BuildTime=$(date +'%Y%m%d%H%M')"
|
||||
go build -ldflags="$GO_LDFLAGS" -o ~/.mshell/mshell-v0.2 main-waveshell.go
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.amd64 main-waveshell.go
|
||||
GOOS=linux GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.arm64 main-waveshell.go
|
||||
GOOS=darwin GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.amd64 main-waveshell.go
|
||||
GOOS=darwin GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.arm64 main-waveshell.go
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.amd64 main-waveshell.go
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-linux.arm64 main-waveshell.go
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.amd64 main-waveshell.go
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="$GO_LDFLAGS" -o ../bin/mshell/mshell-v0.3-darwin.arm64 main-waveshell.go
|
||||
```
|
||||
|
||||
```bash
|
||||
|
||||
+49
-23
@@ -49,6 +49,14 @@ textarea {
|
||||
}
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
font-family: @text-s1-font;
|
||||
color: @text-primary;
|
||||
}
|
||||
|
||||
.text-standard {
|
||||
font-size: 12.5px;
|
||||
font-weight: 300;
|
||||
@@ -80,6 +88,15 @@ textarea {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
body a {
|
||||
color: @wave-green;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
color: @wave-green;
|
||||
}
|
||||
}
|
||||
|
||||
body code {
|
||||
font-family: @terminal-font;
|
||||
}
|
||||
@@ -148,10 +165,10 @@ svg.icon {
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
background-color: @button-background !important;
|
||||
color: @prompt-green;
|
||||
color: @wave-green;
|
||||
.hoverEffect;
|
||||
&:hover {
|
||||
color: @prompt-green;
|
||||
color: @wave-green;
|
||||
}
|
||||
&.disabled {
|
||||
color: fade(@disabled-color, 60%);
|
||||
@@ -176,12 +193,6 @@ svg.icon {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
a:hover {
|
||||
color: #485fc7;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -219,7 +230,8 @@ a.a-block {
|
||||
|
||||
.history-view,
|
||||
.bookmarks-view,
|
||||
.plugins-view {
|
||||
.plugins-view,
|
||||
.connections-view {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -465,85 +477,99 @@ a.a-block {
|
||||
}
|
||||
|
||||
.icon.color-red {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-red;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-green {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-green;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-orange {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-orange;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-blue {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-blue;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-yellow {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-yellow;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-pink {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-pink;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-mint {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-mint;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-cyan {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-cyan;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-violet {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-violet;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-white {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-white;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon.status-connected {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @status-connected;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon.status-connecting {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @status-connecting;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon.status-disconnected {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @status-disconnected;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon.status-error {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @status-error;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-47
@@ -15,22 +15,15 @@ import { WorkspaceView } from "./workspace/workspaceview";
|
||||
import { PluginsView } from "./pluginsview/pluginsview";
|
||||
import { BookmarksView } from "./bookmarks/bookmarks";
|
||||
import { HistoryView } from "./history/history";
|
||||
import { ConnectionsView } from "./connections/connections";
|
||||
import {
|
||||
ScreenSettingsModal,
|
||||
SessionSettingsModal,
|
||||
LineSettingsModal,
|
||||
ClientSettingsModal,
|
||||
} from "./common/modals/settings";
|
||||
import { RemotesModal } from "./connections/connections";
|
||||
import { TosModal } from "./common/modals/modals";
|
||||
import { MainSideBar } from "./sidebar/sidebar";
|
||||
import {
|
||||
DisconnectedModal,
|
||||
ClientStopModal,
|
||||
AlertModal,
|
||||
AboutModal,
|
||||
CreateRemoteConnModal,
|
||||
} from "./common/modals/modals";
|
||||
import { DisconnectedModal, ClientStopModal, ModalsProvider } from "./common/modals/modals";
|
||||
import { ErrorBoundary } from "./common/error/errorboundary";
|
||||
import "./app.less";
|
||||
|
||||
@@ -64,7 +57,7 @@ class App extends React.Component<{}, {}> {
|
||||
opts.showCut = true;
|
||||
}
|
||||
let sel = window.getSelection();
|
||||
if (!isBlank(sel.toString())) {
|
||||
if (!isBlank(sel?.toString())) {
|
||||
GlobalModel.contextEditMenu(e, opts);
|
||||
} else {
|
||||
if (isInNonTermInput) {
|
||||
@@ -81,18 +74,13 @@ class App extends React.Component<{}, {}> {
|
||||
}
|
||||
|
||||
render() {
|
||||
let screenSettingsModal = GlobalModel.screenSettingsModal.get();
|
||||
let sessionSettingsModal = GlobalModel.sessionSettingsModal.get();
|
||||
let lineSettingsModal = GlobalModel.lineSettingsModal.get();
|
||||
let clientSettingsModal = GlobalModel.clientSettingsModal.get();
|
||||
let remotesModel = GlobalModel.remotesModalModel;
|
||||
let remotesModal = remotesModel.isOpen();
|
||||
let selectedRemoteId = remotesModel.selectedRemoteId.get();
|
||||
let remoteEdit = remotesModel.remoteEdit.get();
|
||||
let remotesModel = GlobalModel.remotesModel;
|
||||
let disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get();
|
||||
let hasClientStop = GlobalModel.getHasClientStop();
|
||||
let dcWait = this.dcWait.get();
|
||||
let platform = GlobalModel.getPlatform();
|
||||
|
||||
if (disconnected || hasClientStop) {
|
||||
if (!dcWait) {
|
||||
setTimeout(() => this.updateDcWait(true), 1500);
|
||||
@@ -117,7 +105,6 @@ class App extends React.Component<{}, {}> {
|
||||
if (dcWait) {
|
||||
setTimeout(() => this.updateDcWait(false), 0);
|
||||
}
|
||||
//console.log(`GlobalModel.activeMainView.get() = ${GlobalModel.activeMainView.get()}`); // @mike - if I remove this, I cant see plugins
|
||||
return (
|
||||
<div id="main" className={"platform-" + platform} onContextMenu={this.handleContextMenu}>
|
||||
<div className="main-content">
|
||||
@@ -127,37 +114,10 @@ class App extends React.Component<{}, {}> {
|
||||
<WorkspaceView />
|
||||
<HistoryView />
|
||||
<BookmarksView />
|
||||
<ConnectionsView model={remotesModel} />
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
<AlertModal />
|
||||
<If condition={GlobalModel.needsTos()}>
|
||||
<TosModal />
|
||||
</If>
|
||||
<If condition={GlobalModel.aboutModalOpen.get()}>
|
||||
<AboutModal />
|
||||
</If>
|
||||
<If condition={remoteEdit !== null && !remoteEdit.old}>
|
||||
<CreateRemoteConnModal model={remotesModel} remoteEdit={remoteEdit} />
|
||||
</If>
|
||||
<If condition={screenSettingsModal != null}>
|
||||
<ScreenSettingsModal
|
||||
key={screenSettingsModal.sessionId + ":" + screenSettingsModal.screenId}
|
||||
sessionId={screenSettingsModal.sessionId}
|
||||
screenId={screenSettingsModal.screenId}
|
||||
/>
|
||||
</If>
|
||||
<If condition={sessionSettingsModal != null}>
|
||||
<SessionSettingsModal key={sessionSettingsModal} sessionId={sessionSettingsModal} />
|
||||
</If>
|
||||
<If condition={lineSettingsModal != null}>
|
||||
<LineSettingsModal key={String(lineSettingsModal)} linenum={lineSettingsModal} />
|
||||
</If>
|
||||
<If condition={clientSettingsModal}>
|
||||
<ClientSettingsModal />
|
||||
</If>
|
||||
<If condition={remotesModal}>
|
||||
<RemotesModal model={GlobalModel.remotesModalModel} />
|
||||
</If>
|
||||
<ModalsProvider />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
export const ABOUT = "about";
|
||||
export const CREATE_REMOTE = "createRemote";
|
||||
export const VIEW_REMOTE = "viewRemote";
|
||||
export const EDIT_REMOTE = "editRemote";
|
||||
export const ALERT = "alert";
|
||||
export const SCREEN_SETTINGS = "screenSettings";
|
||||
export const SESSION_SETTINGS = "sessionSettings";
|
||||
export const LINE_SETTINGS = "lineSettings";
|
||||
export const CLIENT_SETTINGS = "clientSettings";
|
||||
|
||||
export const LineContainer_Main = "main";
|
||||
export const LineContainer_History = "history";
|
||||
export const LineContainer_Sidebar = "sidebar";
|
||||
+251
-35
@@ -134,7 +134,7 @@
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 23px;
|
||||
height: 22px;
|
||||
|
||||
input {
|
||||
opacity: 0;
|
||||
@@ -160,8 +160,8 @@
|
||||
content: "";
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
left: 2px;
|
||||
bottom: 2px;
|
||||
background-color: @term-white;
|
||||
transition: 0.5s;
|
||||
border-radius: 50%;
|
||||
@@ -247,7 +247,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.button.is-prompt-green {
|
||||
.button.is-wave-green {
|
||||
background-color: #222;
|
||||
color: @term-white;
|
||||
|
||||
@@ -257,33 +257,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button {
|
||||
display: flex;
|
||||
padding: 6px 16px !important;
|
||||
color: @term-white !important;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border-radius: 6px !important;
|
||||
height: auto !important;
|
||||
|
||||
&:hover {
|
||||
color: @term-white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button.is-wave-green {
|
||||
color: @term-bright-white !important;
|
||||
background: @term-green !important;
|
||||
|
||||
&:hover {
|
||||
background-color: @term-green;
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.8) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.6) inset;
|
||||
color: @term-bright-white !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.button.is-plain,
|
||||
.button.is-prompt-cancel {
|
||||
background-color: #222;
|
||||
@@ -637,13 +610,18 @@
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
height: 44px;
|
||||
width: 412px;
|
||||
min-width: 150px;
|
||||
width: 100%;
|
||||
border: 1px solid var(--element-separator, rgba(241, 246, 243, 0.15));
|
||||
border-radius: 6px;
|
||||
background: var(--element-hover-2, rgba(255, 255, 255, 0.06));
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||
|
||||
&.no-label {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
&-label {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
@@ -801,10 +779,18 @@
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||
|
||||
&:hover {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
&.focused {
|
||||
border-color: @term-green;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: @term-red;
|
||||
}
|
||||
@@ -859,7 +845,7 @@
|
||||
justify-content: center;
|
||||
|
||||
i {
|
||||
font-size: 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,11 +869,11 @@
|
||||
background-color: #444;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
max-width: 300px;
|
||||
width: 300px;
|
||||
|
||||
i {
|
||||
display: inline;
|
||||
font-size: 16px;
|
||||
font-size: 13px;
|
||||
fill: @base-color;
|
||||
padding-top: 0.2em;
|
||||
}
|
||||
@@ -931,3 +917,233 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button {
|
||||
background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
|
||||
display: flex;
|
||||
padding: 6px 16px;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border-radius: 6px;
|
||||
height: auto;
|
||||
|
||||
&:hover {
|
||||
color: @term-white;
|
||||
}
|
||||
|
||||
i {
|
||||
fill: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
&.primary {
|
||||
color: @term-green;
|
||||
background: none;
|
||||
|
||||
i {
|
||||
fill: @term-green;
|
||||
}
|
||||
|
||||
&.solid {
|
||||
color: @term-bright-white;
|
||||
background: @term-green;
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.8) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.6) inset;
|
||||
|
||||
i {
|
||||
fill: @term-white;
|
||||
}
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
border: 1px solid @term-green;
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
// Styles for .ghost are already defined above
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: @term-bright-white;
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
color: @term-white;
|
||||
background: none;
|
||||
|
||||
&.solid {
|
||||
background: rgba(255, 255, 255, 0.09);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
border: 1px solid rgba(255, 255, 255, 0.09);
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
padding: 6px 10px;
|
||||
|
||||
i {
|
||||
fill: @term-green;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.color-yellow {
|
||||
&.solid {
|
||||
border-color: @warning-yellow;
|
||||
background-color: mix(@warning-yellow, @term-white, 50%);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
color: @warning-yellow;
|
||||
border-color: @warning-yellow;
|
||||
&:hover {
|
||||
color: @term-white;
|
||||
border-color: @term-white;
|
||||
}
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
}
|
||||
}
|
||||
|
||||
&.color-red {
|
||||
&.solid {
|
||||
border-color: @term-red;
|
||||
background-color: mix(@term-red, @term-white, 50%);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
color: @term-red;
|
||||
border-color: @term-red;
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.link-button {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-status-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.dot {
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.dot.green {
|
||||
background-color: @status-connected;
|
||||
}
|
||||
|
||||
.dot.red {
|
||||
background-color: @status-error;
|
||||
}
|
||||
|
||||
.dot.gray {
|
||||
background-color: @status-disconnected;
|
||||
}
|
||||
|
||||
.dot.yellow {
|
||||
background-color: @status-connecting;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 500;
|
||||
|
||||
.wave-modal-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(21, 23, 21, 0.7);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal {
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
border-radius: 10px;
|
||||
background: #151715;
|
||||
box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.35), 0px 10px 24px 0px rgba(0, 0, 0, 0.45),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||
|
||||
.wave-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
.wave-modal-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 14px 12px 20px;
|
||||
justify-content: space-between;
|
||||
line-height: 20px;
|
||||
border-bottom: 1px solid rgba(250, 250, 250, 0.1);
|
||||
|
||||
.wave-modal-title {
|
||||
color: #eceeec;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
button {
|
||||
i {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal-body {
|
||||
width: 100%;
|
||||
padding: 0px 20px;
|
||||
}
|
||||
|
||||
.wave-modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
padding: 0 20px 20px;
|
||||
|
||||
button:last-child {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+233
-47
@@ -99,7 +99,7 @@ class Toggle extends React.Component<{ checked: boolean; onChange: (value: boole
|
||||
}
|
||||
|
||||
class Checkbox extends React.Component<
|
||||
{ checked: boolean; onChange: (value: boolean) => void; label: string; id: string },
|
||||
{ checked: boolean; onChange: (value: boolean) => void; label: React.ReactNode; id: string },
|
||||
{}
|
||||
> {
|
||||
render() {
|
||||
@@ -150,6 +150,7 @@ interface TooltipProps {
|
||||
message: React.ReactNode;
|
||||
icon?: React.ReactNode; // Optional icon property
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface TooltipState {
|
||||
@@ -185,8 +186,8 @@ class Tooltip extends React.Component<TooltipProps, TooltipState> {
|
||||
if (iconElement) {
|
||||
const rect = iconElement.getBoundingClientRect();
|
||||
return {
|
||||
top: `${rect.bottom + window.scrollY - 29.5}px`,
|
||||
left: `${rect.left + window.scrollX + rect.width / 2 - 19}px`,
|
||||
top: `${rect.bottom + window.scrollY - 29}px`,
|
||||
left: `${rect.left + window.scrollX + rect.width / 2 - 17.5}px`,
|
||||
};
|
||||
}
|
||||
return {};
|
||||
@@ -199,7 +200,7 @@ class Tooltip extends React.Component<TooltipProps, TooltipState> {
|
||||
const style = this.calculatePosition();
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<div className="wave-tooltip" style={style}>
|
||||
<div className={cn("wave-tooltip", this.props.className)} style={style}>
|
||||
{this.props.icon && <div className="wave-tooltip-icon">{this.props.icon}</div>}
|
||||
<div className="wave-tooltip-message">{this.props.message}</div>
|
||||
</div>,
|
||||
@@ -217,6 +218,115 @@ class Tooltip extends React.Component<TooltipProps, TooltipState> {
|
||||
}
|
||||
}
|
||||
|
||||
type ButtonVariantType = "outlined" | "solid" | "ghost";
|
||||
type ButtonThemeType = "primary" | "secondary";
|
||||
|
||||
interface ButtonProps {
|
||||
theme?: ButtonThemeType;
|
||||
children: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
disabled?: boolean;
|
||||
variant?: ButtonVariantType;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
color?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
class Button extends React.Component<ButtonProps> {
|
||||
static defaultProps = {
|
||||
theme: "primary",
|
||||
variant: "solid",
|
||||
color: "",
|
||||
style: {},
|
||||
};
|
||||
|
||||
@boundMethod
|
||||
handleClick() {
|
||||
if (this.props.onClick && !this.props.disabled) {
|
||||
this.props.onClick();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { leftIcon, rightIcon, theme, children, disabled, variant, color, style } = this.props;
|
||||
|
||||
return (
|
||||
<button
|
||||
className={cn("wave-button", theme, variant, color, { disabled: disabled })}
|
||||
onClick={this.handleClick}
|
||||
disabled={disabled}
|
||||
style={style}
|
||||
>
|
||||
{leftIcon && <span className="icon-left">{leftIcon}</span>}
|
||||
{children}
|
||||
{rightIcon && <span className="icon-right">{rightIcon}</span>}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class IconButton extends Button {
|
||||
render() {
|
||||
const { children, theme, variant = "solid", ...rest } = this.props;
|
||||
const className = `wave-button icon-button ${theme} ${variant}`;
|
||||
|
||||
return (
|
||||
<button {...rest} className={className}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default IconButton;
|
||||
|
||||
interface LinkButtonProps extends ButtonProps {
|
||||
href: string;
|
||||
target?: string;
|
||||
}
|
||||
|
||||
class LinkButton extends IconButton {
|
||||
render() {
|
||||
// @ts-ignore
|
||||
const { href, target, leftIcon, rightIcon, children, theme, variant }: LinkButtonProps = this.props;
|
||||
|
||||
return (
|
||||
<a href={href} target={target} className={`wave-button link-button`}>
|
||||
<button {...this.props} className={`icon-button ${theme} ${variant}`}>
|
||||
{leftIcon && <span className="icon-left">{leftIcon}</span>}
|
||||
{children}
|
||||
{rightIcon && <span className="icon-right">{rightIcon}</span>}
|
||||
</button>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
}
|
||||
interface StatusProps {
|
||||
status: "green" | "red" | "gray" | "yellow";
|
||||
text: string;
|
||||
}
|
||||
|
||||
class Status extends React.Component<StatusProps> {
|
||||
@boundMethod
|
||||
renderDot() {
|
||||
const { status } = this.props;
|
||||
|
||||
return <div className={`dot ${status}`} />;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { text } = this.props;
|
||||
|
||||
return (
|
||||
<div className="wave-status-container">
|
||||
{this.renderDot()}
|
||||
<span>{text}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface TextFieldDecorationProps {
|
||||
startDecoration?: React.ReactNode;
|
||||
endDecoration?: React.ReactNode;
|
||||
@@ -232,6 +342,7 @@ interface TextFieldProps {
|
||||
required?: boolean;
|
||||
maxLength?: number;
|
||||
autoFocus?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
interface TextFieldState {
|
||||
@@ -242,7 +353,6 @@ interface TextFieldState {
|
||||
hasContent: boolean;
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
||||
inputRef: React.RefObject<HTMLInputElement>;
|
||||
state: TextFieldState;
|
||||
@@ -267,6 +377,22 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
||||
}
|
||||
}
|
||||
|
||||
// Method to handle focus at the component level
|
||||
@boundMethod
|
||||
handleComponentFocus() {
|
||||
if (this.inputRef.current && !this.inputRef.current.contains(document.activeElement)) {
|
||||
this.inputRef.current.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// Method to handle blur at the component level
|
||||
@boundMethod
|
||||
handleComponentBlur() {
|
||||
if (this.inputRef.current?.contains(document.activeElement)) {
|
||||
this.inputRef.current.blur();
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleFocus() {
|
||||
this.setState({ focused: true });
|
||||
@@ -311,14 +437,23 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { label, value, placeholder, decoration, className, maxLength, autoFocus } = this.props;
|
||||
const { label, value, placeholder, decoration, className, maxLength, autoFocus, disabled } = this.props;
|
||||
const { focused, internalValue, error } = this.state;
|
||||
|
||||
// Decide if the input should behave as controlled or uncontrolled
|
||||
const inputValue = value !== undefined ? value : internalValue;
|
||||
const inputValue = value ?? internalValue;
|
||||
|
||||
return (
|
||||
<div className={cn(`wave-textfield ${className || ""}`, { focused: focused, error: error })}>
|
||||
<div
|
||||
className={cn(`wave-textfield ${className || ""}`, {
|
||||
focused: focused,
|
||||
error: error,
|
||||
disabled: disabled,
|
||||
})}
|
||||
onFocus={this.handleComponentFocus}
|
||||
onBlur={this.handleComponentBlur}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{decoration?.startDecoration && <>{decoration.startDecoration}</>}
|
||||
<div className="wave-textfield-inner">
|
||||
<label
|
||||
@@ -341,6 +476,7 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
||||
placeholder={placeholder}
|
||||
maxLength={maxLength}
|
||||
autoFocus={autoFocus}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
{decoration?.endDecoration && <>{decoration.endDecoration}</>}
|
||||
@@ -372,34 +508,10 @@ class NumberField extends TextField {
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {
|
||||
// Allow backspace, delete, tab, escape, and enter
|
||||
if (
|
||||
[46, 8, 9, 27, 13].includes(event.keyCode) ||
|
||||
// Allow: Ctrl+A, Ctrl+C, Ctrl+X
|
||||
((event.keyCode === 65 || event.keyCode === 67 || event.keyCode === 88) && event.ctrlKey === true) ||
|
||||
// Allow: home, end, left, right
|
||||
(event.keyCode >= 35 && event.keyCode <= 39)
|
||||
) {
|
||||
return; // let it happen, don't do anything
|
||||
}
|
||||
// Ensure that it is a number and stop the keypress
|
||||
if (
|
||||
(event.shiftKey || event.keyCode < 48 || event.keyCode > 57) &&
|
||||
(event.keyCode < 96 || event.keyCode > 105)
|
||||
) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
// Use the render method from TextField but add the onKeyDown handler
|
||||
const renderedTextField = super.render();
|
||||
|
||||
return React.cloneElement(renderedTextField, {
|
||||
onKeyDown: this.handleKeyDown,
|
||||
});
|
||||
return React.cloneElement(renderedTextField);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,7 +549,7 @@ class PasswordField extends TextField {
|
||||
render() {
|
||||
const { decoration, className, placeholder, maxLength, label } = this.props;
|
||||
const { focused, internalValue, error, passwordVisible } = this.state;
|
||||
const inputValue = this.props.value !== undefined ? this.props.value : internalValue;
|
||||
const inputValue = this.props.value ?? internalValue;
|
||||
|
||||
// The input should always receive the real value
|
||||
const inputProps = {
|
||||
@@ -617,7 +729,7 @@ class InlineSettingsTextEdit extends React.Component<
|
||||
<div
|
||||
onClick={this.confirmChange}
|
||||
title="Confirm (Enter)"
|
||||
className="button is-prompt-green is-outlined is-small"
|
||||
className="button is-wave-green is-outlined is-small"
|
||||
>
|
||||
<span className="icon is-small">
|
||||
<i className="fa-sharp fa-solid fa-check" />
|
||||
@@ -662,7 +774,7 @@ class InfoMessage extends React.Component<{ width: number; children: React.React
|
||||
function LinkRenderer(props: any): any {
|
||||
let newUrl = "https://extern?" + encodeURIComponent(props.href);
|
||||
return (
|
||||
<a href={newUrl} target="_blank">
|
||||
<a href={newUrl} target="_blank" rel={"noopener"}>
|
||||
{props.children}
|
||||
</a>
|
||||
);
|
||||
@@ -729,7 +841,7 @@ interface DropdownDecorationProps {
|
||||
}
|
||||
|
||||
interface DropdownProps {
|
||||
label: string;
|
||||
label?: string;
|
||||
options: { value: string; label: string }[];
|
||||
value?: string;
|
||||
className?: string;
|
||||
@@ -896,7 +1008,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
const { label, options, value, placeholder, decoration, className, required } = this.props;
|
||||
const { isOpen, internalValue, highlightedIndex, isTouched } = this.state;
|
||||
|
||||
const currentValue = value !== undefined ? value : internalValue;
|
||||
const currentValue = value ?? internalValue;
|
||||
const selectedOptionLabel =
|
||||
options.find((option) => option.value === currentValue)?.label || placeholder || internalValue;
|
||||
|
||||
@@ -916,7 +1028,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
{options.map((option, index) => (
|
||||
<div
|
||||
key={option.value}
|
||||
className={cn("wave-dropdown-item", {
|
||||
className={cn("wave-dropdown-item unselectable", {
|
||||
"wave-dropdown-item-highlighted": index === highlightedIndex,
|
||||
})}
|
||||
onClick={(e) => this.handleSelect(option.value, e)}
|
||||
@@ -933,8 +1045,9 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(`wave-dropdown ${className || ""}`, {
|
||||
className={cn("wave-dropdown", className, {
|
||||
"wave-dropdown-error": isError,
|
||||
"no-label": !label,
|
||||
})}
|
||||
ref={this.wrapperRef}
|
||||
tabIndex={0}
|
||||
@@ -943,15 +1056,19 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
onFocus={this.handleFocus}
|
||||
>
|
||||
{decoration?.startDecoration && <>{decoration.startDecoration}</>}
|
||||
<If condition={label}>
|
||||
<div
|
||||
className={cn("wave-dropdown-label unselectable", {
|
||||
float: shouldLabelFloat,
|
||||
"offset-left": decoration?.startDecoration,
|
||||
})}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
</If>
|
||||
<div
|
||||
className={cn("wave-dropdown-label", {
|
||||
float: shouldLabelFloat,
|
||||
"offset-left": decoration?.startDecoration,
|
||||
})}
|
||||
className={cn("wave-dropdown-display unselectable", { "offset-left": decoration?.startDecoration })}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
<div className={cn("wave-dropdown-display", { "offset-left": decoration?.startDecoration })}>
|
||||
{selectedOptionLabel}
|
||||
</div>
|
||||
<div className={cn("wave-dropdown-arrow", { "wave-dropdown-arrow-rotate": isOpen })}>
|
||||
@@ -964,6 +1081,70 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
}
|
||||
}
|
||||
|
||||
interface ModalHeaderProps {
|
||||
onClose: () => void;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const ModalHeader: React.FC<ModalHeaderProps> = ({ onClose, title }) => (
|
||||
<div className="wave-modal-header">
|
||||
{<div className="wave-modal-title">{title}</div>}
|
||||
<IconButton theme="secondary" variant="ghost" onClick={onClose}>
|
||||
<i className="fa-sharp fa-solid fa-xmark"></i>
|
||||
</IconButton>
|
||||
</div>
|
||||
);
|
||||
|
||||
interface ModalFooterProps {
|
||||
onCancel?: () => void;
|
||||
onOk?: () => void;
|
||||
cancelLabel?: string;
|
||||
okLabel?: string;
|
||||
}
|
||||
|
||||
const ModalFooter: React.FC<ModalFooterProps> = ({ onCancel, onOk, cancelLabel = "Cancel", okLabel = "Ok" }) => (
|
||||
<div className="wave-modal-footer">
|
||||
{onCancel && (
|
||||
<Button theme="secondary" onClick={onCancel}>
|
||||
{cancelLabel}
|
||||
</Button>
|
||||
)}
|
||||
{onOk && <Button onClick={onOk}>{okLabel}</Button>}
|
||||
</div>
|
||||
);
|
||||
|
||||
interface ModalProps {
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
onClickBackdrop?: () => void;
|
||||
}
|
||||
|
||||
class Modal extends React.Component<ModalProps> {
|
||||
static Header = ModalHeader;
|
||||
static Footer = ModalFooter;
|
||||
|
||||
renderBackdrop(onClick: (() => void) | undefined) {
|
||||
return <div className="wave-modal-backdrop" onClick={onClick}></div>;
|
||||
}
|
||||
|
||||
renderModal() {
|
||||
const { className, children } = this.props;
|
||||
|
||||
return (
|
||||
<div className="wave-modal-container">
|
||||
{this.renderBackdrop(this.props.onClickBackdrop)}
|
||||
<div className={`wave-modal ${className}`}>
|
||||
<div className="wave-modal-content">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return ReactDOM.createPortal(this.renderModal(), document.getElementById("app") );
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
CmdStrCode,
|
||||
Toggle,
|
||||
@@ -980,4 +1161,9 @@ export {
|
||||
NumberField,
|
||||
PasswordField,
|
||||
Tooltip,
|
||||
Button,
|
||||
IconButton,
|
||||
LinkButton,
|
||||
Status,
|
||||
Modal,
|
||||
};
|
||||
|
||||
+392
-189
File diff suppressed because it is too large
Load Diff
+972
-329
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import {
|
||||
AboutModal,
|
||||
CreateRemoteConnModal,
|
||||
ViewRemoteConnDetailModal,
|
||||
EditRemoteConnModal,
|
||||
AlertModal,
|
||||
} from "./modals";
|
||||
import { ScreenSettingsModal, SessionSettingsModal, LineSettingsModal, ClientSettingsModal } from "./settings";
|
||||
import * as constants from "../../appconst";
|
||||
|
||||
const modalsRegistry: { [key: string]: () => React.ReactElement } = {
|
||||
[constants.ABOUT]: () => <AboutModal />,
|
||||
[constants.CREATE_REMOTE]: () => <CreateRemoteConnModal />,
|
||||
[constants.VIEW_REMOTE]: () => <ViewRemoteConnDetailModal />,
|
||||
[constants.EDIT_REMOTE]: () => <EditRemoteConnModal />,
|
||||
[constants.ALERT]: () => <AlertModal />,
|
||||
[constants.SCREEN_SETTINGS]: () => <ScreenSettingsModal />,
|
||||
[constants.SESSION_SETTINGS]: () => <SessionSettingsModal />,
|
||||
[constants.LINE_SETTINGS]: () => <LineSettingsModal />,
|
||||
[constants.CLIENT_SETTINGS]: () => <ClientSettingsModal />,
|
||||
};
|
||||
|
||||
export { modalsRegistry };
|
||||
+448
-389
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
vertical-align: middle;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
fill: @prompt-green;
|
||||
fill: @wave-green;
|
||||
}
|
||||
|
||||
.term-prompt-branch {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
@background-session: rgba(13, 13, 13, 0.85);
|
||||
@background-session-components: rgba(48, 49, 48, 0.6);
|
||||
@background-session-components-solid: rgb(33, 34, 33);
|
||||
@prompt-green: rgb(88, 193, 66);
|
||||
@wave-green: rgb(88, 193, 66);
|
||||
@disabled-background: rgba(76, 81, 75, 1);
|
||||
@disabled-color: #adadad;
|
||||
@scrollbar-background: rgba(21, 23, 21, 1);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user