diff --git a/web/src/common/src/DatePicker/TimeSetting.jsx b/web/src/common/src/DatePicker/TimeSetting.jsx index 8afc5e34..630092b0 100644 --- a/web/src/common/src/DatePicker/TimeSetting.jsx +++ b/web/src/common/src/DatePicker/TimeSetting.jsx @@ -20,7 +20,7 @@ const timeOuts = [ ]; const TimeSetting = props => { - const { currentLocales, timeFields = [], showTimeField, showTimeInterval, showTimeout, onTimeSettingChange, onCancel } = props; + const { currentLocales, timeFields = [], showTimeField, showTimeInterval, timeIntervalDisabled = false, showTimeout, onTimeSettingChange, onCancel } = props; const [isAuto, setIsAuto] = useState(!props.timeInterval) const [timeField, setTimeField] = useState(props.timeField); @@ -78,7 +78,7 @@ const TimeSetting = props => {
{currentLocales[`datepicker.time_setting.time_interval`]}
- { + { setIsAuto(checked) if (checked) { timeIntervalCache.current = timeInterval; @@ -89,6 +89,13 @@ const TimeSetting = props => { }}/> {currentLocales[`datepicker.time_setting.time_interval.auto`]}
+ { + timeIntervalDisabled && isAuto && ( +
+ {currentLocales[`datepicker.time_setting.time_interval.help`]} +
+ ) + }
{ !isAuto && timeIntervalObject && ( diff --git a/web/src/common/src/DatePicker/TimeSetting.less b/web/src/common/src/DatePicker/TimeSetting.less index 752d81da..23d3072f 100644 --- a/web/src/common/src/DatePicker/TimeSetting.less +++ b/web/src/common/src/DatePicker/TimeSetting.less @@ -37,6 +37,12 @@ justify-content: space-between; gap: 8px; } + + .help { + color: rgba(0, 0, 0, 0.45); + font-size: 12px; + word-break: break-all; + } } .apply { diff --git a/web/src/common/src/DatePicker/index.jsx b/web/src/common/src/DatePicker/index.jsx index 439123fa..2e57d362 100644 --- a/web/src/common/src/DatePicker/index.jsx +++ b/web/src/common/src/DatePicker/index.jsx @@ -87,6 +87,7 @@ const DatePicker = (props) => { timeFields = [], showTimeInterval = false, timeInterval, + timeIntervalDisabled = false, showTimeout = false, timeout, autoFitLoading = false, diff --git a/web/src/common/src/DatePicker/index.md b/web/src/common/src/DatePicker/index.md index 38092a06..2868cb8d 100644 --- a/web/src/common/src/DatePicker/index.md +++ b/web/src/common/src/DatePicker/index.md @@ -23,6 +23,7 @@ | timeFields | 时间字段列表 | string[] | [] | 1.0.0 | | showTimeInterval | 是否显示时间间隔 | boolean | false | 1.0.0 | | timeInterval | 时间间隔 | string | - | 1.0.0 | +| timeIntervalDisabled | 禁用时间间隔 | boolean | false | 1.0.0 | | showTimeout | 是否显示超时时间 | boolean | false | 1.0.0 | | timeout | 超时时间 | string | 10s | 1.0.0 | | onTimeSettingChange | 时间配置变更的回调 | ({timeField: string, timeInterval: string, timeout: string}) => void | - | 1.0.0 | diff --git a/web/src/common/src/DatePicker/locales/en-US.js b/web/src/common/src/DatePicker/locales/en-US.js index 817f52a5..24a57dfc 100644 --- a/web/src/common/src/DatePicker/locales/en-US.js +++ b/web/src/common/src/DatePicker/locales/en-US.js @@ -21,6 +21,7 @@ export default { "datepicker.time_setting.time_field": "Time field", "datepicker.time_setting.time_interval": "Time interval", "datepicker.time_setting.time_interval.auto": "Auto", + "datepicker.time_setting.time_interval.help": "Because of the long time range, time interval can only be calculated automatically.", "datepicker.time_setting.time_interval.ms": "Millisecond", "datepicker.time_setting.time_interval.s": "Second", "datepicker.time_setting.time_interval.m": "Minute", diff --git a/web/src/common/src/DatePicker/locales/zh-CN.js b/web/src/common/src/DatePicker/locales/zh-CN.js index 2eca598a..accc0a49 100644 --- a/web/src/common/src/DatePicker/locales/zh-CN.js +++ b/web/src/common/src/DatePicker/locales/zh-CN.js @@ -21,6 +21,7 @@ export default { "datepicker.time_setting.time_field": "时间字段", "datepicker.time_setting.time_interval": "时间间隔", "datepicker.time_setting.time_interval.auto": "自动", + "datepicker.time_setting.time_interval.help": "由于时间跨度较长,仅支持自动计算时间间隔。", "datepicker.time_setting.time_interval.ms": "毫秒", "datepicker.time_setting.time_interval.s": "秒", "datepicker.time_setting.time_interval.m": "分", diff --git a/web/src/components/Overview/Detail/Metrics/index.js b/web/src/components/Overview/Detail/Metrics/index.js index 7d40ed49..8e886581 100644 --- a/web/src/components/Overview/Detail/Metrics/index.js +++ b/web/src/components/Overview/Detail/Metrics/index.js @@ -15,7 +15,7 @@ import { formatMessage } from "umi/locale"; import DatePicker from "@/common/src/DatePicker"; import { getLocale } from "umi/locale"; import { getTimezone } from "@/utils/utils"; -import { getAllTimeSettingsCache, TIME_SETTINGS_KEY } from "../../Monitor"; +import { getAllTimeSettingsCache, initState, TIME_SETTINGS_KEY } from "../../Monitor"; const { TabPane } = Tabs; @@ -33,37 +33,27 @@ export default (props) => { const allTimeSettingsCache = getAllTimeSettingsCache() || {} const [spinning, setSpinning] = useState(false); - const [state, setState] = useState({ + const [state, setState] = useState(initState({ timeRange: { min: "now-15m", max: "now", - timeFormatter: formatter.dates(1), }, timeInterval: allTimeSettingsCache.timeInterval, timeout: allTimeSettingsCache.timeout || '10s', - }); + })); const [refresh, setRefresh] = useState({ isRefreshPaused: allTimeSettingsCache.isRefreshPaused || false, refreshInterval: allTimeSettingsCache.refreshInterval || 30000 }); const [timeZone, setTimeZone] = useState(() => allTimeSettingsCache.timeZone || getTimezone()); const handleTimeChange = ({ start, end, timeInterval, timeout }) => { - const bounds = calculateBounds({ - from: start, - to: end, - }); - const day = moment - .duration(bounds.max.valueOf() - bounds.min.valueOf()) - .asDays(); - const intDay = parseInt(day) + 1; - setState({ + setState(initState({ timeRange: { min: start, max: end, - timeFormatter: formatter.dates(intDay), }, timeInterval: timeInterval || state.timeInterval, timeout: timeout || state.timeout - }); + })); setSpinning(true); }; @@ -115,6 +105,7 @@ export default (props) => { showTimeout={true} timeout={state.timeout} timeInterval={state.timeInterval} + timeIntervalDisabled={state.timeIntervalDisabled} onTimeSettingChange={(timeSetting) => { onTimeSettingsChange({ timeInterval: timeSetting.timeInterval, diff --git a/web/src/components/Overview/Monitor/index.jsx b/web/src/components/Overview/Monitor/index.jsx index 07eec0fc..6aa58222 100644 --- a/web/src/components/Overview/Monitor/index.jsx +++ b/web/src/components/Overview/Monitor/index.jsx @@ -54,6 +54,36 @@ export const getAllTimeSettingsCache = () => { } } +const getDuration = (from, to) => { + if (!from || !to) return; + const bounds = calculateBounds({ + from, + to, + }); + return bounds.max.valueOf() - bounds.min.valueOf() +} + +export const initState = (state = {}) => { + const { timeRange, timeInterval, timeout } = state || {} + const from = timeRange?.min || "now-15m" + const to = timeRange?.max || "now" + const duration = getDuration(from, to); + const gtOneHour = moment.duration(duration).asHours() > 1 + const day = moment.duration(duration).asDays(); + const intDay = parseInt(day) + 1; + return { + ...state, + timeRange: { + min: from, + max: to, + timeFormatter: formatter.dates(intDay), + }, + timeInterval: gtOneHour ? undefined : timeInterval, + timeIntervalDisabled: gtOneHour, + timeout: timeout || '10s', + } +} + const Monitor = (props) => { const { selectedCluster, @@ -71,19 +101,16 @@ const Monitor = (props) => { const [spinning, setSpinning] = useState(false); - const [state, setState] = useState( - formatState({ - timeRange: { - min: param?.timeRange?.min || "now-15m", - max: param?.timeRange?.max || "now", - timeFormatter: formatter.dates(1), - }, - timeInterval: formatTimeInterval(param?.timeInterval) || allTimeSettingsCache.timeInterval, - timeout: formatTimeout(param?.timeout) || allTimeSettingsCache.timeout || '10s', - param: param, - refresh: true, - }) - ); + const [state, setState] = useState(formatState(initState({ + timeRange: { + min: param?.timeRange?.min || "now-15m", + max: param?.timeRange?.max || "now", + }, + timeInterval: formatTimeInterval(param?.timeInterval) || allTimeSettingsCache.timeInterval, + timeout: formatTimeout(param?.timeout) || allTimeSettingsCache.timeout || '10s', + param: param, + refresh: true, + }))); const [refresh, setRefresh] = useState({ isRefreshPaused: typeof allTimeSettingsCache.isRefreshPaused !== 'undefined' ? allTimeSettingsCache.isRefreshPaused : true, refreshInterval: allTimeSettingsCache.refreshInterval || 30000 }); const [timeZone, setTimeZone] = useState(() => allTimeSettingsCache.timeZone || getTimezone()); @@ -93,25 +120,16 @@ const Monitor = (props) => { }, [state.timeRange, state.timeInterval, state.timeout]); const handleTimeChange = useCallback(({ start, end, timeInterval, timeout, refresh }) => { - const bounds = calculateBounds({ - from: start, - to: end, - }); - const day = moment - .duration(bounds.max.valueOf() - bounds.min.valueOf()) - .asDays(); - const intDay = parseInt(day) + 1; - setState({ + setState(initState({ ...state, timeRange: { min: start, max: end, - timeFormatter: formatter.dates(intDay), }, timeInterval: timeInterval || state.timeInterval, timeout: timeout || state.timeout, refresh - }); + })); }, [state]) const onInfoChange = (info) => { @@ -163,6 +181,7 @@ const Monitor = (props) => { showTimeSetting={true} showTimeInterval={true} timeInterval={state.timeInterval} + timeIntervalDisabled={state.timeIntervalDisabled} showTimeout={true} timeout={state.timeout} onTimeSettingChange={(timeSetting) => { diff --git a/web/src/locales/en-US/error.js b/web/src/locales/en-US/error.js index edfb8f38..88a2cc96 100644 --- a/web/src/locales/en-US/error.js +++ b/web/src/locales/en-US/error.js @@ -1,5 +1,5 @@ export default { "error.split": ", ", "error.unknown": "unknown error, please try again later or contact the support team!", - "error.request_timeout_error": "request timeout, please try again later or contact the support team!", + "error.request_timeout_error": "request timeout, please try again later!", }; diff --git a/web/src/locales/zh-CN/error.js b/web/src/locales/zh-CN/error.js index 2eac32f1..0cc8cc81 100644 --- a/web/src/locales/zh-CN/error.js +++ b/web/src/locales/zh-CN/error.js @@ -1,5 +1,5 @@ export default { "error.split": ",", "error.unknown": "未知错误,请稍后重试或者联系支持团队!", - "error.request_timeout_error": "请求超时,请稍后重试或者联系支持团队!", + "error.request_timeout_error": "请求超时,请稍后重试!", } diff --git a/web/src/pages/Platform/Overview/components/MetricChart.jsx b/web/src/pages/Platform/Overview/components/MetricChart.jsx index 111c4674..ce656274 100644 --- a/web/src/pages/Platform/Overview/components/MetricChart.jsx +++ b/web/src/pages/Platform/Overview/components/MetricChart.jsx @@ -61,7 +61,6 @@ export default (props) => { const fetchData = async (queryParams, fetchUrl, metricKey, timeInterval, showLoading) => { if (!observerRef.current.isInView || !fetchUrl) return; - setError() if (firstFetchRef.current || showLoading) { setLoading(true) } @@ -79,11 +78,12 @@ export default (props) => { ignoreTimeout: true }, false, false) if (res?.error) { - const error = formatResponse(res.error); + const error = formatResponse(res); setError(error?.errorObject?.key ? formatMessage({ id: `${error?.errorObject?.key}` }) : res?.error?.reason) } else if (res && !res.error) { const { metrics = {} } = res || {}; const metric = metrics[metricKey] + setError() setMetric(formatMetric && metric ? formatMetric(metric) : metric); } if (firstFetchRef.current || showLoading) {