Compare commits
4 Commits
acd3fa9304
...
54864fe7d5
Author | SHA1 | Date |
---|---|---|
|
54864fe7d5 | |
|
1cf893149a | |
|
5b4683a735 | |
|
6f5ea748f5 |
|
@ -2,6 +2,7 @@ build/bin
|
||||||
node_modules
|
node_modules
|
||||||
frontend/dist
|
frontend/dist
|
||||||
frontend/wailsjs
|
frontend/wailsjs
|
||||||
|
frontend/package.json.md5
|
||||||
design/
|
design/
|
||||||
.vscode
|
.vscode
|
||||||
.idea
|
.idea
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"tinyrdm/backend/types"
|
||||||
|
sliceutil "tinyrdm/backend/utils/slice"
|
||||||
|
strutil "tinyrdm/backend/utils/string"
|
||||||
|
)
|
||||||
|
|
||||||
|
type cliService struct {
|
||||||
|
ctx context.Context
|
||||||
|
ctxCancel context.CancelFunc
|
||||||
|
mutex sync.Mutex
|
||||||
|
clients map[string]redis.UniversalClient
|
||||||
|
selectedDB map[string]int
|
||||||
|
}
|
||||||
|
|
||||||
|
type cliOutput struct {
|
||||||
|
Content string `json:"content"` // output content
|
||||||
|
Prompt string `json:"prompt,omitempty"` // new line prompt, empty if not ready to input
|
||||||
|
}
|
||||||
|
|
||||||
|
var cli *cliService
|
||||||
|
var onceCli sync.Once
|
||||||
|
|
||||||
|
func Cli() *cliService {
|
||||||
|
if cli == nil {
|
||||||
|
onceCli.Do(func() {
|
||||||
|
cli = &cliService{
|
||||||
|
clients: map[string]redis.UniversalClient{},
|
||||||
|
selectedDB: map[string]int{},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return cli
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cliService) runCommand(server, data string) {
|
||||||
|
if cmds := strings.Split(data, " "); len(cmds) > 0 && len(cmds[0]) > 0 {
|
||||||
|
if client, err := c.getRedisClient(server); err == nil {
|
||||||
|
args := sliceutil.Map(cmds, func(i int) any {
|
||||||
|
return cmds[i]
|
||||||
|
})
|
||||||
|
if result, err := client.Do(c.ctx, args...).Result(); err == nil || err == redis.Nil {
|
||||||
|
if strings.ToLower(cmds[0]) == "select" {
|
||||||
|
// switch database
|
||||||
|
if db, ok := strutil.AnyToInt(cmds[1]); ok {
|
||||||
|
c.selectedDB[server] = db
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.echo(server, strutil.AnyToString(result), true)
|
||||||
|
} else {
|
||||||
|
c.echoError(server, err.Error())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.echoReady(server)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cliService) echo(server, data string, newLineReady bool) {
|
||||||
|
output := cliOutput{
|
||||||
|
Content: data,
|
||||||
|
}
|
||||||
|
if newLineReady {
|
||||||
|
output.Prompt = fmt.Sprintf("%s:db%d> ", server, c.selectedDB[server])
|
||||||
|
}
|
||||||
|
runtime.EventsEmit(c.ctx, "cmd:output:"+server, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cliService) echoReady(server string) {
|
||||||
|
c.echo(server, "", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cliService) echoError(server, data string) {
|
||||||
|
c.echo(server, "\x1b[31m"+data+"\x1b[0m", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cliService) getRedisClient(server string) (redis.UniversalClient, error) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
|
||||||
|
client, ok := c.clients[server]
|
||||||
|
if !ok {
|
||||||
|
var err error
|
||||||
|
conf := Connection().getConnection(server)
|
||||||
|
if conf == nil {
|
||||||
|
return nil, fmt.Errorf("no connection profile named: %s", server)
|
||||||
|
}
|
||||||
|
if client, err = Connection().createRedisClient(conf.ConnectionConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c.clients[server] = client
|
||||||
|
}
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cliService) Start(ctx context.Context) {
|
||||||
|
c.ctx, c.ctxCancel = context.WithCancel(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartCli start a cli session
|
||||||
|
func (c *cliService) StartCli(server string, db int) (resp types.JSResp) {
|
||||||
|
client, err := c.getRedisClient(server)
|
||||||
|
if err != nil {
|
||||||
|
resp.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client.Do(c.ctx, "select", db)
|
||||||
|
c.selectedDB[server] = db
|
||||||
|
|
||||||
|
// monitor input
|
||||||
|
runtime.EventsOn(c.ctx, "cmd:input:"+server, func(data ...interface{}) {
|
||||||
|
if len(data) > 0 {
|
||||||
|
if str, ok := data[0].(string); ok {
|
||||||
|
c.runCommand(server, str)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.echoReady(server)
|
||||||
|
})
|
||||||
|
|
||||||
|
// echo prefix
|
||||||
|
c.echoReady(server)
|
||||||
|
resp.Success = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseCli close cli session
|
||||||
|
func (c *cliService) CloseCli(server string) (resp types.JSResp) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
|
||||||
|
if client, ok := c.clients[server]; ok {
|
||||||
|
client.Close()
|
||||||
|
delete(c.clients, server)
|
||||||
|
delete(c.selectedDB, server)
|
||||||
|
}
|
||||||
|
runtime.EventsOff(c.ctx, "cmd:input:"+server)
|
||||||
|
resp.Success = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseAll close all cli sessions
|
||||||
|
func (c *cliService) CloseAll() {
|
||||||
|
if c.ctxCancel != nil {
|
||||||
|
c.ctxCancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
for server := range c.clients {
|
||||||
|
c.CloseCli(server)
|
||||||
|
}
|
||||||
|
}
|
|
@ -71,7 +71,7 @@ func (c *connectionService) Start(ctx context.Context) {
|
||||||
c.ctx = ctx
|
c.ctx = ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connectionService) Stop(ctx context.Context) {
|
func (c *connectionService) Stop() {
|
||||||
for _, item := range c.connMap {
|
for _, item := range c.connMap {
|
||||||
if item.client != nil {
|
if item.client != nil {
|
||||||
item.cancelFunc()
|
item.cancelFunc()
|
||||||
|
@ -307,9 +307,13 @@ func (c *connectionService) ListConnection() (resp types.JSResp) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *connectionService) getConnection(name string) *types.Connection {
|
||||||
|
return c.conns.GetConnection(name)
|
||||||
|
}
|
||||||
|
|
||||||
// GetConnection get connection profile by name
|
// GetConnection get connection profile by name
|
||||||
func (c *connectionService) GetConnection(name string) (resp types.JSResp) {
|
func (c *connectionService) GetConnection(name string) (resp types.JSResp) {
|
||||||
conn := c.conns.GetConnection(name)
|
conn := c.getConnection(name)
|
||||||
resp.Success = conn != nil
|
resp.Success = conn != nil
|
||||||
resp.Data = conn
|
resp.Data = conn
|
||||||
return
|
return
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
package strutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
sliceutil "tinyrdm/backend/utils/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AnyToString(value interface{}) (s string) {
|
||||||
|
if value == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch value.(type) {
|
||||||
|
case float64:
|
||||||
|
ft := value.(float64)
|
||||||
|
s = strconv.FormatFloat(ft, 'f', -1, 64)
|
||||||
|
case float32:
|
||||||
|
ft := value.(float32)
|
||||||
|
s = strconv.FormatFloat(float64(ft), 'f', -1, 64)
|
||||||
|
case int:
|
||||||
|
it := value.(int)
|
||||||
|
s = strconv.Itoa(it)
|
||||||
|
case uint:
|
||||||
|
it := value.(uint)
|
||||||
|
s = strconv.Itoa(int(it))
|
||||||
|
case int8:
|
||||||
|
it := value.(int8)
|
||||||
|
s = strconv.Itoa(int(it))
|
||||||
|
case uint8:
|
||||||
|
it := value.(uint8)
|
||||||
|
s = strconv.Itoa(int(it))
|
||||||
|
case int16:
|
||||||
|
it := value.(int16)
|
||||||
|
s = strconv.Itoa(int(it))
|
||||||
|
case uint16:
|
||||||
|
it := value.(uint16)
|
||||||
|
s = strconv.Itoa(int(it))
|
||||||
|
case int32:
|
||||||
|
it := value.(int32)
|
||||||
|
s = strconv.Itoa(int(it))
|
||||||
|
case uint32:
|
||||||
|
it := value.(uint32)
|
||||||
|
s = strconv.Itoa(int(it))
|
||||||
|
case int64:
|
||||||
|
it := value.(int64)
|
||||||
|
s = strconv.FormatInt(it, 10)
|
||||||
|
case uint64:
|
||||||
|
it := value.(uint64)
|
||||||
|
s = strconv.FormatUint(it, 10)
|
||||||
|
case string:
|
||||||
|
s = value.(string)
|
||||||
|
case bool:
|
||||||
|
val, _ := value.(bool)
|
||||||
|
if val {
|
||||||
|
s = "True"
|
||||||
|
} else {
|
||||||
|
s = "False"
|
||||||
|
}
|
||||||
|
case []byte:
|
||||||
|
s = string(value.([]byte))
|
||||||
|
case []string:
|
||||||
|
ss := value.([]string)
|
||||||
|
anyStr := sliceutil.Map(ss, func(i int) string {
|
||||||
|
str := AnyToString(ss[i])
|
||||||
|
return strconv.Itoa(i+1) + ") \"" + str + "\""
|
||||||
|
})
|
||||||
|
s = sliceutil.JoinString(anyStr, "\r\n")
|
||||||
|
case []any:
|
||||||
|
as := value.([]any)
|
||||||
|
anyItems := sliceutil.Map(as, func(i int) string {
|
||||||
|
str := AnyToString(as[i])
|
||||||
|
return strconv.Itoa(i+1) + ") \"" + str + "\""
|
||||||
|
})
|
||||||
|
s = sliceutil.JoinString(anyItems, "\r\n")
|
||||||
|
default:
|
||||||
|
b, _ := json.Marshal(value)
|
||||||
|
s = string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//func AnyToHex(val any) (string, bool) {
|
||||||
|
// var src string
|
||||||
|
// switch val.(type) {
|
||||||
|
// case string:
|
||||||
|
// src = val.(string)
|
||||||
|
// case []byte:
|
||||||
|
// src = string(val.([]byte))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if len(src) <= 0 {
|
||||||
|
// return "", false
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var output strings.Builder
|
||||||
|
// for i := range src {
|
||||||
|
// if !utf8.ValidString(src[i : i+1]) {
|
||||||
|
// output.WriteString(fmt.Sprintf("\\x%02x", src[i:i+1]))
|
||||||
|
// } else {
|
||||||
|
// output.WriteString(src[i : i+1])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return output.String(), true
|
||||||
|
//}
|
|
@ -12,15 +12,17 @@
|
||||||
"highlight.js": "^11.9.0",
|
"highlight.js": "^11.9.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"sass": "^1.69.4",
|
"sass": "^1.69.5",
|
||||||
"vue": "^3.3.6",
|
"vue": "^3.3.7",
|
||||||
"vue-i18n": "^9.5.0"
|
"vue-i18n": "^9.6.0",
|
||||||
|
"xterm": "^5.3.0",
|
||||||
|
"xterm-addon-fit": "^0.8.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^4.4.0",
|
"@vitejs/plugin-vue": "^4.4.0",
|
||||||
"naive-ui": "^2.35.0",
|
"naive-ui": "^2.35.0",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.0.3",
|
||||||
"unplugin-auto-import": "^0.16.6",
|
"unplugin-auto-import": "^0.16.7",
|
||||||
"unplugin-icons": "^0.17.1",
|
"unplugin-icons": "^0.17.1",
|
||||||
"unplugin-vue-components": "^0.25.2",
|
"unplugin-vue-components": "^0.25.2",
|
||||||
"vite": "^4.5.0"
|
"vite": "^4.5.0"
|
||||||
|
@ -462,23 +464,23 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/core-base": {
|
"node_modules/@intlify/core-base": {
|
||||||
"version": "9.5.0",
|
"version": "9.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.6.0.tgz",
|
||||||
"integrity": "sha512-y3ufM1RJbI/DSmJf3lYs9ACq3S/iRvaSsE3rPIk0MGH7fp+JxU6rdryv/EYcwfcr3Y1aHFlCBir6S391hRZ57w==",
|
"integrity": "sha512-9xWsUFrQq4iP1amH3cEIlUHsCXO541RGRDfrKqaDhlYvMbf2qTzpSjqeL3kWw1b+rC8XWHw+cgZXa4VPdOzqfg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/message-compiler": "9.5.0",
|
"@intlify/message-compiler": "9.6.0",
|
||||||
"@intlify/shared": "9.5.0"
|
"@intlify/shared": "9.6.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/message-compiler": {
|
"node_modules/@intlify/message-compiler": {
|
||||||
"version": "9.5.0",
|
"version": "9.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.6.0.tgz",
|
||||||
"integrity": "sha512-CAhVNfEZcOVFg0/5MNyt+OFjvs4J/ARjCj2b+54/FvFP0EDJI5lIqMTSDBE7k0atMROSP0SvWCkwu/AZ5xkK1g==",
|
"integrity": "sha512-GucIIYA2H86gdf/lKHAahfLpyYm9Q1IUc/yUEMk8wwwfrzBwuYmTDg90ooed7eRVx2N/omyDyuhKV4cRp3b+DQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/shared": "9.5.0",
|
"@intlify/shared": "9.6.0",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -486,9 +488,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/shared": {
|
"node_modules/@intlify/shared": {
|
||||||
"version": "9.5.0",
|
"version": "9.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.6.0.tgz",
|
||||||
"integrity": "sha512-tAxV14LMXZDZbu32XzLMTsowNlgJNmLwWHYzvMUl6L8gvQeoYiZONjY7AUsqZW8TOZDX9lfvF6adPkk9FSRdDA==",
|
"integrity": "sha512-vZeID7kn10rhgRYZQvjULTOYXDGnC0j49HI0AD9CK08aj4nWmlPai/8awTsMg0qrfHVMTna8ZMNmBZNyFAUCfA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
}
|
}
|
||||||
|
@ -540,9 +542,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/pluginutils": {
|
"node_modules/@rollup/pluginutils": {
|
||||||
"version": "5.0.4",
|
"version": "5.0.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
|
||||||
"integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==",
|
"integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "^1.0.0",
|
"@types/estree": "^1.0.0",
|
||||||
|
@ -553,7 +555,7 @@
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"rollup": "^1.20.0||^2.0.0||^3.0.0"
|
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"rollup": {
|
"rollup": {
|
||||||
|
@ -602,36 +604,36 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.7.tgz",
|
||||||
"integrity": "sha512-2JNjemwaNwf+MkkatATVZi7oAH1Hx0B04DdPH3ZoZ8vKC1xZVP7nl4HIsk8XYd3r+/52sqqoz9TWzYc3yE9dqA==",
|
"integrity": "sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.0",
|
"@babel/parser": "^7.23.0",
|
||||||
"@vue/shared": "3.3.6",
|
"@vue/shared": "3.3.7",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.7.tgz",
|
||||||
"integrity": "sha512-1MxXcJYMHiTPexjLAJUkNs/Tw2eDf2tY3a0rL+LfuWyiKN2s6jvSwywH3PWD8bKICjfebX3GWx2Os8jkRDq3Ng==",
|
"integrity": "sha512-0LwkyJjnUPssXv/d1vNJ0PKfBlDoQs7n81CbO6Q0zdL7H1EzqYRrTVXDqdBVqro0aJjo/FOa1qBAPVI4PGSHBw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.3.6",
|
"@vue/compiler-core": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.7.tgz",
|
||||||
"integrity": "sha512-/Kms6du2h1VrXFreuZmlvQej8B1zenBqIohP0690IUBkJjsFvJxY0crcvVRJ0UhMgSR9dewB+khdR1DfbpArJA==",
|
"integrity": "sha512-7pfldWy/J75U/ZyYIXRVqvLRw3vmfxDo2YLMwVtWVNew8Sm8d6wodM+OYFq4ll/UxfqVr0XKiVwti32PCrruAw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.0",
|
"@babel/parser": "^7.23.0",
|
||||||
"@vue/compiler-core": "3.3.6",
|
"@vue/compiler-core": "3.3.7",
|
||||||
"@vue/compiler-dom": "3.3.6",
|
"@vue/compiler-dom": "3.3.7",
|
||||||
"@vue/compiler-ssr": "3.3.6",
|
"@vue/compiler-ssr": "3.3.7",
|
||||||
"@vue/reactivity-transform": "3.3.6",
|
"@vue/reactivity-transform": "3.3.7",
|
||||||
"@vue/shared": "3.3.6",
|
"@vue/shared": "3.3.7",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.5",
|
"magic-string": "^0.30.5",
|
||||||
"postcss": "^8.4.31",
|
"postcss": "^8.4.31",
|
||||||
|
@ -639,12 +641,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.7.tgz",
|
||||||
"integrity": "sha512-QTIHAfDCHhjXlYGkUg5KH7YwYtdUM1vcFl/FxFDlD6d0nXAmnjizka3HITp8DGudzHndv2PjKVS44vqqy0vP4w==",
|
"integrity": "sha512-TxOfNVVeH3zgBc82kcUv+emNHo+vKnlRrkv8YvQU5+Y5LJGJwSNzcmLUoxD/dNzv0bhQ/F0s+InlgV0NrApJZg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.3.6",
|
"@vue/compiler-dom": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-api": {
|
"node_modules/@vue/devtools-api": {
|
||||||
|
@ -653,41 +655,41 @@
|
||||||
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.7.tgz",
|
||||||
"integrity": "sha512-gtChAumfQz5lSy5jZXfyXbKrIYPf9XEOrIr6rxwVyeWVjFhJwmwPLtV6Yis+M9onzX++I5AVE9j+iPH60U+B8Q==",
|
"integrity": "sha512-cZNVjWiw00708WqT0zRpyAgduG79dScKEPYJXq2xj/aMtk3SKvL3FBt2QKUlh6EHBJ1m8RhBY+ikBUzwc7/khg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity-transform": {
|
"node_modules/@vue/reactivity-transform": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.7.tgz",
|
||||||
"integrity": "sha512-RlJl4dHfeO7EuzU1iJOsrlqWyJfHTkJbvYz/IOJWqu8dlCNWtxWX377WI0VsbAgBizjwD+3ZjdnvSyyFW1YVng==",
|
"integrity": "sha512-APhRmLVbgE1VPGtoLQoWBJEaQk4V8JUsqrQihImVqKT+8U6Qi3t5ATcg4Y9wGAPb3kIhetpufyZ1RhwbZCIdDA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.0",
|
"@babel/parser": "^7.23.0",
|
||||||
"@vue/compiler-core": "3.3.6",
|
"@vue/compiler-core": "3.3.7",
|
||||||
"@vue/shared": "3.3.6",
|
"@vue/shared": "3.3.7",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.5"
|
"magic-string": "^0.30.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.7.tgz",
|
||||||
"integrity": "sha512-qp7HTP1iw1UW2ZGJ8L3zpqlngrBKvLsDAcq5lA6JvEXHmpoEmjKju7ahM9W2p/h51h0OT5F2fGlP/gMhHOmbUA==",
|
"integrity": "sha512-LHq9du3ubLZFdK/BP0Ysy3zhHqRfBn80Uc+T5Hz3maFJBGhci1MafccnL3rpd5/3wVfRHAe6c+PnlO2PAavPTQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.3.6",
|
"@vue/reactivity": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.7.tgz",
|
||||||
"integrity": "sha512-AoX3Cp8NqMXjLbIG9YR6n/pPLWE9TiDdk6wTJHFnl2GpHzDFH1HLBC9wlqqQ7RlnvN3bVLpzPGAAH00SAtOxHg==",
|
"integrity": "sha512-PFQU1oeJxikdDmrfoNQay5nD4tcPNYixUBruZzVX/l0eyZvFKElZUjW4KctCcs52nnpMGO6UDK+jF5oV4GT5Lw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/runtime-core": "3.3.6",
|
"@vue/runtime-core": "3.3.7",
|
||||||
"@vue/shared": "3.3.6",
|
"@vue/shared": "3.3.7",
|
||||||
"csstype": "^3.1.2"
|
"csstype": "^3.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -697,21 +699,21 @@
|
||||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.7.tgz",
|
||||||
"integrity": "sha512-kgLoN43W4ERdZ6dpyy+gnk2ZHtcOaIr5Uc/WUP5DRwutgvluzu2pudsZGoD2b7AEJHByUVMa9k6Sho5lLRCykw==",
|
"integrity": "sha512-UlpKDInd1hIZiNuVVVvLgxpfnSouxKQOSE2bOfQpBuGwxRV/JqqTCyyjXUWiwtVMyeRaZhOYYqntxElk8FhBhw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.3.6",
|
"@vue/compiler-ssr": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "3.3.6"
|
"vue": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.7.tgz",
|
||||||
"integrity": "sha512-Xno5pEqg8SVhomD0kTSmfh30ZEmV/+jZtyh39q6QflrjdJCXah5lrnOLi9KB6a5k5aAHXMXjoMnxlzUkCNfWLQ=="
|
"integrity": "sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg=="
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.10.0",
|
"version": "8.10.0",
|
||||||
|
@ -1545,9 +1547,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.69.4",
|
"version": "1.69.5",
|
||||||
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.69.4.tgz",
|
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.69.5.tgz",
|
||||||
"integrity": "sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA==",
|
"integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": ">=3.0.0 <4.0.0",
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
"immutable": "^4.0.0",
|
"immutable": "^4.0.0",
|
||||||
|
@ -1658,9 +1660,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/unimport": {
|
"node_modules/unimport": {
|
||||||
"version": "3.3.0",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.4.0.tgz",
|
||||||
"integrity": "sha512-3jhq3ZG5hFZzrWGDCpx83kjPzefP/EeuKkIO1T0MA4Zwj+dO/Og1mFvZ4aZ5WSDm0FVbbdVIRH1zKBG7c4wOpg==",
|
"integrity": "sha512-M/lfFEgufIT156QAr/jWHLUn55kEmxBBiQsMxvRSIbquwmeJEyQYgshHDEvQDWlSJrVOOTAgnJ3FvlsrpGkanA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rollup/pluginutils": "^5.0.4",
|
"@rollup/pluginutils": "^5.0.4",
|
||||||
|
@ -1668,12 +1670,12 @@
|
||||||
"fast-glob": "^3.3.1",
|
"fast-glob": "^3.3.1",
|
||||||
"local-pkg": "^0.4.3",
|
"local-pkg": "^0.4.3",
|
||||||
"magic-string": "^0.30.3",
|
"magic-string": "^0.30.3",
|
||||||
"mlly": "^1.4.1",
|
"mlly": "^1.4.2",
|
||||||
"pathe": "^1.1.1",
|
"pathe": "^1.1.1",
|
||||||
"pkg-types": "^1.0.3",
|
"pkg-types": "^1.0.3",
|
||||||
"scule": "^1.0.0",
|
"scule": "^1.0.0",
|
||||||
"strip-literal": "^1.3.0",
|
"strip-literal": "^1.3.0",
|
||||||
"unplugin": "^1.4.0"
|
"unplugin": "^1.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/unplugin": {
|
"node_modules/unplugin": {
|
||||||
|
@ -1689,19 +1691,19 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/unplugin-auto-import": {
|
"node_modules/unplugin-auto-import": {
|
||||||
"version": "0.16.6",
|
"version": "0.16.7",
|
||||||
"resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.16.6.tgz",
|
"resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.16.7.tgz",
|
||||||
"integrity": "sha512-M+YIITkx3C/Hg38hp8HmswP5mShUUyJOzpifv7RTlAbeFlO2Tyw0pwrogSSxnipHDPTtI8VHFBpkYkNKzYSuyA==",
|
"integrity": "sha512-w7XmnRlchq6YUFJVFGSvG1T/6j8GrdYN6Em9Wf0Ye+HXgD/22kont+WnuCAA0UaUoxtuvRR1u/mXKy63g/hfqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@antfu/utils": "^0.7.5",
|
"@antfu/utils": "^0.7.6",
|
||||||
"@rollup/pluginutils": "^5.0.2",
|
"@rollup/pluginutils": "^5.0.5",
|
||||||
"fast-glob": "^3.3.0",
|
"fast-glob": "^3.3.1",
|
||||||
"local-pkg": "^0.4.3",
|
"local-pkg": "^0.5.0",
|
||||||
"magic-string": "^0.30.1",
|
"magic-string": "^0.30.5",
|
||||||
"minimatch": "^9.0.2",
|
"minimatch": "^9.0.3",
|
||||||
"unimport": "^3.0.14",
|
"unimport": "^3.4.0",
|
||||||
"unplugin": "^1.3.2"
|
"unplugin": "^1.5.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
|
@ -1719,6 +1721,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/unplugin-auto-import/node_modules/local-pkg": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"mlly": "^1.4.2",
|
||||||
|
"pkg-types": "^1.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/unplugin-icons": {
|
"node_modules/unplugin-icons": {
|
||||||
"version": "0.17.1",
|
"version": "0.17.1",
|
||||||
"resolved": "https://registry.npmmirror.com/unplugin-icons/-/unplugin-icons-0.17.1.tgz",
|
"resolved": "https://registry.npmmirror.com/unplugin-icons/-/unplugin-icons-0.17.1.tgz",
|
||||||
|
@ -1882,15 +1897,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.7.tgz",
|
||||||
"integrity": "sha512-jJIDETeWJnoY+gfn4ZtMPMS5KtbP4ax+CT4dcQFhTnWEk8xMupFyQ0JxL28nvT/M4+p4a0ptxaV2WY0LiIxvRg==",
|
"integrity": "sha512-YEMDia1ZTv1TeBbnu6VybatmSteGOS3A3YgfINOfraCbf85wdKHzscD6HSS/vB4GAtI7sa1XPX7HcQaJ1l24zA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.3.6",
|
"@vue/compiler-dom": "3.3.7",
|
||||||
"@vue/compiler-sfc": "3.3.6",
|
"@vue/compiler-sfc": "3.3.7",
|
||||||
"@vue/runtime-dom": "3.3.6",
|
"@vue/runtime-dom": "3.3.7",
|
||||||
"@vue/server-renderer": "3.3.6",
|
"@vue/server-renderer": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
|
@ -1902,12 +1917,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue-i18n": {
|
"node_modules/vue-i18n": {
|
||||||
"version": "9.5.0",
|
"version": "9.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.6.0.tgz",
|
||||||
"integrity": "sha512-NiI3Ph1qMstNf7uhYh8trQBOBFLxeJgcOxBq51pCcZ28Vs18Y7BDS58r8HGDKCYgXdLUYqPDXdKatIF4bvBVZg==",
|
"integrity": "sha512-DSUaHmc2qpXpB0oeHXrW4JtOXnzpmAeaPopDIlubRyXkxIdbzGTsQekZYrCoI3rCEouYKwD1tIw01/YYSYqWAw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/core-base": "9.5.0",
|
"@intlify/core-base": "9.6.0",
|
||||||
"@intlify/shared": "9.5.0",
|
"@intlify/shared": "9.6.0",
|
||||||
"@vue/devtools-api": "^6.5.0"
|
"@vue/devtools-api": "^6.5.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -1965,6 +1980,19 @@
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xterm": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm/-/xterm-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg=="
|
||||||
|
},
|
||||||
|
"node_modules/xterm-addon-fit": {
|
||||||
|
"version": "0.8.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
|
||||||
|
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"xterm": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yocto-queue": {
|
"node_modules/yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
|
@ -2201,27 +2229,27 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@intlify/core-base": {
|
"@intlify/core-base": {
|
||||||
"version": "9.5.0",
|
"version": "9.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.6.0.tgz",
|
||||||
"integrity": "sha512-y3ufM1RJbI/DSmJf3lYs9ACq3S/iRvaSsE3rPIk0MGH7fp+JxU6rdryv/EYcwfcr3Y1aHFlCBir6S391hRZ57w==",
|
"integrity": "sha512-9xWsUFrQq4iP1amH3cEIlUHsCXO541RGRDfrKqaDhlYvMbf2qTzpSjqeL3kWw1b+rC8XWHw+cgZXa4VPdOzqfg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@intlify/message-compiler": "9.5.0",
|
"@intlify/message-compiler": "9.6.0",
|
||||||
"@intlify/shared": "9.5.0"
|
"@intlify/shared": "9.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@intlify/message-compiler": {
|
"@intlify/message-compiler": {
|
||||||
"version": "9.5.0",
|
"version": "9.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.6.0.tgz",
|
||||||
"integrity": "sha512-CAhVNfEZcOVFg0/5MNyt+OFjvs4J/ARjCj2b+54/FvFP0EDJI5lIqMTSDBE7k0atMROSP0SvWCkwu/AZ5xkK1g==",
|
"integrity": "sha512-GucIIYA2H86gdf/lKHAahfLpyYm9Q1IUc/yUEMk8wwwfrzBwuYmTDg90ooed7eRVx2N/omyDyuhKV4cRp3b+DQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@intlify/shared": "9.5.0",
|
"@intlify/shared": "9.6.0",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@intlify/shared": {
|
"@intlify/shared": {
|
||||||
"version": "9.5.0",
|
"version": "9.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.6.0.tgz",
|
||||||
"integrity": "sha512-tAxV14LMXZDZbu32XzLMTsowNlgJNmLwWHYzvMUl6L8gvQeoYiZONjY7AUsqZW8TOZDX9lfvF6adPkk9FSRdDA=="
|
"integrity": "sha512-vZeID7kn10rhgRYZQvjULTOYXDGnC0j49HI0AD9CK08aj4nWmlPai/8awTsMg0qrfHVMTna8ZMNmBZNyFAUCfA=="
|
||||||
},
|
},
|
||||||
"@jridgewell/sourcemap-codec": {
|
"@jridgewell/sourcemap-codec": {
|
||||||
"version": "1.4.15",
|
"version": "1.4.15",
|
||||||
|
@ -2261,9 +2289,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@rollup/pluginutils": {
|
"@rollup/pluginutils": {
|
||||||
"version": "5.0.4",
|
"version": "5.0.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
|
||||||
"integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==",
|
"integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/estree": "^1.0.0",
|
"@types/estree": "^1.0.0",
|
||||||
|
@ -2306,36 +2334,36 @@
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@vue/compiler-core": {
|
"@vue/compiler-core": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.7.tgz",
|
||||||
"integrity": "sha512-2JNjemwaNwf+MkkatATVZi7oAH1Hx0B04DdPH3ZoZ8vKC1xZVP7nl4HIsk8XYd3r+/52sqqoz9TWzYc3yE9dqA==",
|
"integrity": "sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/parser": "^7.23.0",
|
"@babel/parser": "^7.23.0",
|
||||||
"@vue/shared": "3.3.6",
|
"@vue/shared": "3.3.7",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-dom": {
|
"@vue/compiler-dom": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.7.tgz",
|
||||||
"integrity": "sha512-1MxXcJYMHiTPexjLAJUkNs/Tw2eDf2tY3a0rL+LfuWyiKN2s6jvSwywH3PWD8bKICjfebX3GWx2Os8jkRDq3Ng==",
|
"integrity": "sha512-0LwkyJjnUPssXv/d1vNJ0PKfBlDoQs7n81CbO6Q0zdL7H1EzqYRrTVXDqdBVqro0aJjo/FOa1qBAPVI4PGSHBw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-core": "3.3.6",
|
"@vue/compiler-core": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-sfc": {
|
"@vue/compiler-sfc": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.7.tgz",
|
||||||
"integrity": "sha512-/Kms6du2h1VrXFreuZmlvQej8B1zenBqIohP0690IUBkJjsFvJxY0crcvVRJ0UhMgSR9dewB+khdR1DfbpArJA==",
|
"integrity": "sha512-7pfldWy/J75U/ZyYIXRVqvLRw3vmfxDo2YLMwVtWVNew8Sm8d6wodM+OYFq4ll/UxfqVr0XKiVwti32PCrruAw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/parser": "^7.23.0",
|
"@babel/parser": "^7.23.0",
|
||||||
"@vue/compiler-core": "3.3.6",
|
"@vue/compiler-core": "3.3.7",
|
||||||
"@vue/compiler-dom": "3.3.6",
|
"@vue/compiler-dom": "3.3.7",
|
||||||
"@vue/compiler-ssr": "3.3.6",
|
"@vue/compiler-ssr": "3.3.7",
|
||||||
"@vue/reactivity-transform": "3.3.6",
|
"@vue/reactivity-transform": "3.3.7",
|
||||||
"@vue/shared": "3.3.6",
|
"@vue/shared": "3.3.7",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.5",
|
"magic-string": "^0.30.5",
|
||||||
"postcss": "^8.4.31",
|
"postcss": "^8.4.31",
|
||||||
|
@ -2343,12 +2371,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-ssr": {
|
"@vue/compiler-ssr": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.7.tgz",
|
||||||
"integrity": "sha512-QTIHAfDCHhjXlYGkUg5KH7YwYtdUM1vcFl/FxFDlD6d0nXAmnjizka3HITp8DGudzHndv2PjKVS44vqqy0vP4w==",
|
"integrity": "sha512-TxOfNVVeH3zgBc82kcUv+emNHo+vKnlRrkv8YvQU5+Y5LJGJwSNzcmLUoxD/dNzv0bhQ/F0s+InlgV0NrApJZg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-dom": "3.3.6",
|
"@vue/compiler-dom": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/devtools-api": {
|
"@vue/devtools-api": {
|
||||||
|
@ -2357,41 +2385,41 @@
|
||||||
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
||||||
},
|
},
|
||||||
"@vue/reactivity": {
|
"@vue/reactivity": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.7.tgz",
|
||||||
"integrity": "sha512-gtChAumfQz5lSy5jZXfyXbKrIYPf9XEOrIr6rxwVyeWVjFhJwmwPLtV6Yis+M9onzX++I5AVE9j+iPH60U+B8Q==",
|
"integrity": "sha512-cZNVjWiw00708WqT0zRpyAgduG79dScKEPYJXq2xj/aMtk3SKvL3FBt2QKUlh6EHBJ1m8RhBY+ikBUzwc7/khg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/reactivity-transform": {
|
"@vue/reactivity-transform": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.7.tgz",
|
||||||
"integrity": "sha512-RlJl4dHfeO7EuzU1iJOsrlqWyJfHTkJbvYz/IOJWqu8dlCNWtxWX377WI0VsbAgBizjwD+3ZjdnvSyyFW1YVng==",
|
"integrity": "sha512-APhRmLVbgE1VPGtoLQoWBJEaQk4V8JUsqrQihImVqKT+8U6Qi3t5ATcg4Y9wGAPb3kIhetpufyZ1RhwbZCIdDA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/parser": "^7.23.0",
|
"@babel/parser": "^7.23.0",
|
||||||
"@vue/compiler-core": "3.3.6",
|
"@vue/compiler-core": "3.3.7",
|
||||||
"@vue/shared": "3.3.6",
|
"@vue/shared": "3.3.7",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.5"
|
"magic-string": "^0.30.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/runtime-core": {
|
"@vue/runtime-core": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.7.tgz",
|
||||||
"integrity": "sha512-qp7HTP1iw1UW2ZGJ8L3zpqlngrBKvLsDAcq5lA6JvEXHmpoEmjKju7ahM9W2p/h51h0OT5F2fGlP/gMhHOmbUA==",
|
"integrity": "sha512-LHq9du3ubLZFdK/BP0Ysy3zhHqRfBn80Uc+T5Hz3maFJBGhci1MafccnL3rpd5/3wVfRHAe6c+PnlO2PAavPTQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/reactivity": "3.3.6",
|
"@vue/reactivity": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/runtime-dom": {
|
"@vue/runtime-dom": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.7.tgz",
|
||||||
"integrity": "sha512-AoX3Cp8NqMXjLbIG9YR6n/pPLWE9TiDdk6wTJHFnl2GpHzDFH1HLBC9wlqqQ7RlnvN3bVLpzPGAAH00SAtOxHg==",
|
"integrity": "sha512-PFQU1oeJxikdDmrfoNQay5nD4tcPNYixUBruZzVX/l0eyZvFKElZUjW4KctCcs52nnpMGO6UDK+jF5oV4GT5Lw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/runtime-core": "3.3.6",
|
"@vue/runtime-core": "3.3.7",
|
||||||
"@vue/shared": "3.3.6",
|
"@vue/shared": "3.3.7",
|
||||||
"csstype": "^3.1.2"
|
"csstype": "^3.1.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -2403,18 +2431,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/server-renderer": {
|
"@vue/server-renderer": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.7.tgz",
|
||||||
"integrity": "sha512-kgLoN43W4ERdZ6dpyy+gnk2ZHtcOaIr5Uc/WUP5DRwutgvluzu2pudsZGoD2b7AEJHByUVMa9k6Sho5lLRCykw==",
|
"integrity": "sha512-UlpKDInd1hIZiNuVVVvLgxpfnSouxKQOSE2bOfQpBuGwxRV/JqqTCyyjXUWiwtVMyeRaZhOYYqntxElk8FhBhw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-ssr": "3.3.6",
|
"@vue/compiler-ssr": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/shared": {
|
"@vue/shared": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.7.tgz",
|
||||||
"integrity": "sha512-Xno5pEqg8SVhomD0kTSmfh30ZEmV/+jZtyh39q6QflrjdJCXah5lrnOLi9KB6a5k5aAHXMXjoMnxlzUkCNfWLQ=="
|
"integrity": "sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg=="
|
||||||
},
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "8.10.0",
|
"version": "8.10.0",
|
||||||
|
@ -3046,9 +3074,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sass": {
|
"sass": {
|
||||||
"version": "1.69.4",
|
"version": "1.69.5",
|
||||||
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.69.4.tgz",
|
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.69.5.tgz",
|
||||||
"integrity": "sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA==",
|
"integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"chokidar": ">=3.0.0 <4.0.0",
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
"immutable": "^4.0.0",
|
"immutable": "^4.0.0",
|
||||||
|
@ -3135,9 +3163,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"unimport": {
|
"unimport": {
|
||||||
"version": "3.3.0",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.4.0.tgz",
|
||||||
"integrity": "sha512-3jhq3ZG5hFZzrWGDCpx83kjPzefP/EeuKkIO1T0MA4Zwj+dO/Og1mFvZ4aZ5WSDm0FVbbdVIRH1zKBG7c4wOpg==",
|
"integrity": "sha512-M/lfFEgufIT156QAr/jWHLUn55kEmxBBiQsMxvRSIbquwmeJEyQYgshHDEvQDWlSJrVOOTAgnJ3FvlsrpGkanA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@rollup/pluginutils": "^5.0.4",
|
"@rollup/pluginutils": "^5.0.4",
|
||||||
|
@ -3145,12 +3173,12 @@
|
||||||
"fast-glob": "^3.3.1",
|
"fast-glob": "^3.3.1",
|
||||||
"local-pkg": "^0.4.3",
|
"local-pkg": "^0.4.3",
|
||||||
"magic-string": "^0.30.3",
|
"magic-string": "^0.30.3",
|
||||||
"mlly": "^1.4.1",
|
"mlly": "^1.4.2",
|
||||||
"pathe": "^1.1.1",
|
"pathe": "^1.1.1",
|
||||||
"pkg-types": "^1.0.3",
|
"pkg-types": "^1.0.3",
|
||||||
"scule": "^1.0.0",
|
"scule": "^1.0.0",
|
||||||
"strip-literal": "^1.3.0",
|
"strip-literal": "^1.3.0",
|
||||||
"unplugin": "^1.4.0"
|
"unplugin": "^1.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unplugin": {
|
"unplugin": {
|
||||||
|
@ -3166,19 +3194,31 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unplugin-auto-import": {
|
"unplugin-auto-import": {
|
||||||
"version": "0.16.6",
|
"version": "0.16.7",
|
||||||
"resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.16.6.tgz",
|
"resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.16.7.tgz",
|
||||||
"integrity": "sha512-M+YIITkx3C/Hg38hp8HmswP5mShUUyJOzpifv7RTlAbeFlO2Tyw0pwrogSSxnipHDPTtI8VHFBpkYkNKzYSuyA==",
|
"integrity": "sha512-w7XmnRlchq6YUFJVFGSvG1T/6j8GrdYN6Em9Wf0Ye+HXgD/22kont+WnuCAA0UaUoxtuvRR1u/mXKy63g/hfqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@antfu/utils": "^0.7.5",
|
"@antfu/utils": "^0.7.6",
|
||||||
"@rollup/pluginutils": "^5.0.2",
|
"@rollup/pluginutils": "^5.0.5",
|
||||||
"fast-glob": "^3.3.0",
|
"fast-glob": "^3.3.1",
|
||||||
"local-pkg": "^0.4.3",
|
"local-pkg": "^0.5.0",
|
||||||
"magic-string": "^0.30.1",
|
"magic-string": "^0.30.5",
|
||||||
"minimatch": "^9.0.2",
|
"minimatch": "^9.0.3",
|
||||||
"unimport": "^3.0.14",
|
"unimport": "^3.4.0",
|
||||||
"unplugin": "^1.3.2"
|
"unplugin": "^1.5.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"local-pkg": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"mlly": "^1.4.2",
|
||||||
|
"pkg-types": "^1.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unplugin-icons": {
|
"unplugin-icons": {
|
||||||
|
@ -3257,24 +3297,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vue": {
|
"vue": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.6.tgz",
|
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.7.tgz",
|
||||||
"integrity": "sha512-jJIDETeWJnoY+gfn4ZtMPMS5KtbP4ax+CT4dcQFhTnWEk8xMupFyQ0JxL28nvT/M4+p4a0ptxaV2WY0LiIxvRg==",
|
"integrity": "sha512-YEMDia1ZTv1TeBbnu6VybatmSteGOS3A3YgfINOfraCbf85wdKHzscD6HSS/vB4GAtI7sa1XPX7HcQaJ1l24zA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-dom": "3.3.6",
|
"@vue/compiler-dom": "3.3.7",
|
||||||
"@vue/compiler-sfc": "3.3.6",
|
"@vue/compiler-sfc": "3.3.7",
|
||||||
"@vue/runtime-dom": "3.3.6",
|
"@vue/runtime-dom": "3.3.7",
|
||||||
"@vue/server-renderer": "3.3.6",
|
"@vue/server-renderer": "3.3.7",
|
||||||
"@vue/shared": "3.3.6"
|
"@vue/shared": "3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vue-i18n": {
|
"vue-i18n": {
|
||||||
"version": "9.5.0",
|
"version": "9.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.6.0.tgz",
|
||||||
"integrity": "sha512-NiI3Ph1qMstNf7uhYh8trQBOBFLxeJgcOxBq51pCcZ28Vs18Y7BDS58r8HGDKCYgXdLUYqPDXdKatIF4bvBVZg==",
|
"integrity": "sha512-DSUaHmc2qpXpB0oeHXrW4JtOXnzpmAeaPopDIlubRyXkxIdbzGTsQekZYrCoI3rCEouYKwD1tIw01/YYSYqWAw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@intlify/core-base": "9.5.0",
|
"@intlify/core-base": "9.6.0",
|
||||||
"@intlify/shared": "9.5.0",
|
"@intlify/shared": "9.6.0",
|
||||||
"@vue/devtools-api": "^6.5.0"
|
"@vue/devtools-api": "^6.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -3314,6 +3354,17 @@
|
||||||
"isexe": "^2.0.0"
|
"isexe": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"xterm": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm/-/xterm-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg=="
|
||||||
|
},
|
||||||
|
"xterm-addon-fit": {
|
||||||
|
"version": "0.8.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
|
||||||
|
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"yocto-queue": {
|
"yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
|
|
|
@ -13,15 +13,17 @@
|
||||||
"highlight.js": "^11.9.0",
|
"highlight.js": "^11.9.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"sass": "^1.69.4",
|
"sass": "^1.69.5",
|
||||||
"vue": "^3.3.6",
|
"vue": "^3.3.7",
|
||||||
"vue-i18n": "^9.5.0"
|
"vue-i18n": "^9.6.0",
|
||||||
|
"xterm": "^5.3.0",
|
||||||
|
"xterm-addon-fit": "^0.8.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^4.4.0",
|
"@vitejs/plugin-vue": "^4.4.0",
|
||||||
"naive-ui": "^2.35.0",
|
"naive-ui": "^2.35.0",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.0.3",
|
||||||
"unplugin-auto-import": "^0.16.6",
|
"unplugin-auto-import": "^0.16.7",
|
||||||
"unplugin-icons": "^0.17.1",
|
"unplugin-icons": "^0.17.1",
|
||||||
"unplugin-vue-components": "^0.25.2",
|
"unplugin-vue-components": "^0.25.2",
|
||||||
"vite": "^4.5.0"
|
"vite": "^4.5.0"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
bc30c6eabdfdaebcae482c47907c6546
|
7c3f3d30a242641f2f308ca9c3a8e4f1
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, onUnmounted, reactive, watch } from 'vue'
|
import { computed, onMounted, onUnmounted, reactive, watch } from 'vue'
|
||||||
import { types } from '@/consts/support_redis_type.js'
|
|
||||||
import ContentValueHash from '@/components/content_value/ContentValueHash.vue'
|
|
||||||
import ContentValueList from '@/components/content_value/ContentValueList.vue'
|
|
||||||
import ContentValueString from '@/components/content_value/ContentValueString.vue'
|
|
||||||
import ContentValueSet from '@/components/content_value/ContentValueSet.vue'
|
|
||||||
import ContentValueZset from '@/components/content_value/ContentValueZSet.vue'
|
|
||||||
import { get, isEmpty, keyBy, map, size, toUpper } from 'lodash'
|
import { get, isEmpty, keyBy, map, size, toUpper } from 'lodash'
|
||||||
import useTabStore from 'stores/tab.js'
|
import useTabStore from 'stores/tab.js'
|
||||||
import useConnectionStore from 'stores/connections.js'
|
import useConnectionStore from 'stores/connections.js'
|
||||||
import ContentServerStatus from '@/components/content_value/ContentServerStatus.vue'
|
import ContentServerStatus from '@/components/content_value/ContentServerStatus.vue'
|
||||||
import ContentValueStream from '@/components/content_value/ContentValueStream.vue'
|
import Status from '@/components/icons/Status.vue'
|
||||||
|
import { useThemeVars } from 'naive-ui'
|
||||||
|
import { BrowserTabType } from '@/consts/browser_tab_type.js'
|
||||||
|
import Terminal from '@/components/icons/Terminal.vue'
|
||||||
|
import Log from '@/components/icons/Log.vue'
|
||||||
|
import Detail from '@/components/icons/Detail.vue'
|
||||||
|
import ContentValueWrapper from '@/components/content_value/ContentValueWrapper.vue'
|
||||||
|
import ContentCli from '@/components/content_value/ContentCli.vue'
|
||||||
|
|
||||||
|
const themeVars = useThemeVars()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} ServerStatusItem
|
* @typedef {Object} ServerStatusItem
|
||||||
|
@ -112,15 +115,6 @@ onUnmounted(() => {
|
||||||
clearInterval(intervalId)
|
clearInterval(intervalId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const valueComponents = {
|
|
||||||
[types.STRING]: ContentValueString,
|
|
||||||
[types.HASH]: ContentValueHash,
|
|
||||||
[types.LIST]: ContentValueList,
|
|
||||||
[types.SET]: ContentValueSet,
|
|
||||||
[types.ZSET]: ContentValueZset,
|
|
||||||
[types.STREAM]: ContentValueStream,
|
|
||||||
}
|
|
||||||
|
|
||||||
const connectionStore = useConnectionStore()
|
const connectionStore = useConnectionStore()
|
||||||
const tabStore = useTabStore()
|
const tabStore = useTabStore()
|
||||||
const tab = computed(() =>
|
const tab = computed(() =>
|
||||||
|
@ -162,6 +156,7 @@ const tabContent = computed(() => {
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
name: tab.name,
|
name: tab.name,
|
||||||
|
subTab: tab.subTab,
|
||||||
type: toUpper(tab.type),
|
type: toUpper(tab.type),
|
||||||
db: tab.db,
|
db: tab.db,
|
||||||
keyPath: tab.key,
|
keyPath: tab.key,
|
||||||
|
@ -177,7 +172,7 @@ const showServerStatus = computed(() => {
|
||||||
return tabContent.value == null || isEmpty(tabContent.value.keyPath)
|
return tabContent.value == null || isEmpty(tabContent.value.keyPath)
|
||||||
})
|
})
|
||||||
|
|
||||||
const showNonexists = computed(() => {
|
const isBlankValue = computed(() => {
|
||||||
return tabContent.value.value == null
|
return tabContent.value.value == null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -192,38 +187,105 @@ const onReloadKey = async () => {
|
||||||
}
|
}
|
||||||
await connectionStore.loadKeyValue(tab.name, tab.db, tab.key, tab.viewAs)
|
await connectionStore.loadKeyValue(tab.name, tab.db, tab.key, tab.viewAs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectedSubTab = computed(() => {
|
||||||
|
const { subTab = 'status' } = tabStore.currentTab || {}
|
||||||
|
return subTab
|
||||||
|
})
|
||||||
|
|
||||||
|
const onSwitchSubTab = (name) => {
|
||||||
|
tabStore.switchSubTab(name)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-container flex-box-v">
|
<div class="content-container flex-box-v">
|
||||||
<div v-if="showServerStatus" class="content-container flex-item-expand flex-box-v">
|
<n-tabs
|
||||||
<!-- select nothing or select server node, display server status -->
|
:tabs-padding="5"
|
||||||
<content-server-status
|
:theme-overrides="{
|
||||||
v-model:auto-refresh="currentServer.autoRefresh"
|
tabFontWeightActive: 'normal',
|
||||||
:auto-loading="currentServer.autoLoading"
|
tabGapSmallLine: '10px',
|
||||||
:info="currentServer.info"
|
tabGapMediumLine: '10px',
|
||||||
:loading="currentServer.loading"
|
tabGapLargeLine: '10px',
|
||||||
:server="currentServer.name"
|
}"
|
||||||
@refresh="refreshInfo(currentServer.name, true)" />
|
:value="selectedSubTab"
|
||||||
</div>
|
class="content-sub-tab"
|
||||||
<div v-else-if="showNonexists" class="content-container flex-item-expand flex-box-v">
|
default-value="status"
|
||||||
<n-empty :description="$t('interface.nonexist_tab_content')" class="empty-content">
|
pane-class="content-sub-tab-pane"
|
||||||
<template #extra>
|
placement="top"
|
||||||
<n-button :focusable="false" @click="onReloadKey">{{ $t('interface.reload') }}</n-button>
|
tab-style="padding-left: 10px; padding-right: 10px;"
|
||||||
|
type="line"
|
||||||
|
@update:value="onSwitchSubTab">
|
||||||
|
<!-- server status pane -->
|
||||||
|
<n-tab-pane :name="BrowserTabType.Status.toString()">
|
||||||
|
<template #tab>
|
||||||
|
<n-space :size="5" :wrap-item="false" align="center" inline justify="center">
|
||||||
|
<n-icon size="16">
|
||||||
|
<status :inverse="selectedSubTab === BrowserTabType.Status.toString()" stroke-width="4" />
|
||||||
|
</n-icon>
|
||||||
|
<span>{{ $t('interface.sub_tab.status') }}</span>
|
||||||
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
</n-empty>
|
<content-server-status
|
||||||
</div>
|
v-model:auto-refresh="currentServer.autoRefresh"
|
||||||
<component
|
:auto-loading="currentServer.autoLoading"
|
||||||
:is="valueComponents[tabContent.type]"
|
:info="currentServer.info"
|
||||||
v-else
|
:loading="currentServer.loading"
|
||||||
:db="tabContent.db"
|
:server="currentServer.name"
|
||||||
:key-code="tabContent.keyCode"
|
@refresh="refreshInfo(currentServer.name, true)" />
|
||||||
:key-path="tabContent.keyPath"
|
</n-tab-pane>
|
||||||
:name="tabContent.name"
|
|
||||||
:size="tabContent.size"
|
<!-- key detail pane -->
|
||||||
:ttl="tabContent.ttl"
|
<n-tab-pane :name="BrowserTabType.KeyDetail.toString()">
|
||||||
:value="tabContent.value"
|
<template #tab>
|
||||||
:view-as="tabContent.viewAs" />
|
<n-space :size="5" :wrap-item="false" align="center" inline justify="center">
|
||||||
|
<n-icon size="16">
|
||||||
|
<detail
|
||||||
|
:inverse="selectedSubTab === BrowserTabType.KeyDetail.toString()"
|
||||||
|
fill-color="none" />
|
||||||
|
</n-icon>
|
||||||
|
<span>{{ $t('interface.sub_tab.key_detail') }}</span>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
<content-value-wrapper
|
||||||
|
:blank="isBlankValue"
|
||||||
|
:type="tabContent.type"
|
||||||
|
:db="tabContent.db"
|
||||||
|
:key-code="tabContent.keyCode"
|
||||||
|
:key-path="tabContent.keyPath"
|
||||||
|
:name="tabContent.name"
|
||||||
|
:size="tabContent.size"
|
||||||
|
:ttl="tabContent.ttl"
|
||||||
|
:value="tabContent.value"
|
||||||
|
:view-as="tabContent.viewAs"
|
||||||
|
@reload="onReloadKey" />
|
||||||
|
</n-tab-pane>
|
||||||
|
|
||||||
|
<!-- cli pane -->
|
||||||
|
<n-tab-pane :name="BrowserTabType.Cli.toString()">
|
||||||
|
<template #tab>
|
||||||
|
<n-space :size="5" :wrap-item="false" align="center" inline justify="center">
|
||||||
|
<n-icon size="16">
|
||||||
|
<terminal :inverse="selectedSubTab === BrowserTabType.Cli.toString()" />
|
||||||
|
</n-icon>
|
||||||
|
<span>{{ $t('interface.sub_tab.cli') }}</span>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
<content-cli :name="currentServer.name" />
|
||||||
|
</n-tab-pane>
|
||||||
|
|
||||||
|
<!-- slow log pane -->
|
||||||
|
<n-tab-pane :name="BrowserTabType.SlowLog.toString()">
|
||||||
|
<template #tab>
|
||||||
|
<n-space :size="5" :wrap-item="false" align="center" inline justify="center">
|
||||||
|
<n-icon size="16">
|
||||||
|
<log :inverse="selectedSubTab === BrowserTabType.SlowLog.toString()" />
|
||||||
|
</n-icon>
|
||||||
|
<span>{{ $t('interface.sub_tab.slow_log') }}</span>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
</n-tab-pane>
|
||||||
|
</n-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -231,27 +293,23 @@ const onReloadKey = async () => {
|
||||||
@import '@/styles/content';
|
@import '@/styles/content';
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
padding: 5px;
|
//padding: 5px 5px 0;
|
||||||
|
//padding-top: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
background-color: v-bind('themeVars.tabColor');
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.content-sub-tab {
|
||||||
|
background-color: v-bind('themeVars.bodyColor');
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
//.tab-item {
|
.content-sub-tab-pane {
|
||||||
// gap: 5px;
|
padding: 0 !important;
|
||||||
// padding: 0 5px 0 10px;
|
height: 100%;
|
||||||
// align-items: center;
|
background-color: v-bind('themeVars.tabColor');
|
||||||
// max-width: 150px;
|
overflow: hidden;
|
||||||
//
|
}
|
||||||
// transition: all var(--transition-duration-fast) var(--transition-function-ease-in-out-bezier);
|
|
||||||
//
|
|
||||||
// &-label {
|
|
||||||
// font-size: 15px;
|
|
||||||
// text-align: center;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// &-close {
|
|
||||||
// &:hover {
|
|
||||||
// background-color: rgb(176, 177, 182, 0.4);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import ToggleServer from '@/components/icons/ToggleServer.vue'
|
import Server from '@/components/icons/Server.vue'
|
||||||
import useTabStore from 'stores/tab.js'
|
import useTabStore from 'stores/tab.js'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
@ -52,7 +52,7 @@ const tab = computed(() =>
|
||||||
<n-tabs
|
<n-tabs
|
||||||
v-model:value="tabStore.activatedIndex"
|
v-model:value="tabStore.activatedIndex"
|
||||||
:closable="true"
|
:closable="true"
|
||||||
:tabs-padding="2"
|
:tabs-padding="0"
|
||||||
:tab-style="{
|
:tab-style="{
|
||||||
borderStyle: 'solid',
|
borderStyle: 'solid',
|
||||||
borderWidth: '1px',
|
borderWidth: '1px',
|
||||||
|
@ -82,7 +82,9 @@ const tab = computed(() =>
|
||||||
:class="tabClass(i)"
|
:class="tabClass(i)"
|
||||||
@dblclick.stop="() => {}">
|
@dblclick.stop="() => {}">
|
||||||
<n-space :size="5" :wrap-item="false" align="center" inline justify="center">
|
<n-space :size="5" :wrap-item="false" align="center" inline justify="center">
|
||||||
<n-icon :component="ToggleServer" size="18" />
|
<n-icon size="18">
|
||||||
|
<server stroke-width="4" />
|
||||||
|
</n-icon>
|
||||||
<n-ellipsis style="max-width: 150px">{{ t.label }}</n-ellipsis>
|
<n-ellipsis style="max-width: 150px">{{ t.label }}</n-ellipsis>
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-tab>
|
</n-tab>
|
||||||
|
|
|
@ -0,0 +1,396 @@
|
||||||
|
<script setup>
|
||||||
|
import { Terminal } from 'xterm'
|
||||||
|
import { FitAddon } from 'xterm-addon-fit'
|
||||||
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
|
import 'xterm/css/xterm.css'
|
||||||
|
import { EventsEmit, EventsOff, EventsOn } from 'wailsjs/runtime/runtime.js'
|
||||||
|
import { get, isEmpty, set, size } from 'lodash'
|
||||||
|
import { CloseCli, StartCli } from 'wailsjs/go/services/cliService.js'
|
||||||
|
import usePreferencesStore from 'stores/preferences.js'
|
||||||
|
import { i18nGlobal } from '@/utils/i18n.js'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
name: String,
|
||||||
|
activated: Boolean,
|
||||||
|
})
|
||||||
|
|
||||||
|
const prefStore = usePreferencesStore()
|
||||||
|
const termRef = ref(null)
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {xterm.Terminal|null}
|
||||||
|
*/
|
||||||
|
let termInst = null
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {xterm-addon-fit.FitAddon|null}
|
||||||
|
*/
|
||||||
|
let fitAddonInst = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return {{fitAddon: xterm-addon-fit.FitAddon, term: Terminal}}
|
||||||
|
*/
|
||||||
|
const newTerm = () => {
|
||||||
|
const term = new Terminal({
|
||||||
|
allowProposedApi: true,
|
||||||
|
fontSize: prefStore.general.fontSize || 14,
|
||||||
|
cursorBlink: true,
|
||||||
|
disableStdin: false,
|
||||||
|
screenReaderMode: true,
|
||||||
|
// LogLevel: 'debug',
|
||||||
|
theme: {
|
||||||
|
// foreground: '#ECECEC',
|
||||||
|
background: '#000000',
|
||||||
|
// cursor: 'help',
|
||||||
|
// lineHeight: 20,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const fitAddon = new FitAddon()
|
||||||
|
term.open(termRef.value)
|
||||||
|
term.loadAddon(fitAddon)
|
||||||
|
|
||||||
|
term.onData(onTermData)
|
||||||
|
return { term, fitAddon }
|
||||||
|
}
|
||||||
|
|
||||||
|
let intervalID
|
||||||
|
onMounted(() => {
|
||||||
|
const { term, fitAddon } = newTerm()
|
||||||
|
termInst = term
|
||||||
|
fitAddonInst = fitAddon
|
||||||
|
// window.addEventListener('resize', resizeTerm)
|
||||||
|
|
||||||
|
term.writeln('\r\n' + i18nGlobal.t('interface.cli_welcome'))
|
||||||
|
// term.write('\x1b[4h') // insert mode
|
||||||
|
CloseCli(props.name)
|
||||||
|
StartCli(props.name, 0)
|
||||||
|
|
||||||
|
EventsOn(`cmd:output:${props.name}`, receiveTermOutput)
|
||||||
|
fitAddon.fit()
|
||||||
|
term.focus()
|
||||||
|
|
||||||
|
intervalID = setInterval(() => {
|
||||||
|
if (props.activated) {
|
||||||
|
resizeTerm()
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(intervalID)
|
||||||
|
// window.removeEventListener('resize', resizeTerm)
|
||||||
|
EventsOff(`cmd:output:${props.name}`)
|
||||||
|
termInst.dispose()
|
||||||
|
termInst = null
|
||||||
|
console.warn('destroy term')
|
||||||
|
})
|
||||||
|
|
||||||
|
const resizeTerm = () => {
|
||||||
|
if (fitAddonInst != null) {
|
||||||
|
fitAddonInst.fit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => prefStore.general.fontSize,
|
||||||
|
(fontSize) => {
|
||||||
|
if (termInst != null) {
|
||||||
|
termInst.options.fontSize = fontSize
|
||||||
|
}
|
||||||
|
resizeTerm()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const prefixContent = computed(() => {
|
||||||
|
return '\x1b[33m' + promptPrefix.value + '\x1b[0m'
|
||||||
|
})
|
||||||
|
|
||||||
|
let promptPrefix = ref('')
|
||||||
|
let inputCursor = 0
|
||||||
|
const inputHistory = []
|
||||||
|
let historyIndex = 0
|
||||||
|
let waitForOutput = false
|
||||||
|
const onTermData = (data) => {
|
||||||
|
if (termInst == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
const cc = data.charCodeAt(0)
|
||||||
|
switch (cc) {
|
||||||
|
case 127: // backspace
|
||||||
|
deleteInput(true)
|
||||||
|
return
|
||||||
|
|
||||||
|
case 13: // enter
|
||||||
|
// try to process local command first
|
||||||
|
console.log('enter con', getCurrentInput())
|
||||||
|
switch (getCurrentInput()) {
|
||||||
|
case 'clear':
|
||||||
|
case 'clr':
|
||||||
|
termInst.clear()
|
||||||
|
replaceTermInput()
|
||||||
|
newInputLine()
|
||||||
|
return
|
||||||
|
|
||||||
|
default: // send command to server
|
||||||
|
flushTermInput()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case 27:
|
||||||
|
switch (data.substring(1)) {
|
||||||
|
case '[A': // arrow up
|
||||||
|
changeHistory(true)
|
||||||
|
return
|
||||||
|
case '[B': // arrow down
|
||||||
|
changeHistory(false)
|
||||||
|
return
|
||||||
|
case '[C': // arrow right ->
|
||||||
|
moveInputCursor(1)
|
||||||
|
return
|
||||||
|
case '[D': // arrow left <-
|
||||||
|
moveInputCursor(-1)
|
||||||
|
return
|
||||||
|
case '[3~': // del
|
||||||
|
deleteInput(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case 9: // tab
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInput(data)
|
||||||
|
// term.write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* move input cursor by step
|
||||||
|
* @param {number} step above 0 indicate move right; 0 indicate move to last
|
||||||
|
*/
|
||||||
|
const moveInputCursor = (step) => {
|
||||||
|
if (termInst == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateCursor = false
|
||||||
|
if (step > 0) {
|
||||||
|
// move right
|
||||||
|
const currentLine = getCurrentInput()
|
||||||
|
if (inputCursor + step <= currentLine.length) {
|
||||||
|
inputCursor += step
|
||||||
|
updateCursor = true
|
||||||
|
}
|
||||||
|
} else if (step < 0) {
|
||||||
|
// move left
|
||||||
|
if (inputCursor + step >= 0) {
|
||||||
|
inputCursor += step
|
||||||
|
updateCursor = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// update cursor position only
|
||||||
|
const currentLine = getCurrentInput()
|
||||||
|
inputCursor = Math.min(Math.max(0, inputCursor), currentLine.length)
|
||||||
|
updateCursor = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateCursor) {
|
||||||
|
termInst.write(`\x1B[${size(promptPrefix.value) + inputCursor + 1}G`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update current input cache and refresh term
|
||||||
|
* @param {string} data
|
||||||
|
*/
|
||||||
|
const updateInput = (data) => {
|
||||||
|
if (data == null || data.length <= 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (termInst == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentLine = getCurrentInput()
|
||||||
|
if (inputCursor < currentLine.length) {
|
||||||
|
// insert
|
||||||
|
currentLine = currentLine.substring(0, inputCursor) + data + currentLine.substring(inputCursor)
|
||||||
|
replaceTermInput()
|
||||||
|
termInst.write(currentLine)
|
||||||
|
moveInputCursor(data.length)
|
||||||
|
} else {
|
||||||
|
// append
|
||||||
|
currentLine += data
|
||||||
|
termInst.write(data)
|
||||||
|
inputCursor += data.length
|
||||||
|
}
|
||||||
|
updateCurrentInput(currentLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {boolean} back backspace or not
|
||||||
|
*/
|
||||||
|
const deleteInput = (back = false) => {
|
||||||
|
if (termInst == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentLine = getCurrentInput()
|
||||||
|
if (inputCursor < currentLine.length) {
|
||||||
|
// delete middle part
|
||||||
|
if (back) {
|
||||||
|
currentLine = currentLine.substring(0, inputCursor - 1) + currentLine.substring(inputCursor)
|
||||||
|
inputCursor -= 1
|
||||||
|
} else {
|
||||||
|
currentLine = currentLine.substring(0, inputCursor) + currentLine.substring(inputCursor + 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// delete last one
|
||||||
|
currentLine = currentLine.slice(0, -1)
|
||||||
|
inputCursor -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceTermInput()
|
||||||
|
termInst.write(currentLine)
|
||||||
|
updateCurrentInput(currentLine)
|
||||||
|
moveInputCursor(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCurrentInput = () => {
|
||||||
|
return get(inputHistory, historyIndex, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateCurrentInput = (input) => {
|
||||||
|
set(inputHistory, historyIndex, input || '')
|
||||||
|
}
|
||||||
|
|
||||||
|
const newInputLine = () => {
|
||||||
|
if (historyIndex >= 0 && historyIndex < inputHistory.length - 1) {
|
||||||
|
// edit prev history, move to last
|
||||||
|
const pop = inputHistory.splice(historyIndex, 1)
|
||||||
|
inputHistory[inputHistory.length - 1] = pop[0]
|
||||||
|
}
|
||||||
|
if (get(inputHistory, inputHistory.length - 1, '')) {
|
||||||
|
historyIndex = inputHistory.length
|
||||||
|
updateCurrentInput('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get prev or next history record
|
||||||
|
* @param prev
|
||||||
|
* @return {*|null}
|
||||||
|
*/
|
||||||
|
const changeHistory = (prev) => {
|
||||||
|
let currentLine = null
|
||||||
|
if (prev) {
|
||||||
|
if (historyIndex > 0) {
|
||||||
|
historyIndex -= 1
|
||||||
|
currentLine = inputHistory[historyIndex]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (historyIndex < inputHistory.length - 1) {
|
||||||
|
historyIndex += 1
|
||||||
|
currentLine = inputHistory[historyIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentLine != null) {
|
||||||
|
if (termInst == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceTermInput()
|
||||||
|
termInst.write(currentLine)
|
||||||
|
moveInputCursor(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flush terminal input and send current prompt to server
|
||||||
|
* @param {boolean} flushCmd
|
||||||
|
*/
|
||||||
|
const flushTermInput = (flushCmd = false) => {
|
||||||
|
const currentLine = getCurrentInput()
|
||||||
|
console.log('===send cmd', currentLine, currentLine.length)
|
||||||
|
EventsEmit(`cmd:input:${props.name}`, currentLine)
|
||||||
|
inputCursor = 0
|
||||||
|
// historyIndex = inputHistory.length
|
||||||
|
waitForOutput = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clear current input line and replace with new content
|
||||||
|
* @param {string} [content]
|
||||||
|
*/
|
||||||
|
const replaceTermInput = (content = '') => {
|
||||||
|
if (termInst == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// erase current line and write new content
|
||||||
|
termInst.write('\r\x1B[K' + prefixContent.value + (content || ''))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process receive output content
|
||||||
|
* @param {{content, prompt}} data
|
||||||
|
*/
|
||||||
|
const receiveTermOutput = (data) => {
|
||||||
|
if (termInst == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { content, prompt } = data || {}
|
||||||
|
if (!isEmpty(content)) {
|
||||||
|
termInst.write('\r\n' + content)
|
||||||
|
}
|
||||||
|
if (!isEmpty(prompt)) {
|
||||||
|
promptPrefix.value = prompt
|
||||||
|
termInst.write('\r\n' + prefixContent.value)
|
||||||
|
waitForOutput = false
|
||||||
|
inputCursor = 0
|
||||||
|
newInputLine()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="termRef" class="xterm" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.xterm {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.xterm-screen {
|
||||||
|
padding: 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xterm-viewport::-webkit-scrollbar {
|
||||||
|
background-color: #000000;
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xterm-viewport::-webkit-scrollbar-thumb {
|
||||||
|
background: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xterm-decoration-overview-ruler {
|
||||||
|
right: 1px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -75,7 +75,7 @@ const infoFilter = ref('')
|
||||||
<template>
|
<template>
|
||||||
<n-scrollbar ref="scrollRef">
|
<n-scrollbar ref="scrollRef">
|
||||||
<n-back-top :listen-to="scrollRef" />
|
<n-back-top :listen-to="scrollRef" />
|
||||||
<n-space vertical>
|
<n-space vertical :wrap-item="false" :size="5" style="padding: 5px">
|
||||||
<n-card>
|
<n-card>
|
||||||
<template #header>
|
<template #header>
|
||||||
<n-space :wrap-item="false" align="center" inline size="small">
|
<n-space :wrap-item="false" align="center" inline size="small">
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<script setup>
|
||||||
|
import { types } from '@/consts/value_view_type.js'
|
||||||
|
import { types as redisTypes } from '@/consts/support_redis_type.js'
|
||||||
|
import ContentValueString from '@/components/content_value/ContentValueString.vue'
|
||||||
|
import ContentValueHash from '@/components/content_value/ContentValueHash.vue'
|
||||||
|
import ContentValueList from '@/components/content_value/ContentValueList.vue'
|
||||||
|
import ContentValueSet from '@/components/content_value/ContentValueSet.vue'
|
||||||
|
import ContentValueZset from '@/components/content_value/ContentValueZSet.vue'
|
||||||
|
import ContentValueStream from '@/components/content_value/ContentValueStream.vue'
|
||||||
|
import { useThemeVars } from 'naive-ui'
|
||||||
|
|
||||||
|
const themeVars = useThemeVars()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
blank: Boolean,
|
||||||
|
type: String,
|
||||||
|
name: String,
|
||||||
|
db: Number,
|
||||||
|
keyPath: String,
|
||||||
|
keyCode: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
ttl: {
|
||||||
|
type: Number,
|
||||||
|
default: -1,
|
||||||
|
},
|
||||||
|
value: [String, Object],
|
||||||
|
size: Number,
|
||||||
|
viewAs: {
|
||||||
|
type: String,
|
||||||
|
default: types.PLAIN_TEXT,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['reload'])
|
||||||
|
|
||||||
|
const valueComponents = {
|
||||||
|
[redisTypes.STRING]: ContentValueString,
|
||||||
|
[redisTypes.HASH]: ContentValueHash,
|
||||||
|
[redisTypes.LIST]: ContentValueList,
|
||||||
|
[redisTypes.SET]: ContentValueSet,
|
||||||
|
[redisTypes.ZSET]: ContentValueZset,
|
||||||
|
[redisTypes.STREAM]: ContentValueStream,
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<n-empty v-if="props.blank" :description="$t('interface.nonexist_tab_content')" class="empty-content">
|
||||||
|
<template #extra>
|
||||||
|
<n-button :focusable="false" @click="emit('reload')">{{ $t('interface.reload') }}</n-button>
|
||||||
|
</template>
|
||||||
|
</n-empty>
|
||||||
|
<component
|
||||||
|
class="content-value-wrapper"
|
||||||
|
:is="valueComponents[props.type]"
|
||||||
|
v-else
|
||||||
|
:db="props.db"
|
||||||
|
:key-code="props.keyCode"
|
||||||
|
:key-path="props.keyPath"
|
||||||
|
:name="props.name"
|
||||||
|
:size="props.size"
|
||||||
|
:ttl="props.ttl"
|
||||||
|
:value="props.value"
|
||||||
|
:view-as="props.viewAs" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.content-value-wrapper {
|
||||||
|
background-color: v-bind('themeVars.bodyColor');
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -2,7 +2,7 @@
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
inverse: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
@ -10,18 +10,14 @@ const props = defineProps({
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 3,
|
default: 3,
|
||||||
},
|
},
|
||||||
fillColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#dc423c',
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg v-if="props.modelValue" fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
<svg v-if="props.inverse" fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect
|
<rect
|
||||||
:fill="props.fillColor"
|
fill="currentColor"
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
height="8"
|
height="8"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
|
@ -30,8 +26,8 @@ const props = defineProps({
|
||||||
x="4"
|
x="4"
|
||||||
y="34" />
|
y="34" />
|
||||||
<rect
|
<rect
|
||||||
:fill="props.fillColor"
|
fill="currentColor"
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
height="12"
|
height="12"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
|
@ -40,20 +36,20 @@ const props = defineProps({
|
||||||
x="8"
|
x="8"
|
||||||
y="6" />
|
y="6" />
|
||||||
<path
|
<path
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M24 34V18"
|
d="M24 34V18"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
<path
|
<path
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M8 34V26H40V34"
|
d="M8 34V26H40V34"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
<rect
|
<rect
|
||||||
:fill="props.fillColor"
|
fill="currentColor"
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
height="8"
|
height="8"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
|
@ -62,8 +58,8 @@ const props = defineProps({
|
||||||
x="36"
|
x="36"
|
||||||
y="34" />
|
y="34" />
|
||||||
<rect
|
<rect
|
||||||
:fill="props.fillColor"
|
fill="currentColor"
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
height="8"
|
height="8"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
|
@ -78,50 +74,6 @@ const props = defineProps({
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
</svg>
|
</svg>
|
||||||
<svg v-else fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path
|
|
||||||
:stroke-width="props.strokeWidth"
|
|
||||||
d="M5 24L43 24"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
<path
|
|
||||||
:stroke-width="props.strokeWidth"
|
|
||||||
d="M28 4H20C18.8954 4 18 4.89543 18 6V14C18 15.1046 18.8954 16 20 16H28C29.1046 16 30 15.1046 30 14V6C30 4.89543 29.1046 4 28 4Z"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
<path
|
|
||||||
:stroke-width="props.strokeWidth"
|
|
||||||
d="M16 32H8C6.89543 32 6 32.8954 6 34V42C6 43.1046 6.89543 44 8 44H16C17.1046 44 18 43.1046 18 42V34C18 32.8954 17.1046 32 16 32Z"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
<path
|
|
||||||
:stroke-width="props.strokeWidth"
|
|
||||||
d="M40 32H32C30.8954 32 30 32.8954 30 34V42C30 43.1046 30.8954 44 32 44H40C41.1046 44 42 43.1046 42 42V34C42 32.8954 41.1046 32 40 32Z"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
<path
|
|
||||||
:stroke-width="props.strokeWidth"
|
|
||||||
d="M24 24V16"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
<path
|
|
||||||
:stroke-width="props.strokeWidth"
|
|
||||||
d="M36 32V24"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
<path
|
|
||||||
:stroke-width="props.strokeWidth"
|
|
||||||
d="M12 32V24"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round" />
|
|
||||||
</svg>
|
|
||||||
<svg v-else fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
<svg v-else fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect
|
<rect
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
|
@ -2,7 +2,7 @@
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
inverse: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
@ -10,39 +10,35 @@ const props = defineProps({
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 3,
|
default: 3,
|
||||||
},
|
},
|
||||||
fillColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#dc423c',
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg v-if="props.modelValue" fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
<svg v-if="props.inverse" fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M44.0001 11C44.0001 11 44 36.0623 44 38C44 41.3137 35.0457 44 24 44C12.9543 44 4.00003 41.3137 4.00003 38C4.00003 36.1423 4 11 4 11"
|
d="M44.0001 11C44.0001 11 44 36.0623 44 38C44 41.3137 35.0457 44 24 44C12.9543 44 4.00003 41.3137 4.00003 38C4.00003 36.1423 4 11 4 11"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
<path
|
<path
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M44 29C44 32.3137 35.0457 35 24 35C12.9543 35 4 32.3137 4 29"
|
d="M44 29C44 32.3137 35.0457 35 24 35C12.9543 35 4 32.3137 4 29"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
<path
|
<path
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M44 20C44 23.3137 35.0457 26 24 26C12.9543 26 4 23.3137 4 20"
|
d="M44 20C44 23.3137 35.0457 26 24 26C12.9543 26 4 23.3137 4 20"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
<ellipse
|
<ellipse
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
cx="24"
|
cx="24"
|
||||||
cy="10"
|
cy="10"
|
||||||
fill="#dc423c"
|
fill="currentColor"
|
||||||
rx="20"
|
rx="20"
|
||||||
ry="6"
|
ry="6"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
|
@ -0,0 +1,109 @@
|
||||||
|
<script setup>
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
inverse: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
strokeWidth: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 3,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<svg v-if="props.inverse" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect
|
||||||
|
x="6"
|
||||||
|
y="6"
|
||||||
|
width="36"
|
||||||
|
height="36"
|
||||||
|
rx="3"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<rect
|
||||||
|
x="13"
|
||||||
|
y="13"
|
||||||
|
width="8"
|
||||||
|
height="8"
|
||||||
|
fill="#FFF"
|
||||||
|
stroke="#FFF"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M27 13L35 13"
|
||||||
|
stroke="#FFF"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M27 20L35 20"
|
||||||
|
stroke="#FFF"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M13 28L35 28"
|
||||||
|
stroke="#FFF"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M13 35H35"
|
||||||
|
stroke="#FFF"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
<svg v-else viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect
|
||||||
|
x="6"
|
||||||
|
y="6"
|
||||||
|
width="36"
|
||||||
|
height="36"
|
||||||
|
rx="3"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<rect
|
||||||
|
x="13"
|
||||||
|
y="13"
|
||||||
|
width="8"
|
||||||
|
height="8"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M27 13L35 13"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M27 20L35 20"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M13 28L35 28"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M13 35H35"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -2,7 +2,7 @@
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
open: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
@ -18,7 +18,7 @@ const props = defineProps({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg v-if="props.modelValue" fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
<svg v-if="props.open" fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M4 9V41L9 21H39.5V15C39.5 13.8954 38.6046 13 37.5 13H24L19 7H6C4.89543 7 4 7.89543 4 9Z"
|
d="M4 9V41L9 21H39.5V15C39.5 13.8954 38.6046 13 37.5 13H24L19 7H6C4.89543 7 4 7.89543 4 9Z"
|
||||||
|
@ -26,7 +26,7 @@ const props = defineProps({
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
<path
|
<path
|
||||||
:fill="props.fillColor"
|
:fill="props.fillColor || 'currentColor'"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M40 41L44 21H8.8125L4 41H40Z"
|
d="M40 41L44 21H8.8125L4 41H40Z"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
|
@ -35,7 +35,7 @@ const props = defineProps({
|
||||||
</svg>
|
</svg>
|
||||||
<svg v-else fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
<svg v-else fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
:fill="props.fillColor"
|
:fill="props.fillColor || 'currentColor'"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M5 8C5 6.89543 5.89543 6 7 6H19L24 12H41C42.1046 12 43 12.8954 43 14V40C43 41.1046 42.1046 42 41 42H7C5.89543 42 5 41.1046 5 40V8Z"
|
d="M5 8C5 6.89543 5.89543 6 7 6H19L24 12H41C42.1046 12 43 12.8954 43 14V40C43 41.1046 42.1046 42 41 42H7C5.89543 42 5 41.1046 5 40V8Z"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
|
@ -1,5 +1,9 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
inverse: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
strokeWidth: {
|
strokeWidth: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 3,
|
default: 3,
|
||||||
|
@ -8,7 +12,26 @@ const props = defineProps({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
<svg v-if="props.inverse" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect
|
||||||
|
x="13"
|
||||||
|
y="10"
|
||||||
|
width="28"
|
||||||
|
height="34"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="3"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M35 10V4H8C7.44772 4 7 4.44772 7 5V38H13"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="3"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path d="M21 22H33" stroke="#FFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
<path d="M21 30H33" stroke="#FFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
<svg v-else fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect
|
<rect
|
||||||
:stroke-width="strokeWidth"
|
:stroke-width="strokeWidth"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
inverse: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
@ -10,18 +10,14 @@ const props = defineProps({
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 3,
|
default: 3,
|
||||||
},
|
},
|
||||||
fillColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#dc423c',
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg v-if="props.modelValue" fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
<svg v-if="props.inverse" fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
:fill="props.fillColor"
|
fill="currentColor"
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M41 4H7C5.34315 4 4 5.34315 4 7V41C4 42.6569 5.34315 44 7 44H41C42.6569 44 44 42.6569 44 41V7C44 5.34315 42.6569 4 41 4Z"
|
d="M41 4H7C5.34315 4 4 5.34315 4 7V41C4 42.6569 5.34315 44 7 44H41C42.6569 44 44 42.6569 44 41V7C44 5.34315 42.6569 4 41 4Z"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
|
@ -40,13 +36,13 @@ const props = defineProps({
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
<path
|
<path
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M44 37V27"
|
d="M44 37V27"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round" />
|
stroke-linejoin="round" />
|
||||||
<path
|
<path
|
||||||
:stroke="props.fillColor"
|
stroke="currentColor"
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
d="M4 37V27"
|
d="M4 37V27"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
|
@ -1,5 +1,9 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
inverse: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
strokeWidth: {
|
strokeWidth: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 3,
|
default: 3,
|
||||||
|
@ -8,7 +12,17 @@ const props = defineProps({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
<svg v-if="props.inverse" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M42 8H6C4.89543 8 4 8.89543 4 10V38C4 39.1046 4.89543 40 6 40H42C43.1046 40 44 39.1046 44 38V10C44 8.89543 43.1046 8 42 8Z"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="3" />
|
||||||
|
<path d="M24 17V31" stroke="#FFF" :stroke-width="props.strokeWidth" stroke-linecap="round" />
|
||||||
|
<path d="M32 24V31" stroke="#FFF" :stroke-width="props.strokeWidth" stroke-linecap="round" />
|
||||||
|
<path d="M16 22V31" stroke="#FFF" :stroke-width="props.strokeWidth" stroke-linecap="round" />
|
||||||
|
</svg>
|
||||||
|
<svg v-else fill="none" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect
|
<rect
|
||||||
:stroke-width="props.strokeWidth"
|
:stroke-width="props.strokeWidth"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<script setup>
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
inverse: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
strokeWidth: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 3,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<svg v-if="props.inverse" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect
|
||||||
|
x="4"
|
||||||
|
y="8"
|
||||||
|
width="40"
|
||||||
|
height="32"
|
||||||
|
rx="2"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M12 18L19 24L12 30"
|
||||||
|
stroke="#FFF"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M23 32H36"
|
||||||
|
stroke="#FFF"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
<svg v-else viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect
|
||||||
|
x="4"
|
||||||
|
y="8"
|
||||||
|
width="40"
|
||||||
|
height="32"
|
||||||
|
rx="2"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M12 18L19 24L12 30"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M23 32H36"
|
||||||
|
stroke="currentColor"
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -4,7 +4,7 @@ import { ConnectionType } from '@/consts/connection_type.js'
|
||||||
import { NIcon, NSpace, NTag } from 'naive-ui'
|
import { NIcon, NSpace, NTag } from 'naive-ui'
|
||||||
import Key from '@/components/icons/Key.vue'
|
import Key from '@/components/icons/Key.vue'
|
||||||
import Binary from '@/components/icons/Binary.vue'
|
import Binary from '@/components/icons/Binary.vue'
|
||||||
import ToggleDb from '@/components/icons/ToggleDb.vue'
|
import Database from '@/components/icons/Database.vue'
|
||||||
import { find, get, includes, indexOf, isEmpty, remove, size, startsWith } from 'lodash'
|
import { find, get, includes, indexOf, isEmpty, remove, size, startsWith } from 'lodash'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import Refresh from '@/components/icons/Refresh.vue'
|
import Refresh from '@/components/icons/Refresh.vue'
|
||||||
|
@ -399,9 +399,9 @@ const renderPrefix = ({ option }) => {
|
||||||
case ConnectionType.RedisDB:
|
case ConnectionType.RedisDB:
|
||||||
return h(
|
return h(
|
||||||
NIcon,
|
NIcon,
|
||||||
{ size: 20 },
|
{ size: 20, color: option.opened === true ? '#dc423c' : undefined },
|
||||||
{
|
{
|
||||||
default: () => h(ToggleDb, { modelValue: option.opened === true }),
|
default: () => h(Database, { inverse: option.opened === true }),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
case ConnectionType.RedisKey:
|
case ConnectionType.RedisKey:
|
||||||
|
|
|
@ -4,9 +4,9 @@ import { h, nextTick, reactive, ref } from 'vue'
|
||||||
import useConnectionStore from 'stores/connections.js'
|
import useConnectionStore from 'stores/connections.js'
|
||||||
import { NIcon, NSpace, NText, useThemeVars } from 'naive-ui'
|
import { NIcon, NSpace, NText, useThemeVars } from 'naive-ui'
|
||||||
import { ConnectionType } from '@/consts/connection_type.js'
|
import { ConnectionType } from '@/consts/connection_type.js'
|
||||||
import ToggleFolder from '@/components/icons/ToggleFolder.vue'
|
import Folder from '@/components/icons/Folder.vue'
|
||||||
import ToggleServer from '@/components/icons/ToggleServer.vue'
|
import Server from '@/components/icons/Server.vue'
|
||||||
import ToggleCluster from '@/components/icons/ToggleCluster.vue'
|
import Cluster from '@/components/icons/Cluster.vue'
|
||||||
import { debounce, get, includes, indexOf, isEmpty, split } from 'lodash'
|
import { debounce, get, includes, indexOf, isEmpty, split } from 'lodash'
|
||||||
import Config from '@/components/icons/Config.vue'
|
import Config from '@/components/icons/Config.vue'
|
||||||
import Delete from '@/components/icons/Delete.vue'
|
import Delete from '@/components/icons/Delete.vue'
|
||||||
|
@ -185,8 +185,8 @@ const renderPrefix = ({ option }) => {
|
||||||
{ size: 20 },
|
{ size: 20 },
|
||||||
{
|
{
|
||||||
default: () =>
|
default: () =>
|
||||||
h(ToggleFolder, {
|
h(Folder, {
|
||||||
modelValue: opened,
|
open: opened,
|
||||||
fillColor: `rgba(255,206,120,${iconTransparency})`,
|
fillColor: `rgba(255,206,120,${iconTransparency})`,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -194,14 +194,14 @@ const renderPrefix = ({ option }) => {
|
||||||
case ConnectionType.Server:
|
case ConnectionType.Server:
|
||||||
const connected = connectionStore.isConnected(option.name)
|
const connected = connectionStore.isConnected(option.name)
|
||||||
const color = getServerMarkColor(option.name)
|
const color = getServerMarkColor(option.name)
|
||||||
const icon = option.cluster === true ? ToggleCluster : ToggleServer
|
const icon = option.cluster === true ? Cluster : Server
|
||||||
return h(
|
return h(
|
||||||
NIcon,
|
NIcon,
|
||||||
{ size: 20, color: !!!connected ? color : undefined },
|
{ size: 20, color: !!!connected ? color : '#dc423c' },
|
||||||
{
|
{
|
||||||
default: () =>
|
default: () =>
|
||||||
h(icon, {
|
h(icon, {
|
||||||
modelValue: !!connected,
|
inverse: !!connected,
|
||||||
fillColor: `rgba(220,66,60,${iconTransparency})`,
|
fillColor: `rgba(220,66,60,${iconTransparency})`,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, h } from 'vue'
|
import { computed, h } from 'vue'
|
||||||
import { NIcon, useThemeVars } from 'naive-ui'
|
import { NIcon, useThemeVars } from 'naive-ui'
|
||||||
import ToggleDb from '@/components/icons/ToggleDb.vue'
|
import Database from '@/components/icons/Database.vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import ToggleServer from '@/components/icons/ToggleServer.vue'
|
import Server from '@/components/icons/Server.vue'
|
||||||
import IconButton from '@/components/common/IconButton.vue'
|
import IconButton from '@/components/common/IconButton.vue'
|
||||||
import Config from '@/components/icons/Config.vue'
|
import Config from '@/components/icons/Config.vue'
|
||||||
import useDialogStore from 'stores/dialog.js'
|
import useDialogStore from 'stores/dialog.js'
|
||||||
|
@ -40,13 +40,13 @@ const menuOptions = computed(() => {
|
||||||
{
|
{
|
||||||
label: i18n.t('ribbon.browser'),
|
label: i18n.t('ribbon.browser'),
|
||||||
key: 'browser',
|
key: 'browser',
|
||||||
icon: renderIcon(ToggleDb),
|
icon: renderIcon(Database),
|
||||||
show: connectionStore.anyConnectionOpened,
|
show: connectionStore.anyConnectionOpened,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: i18n.t('ribbon.server'),
|
label: i18n.t('ribbon.server'),
|
||||||
key: 'server',
|
key: 'server',
|
||||||
icon: renderIcon(ToggleServer),
|
icon: renderIcon(Server),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: i18n.t('ribbon.log'),
|
label: i18n.t('ribbon.log'),
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
* all types of Browser sub tabs
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
export const BrowserTabType = {
|
||||||
|
Status: 'status',
|
||||||
|
KeyDetail: 'key_detail',
|
||||||
|
Cli: 'cli',
|
||||||
|
SlowLog: 'slow_log',
|
||||||
|
}
|
|
@ -87,13 +87,20 @@
|
||||||
"load_more": "Load More Keys",
|
"load_more": "Load More Keys",
|
||||||
"load_all": "Load All Left Keys",
|
"load_all": "Load All Left Keys",
|
||||||
"more_action": "More Action",
|
"more_action": "More Action",
|
||||||
"nonexist_tab_content": "Selected key does not exist. Please retry",
|
"nonexist_tab_content": "Selected key does not exist or no key is selected. Please retry",
|
||||||
"empty_server_content": "Select and open a connection from the left",
|
"empty_server_content": "Select and open a connection from the left",
|
||||||
"empty_server_list": "No redis server",
|
"empty_server_list": "No redis server",
|
||||||
"action": "Action",
|
"action": "Action",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
"score": "Score",
|
"score": "Score",
|
||||||
"total": "Length: {size}"
|
"total": "Length: {size}",
|
||||||
|
"cli_welcome": "Welcome to Tiny RDM Redis Console",
|
||||||
|
"sub_tab": {
|
||||||
|
"status": "Status",
|
||||||
|
"key_detail": "Key Detail",
|
||||||
|
"cli": "Command Line",
|
||||||
|
"slow_log": "Slow Log"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"ribbon": {
|
"ribbon": {
|
||||||
"server": "Server",
|
"server": "Server",
|
||||||
|
|
|
@ -87,13 +87,20 @@
|
||||||
"load_more": "加载更多键",
|
"load_more": "加载更多键",
|
||||||
"load_all": "加载剩余所有键",
|
"load_all": "加载剩余所有键",
|
||||||
"more_action": "更多操作",
|
"more_action": "更多操作",
|
||||||
"nonexist_tab_content": "所选键不存在,请尝试刷新重试",
|
"nonexist_tab_content": "所选键不存在或未选中任何键,请尝试刷新重试",
|
||||||
"empty_server_content": "可以从左边选择并打开连接",
|
"empty_server_content": "可以从左边选择并打开连接",
|
||||||
"empty_server_list": "还没添加Redis服务器",
|
"empty_server_list": "还没添加Redis服务器",
|
||||||
"action": "操作",
|
"action": "操作",
|
||||||
"type": "类型",
|
"type": "类型",
|
||||||
"score": "分值",
|
"score": "分值",
|
||||||
"total": "总数:{size}"
|
"total": "总数:{size}",
|
||||||
|
"cli_welcome": "欢迎使用Tiny RDM的Redis命令行控制台",
|
||||||
|
"sub_tab": {
|
||||||
|
"status": "状态",
|
||||||
|
"key_detail": "键详情",
|
||||||
|
"cli": "命令行",
|
||||||
|
"slow_log": "慢日志"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"ribbon": {
|
"ribbon": {
|
||||||
"server": "服务器",
|
"server": "服务器",
|
||||||
|
|
|
@ -52,7 +52,7 @@ import useTabStore from './tab.js'
|
||||||
import { types } from '@/consts/support_redis_type.js'
|
import { types } from '@/consts/support_redis_type.js'
|
||||||
import { decodeRedisKey, nativeRedisKey } from '@/utils/key_convert.js'
|
import { decodeRedisKey, nativeRedisKey } from '@/utils/key_convert.js'
|
||||||
import { KeyViewType } from '@/consts/key_view_type.js'
|
import { KeyViewType } from '@/consts/key_view_type.js'
|
||||||
import { nextTick } from 'vue'
|
import { BrowserTabType } from '@/consts/browser_tab_type.js'
|
||||||
|
|
||||||
const useConnectionStore = defineStore('connections', {
|
const useConnectionStore = defineStore('connections', {
|
||||||
/**
|
/**
|
||||||
|
@ -668,6 +668,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
const k = decodeRedisKey(key)
|
const k = decodeRedisKey(key)
|
||||||
const binaryKey = k !== key
|
const binaryKey = k !== key
|
||||||
tab.upsertTab({
|
tab.upsertTab({
|
||||||
|
subTab: BrowserTabType.KeyDetail,
|
||||||
server,
|
server,
|
||||||
db,
|
db,
|
||||||
type,
|
type,
|
||||||
|
@ -690,6 +691,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
}
|
}
|
||||||
|
|
||||||
tab.upsertTab({
|
tab.upsertTab({
|
||||||
|
subTab: BrowserTabType.Status,
|
||||||
server,
|
server,
|
||||||
db,
|
db,
|
||||||
type: 'none',
|
type: 'none',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { find, findIndex, get, size } from 'lodash'
|
import { find, findIndex, get, isEmpty, set, size } from 'lodash'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
const useTabStore = defineStore('tab', {
|
const useTabStore = defineStore('tab', {
|
||||||
|
@ -6,6 +6,7 @@ const useTabStore = defineStore('tab', {
|
||||||
* @typedef {Object} TabItem
|
* @typedef {Object} TabItem
|
||||||
* @property {string} name connection name
|
* @property {string} name connection name
|
||||||
* @property {boolean} blank is blank tab
|
* @property {boolean} blank is blank tab
|
||||||
|
* @property {string} subTab secondary tab value
|
||||||
* @property {string} [title] tab title
|
* @property {string} [title] tab title
|
||||||
* @property {string} [icon] tab icon
|
* @property {string} [icon] tab icon
|
||||||
* @property {string[]} selectedKeys
|
* @property {string[]} selectedKeys
|
||||||
|
@ -64,12 +65,16 @@ const useTabStore = defineStore('tab', {
|
||||||
*
|
*
|
||||||
* @param idx
|
* @param idx
|
||||||
* @param {boolean} [switchNav]
|
* @param {boolean} [switchNav]
|
||||||
|
* @param {string} [subTab]
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_setActivatedIndex(idx, switchNav) {
|
_setActivatedIndex(idx, switchNav, subTab) {
|
||||||
this.activatedIndex = idx
|
this.activatedIndex = idx
|
||||||
if (switchNav === true) {
|
if (switchNav === true) {
|
||||||
this.nav = idx >= 0 ? 'browser' : 'server'
|
this.nav = idx >= 0 ? 'browser' : 'server'
|
||||||
|
if (!isEmpty(subTab)) {
|
||||||
|
set(this.tabList, [idx, 'subTab'], subTab)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
this.nav = 'server'
|
this.nav = 'server'
|
||||||
|
@ -79,6 +84,7 @@ const useTabStore = defineStore('tab', {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* update or insert a new tab if not exists with the same name
|
* update or insert a new tab if not exists with the same name
|
||||||
|
* @param {string} subTab
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} [db]
|
* @param {number} [db]
|
||||||
* @param {number} [type]
|
* @param {number} [type]
|
||||||
|
@ -89,11 +95,13 @@ const useTabStore = defineStore('tab', {
|
||||||
* @param {*} [value]
|
* @param {*} [value]
|
||||||
* @param {string} [viewAs]
|
* @param {string} [viewAs]
|
||||||
*/
|
*/
|
||||||
upsertTab({ server, db, type, ttl, key, keyCode, size, value, viewAs }) {
|
upsertTab({ subTab, server, db, type, ttl, key, keyCode, size, value, viewAs }) {
|
||||||
let tabIndex = findIndex(this.tabList, { name: server })
|
let tabIndex = findIndex(this.tabList, { name: server })
|
||||||
if (tabIndex === -1) {
|
if (tabIndex === -1) {
|
||||||
this.tabList.push({
|
this.tabList.push({
|
||||||
name: server,
|
name: server,
|
||||||
|
title: server,
|
||||||
|
subTab,
|
||||||
server,
|
server,
|
||||||
db,
|
db,
|
||||||
type,
|
type,
|
||||||
|
@ -105,21 +113,23 @@ const useTabStore = defineStore('tab', {
|
||||||
viewAs,
|
viewAs,
|
||||||
})
|
})
|
||||||
tabIndex = this.tabList.length - 1
|
tabIndex = this.tabList.length - 1
|
||||||
|
} else {
|
||||||
|
const tab = this.tabList[tabIndex]
|
||||||
|
tab.blank = false
|
||||||
|
tab.subTab = subTab
|
||||||
|
// tab.title = db !== undefined ? `${server}/db${db}` : `${server}`
|
||||||
|
tab.title = server
|
||||||
|
tab.server = server
|
||||||
|
tab.db = db
|
||||||
|
tab.type = type
|
||||||
|
tab.ttl = ttl
|
||||||
|
tab.key = key
|
||||||
|
tab.keyCode = keyCode
|
||||||
|
tab.size = size
|
||||||
|
tab.value = value
|
||||||
|
tab.viewAs = viewAs
|
||||||
}
|
}
|
||||||
const tab = this.tabList[tabIndex]
|
this._setActivatedIndex(tabIndex, true, subTab)
|
||||||
tab.blank = false
|
|
||||||
// tab.title = db !== undefined ? `${server}/db${db}` : `${server}`
|
|
||||||
tab.title = server
|
|
||||||
tab.server = server
|
|
||||||
tab.db = db
|
|
||||||
tab.type = type
|
|
||||||
tab.ttl = ttl
|
|
||||||
tab.key = key
|
|
||||||
tab.keyCode = keyCode
|
|
||||||
tab.size = size
|
|
||||||
tab.value = value
|
|
||||||
tab.viewAs = viewAs
|
|
||||||
this._setActivatedIndex(tabIndex, true)
|
|
||||||
// this.activatedTab = tab.name
|
// this.activatedTab = tab.name
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -162,6 +172,14 @@ const useTabStore = defineStore('tab', {
|
||||||
// this.activatedIndex = tabIndex
|
// this.activatedIndex = tabIndex
|
||||||
},
|
},
|
||||||
|
|
||||||
|
switchSubTab(name) {
|
||||||
|
const tab = this.currentTab
|
||||||
|
if (tab == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tab.subTab = name
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {number} tabIndex
|
* @param {number} tabIndex
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
.content-container {
|
.content-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding-top: 2px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ body {
|
||||||
background-color: #0000;
|
background-color: #0000;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
font-family: v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
font-family: v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||||
//--wails-draggable: drag;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
|
@ -75,7 +75,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
//height: 100%;
|
height: 100%;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
@ -95,6 +95,7 @@ body {
|
||||||
.value-wrapper {
|
.value-wrapper {
|
||||||
//border-top: v-bind('themeVars.borderColor') 1px solid;
|
//border-top: v-bind('themeVars.borderColor') 1px solid;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -37,7 +37,7 @@ require (
|
||||||
github.com/tkrajina/go-reflector v0.5.6 // indirect
|
github.com/tkrajina/go-reflector v0.5.6 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
github.com/wailsapp/go-webview2 v1.0.8 // indirect
|
github.com/wailsapp/go-webview2 v1.0.10 // indirect
|
||||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
|
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
|
||||||
golang.org/x/net v0.17.0 // indirect
|
golang.org/x/net v0.17.0 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -82,8 +82,8 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ
|
||||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68 h1:Ah2/69Z24rwD6OByyOdpJDmttftz0FTF8Q4QZ/SF1E4=
|
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68 h1:Ah2/69Z24rwD6OByyOdpJDmttftz0FTF8Q4QZ/SF1E4=
|
||||||
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68/go.mod h1:EqKqAeKddSL9XSGnfXd/7iLncccKhR16HBKVva7ENw8=
|
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68/go.mod h1:EqKqAeKddSL9XSGnfXd/7iLncccKhR16HBKVva7ENw8=
|
||||||
github.com/wailsapp/go-webview2 v1.0.8 h1:hyoFPlMSfb/NM64wuVbgBaq1MASJjqsSUYhN+Rbcr9Y=
|
github.com/wailsapp/go-webview2 v1.0.10 h1:PP5Hug6pnQEAhfRzLCoOh2jJaPdrqeRgJKZhyYyDV/w=
|
||||||
github.com/wailsapp/go-webview2 v1.0.8/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
|
github.com/wailsapp/go-webview2 v1.0.10/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
|
||||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||||
github.com/wailsapp/wails/v2 v2.6.0 h1:EyH0zR/EO6dDiqNy8qU5spaXDfkluiq77xrkabPYD4c=
|
github.com/wailsapp/wails/v2 v2.6.0 h1:EyH0zR/EO6dDiqNy8qU5spaXDfkluiq77xrkabPYD4c=
|
||||||
|
|
6
main.go
6
main.go
|
@ -28,6 +28,7 @@ func main() {
|
||||||
// Create an instance of the app structure
|
// Create an instance of the app structure
|
||||||
sysSvc := services.System()
|
sysSvc := services.System()
|
||||||
connSvc := services.Connection()
|
connSvc := services.Connection()
|
||||||
|
cliSvc := services.Cli()
|
||||||
prefSvc := services.Preferences()
|
prefSvc := services.Preferences()
|
||||||
prefSvc.SetAppVersion(version)
|
prefSvc.SetAppVersion(version)
|
||||||
windowWidth, windowHeight := prefSvc.GetWindowSize()
|
windowWidth, windowHeight := prefSvc.GetWindowSize()
|
||||||
|
@ -56,16 +57,19 @@ func main() {
|
||||||
OnStartup: func(ctx context.Context) {
|
OnStartup: func(ctx context.Context) {
|
||||||
sysSvc.Start(ctx)
|
sysSvc.Start(ctx)
|
||||||
connSvc.Start(ctx)
|
connSvc.Start(ctx)
|
||||||
|
cliSvc.Start(ctx)
|
||||||
|
|
||||||
services.GA().SetSecretKey(gaMeasurementID, gaSecretKey)
|
services.GA().SetSecretKey(gaMeasurementID, gaSecretKey)
|
||||||
services.GA().Startup(version)
|
services.GA().Startup(version)
|
||||||
},
|
},
|
||||||
OnShutdown: func(ctx context.Context) {
|
OnShutdown: func(ctx context.Context) {
|
||||||
connSvc.Stop(ctx)
|
connSvc.Stop()
|
||||||
|
cliSvc.CloseAll()
|
||||||
},
|
},
|
||||||
Bind: []interface{}{
|
Bind: []interface{}{
|
||||||
sysSvc,
|
sysSvc,
|
||||||
connSvc,
|
connSvc,
|
||||||
|
cliSvc,
|
||||||
prefSvc,
|
prefSvc,
|
||||||
},
|
},
|
||||||
Mac: &mac.Options{
|
Mac: &mac.Options{
|
||||||
|
|
Loading…
Reference in New Issue