Skip to content

Commit

Permalink
ui: Improve settings description for Statement (#920)
Browse files Browse the repository at this point in the history
  • Loading branch information
breezewish authored May 12, 2021
1 parent 2c9d3ab commit 149387b
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 166 deletions.
10 changes: 5 additions & 5 deletions pkg/apiserver/statement/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ type testConfig struct {
}

func (t *testConfigSuite) Test_buildConfigQuerySQL_struct_success(c *C) {
testConfigStmt := "SELECT @@GLOBAL.tidb_enable_stmt_summary as tidb_enable_stmt_summary,@@GLOBAL.tidb_stmt_summary_refresh_interval as tidb_stmt_summary_refresh_interval"
testConfigStmt := "SELECT @@GLOBAL.tidb_enable_stmt_summary AS tidb_enable_stmt_summary, @@GLOBAL.tidb_stmt_summary_refresh_interval AS tidb_stmt_summary_refresh_interval"
c.Assert(buildConfigQuerySQL(testConfig{}), Equals, testConfigStmt)
}

func (t *testConfigSuite) Test_buildConfigQuerySQL_ptr_success(c *C) {
testConfigStmt := "SELECT @@GLOBAL.tidb_enable_stmt_summary as tidb_enable_stmt_summary,@@GLOBAL.tidb_stmt_summary_refresh_interval as tidb_stmt_summary_refresh_interval"
testConfigStmt := "SELECT @@GLOBAL.tidb_enable_stmt_summary AS tidb_enable_stmt_summary, @@GLOBAL.tidb_stmt_summary_refresh_interval AS tidb_stmt_summary_refresh_interval"
c.Assert(buildConfigQuerySQL(&testConfig{}), Equals, testConfigStmt)
}

Expand All @@ -49,17 +49,17 @@ type testConfig2 struct {
}

func (t *testConfigSuite) Test_buildConfigQuerySQL_without_gorm_tag(c *C) {
testConfigStmt := "SELECT @@GLOBAL.tidb_enable_stmt_summary as tidb_enable_stmt_summary"
testConfigStmt := "SELECT @@GLOBAL.tidb_enable_stmt_summary AS tidb_enable_stmt_summary"
c.Assert(buildConfigQuerySQL(&testConfig2{}), Equals, testConfigStmt)
}

func (t *testConfigSuite) Test_buildConfigUpdateSQL_struct_success(c *C) {
testConfigStmt := "SET @@GLOBAL.tidb_enable_stmt_summary = true,@@GLOBAL.tidb_stmt_summary_refresh_interval = 1800"
testConfigStmt := "SET @@GLOBAL.tidb_enable_stmt_summary = true, @@GLOBAL.tidb_stmt_summary_refresh_interval = 1800"
c.Assert(buildConfigUpdateSQL(testConfig{Enable: true, RefreshInterval: 1800}), Equals, testConfigStmt)
}

func (t *testConfigSuite) Test_buildConfigUpdateSQL_ptr_success(c *C) {
testConfigStmt := "SET @@GLOBAL.tidb_enable_stmt_summary = true,@@GLOBAL.tidb_stmt_summary_refresh_interval = 1800"
testConfigStmt := "SET @@GLOBAL.tidb_enable_stmt_summary = true, @@GLOBAL.tidb_stmt_summary_refresh_interval = 1800"
c.Assert(buildConfigUpdateSQL(&testConfig{Enable: true, RefreshInterval: 1800}), Equals, testConfigStmt)
}

Expand Down
1 change: 1 addition & 0 deletions pkg/apiserver/statement/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ type EditableConfig struct {
RefreshInterval int `json:"refresh_interval" gorm:"column:tidb_stmt_summary_refresh_interval"`
HistorySize int `json:"history_size" gorm:"column:tidb_stmt_summary_history_size"`
MaxSize int `json:"max_size" gorm:"column:tidb_stmt_summary_max_stmt_count"`
InternalQuery bool `json:"internal_query" gorm:"column:tidb_stmt_summary_internal_query"`
}

// @Summary Get statement configurations
Expand Down
2 changes: 1 addition & 1 deletion ui/lib/apps/KeyViz/components/KeyVizSettingForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function KeyVizSettingForm({ onClose, onConfigUpdated }: Props) {
<Form.Item
name="auto_collection_disabled"
label={t('keyviz.settings.switch')}
tooltip={t('keyviz.settings.switch_tooltip')}
extra={t('keyviz.settings.switch_tooltip')}
{...negateSwitchProps}
>
<Switch />
Expand Down
2 changes: 1 addition & 1 deletion ui/lib/apps/KeyViz/translations/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ keyviz:
open_setting: Open Settings
close_keyviz: Disable Key Visualizer Feature
close_keyviz_warning: Are you sure want to disable this feature? Current visual reports will be cleared.
switch: Enable
switch: Enable Feature
switch_tooltip: Whether Key Visualizer feature is enabled. When enabled, there will be small overhead.
policy: Policy
policy_db: TiDB
Expand Down
4 changes: 2 additions & 2 deletions ui/lib/apps/KeyViz/translations/zh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ keyviz:
open_setting: 打开设置
close_keyviz: 关闭流量可视化功能
close_keyviz_warning: 确认要关闭该功能吗?关闭后现有历史记录也将被清空!
switch: 总开关
switch_tooltip: 是否开启流量可视化,流量可视化启用时将会增加少量资源开销
switch: 启用功能
switch_tooltip: 是否启用流量可视化功能,关闭后将不能使用流量可视化功能,但能减少一些 PD 的 CPU 资源开销。
policy: 模式
policy_db: TiDB
policy_kv: 原生 KV
Expand Down
275 changes: 128 additions & 147 deletions ui/lib/apps/Statement/pages/List/StatementSettingForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useEffect, useMemo, useState } from 'react'
import React, { useState, useCallback } from 'react'
import {
Form,
InputNumber,
Skeleton,
Switch,
Input,
Expand All @@ -21,185 +20,167 @@ interface Props {
onConfigUpdated: () => any
}

type InternalStatementConfig = StatementEditableConfig & {
max_refresh_interval: number
max_history_size: number
}

const convertArrToObj = (arr: number[]) =>
arr.reduce((acc, cur) => {
acc[cur] = cur
return acc
}, {})

const REFRESH_INTERVAL_MARKS = convertArrToObj([1, 5, 15, 30, 60])
const HISTORY_SIZE_MARKS = convertArrToObj([1, 64, 128, 192, 255])

function StatementSettingForm({ onClose, onConfigUpdated }: Props) {
const [submitting, setSubmitting] = useState(false)
const { t } = useTranslation()

const [curRefreshInterval, setCurRefreshInterval] = useState(0)
const [curHistorySize, setCurHistorySize] = useState(0)
const dataRetainDuration = useMemo(() => {
const totalMins = curRefreshInterval * curHistorySize
const day = Math.floor(totalMins / (24 * 60))
const hour = Math.floor((totalMins - day * 24 * 60) / 60)
const min = totalMins - day * 24 * 60 - hour * 60
return `${day} day ${hour} hour ${min} min`
}, [curRefreshInterval, curHistorySize])

const {
data: oriConfig,
data: initialConfig,
isLoading: loading,
error,
} = useClientRequest((reqConfig) =>
client.getInstance().statementsConfigGet(reqConfig)
)

const config = useMemo(() => {
if (oriConfig) {
const refresh_interval = Math.ceil(oriConfig.refresh_interval! / 60)
const max_refresh_interval = Math.max(refresh_interval, 60)
const max_history_size = Math.max(oriConfig.history_size!, 255)

return {
...oriConfig,
refresh_interval,
max_refresh_interval,
max_history_size,
} as InternalStatementConfig
}
return null
}, [oriConfig])

useEffect(() => {
if (config) {
setCurRefreshInterval(config.refresh_interval!)
setCurHistorySize(config.history_size!)
}
}, [config])
const handleSubmit = useCallback(
(values) => {
async function updateConfig(values) {
const newConfig: StatementEditableConfig = {
enable: values.enable,
max_size: values.max_size,
refresh_interval: values.refresh_interval * 60,
history_size: values.history_size,
internal_query: values.internal_query,
}
try {
setSubmitting(true)
await client.getInstance().statementsConfigPost(newConfig)
onClose()
onConfigUpdated()
} finally {
setSubmitting(false)
}
}

async function updateConfig(values) {
const newConfig: StatementEditableConfig = {
enable: values.enable,
max_size: values.max_size,
refresh_interval: values.refresh_interval * 60,
history_size: values.history_size,
}
try {
setSubmitting(true)
await client.getInstance().statementsConfigPost(newConfig)
onClose()
onConfigUpdated()
} finally {
setSubmitting(false)
}
}

function handleSubmit(values) {
if (oriConfig?.enable && !values.enable) {
// warning
Modal.confirm({
title: t('statement.settings.close_statement'),
icon: <ExclamationCircleOutlined />,
content: t('statement.settings.close_statement_warning'),
okText: t('statement.settings.actions.close'),
cancelText: t('statement.settings.actions.cancel'),
okButtonProps: { danger: true },
onOk: () => updateConfig(values),
})
} else {
updateConfig(values)
}
}
if (!values.enable) {
// warning
Modal.confirm({
title: t('statement.settings.close_statement'),
icon: <ExclamationCircleOutlined />,
content: t('statement.settings.close_statement_warning'),
okText: t('statement.settings.actions.close'),
cancelText: t('statement.settings.actions.cancel'),
okButtonProps: { danger: true },
onOk: () => updateConfig(values),
})
} else {
updateConfig(values)
}
},
[t, onClose, onConfigUpdated]
)

return (
<>
{error && <ErrorBar errors={[error]} />}
{loading && <Skeleton active={true} paragraph={{ rows: 5 }} />}
{!loading && config && (
<Form layout="vertical" initialValues={config} onFinish={handleSubmit}>
{!loading && initialConfig && (
<Form
layout="vertical"
initialValues={{
...initialConfig,
refresh_interval: Math.floor(
(initialConfig.refresh_interval ?? 0) / 60
),
}}
onFinish={handleSubmit}
>
<Form.Item
name="enable"
valuePropName="checked"
label={t('statement.settings.switch')}
extra={t('statement.settings.switch_tooltip')}
>
<Switch />
<Form.Item noStyle name="enable" valuePropName="checked">
<Switch />
</Form.Item>
</Form.Item>
<Form.Item
noStyle
shouldUpdate={(prev, cur) => prev.enable !== cur.enable}
>
{({ getFieldValue }) => {
return (
getFieldValue('enable') && (
<Form.Item noStyle>
<Form.Item
name="max_size"
label={t('statement.settings.max_size')}
>
<InputNumber min={1} />
</Form.Item>
<Form.Item label={t('statement.settings.refresh_interval')}>
<Input.Group>
<Form.Item noStyle name="refresh_interval">
<InputNumber
min={1}
max={config.max_refresh_interval}
formatter={(value) => `${value} min`}
parser={(value) =>
value?.replace(/[^\d]/g, '') || ''
}
onChange={(val) =>
setCurRefreshInterval(val as number)
}
/>
</Form.Item>
<Form.Item noStyle name="refresh_interval">
<Slider
min={1}
max={config.max_refresh_interval}
marks={{
...REFRESH_INTERVAL_MARKS,
[config.max_refresh_interval]: `${config.max_refresh_interval}`,
}}
onChange={(val) => setCurRefreshInterval(val)}
/>
</Form.Item>
</Input.Group>
</Form.Item>
<Form.Item label={t('statement.settings.history_size')}>
<Input.Group>
<Form.Item noStyle name="history_size">
<InputNumber
min={1}
max={config.max_history_size}
onChange={(val) => setCurHistorySize(val as number)}
/>
</Form.Item>
<Form.Item noStyle name="history_size">
<Slider
min={1}
max={config.max_history_size}
marks={{
...HISTORY_SIZE_MARKS,
[config.max_history_size]: `${config.max_history_size}`,
}}
onChange={(val) => setCurHistorySize(val)}
/>
</Form.Item>
</Input.Group>
</Form.Item>
<Form.Item label={t('statement.settings.keep_duration')}>
<span style={{ color: '#555' }}>
{dataRetainDuration}
</span>
</Form.Item>
{({ getFieldValue }) =>
getFieldValue('enable') && (
<>
<Form.Item
label={t('statement.settings.max_size')}
extra={t('statement.settings.max_size_tooltip')}
>
<Input.Group>
<Form.Item noStyle name="max_size">
<Slider
min={0}
max={5000}
step={100}
marks={convertArrToObj([200, 1000, 2000, 5000])}
/>
</Form.Item>
</Input.Group>
</Form.Item>
<Form.Item
label={t('statement.settings.refresh_interval')}
extra={t('statement.settings.refresh_interval_tooltip')}
>
<Input.Group>
<Form.Item noStyle name="refresh_interval">
<Slider
min={1}
max={60}
step={null}
marks={convertArrToObj([1, 5, 15, 30, 60])}
/>
</Form.Item>
</Input.Group>
</Form.Item>
<Form.Item
label={t('statement.settings.history_size')}
extra={t('statement.settings.history_size_tooltip')}
>
<Input.Group>
<Form.Item noStyle name="history_size">
<Slider
min={1}
max={255}
marks={convertArrToObj([1, 255])}
/>
</Form.Item>
</Input.Group>
</Form.Item>
<Form.Item
label={t('statement.settings.keep_duration')}
extra={t('statement.settings.keep_duration_tooltip')}
shouldUpdate={(prev, cur) =>
prev.refresh_interval !== cur.refresh_interval ||
prev.history_size !== cur.history_size
}
>
{({ getFieldValue }) => {
const refreshInterval =
getFieldValue('refresh_interval') || 0
const historySize = getFieldValue('history_size') || 0
const totalMins = refreshInterval * historySize
const day = Math.floor(totalMins / (24 * 60))
const hour = Math.floor((totalMins - day * 24 * 60) / 60)
const min = totalMins - day * 24 * 60 - hour * 60
return `${day} day ${hour} hour ${min} min`
}}
</Form.Item>
<Form.Item
label={t('statement.settings.internal_query')}
extra={t('statement.settings.internal_query_tooltip')}
name="internal_query"
valuePropName="checked"
>
<Switch />
</Form.Item>
)
</>
)
}}
}
</Form.Item>
<Form.Item>
<Space>
Expand Down
Loading

0 comments on commit 149387b

Please sign in to comment.