perf: set status auto refresh on by default and save to connection profile
This commit is contained in:
parent
6538313da8
commit
9402af2433
|
@ -367,11 +367,31 @@ func (c *connectionService) SaveLastDB(name string, db int) (resp types.JSResp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if param.LastDB != db {
|
||||||
param.LastDB = db
|
param.LastDB = db
|
||||||
if err := c.conns.UpdateConnection(name, param.ConnectionConfig); err != nil {
|
if err := c.conns.UpdateConnection(name, param.ConnectionConfig); err != nil {
|
||||||
resp.Msg = "save connection fail:" + err.Error()
|
resp.Msg = "save connection fail:" + err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
resp.Success = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveRefreshInterval save auto refresh interval
|
||||||
|
func (c *connectionService) SaveRefreshInterval(name string, interval int) (resp types.JSResp) {
|
||||||
|
param := c.conns.GetConnection(name)
|
||||||
|
if param == nil {
|
||||||
|
resp.Msg = "no connection named \"" + name + "\""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if param.RefreshInterval != interval {
|
||||||
|
param.RefreshInterval = interval
|
||||||
|
if err := c.conns.UpdateConnection(name, param.ConnectionConfig); err != nil {
|
||||||
|
resp.Msg = "save connection fail:" + err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
resp.Success = true
|
resp.Success = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ func (c *ConnectionsStorage) defaultConnectionItem() types.ConnectionConfig {
|
||||||
DBFilterList: []int{},
|
DBFilterList: []int{},
|
||||||
LoadSize: consts.DEFAULT_LOAD_SIZE,
|
LoadSize: consts.DEFAULT_LOAD_SIZE,
|
||||||
MarkColor: "",
|
MarkColor: "",
|
||||||
|
RefreshInterval: 5,
|
||||||
Sentinel: types.ConnectionSentinel{
|
Sentinel: types.ConnectionSentinel{
|
||||||
Master: "mymaster",
|
Master: "mymaster",
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,6 +19,7 @@ type ConnectionConfig struct {
|
||||||
KeyView int `json:"keyView,omitempty" yaml:"key_view,omitempty"`
|
KeyView int `json:"keyView,omitempty" yaml:"key_view,omitempty"`
|
||||||
LoadSize int `json:"loadSize,omitempty" yaml:"load_size,omitempty"`
|
LoadSize int `json:"loadSize,omitempty" yaml:"load_size,omitempty"`
|
||||||
MarkColor string `json:"markColor,omitempty" yaml:"mark_color,omitempty"`
|
MarkColor string `json:"markColor,omitempty" yaml:"mark_color,omitempty"`
|
||||||
|
RefreshInterval int `json:"refreshInterval,omitempty" yaml:"refreshInterval,omitempty"`
|
||||||
SSL ConnectionSSL `json:"ssl,omitempty" yaml:"ssl,omitempty"`
|
SSL ConnectionSSL `json:"ssl,omitempty" yaml:"ssl,omitempty"`
|
||||||
SSH ConnectionSSH `json:"ssh,omitempty" yaml:"ssh,omitempty"`
|
SSH ConnectionSSH `json:"ssh,omitempty" yaml:"ssh,omitempty"`
|
||||||
Sentinel ConnectionSentinel `json:"sentinel,omitempty" yaml:"sentinel,omitempty"`
|
Sentinel ConnectionSentinel `json:"sentinel,omitempty" yaml:"sentinel,omitempty"`
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0024a462d0c3d76d35aeb433518d8b5e
|
c2681c210327633ae1a043d772209dc7
|
|
@ -124,7 +124,9 @@ watch(
|
||||||
<span>{{ $t('interface.sub_tab.status') }}</span>
|
<span>{{ $t('interface.sub_tab.status') }}</span>
|
||||||
</n-space>
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
<content-server-status :server="props.server" />
|
<content-server-status
|
||||||
|
:pause="selectedSubTab !== BrowserTabType.Status.toString()"
|
||||||
|
:server="props.server" />
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
|
|
||||||
<!-- key detail pane -->
|
<!-- key detail pane -->
|
||||||
|
|
|
@ -13,13 +13,16 @@ import dayjs from 'dayjs'
|
||||||
import { convertBytes, formatBytes } from '@/utils/byte_convert.js'
|
import { convertBytes, formatBytes } from '@/utils/byte_convert.js'
|
||||||
import usePreferencesStore from 'stores/preferences.js'
|
import usePreferencesStore from 'stores/preferences.js'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import useConnectionStore from 'stores/connections.js'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
server: String,
|
server: String,
|
||||||
|
pause: Boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
const browserStore = useBrowserStore()
|
const browserStore = useBrowserStore()
|
||||||
const prefStore = usePreferencesStore()
|
const prefStore = usePreferencesStore()
|
||||||
|
const connectionStore = useConnectionStore()
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
const themeVars = useThemeVars()
|
const themeVars = useThemeVars()
|
||||||
const serverInfo = ref({})
|
const serverInfo = ref({})
|
||||||
|
@ -125,13 +128,19 @@ const isLoading = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const startAutoRefresh = async () => {
|
const startAutoRefresh = async () => {
|
||||||
|
// connectionStore.getRefreshInterval()
|
||||||
let lastExec = Date.now()
|
let lastExec = Date.now()
|
||||||
do {
|
do {
|
||||||
if (!pageState.autoRefresh) {
|
if (!pageState.autoRefresh) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
await timeout(100)
|
await timeout(100)
|
||||||
if (pageState.loading || pageState.autoLoading || Date.now() - lastExec < pageState.refreshInterval * 1000) {
|
if (
|
||||||
|
props.pause ||
|
||||||
|
pageState.loading ||
|
||||||
|
pageState.autoLoading ||
|
||||||
|
Date.now() - lastExec < pageState.refreshInterval * 1000
|
||||||
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
lastExec = Date.now()
|
lastExec = Date.now()
|
||||||
|
@ -147,13 +156,23 @@ const stopAutoRefresh = () => {
|
||||||
const onToggleRefresh = (on) => {
|
const onToggleRefresh = (on) => {
|
||||||
if (on) {
|
if (on) {
|
||||||
tabVal.value = 'activity'
|
tabVal.value = 'activity'
|
||||||
|
connectionStore.saveRefreshInterval(props.server, pageState.refreshInterval || 5)
|
||||||
startAutoRefresh()
|
startAutoRefresh()
|
||||||
} else {
|
} else {
|
||||||
|
connectionStore.saveRefreshInterval(props.server, -1)
|
||||||
stopAutoRefresh()
|
stopAutoRefresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
const interval = connectionStore.getRefreshInterval(props.server)
|
||||||
|
if (interval >= 0) {
|
||||||
|
pageState.autoRefresh = true
|
||||||
|
pageState.refreshInterval = interval === 0 ? 5 : interval
|
||||||
|
onToggleRefresh(true)
|
||||||
|
} else {
|
||||||
|
setTimeout(refreshInfo, 5000)
|
||||||
|
}
|
||||||
refreshInfo()
|
refreshInfo()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -208,15 +227,15 @@ const totalKeys = computed(() => {
|
||||||
return sum(toArray(nums))
|
return sum(toArray(nums))
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabVal = ref('info')
|
const tabVal = ref('activity')
|
||||||
const envFilter = reactive({
|
const infoFilter = reactive({
|
||||||
keyword: '',
|
keyword: '',
|
||||||
group: 'CPU',
|
group: 'CPU',
|
||||||
})
|
})
|
||||||
|
|
||||||
const env = computed(() => {
|
const info = computed(() => {
|
||||||
if (!isEmpty(envFilter.group)) {
|
if (!isEmpty(infoFilter.group)) {
|
||||||
const val = serverInfo.value[envFilter.group]
|
const val = serverInfo.value[infoFilter.group]
|
||||||
if (!isEmpty(val)) {
|
if (!isEmpty(val)) {
|
||||||
return map(val, (v, k) => ({
|
return map(val, (v, k) => ({
|
||||||
key: k,
|
key: k,
|
||||||
|
@ -235,10 +254,10 @@ const env = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const onFilterGroup = (group) => {
|
const onFilterGroup = (group) => {
|
||||||
if (group === envFilter.group) {
|
if (group === infoFilter.group) {
|
||||||
envFilter.group = ''
|
infoFilter.group = ''
|
||||||
} else {
|
} else {
|
||||||
envFilter.group = group
|
infoFilter.group = group
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +364,7 @@ const chartOption = {
|
||||||
scales: {
|
scales: {
|
||||||
y: {
|
y: {
|
||||||
beginAtZero: true,
|
beginAtZero: true,
|
||||||
|
stepSize: 1024,
|
||||||
suggestedMin: 0,
|
suggestedMin: 0,
|
||||||
ticks: {
|
ticks: {
|
||||||
precision: 0,
|
precision: 0,
|
||||||
|
@ -365,7 +385,7 @@ const byteChartOption = {
|
||||||
precision: 0,
|
precision: 0,
|
||||||
// format display y axios tag
|
// format display y axios tag
|
||||||
callback: function (value, index, values) {
|
callback: function (value, index, values) {
|
||||||
return formatBytes(value, 0)
|
return formatBytes(value, 1)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -429,7 +449,6 @@ const byteChartOption = {
|
||||||
@toggle="onToggleRefresh" />
|
@toggle="onToggleRefresh" />
|
||||||
</n-popover>
|
</n-popover>
|
||||||
</template>
|
</template>
|
||||||
<n-spin :show="pageState.loading">
|
|
||||||
<n-grid style="min-width: 500px" x-gap="5">
|
<n-grid style="min-width: 500px" x-gap="5">
|
||||||
<n-gi :span="6">
|
<n-gi :span="6">
|
||||||
<n-statistic :label="$t('status.uptime')" :value="uptime.value">
|
<n-statistic :label="$t('status.uptime')" :value="uptime.value">
|
||||||
|
@ -454,7 +473,6 @@ const byteChartOption = {
|
||||||
</n-statistic>
|
</n-statistic>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
</n-grid>
|
</n-grid>
|
||||||
</n-spin>
|
|
||||||
</n-card>
|
</n-card>
|
||||||
<n-card class="flex-item-expand" content-style="padding: 0; height: 100%;" embedded style="overflow: hidden">
|
<n-card class="flex-item-expand" content-style="padding: 0; height: 100%;" embedded style="overflow: hidden">
|
||||||
<n-tabs
|
<n-tabs
|
||||||
|
@ -466,7 +484,7 @@ const byteChartOption = {
|
||||||
type="line">
|
type="line">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<div v-if="tabVal === 'info'" style="padding-right: 10px">
|
<div v-if="tabVal === 'info'" style="padding-right: 10px">
|
||||||
<n-input v-model:value="envFilter.keyword" clearable placeholder="">
|
<n-input v-model:value="infoFilter.keyword" clearable placeholder="">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<icon-button :icon="Filter" size="18" />
|
<icon-button :icon="Filter" size="18" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -474,46 +492,6 @@ const byteChartOption = {
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- environment tab pane -->
|
|
||||||
<n-tab-pane :tab="$t('status.env_info')" name="info">
|
|
||||||
<n-space :wrap="false" :wrap-item="false" class="flex-item-expand">
|
|
||||||
<n-space align="end" item-style="padding: 0 5px;" vertical>
|
|
||||||
<n-button
|
|
||||||
v-for="(v, k) in serverInfo"
|
|
||||||
:key="k"
|
|
||||||
:disabled="isEmpty(v)"
|
|
||||||
:focusable="false"
|
|
||||||
:type="envFilter.group === k ? 'primary' : 'default'"
|
|
||||||
secondary
|
|
||||||
size="small"
|
|
||||||
@click="onFilterGroup(k)">
|
|
||||||
<span style="min-width: 80px">{{ k }}</span>
|
|
||||||
</n-button>
|
|
||||||
</n-space>
|
|
||||||
<n-data-table
|
|
||||||
:columns="[
|
|
||||||
{
|
|
||||||
title: $t('common.key'),
|
|
||||||
key: 'key',
|
|
||||||
defaultSortOrder: 'ascend',
|
|
||||||
minWidth: 80,
|
|
||||||
titleAlign: 'center',
|
|
||||||
filterOptionValue: envFilter.keyword,
|
|
||||||
filter(value, row) {
|
|
||||||
return !!~row.key.indexOf(value.toString())
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ title: $t('common.value'), titleAlign: 'center', key: 'value' },
|
|
||||||
]"
|
|
||||||
:data="env"
|
|
||||||
:loading="pageState.loading"
|
|
||||||
:single-line="false"
|
|
||||||
class="flex-item-expand"
|
|
||||||
flex-height
|
|
||||||
striped />
|
|
||||||
</n-space>
|
|
||||||
</n-tab-pane>
|
|
||||||
|
|
||||||
<!-- activity tab pane -->
|
<!-- activity tab pane -->
|
||||||
<n-tab-pane
|
<n-tab-pane
|
||||||
:tab="$t('status.activity_status')"
|
:tab="$t('status.activity_status')"
|
||||||
|
@ -535,6 +513,46 @@ const byteChartOption = {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
|
|
||||||
|
<!-- info tab pane -->
|
||||||
|
<n-tab-pane :tab="$t('status.server_info')" name="info">
|
||||||
|
<n-space :wrap="false" :wrap-item="false" class="flex-item-expand">
|
||||||
|
<n-space align="end" item-style="padding: 0 5px;" vertical>
|
||||||
|
<n-button
|
||||||
|
v-for="(v, k) in serverInfo"
|
||||||
|
:key="k"
|
||||||
|
:disabled="isEmpty(v)"
|
||||||
|
:focusable="false"
|
||||||
|
:type="infoFilter.group === k ? 'primary' : 'default'"
|
||||||
|
secondary
|
||||||
|
size="small"
|
||||||
|
@click="onFilterGroup(k)">
|
||||||
|
<span style="min-width: 80px">{{ k }}</span>
|
||||||
|
</n-button>
|
||||||
|
</n-space>
|
||||||
|
<n-data-table
|
||||||
|
:columns="[
|
||||||
|
{
|
||||||
|
title: $t('common.key'),
|
||||||
|
key: 'key',
|
||||||
|
defaultSortOrder: 'ascend',
|
||||||
|
minWidth: 80,
|
||||||
|
titleAlign: 'center',
|
||||||
|
filterOptionValue: infoFilter.keyword,
|
||||||
|
filter(value, row) {
|
||||||
|
return !!~row.key.indexOf(value.toString())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ title: $t('common.value'), titleAlign: 'center', key: 'value' },
|
||||||
|
]"
|
||||||
|
:data="info"
|
||||||
|
:loading="pageState.loading"
|
||||||
|
:single-line="false"
|
||||||
|
class="flex-item-expand"
|
||||||
|
flex-height
|
||||||
|
striped />
|
||||||
|
</n-space>
|
||||||
|
</n-tab-pane>
|
||||||
</n-tabs>
|
</n-tabs>
|
||||||
</n-card>
|
</n-card>
|
||||||
</n-space>
|
</n-space>
|
||||||
|
|
|
@ -359,8 +359,7 @@
|
||||||
"connected_clients": "Clients",
|
"connected_clients": "Clients",
|
||||||
"total_keys": "Keys",
|
"total_keys": "Keys",
|
||||||
"memory_used": "Memory",
|
"memory_used": "Memory",
|
||||||
"all_info": "Information",
|
"server_info": "Server Info",
|
||||||
"env_info": "Environment",
|
|
||||||
"activity_status": "Activity",
|
"activity_status": "Activity",
|
||||||
"act_cmd": "Commands Per Second",
|
"act_cmd": "Commands Per Second",
|
||||||
"act_network_input": "Network Input",
|
"act_network_input": "Network Input",
|
||||||
|
|
|
@ -359,8 +359,7 @@
|
||||||
"connected_clients": "已连客户端",
|
"connected_clients": "已连客户端",
|
||||||
"total_keys": "键总数",
|
"total_keys": "键总数",
|
||||||
"memory_used": "内存使用",
|
"memory_used": "内存使用",
|
||||||
"all_info": "全部信息",
|
"server_info": "状态信息",
|
||||||
"env_info": "运行环境",
|
|
||||||
"activity_status": "活动状态",
|
"activity_status": "活动状态",
|
||||||
"act_cmd": "命令执行数/秒",
|
"act_cmd": "命令执行数/秒",
|
||||||
"act_network_input": "网络输入",
|
"act_network_input": "网络输入",
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
RenameGroup,
|
RenameGroup,
|
||||||
SaveConnection,
|
SaveConnection,
|
||||||
SaveLastDB,
|
SaveLastDB,
|
||||||
|
SaveRefreshInterval,
|
||||||
SaveSortedConnection,
|
SaveSortedConnection,
|
||||||
} from 'wailsjs/go/services/connectionService.js'
|
} from 'wailsjs/go/services/connectionService.js'
|
||||||
import { ConnectionType } from '@/consts/connection_type.js'
|
import { ConnectionType } from '@/consts/connection_type.js'
|
||||||
|
@ -31,6 +32,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @property {string} defaultFilter
|
* @property {string} defaultFilter
|
||||||
* @property {string} keySeparator
|
* @property {string} keySeparator
|
||||||
* @property {string} markColor
|
* @property {string} markColor
|
||||||
|
* @property {number} refreshInterval
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +65,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
const conns = []
|
const conns = []
|
||||||
const groups = []
|
const groups = []
|
||||||
const profiles = {}
|
const profiles = {}
|
||||||
const { data = [{ groupName: '', connections: [] }] } = await ListConnection()
|
const { data = [{ groupName: '', connections: [], refreshInterval: 5 }] } = await ListConnection()
|
||||||
for (const conn of data) {
|
for (const conn of data) {
|
||||||
if (conn.type !== 'group') {
|
if (conn.type !== 'group') {
|
||||||
// top level
|
// top level
|
||||||
|
@ -79,6 +81,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
defaultFilter: conn.defaultFilter,
|
defaultFilter: conn.defaultFilter,
|
||||||
keySeparator: conn.keySeparator,
|
keySeparator: conn.keySeparator,
|
||||||
markColor: conn.markColor,
|
markColor: conn.markColor,
|
||||||
|
refreshInterval: conn.refreshInterval,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// custom group
|
// custom group
|
||||||
|
@ -99,6 +102,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
defaultFilter: item.defaultFilter,
|
defaultFilter: item.defaultFilter,
|
||||||
keySeparator: item.keySeparator,
|
keySeparator: item.keySeparator,
|
||||||
markColor: item.markColor,
|
markColor: item.markColor,
|
||||||
|
refreshInterval: conn.refreshInterval,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conns.push({
|
conns.push({
|
||||||
|
@ -369,6 +373,32 @@ const useConnectionStore = defineStore('connections', {
|
||||||
const { keySeparator = ':' } = this.serverProfile[name] || {}
|
const { keySeparator = ':' } = this.serverProfile[name] || {}
|
||||||
return keySeparator
|
return keySeparator
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get default status refresh interval by server name
|
||||||
|
* @param {string} name
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
getRefreshInterval(name) {
|
||||||
|
const { refreshInterval = 5 } = this.serverProfile[name] || {}
|
||||||
|
return refreshInterval
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set and save default refresh interval
|
||||||
|
* @param {string} name
|
||||||
|
* @param {number} interval
|
||||||
|
* @return {Promise<{success: boolean}|{msg: undefined, success: boolean}>}
|
||||||
|
*/
|
||||||
|
async saveRefreshInterval(name, interval) {
|
||||||
|
const profile = this.serverProfile[name] || {}
|
||||||
|
profile.refreshInterval = interval
|
||||||
|
const { success, msg } = await SaveRefreshInterval(name, interval)
|
||||||
|
if (!success) {
|
||||||
|
return { success: false, msg }
|
||||||
|
}
|
||||||
|
return { success: true }
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -277,10 +277,6 @@ const usePreferencesStore = defineStore('preferences', {
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
|
|
||||||
setAsideWidth(width) {
|
|
||||||
this.behavior.asideWidth = Math.max(width, 300)
|
|
||||||
},
|
|
||||||
|
|
||||||
async checkForUpdate(manual = false) {
|
async checkForUpdate(manual = false) {
|
||||||
let msgRef = null
|
let msgRef = null
|
||||||
if (manual) {
|
if (manual) {
|
||||||
|
|
|
@ -71,6 +71,9 @@ export const themeOverrides = {
|
||||||
optionTextColorHover: '#FFF',
|
optionTextColorHover: '#FFF',
|
||||||
optionHeightMedium: '28px',
|
optionHeightMedium: '28px',
|
||||||
},
|
},
|
||||||
|
Divider: {
|
||||||
|
color: '#AAAAAB',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue