mirror of
https://github.com/qishibo/AnotherRedisDesktopManager.git
synced 2026-02-01 17:27:13 +00:00
merge master
This commit is contained in:
commit
2073217886
12
README.md
12
README.md
@ -42,13 +42,7 @@
|
||||
- Or **sponsor** by app store, It's not free, and I will be very grateful to you.
|
||||
<br/>[](https://apps.apple.com/app/id1516451072)
|
||||
|
||||
<!--
|
||||
> If **Mac** warning `Another Desktop Manager can't be opened because it is from an unidentified developer`. Open `Settings->Security` and click **`Open Anyway`**
|
||||
|
||||

|
||||
|
||||

|
||||
-->
|
||||
|
||||
## Enjoy!
|
||||
|
||||
@ -119,7 +113,7 @@ cd AnotherRedisDesktopManager
|
||||
npm install
|
||||
|
||||
# if download electron failed during installing, use this command
|
||||
# ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/" npm install
|
||||
# ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/" npm install
|
||||
|
||||
# serve with hot reload at localhost:9988
|
||||
npm start
|
||||
@ -154,7 +148,7 @@ cd AnotherRedisDesktopManager
|
||||
npm install --platform=win32
|
||||
|
||||
# if download electron failed during installing, use this command
|
||||
# npm config set ELECTRON_MIRROR http://npm.taobao.org/mirrors/electron/
|
||||
# npm config set ELECTRON_MIRROR https://npmmirror.com/mirrors/electron/
|
||||
# npm install --platform=win32
|
||||
|
||||
# serve with hot reload at localhost:9988
|
||||
@ -214,7 +208,7 @@ This project exists thanks to all the people who contribute.
|
||||
| ------ | ------ |
|
||||
| `Name` | Custom name |
|
||||
| `Command` | Executable commands, such as `xxx.py` `xxx.js` `xxx.class` etc. The file needs `x` permission, which can be executed in the form of `./xxx.py`; It can also be set to `/bin/node` `/bin/bash` or other system commands, and the script path needs to be placed in Params |
|
||||
| `Params` | Parameters spliced after `Command`, such as "--key `{KEY}` --value `{VALUE}`", where `{KEY}` and `{VALUE}` will be replaced with the corresponding Redis key and value. Note that if the content is invisible such as binary, you can use `{HEX}` instead of `{VALUE}`, and `{HEX}` will be replaced with the hexadecimal string |
|
||||
| `Params` | Parameters spliced after `Command`, such as "--key `{KEY}` --value `{VALUE}`", where `{KEY}` and `{VALUE}` will be replaced with the corresponding Redis key and value. Note that if the content is invisible such as binary, you can use `{HEX}` instead of `{VALUE}`, and `{HEX}` will be replaced with the hexadecimal string. If HEX is too long (>8000 chars), it will be written to a temporary file. You can use `{HEX_FILE}` to obtain the file path, and read by yourself in the script |
|
||||
|
||||
### Configuration example:
|
||||
> Add env to the first line of the script, the final executed command is: `./home/qii/pickle_decoder.py {HEX}`, the script can receive parameters via `argv[1]`, ref [#978](https://github.com/qishibo/AnotherRedisDesktopManager/issues/987#issuecomment-1294844707)
|
||||
|
||||
@ -37,13 +37,6 @@
|
||||
- 或者通过App Store**赞助**, 然后让App Store帮你自动更新版本
|
||||
<br/>[](https://apps.apple.com/app/id1516451072)
|
||||
|
||||
<!--
|
||||
> If **Mac** warning `Another Desktop Manager can't be opened because it is from an unidentified developer`. Open `Settings->Security` and click **`Open Anyway`**
|
||||
|
||||

|
||||
|
||||

|
||||
-->
|
||||
|
||||
|
||||
## 起飞!
|
||||
@ -116,7 +109,7 @@ cd AnotherRedisDesktopManager
|
||||
npm install
|
||||
|
||||
# if download electron failed during installing, use this command
|
||||
# ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/" npm install
|
||||
# ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/" npm install
|
||||
|
||||
# serve with hot reload at localhost:9988
|
||||
npm start
|
||||
@ -151,7 +144,7 @@ cd AnotherRedisDesktopManager
|
||||
npm install --platform=win32
|
||||
|
||||
# if download electron failed during installing, use this command
|
||||
# npm config set ELECTRON_MIRROR http://npm.taobao.org/mirrors/electron/
|
||||
# npm config set ELECTRON_MIRROR https://npmmirror.com/mirrors/electron/
|
||||
# npm install --platform=win32
|
||||
|
||||
# serve with hot reload at localhost:9988
|
||||
@ -188,7 +181,7 @@ npm run pack:linux
|
||||
- 通过 [OpenCollective](https://opencollective.com/AnotherRedisDesktopManager)
|
||||
- 如果你是Mac用户, 也可以通过从[App Store](https://apps.apple.com/app/id1516451072)购买来赞助, 然后应用商店会为你自动更新
|
||||
<br>[](https://apps.apple.com/app/id1516451072)
|
||||
- 如果你是Windows用户,还可以通过从[Windows Store](https://www.microsoft.com/store/apps/9MTD84X0JFHZ)购买来赞助,商店就会帮你自动更新
|
||||
- 如果你是Windows用户,还可以通过从[Win Store](https://www.microsoft.com/store/apps/9MTD84X0JFHZ)购买来赞助,商店就会帮你自动更新
|
||||
<br>[](https://www.microsoft.com/store/apps/9MTD84X0JFHZ)
|
||||
- 微信赞助码 [觉得好用,赞助一些大白兔🐇奶糖!]
|
||||
|
||||
@ -213,10 +206,10 @@ npm run pack:linux
|
||||
| ------ | ------ |
|
||||
| `Name` | 自定义名称 |
|
||||
| `Command` | 可执行命令,如`xxx.py` `xxx.js` `xxx.class`等,该文件需要具有可执行的`x`权限,可以通过形如`./xxx.py`方式执行;也可以直接用系统命令`/bin/node` `/bin/bash`等,此时需要把脚本路径放到Params里 |
|
||||
| `Params` | 拼接在`Command`后的参数,如"--key `{KEY}` --value `{VALUE}`",其中`{KEY}`和`{VALUE}`在执行时会被替换成对应的Redis key和value。注意如果内容为二进制等不可见字符时,可以使用`{HEX}`代替`{VALUE}`,`{HEX}`会被替换成对应value的16进制即hex编码 |
|
||||
| `Params` | 拼接在`Command`后的参数,如"--key `{KEY}` --value `{VALUE}`",其中`{KEY}`和`{VALUE}`在执行时会被替换成对应的Redis key和value。注意如果内容为二进制等不可见字符时,可以使用`{HEX}`,`{HEX}`会被替换成对应value的16进制即hex编码。如果HEX过长(>8000字符)时会被写入到临时文件,可以用`{HEX_FILE}`获取文件路径,脚本中自行读取即可 |
|
||||
|
||||
### 配置样例:
|
||||
> 脚本文件首行要增加env说明,最终执行的命令如: `./home/qii/pickle_decoder.py {HEX}`, 脚本中可以使用`argv[1]`接收参数,参考 [#978](https://github.com/qishibo/AnotherRedisDesktopManager/issues/987#issuecomment-1294844707)
|
||||
> 脚本文件首行一般要增加env说明,最终执行的命令如: `./home/qii/pickle_decoder.py {HEX}`, 脚本中可以使用`argv[1]`接收参数,参考 [#978](https://github.com/qishibo/AnotherRedisDesktopManager/issues/987#issuecomment-1294844707)
|
||||
|
||||
| Command | Params |
|
||||
| ------ | ------ |
|
||||
@ -332,6 +325,6 @@ npm run pack:linux
|
||||
|
||||
## Support
|
||||
|
||||
[goanother.com](https://goanother.com/) [Producthunt](https://www.producthunt.com/posts/another-redis-desktop-manager) [Weibo@shiboooo](https://weibo.com/shiboooo?is_hot=1) [Download Analysis](https://qii404.me/github-release-statistics/?repo=/qishibo/AnotherRedisDesktopManager/)
|
||||
[goanother.com](https://goanother.com/) [Producthunt](https://www.producthunt.com/posts/another-redis-desktop-manager) [Download Analysis](https://qii404.me/github-release-statistics/?repo=/qishibo/AnotherRedisDesktopManager/)
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "another-desktop-manager",
|
||||
"productName": "Another Desktop Manager",
|
||||
"version": "1.6.5",
|
||||
"version": "1.6.7",
|
||||
"description": "A faster, better and more stable redis desktop manager.",
|
||||
"author": "Another",
|
||||
"private": true,
|
||||
|
||||
@ -211,7 +211,7 @@ export default {
|
||||
// 300ms after menu expand animination
|
||||
setTimeout(() => {
|
||||
let scrollTop = 0;
|
||||
const menus = document.querySelectorAll('.connections-list>ul');
|
||||
const menus = document.querySelectorAll('.connections-wrap .connections-list>ul');
|
||||
|
||||
// calc height sum of all above menus
|
||||
for (const menu of menus) {
|
||||
@ -223,8 +223,8 @@ export default {
|
||||
|
||||
// if connections filter input exists, scroll more
|
||||
// 32 = height('.filter-input')+margin
|
||||
const offset = document.querySelector('.connections-list .filter-input') ? 32 : 0;
|
||||
document.querySelector('.connections-list').scrollTo({
|
||||
const offset = document.querySelector('.connections-wrap .filter-input') ? 32 : 0;
|
||||
document.querySelector('.connections-wrap').scrollTo({
|
||||
top: scrollTop + offset,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="connections-list">
|
||||
<div class="filter-input">
|
||||
<div class="connections-wrap">
|
||||
<!-- search connections input -->
|
||||
<div v-if="connections.length>=filterEnableNum" class="filter-input">
|
||||
<el-input
|
||||
v-if="connections.length>=filterEnableNum"
|
||||
v-model="filterMode"
|
||||
suffix-icon="el-icon-search"
|
||||
:placeholder="$t('message.search_connection')"
|
||||
@ -10,13 +10,17 @@
|
||||
size="mini">
|
||||
</el-input>
|
||||
</div>
|
||||
<ConnectionWrapper
|
||||
v-for="item, index of filteredConnections"
|
||||
:key="item.key ? item.key : item.connectionName"
|
||||
:index="index"
|
||||
:globalSettings="globalSettings"
|
||||
:config='item'>
|
||||
</ConnectionWrapper>
|
||||
|
||||
<!-- connections list -->
|
||||
<div class="connections-list">
|
||||
<ConnectionWrapper
|
||||
v-for="item, index of filteredConnections"
|
||||
:key="item.key ? item.key : item.connectionName"
|
||||
:index="index"
|
||||
:globalSettings="globalSettings"
|
||||
:config='item'>
|
||||
</ConnectionWrapper>
|
||||
</div>
|
||||
|
||||
<ScrollToTop parentNum='1' :posRight='false'></ScrollToTop>
|
||||
</div>
|
||||
@ -74,7 +78,7 @@ export default {
|
||||
this.connections = slovedConnections;
|
||||
},
|
||||
sortOrder() {
|
||||
const dragWrapper = document.querySelector('.connections-list ');
|
||||
const dragWrapper = document.querySelector('.connections-list');
|
||||
Sortable.create(dragWrapper, {
|
||||
handle: '.el-submenu__title',
|
||||
animation: 400,
|
||||
@ -99,13 +103,17 @@ export default {
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
.connections-list {
|
||||
.connections-wrap {
|
||||
height: calc(100vh - 59px);
|
||||
overflow-y: auto;
|
||||
margin-top: 11px;
|
||||
}
|
||||
.connections-list .filter-input {
|
||||
.connections-wrap .filter-input {
|
||||
padding-right: 13px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
/* set drag area min height, target to the end will be correct */
|
||||
.connections-wrap .connections-list {
|
||||
min-height: calc(100vh - 110px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -273,13 +273,13 @@ export default {
|
||||
|
||||
.key-header-item.key-name-input {
|
||||
width: calc(100% - 402px);
|
||||
min-width: 220px;
|
||||
min-width: 218px;
|
||||
max-width: 800px;
|
||||
margin-right: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.key-header-item.key-ttl-input {
|
||||
width: 220px;
|
||||
width: 218px;
|
||||
margin-right: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@ -368,10 +368,23 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// get real node name in ssh+cluster, instead of local port
|
||||
const natMap = this.client.options.natMap;
|
||||
const clusterNodeNames = {};
|
||||
|
||||
if (natMap && Object.keys(natMap).length) {
|
||||
for (const real in natMap) {
|
||||
clusterNodeNames[`${natMap[real].host}:${natMap[real].port}`] = real;
|
||||
}
|
||||
}
|
||||
|
||||
nodes.map((node) => {
|
||||
node.call('INFO', 'KEYSPACE').then((reply) => {
|
||||
const { options } = node;
|
||||
const name = `${options.host}:${options.port}`;
|
||||
|
||||
// fix #1221 node name in ssh+cluster
|
||||
let name = `${options.host}:${options.port}`;
|
||||
name = clusterNodeNames[name] || name;
|
||||
|
||||
const keys = this.initDbKeys(this.initStatus(reply), name);
|
||||
|
||||
|
||||
@ -82,18 +82,12 @@ export default {
|
||||
this.fullCommand = command.replace(
|
||||
'{VALUE}',
|
||||
this.content,
|
||||
).replace(
|
||||
'{HEX}',
|
||||
hexStr,
|
||||
);
|
||||
|
||||
// in case of long content in template
|
||||
this.previewCommand = command.replace(
|
||||
'{VALUE}',
|
||||
this.$util.cutString(this.content.toString(), this.previewContentMax),
|
||||
).replace(
|
||||
'{HEX}',
|
||||
this.$util.cutString(hexStr, this.previewContentMax),
|
||||
);
|
||||
|
||||
// if content is too long, write to file simultaneously
|
||||
@ -109,8 +103,12 @@ export default {
|
||||
return this.$message.error(err);
|
||||
}
|
||||
|
||||
this.fullCommand = this.fullCommand.replace('{HEX_FILE}', filePath);
|
||||
this.previewCommand = this.previewCommand.replace('{HEX_FILE}', filePath);
|
||||
this.fullCommand = this.fullCommand
|
||||
.replace('{HEX_FILE}', filePath)
|
||||
.replace('{HEX}', '<Content Too Long, Use {HEX_FILE} Instead!>');
|
||||
this.previewCommand = this.previewCommand
|
||||
.replace('{HEX_FILE}', filePath)
|
||||
.replace('{HEX}', '<Content Too Long, Use {HEX_FILE} Instead!>');
|
||||
|
||||
this.exec();
|
||||
});
|
||||
@ -118,8 +116,17 @@ export default {
|
||||
}
|
||||
// common content just exec
|
||||
else {
|
||||
this.fullCommand = this.fullCommand.replace('{HEX_FILE}', '');
|
||||
this.previewCommand = this.previewCommand.replace('{HEX_FILE}', '');
|
||||
this.fullCommand = this.fullCommand
|
||||
.replace('{HEX}', hexStr)
|
||||
.replace('{HEX_FILE}', '<Use {HEX} Instead!>');
|
||||
|
||||
this.previewCommand = this.previewCommand
|
||||
.replace(
|
||||
'{HEX}',
|
||||
this.$util.cutString(hexStr, this.previewContentMax),
|
||||
)
|
||||
.replace('{HEX_FILE}', '<Use {HEX} Instead!>');
|
||||
|
||||
this.exec();
|
||||
}
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user