Skip to content

Commit 9008af2

Browse files
committed
refactor: support setting default cluster
1 parent 731a7ea commit 9008af2

19 files changed

Lines changed: 160 additions & 51 deletions

File tree

src/components/Graph/api.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const fetchHistory = (params?, signalKey?) => {
3939
});
4040
};
4141

42-
export const fetchHistoryBatch = (data, signalKey) => {
42+
export const fetchHistoryBatch = (data, signalKey, datasourceValue) => {
4343
const controller = new AbortController();
4444
const { signal } = controller;
4545
if (signalKey && signals[signalKey] && signals[signalKey].abort) {
@@ -50,6 +50,9 @@ export const fetchHistoryBatch = (data, signalKey) => {
5050
method: RequestMethod.Post,
5151
data,
5252
signal,
53+
headers: {
54+
'X-Cluster': datasourceValue,
55+
},
5356
}).finally(() => {
5457
delete signals[signalKey];
5558
});

src/pages/chart/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export default function Chart() {
147147
},
148148
},
149149
})}
150+
datasourceValue={curCluster}
150151
isPreview
151152
/>
152153
</div>

src/pages/dashboard/Detail/Detail.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export default function DetailV2({ isPreview = false }: { isPreview?: boolean })
6161
const { id } = useParams<URLParam>();
6262
const refreshRef = useRef<{ closeRefresh: Function }>();
6363
const { clusters } = useSelector<CommonRootState, CommonStoreState>((state) => state.common);
64-
const [curCluster, setCurCluster] = useState<string>(localCluster || clusters[0]);
6564
const [dashboard, setDashboard] = useState<Dashboard>({
6665
create_by: '',
6766
favorite: 0,
@@ -71,6 +70,7 @@ export default function DetailV2({ isPreview = false }: { isPreview?: boolean })
7170
update_at: 0,
7271
update_by: '',
7372
});
73+
const [curCluster, setCurCluster] = useState<string>();
7474
const [variableConfig, setVariableConfig] = useState<IVariable[]>();
7575
const [variableConfigWithOptions, setVariableConfigWithOptions] = useState<IVariable[]>();
7676
const [dashboardLinks, setDashboardLinks] = useState<ILink[]>();
@@ -94,6 +94,10 @@ export default function DetailV2({ isPreview = false }: { isPreview?: boolean })
9494
getDashboard(id).then((res) => {
9595
updateAtRef.current = res.update_at;
9696
setDashboard(res);
97+
if (!curCluster) {
98+
const dashboardConfigs: any = JSONParse(res.configs);
99+
setCurCluster(dashboardConfigs.datasourceValue || localCluster || clusters[0]);
100+
}
97101
if (res.configs) {
98102
const configs = JSONParse(res.configs);
99103
// TODO: configs 中可能没有 var 属性会导致 VariableConfig 报错
@@ -156,6 +160,8 @@ export default function DetailV2({ isPreview = false }: { isPreview?: boolean })
156160
}
157161
}, 2000);
158162

163+
if (!curCluster) return null;
164+
159165
return (
160166
<PageLayout
161167
customArea={

src/pages/dashboard/Editor/Form.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ function FormCpt(props, ref) {
7272
<div style={{ marginBottom: 10, height: 300 }}>
7373
<Form.Item shouldUpdate noStyle>
7474
{({ getFieldsValue }) => {
75-
return <Renderer dashboardId={id} time={range} step={step} values={getFieldsValue()} variableConfig={variableConfigWithOptions} isPreview />;
75+
return (
76+
<Renderer datasourceValue={cluster} dashboardId={id} time={range} step={step} values={getFieldsValue()} variableConfig={variableConfigWithOptions} isPreview />
77+
);
7678
}}
7779
</Form.Item>
7880
</div>

src/pages/dashboard/List/Form.tsx

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,19 @@
1414
* limitations under the License.
1515
*
1616
*/
17-
import React from 'react';
17+
import React, { useEffect } from 'react';
1818
import _ from 'lodash';
1919
import { Form, Modal, Input, Select, message } from 'antd';
2020
import ModalHOC, { ModalWrapProps } from '@/components/ModalHOC';
21-
import { updateDashboard, createDashboard } from '@/services/dashboardV2';
21+
import { updateDashboard, createDashboard, updateDashboardConfigs, getDashboard } from '@/services/dashboardV2';
22+
import { JSONParse } from '../utils';
2223

2324
interface IProps {
2425
mode: 'crate' | 'edit';
2526
initialValues?: any;
2627
busiId: number;
2728
refreshList: () => void;
29+
clusters: string[];
2830
}
2931

3032
const layout = {
@@ -41,33 +43,58 @@ const titleMap = {
4143
};
4244

4345
function FormCpt(props: IProps & ModalWrapProps) {
44-
const { mode, initialValues = {}, visible, busiId, refreshList, destroy } = props;
46+
const { mode, initialValues = {}, visible, busiId, refreshList, destroy, clusters } = props;
4547
const [form] = Form.useForm();
4648
const handleOk = async () => {
47-
const values = await form.validateFields();
49+
try {
50+
const values = await form.validateFields();
51+
let result;
4852

49-
if (mode === 'edit') {
50-
await updateDashboard(initialValues.id, {
51-
name: values.name,
52-
tags: _.join(values.tags, ' '),
53-
});
54-
message.success('编辑大盘成功');
55-
} else if (mode === 'crate') {
56-
await createDashboard(busiId, {
57-
name: values.name,
58-
tags: _.join(values.tags, ' '),
59-
configs: JSON.stringify({
60-
var: [],
61-
panels: [],
62-
version: '2.0.0',
63-
}),
53+
if (mode === 'edit') {
54+
result = await updateDashboard(initialValues.id, {
55+
name: values.name,
56+
tags: _.join(values.tags, ' '),
57+
});
58+
message.success('编辑大盘成功');
59+
} else if (mode === 'crate') {
60+
result = await createDashboard(busiId, {
61+
name: values.name,
62+
tags: _.join(values.tags, ' '),
63+
configs: JSON.stringify({
64+
var: [],
65+
panels: [],
66+
version: '2.0.0',
67+
}),
68+
});
69+
message.success('新建大盘成功');
70+
}
71+
if (result) {
72+
const configs = JSONParse(result.configs);
73+
await updateDashboardConfigs(result.id, {
74+
configs: JSON.stringify({
75+
...configs,
76+
datasourceValue: values.datasourceValue,
77+
}),
78+
});
79+
}
80+
refreshList();
81+
destroy();
82+
} catch (error) {
83+
message.error('操作失败');
84+
}
85+
};
86+
87+
useEffect(() => {
88+
if (initialValues.id) {
89+
getDashboard(initialValues.id).then((res) => {
90+
const configs = JSONParse(res.configs);
91+
form.setFieldsValue({
92+
datasourceValue: configs.datasourceValue,
93+
});
6494
});
65-
message.success('新建大盘成功');
6695
}
96+
}, [initialValues.id]);
6797

68-
refreshList();
69-
destroy();
70-
};
7198
return (
7299
<Modal
73100
title={titleMap[mode]}
@@ -109,6 +136,23 @@ function FormCpt(props: IProps & ModalWrapProps) {
109136
placeholder={'请输入分类标签(请用回车分割)'}
110137
/>
111138
</Form.Item>
139+
<Form.Item
140+
wrapperCol={{
141+
span: 24,
142+
}}
143+
label='默认集群'
144+
name='datasourceValue'
145+
>
146+
<Select>
147+
{_.map(clusters, (item) => {
148+
return (
149+
<Select.Option key={item} value={item}>
150+
{item}
151+
</Select.Option>
152+
);
153+
})}
154+
</Select>
155+
</Form.Item>
112156
<Form.Item name='id' hidden>
113157
<Input />
114158
</Form.Item>

src/pages/dashboard/List/Header.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
import React from 'react';
1818
import { Input, Button, Dropdown, Modal, message } from 'antd';
1919
import { SearchOutlined, DownOutlined } from '@ant-design/icons';
20+
import { useSelector } from 'react-redux';
2021
import { removeDashboards } from '@/services/dashboardV2';
22+
import { RootState as CommonRootState } from '@/store/common';
23+
import { CommonStoreState } from '@/store/commonInterface';
2124
import FormCpt from './Form';
2225
import Import from './Import';
2326

@@ -30,6 +33,7 @@ interface IProps {
3033
}
3134

3235
export default function Header(props: IProps) {
36+
const { clusters } = useSelector<CommonRootState, CommonStoreState>((state) => state.common);
3337
const { busiId, selectRowKeys, refreshList, searchVal, onSearchChange } = props;
3438

3539
return (
@@ -54,6 +58,7 @@ export default function Header(props: IProps) {
5458
mode: 'crate',
5559
busiId,
5660
refreshList,
61+
clusters,
5762
});
5863
}}
5964
ghost

src/pages/dashboard/List/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,23 @@ import { Table, Tag, Modal, Switch, message } from 'antd';
2323
import { FundViewOutlined } from '@ant-design/icons';
2424
import moment from 'moment';
2525
import _ from 'lodash';
26+
import { useSelector } from 'react-redux';
2627
import queryString from 'query-string';
2728
import { Dashboard as DashboardType } from '@/store/dashboardInterface';
2829
import { getDashboards, cloneDashboard, removeDashboards, getDashboard, updateDashboardPublic } from '@/services/dashboardV2';
2930
import PageLayout from '@/components/pageLayout';
3031
import LeftTree from '@/components/LeftTree';
3132
import BlankBusinessPlaceholder from '@/components/BlankBusinessPlaceholder';
33+
import { RootState as CommonRootState } from '@/store/common';
34+
import { CommonStoreState } from '@/store/commonInterface';
3235
import Header from './Header';
3336
import FormCpt from './Form';
3437
import Export from './Export';
3538
import { exportDataStringify } from './utils';
3639
import './style.less';
3740

3841
export default function index() {
42+
const { clusters } = useSelector<CommonRootState, CommonStoreState>((state) => state.common);
3943
const history = useHistory();
4044
const [busiId, setBusiId] = useState<number>();
4145
const [list, setList] = useState([]);
@@ -188,6 +192,7 @@ export default function index() {
188192
refreshList: () => {
189193
setRefreshKey(_.uniqueId('refreshKey_'));
190194
},
195+
clusters,
191196
});
192197
}}
193198
>

src/pages/dashboard/Panels/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ function index(props: IProps) {
150150
step={step}
151151
values={item as any}
152152
variableConfig={variableConfig}
153+
datasourceValue={curCluster}
153154
onCloneClick={() => {
154155
const newPanels = updatePanelsInsertNewPanel(panels, {
155156
...item,

src/pages/dashboard/Renderer/Renderer/Timeseries/index.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,26 @@ interface IProps {
4141
onClick?: (event: any, datetime: Date, value: number) => void;
4242
}
4343

44+
function getStartAndEndByTargets(targets: any[]) {
45+
let start = undefined as number | undefined;
46+
let end = undefined as number | undefined;
47+
_.forEach(targets, (target) => {
48+
if (target.time) {
49+
const { start: targetStart, end: targetEnd } = parseRange(target.time);
50+
if (!start || targetStart?.unix()! < start) {
51+
start = targetStart?.unix()!;
52+
}
53+
if (!end || targetEnd?.unix()! > end) {
54+
end = targetEnd?.unix()!;
55+
}
56+
}
57+
});
58+
return { start, end };
59+
}
60+
4461
export default function index(props: IProps) {
4562
const { time, values, series, inDashboard = true, chartHeight = '200px', tableHeight = '200px', themeMode = '', onClick } = props;
46-
const { custom, options = {} } = values;
63+
const { custom, options = {}, targets } = values;
4764
const { lineWidth = 1, gradientMode = 'none', scaleDistribution } = custom;
4865
const [seriesData, setSeriesData] = useState(series);
4966
const [activeLegend, setActiveLegend] = useState('');
@@ -122,8 +139,9 @@ export default function index(props: IProps) {
122139
let xAxisDamin = {};
123140
if (time) {
124141
const parsedRange = parseRange(time);
125-
const start = moment(parsedRange.start).unix();
126-
const end = moment(parsedRange.end).unix();
142+
const startAndEnd = getStartAndEndByTargets(targets);
143+
const start = startAndEnd.start || moment(parsedRange.start).unix();
144+
const end = startAndEnd.end || moment(parsedRange.end).unix();
127145
xAxisDamin = { min: start, max: end };
128146
}
129147
if (chartRef.current) {

src/pages/dashboard/Renderer/Renderer/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ interface IProps {
4646
values: IPanel;
4747
variableConfig?: IVariable[];
4848
isPreview?: boolean; // 是否是预览,预览中不显示编辑和分享
49+
datasourceValue: string;
4950
onCloneClick?: () => void;
5051
onShareClick?: () => void;
5152
onEditClick?: () => void;
@@ -60,7 +61,7 @@ function replaceFieldWithVariable(dashboardId, value: string, variableConfig?: I
6061
}
6162

6263
function index(props: IProps) {
63-
const { themeMode, dashboardId, id, step, variableConfig, isPreview, onCloneClick, onShareClick, onEditClick, onDeleteClick } = props;
64+
const { themeMode, dashboardId, id, step, variableConfig, isPreview, datasourceValue, onCloneClick, onShareClick, onEditClick, onDeleteClick } = props;
6465
const [time, setTime] = useState(props.time);
6566
const [visible, setVisible] = useState(false);
6667
const values = _.cloneDeep(props.values);
@@ -74,6 +75,7 @@ function index(props: IProps) {
7475
step,
7576
targets: values.targets,
7677
variableConfig,
78+
datasourceValue,
7779
inViewPort: isPreview || inViewPort,
7880
datasourceCate: values.datasourceCate || 'prometheus',
7981
datasourceName: values.datasourceName,

0 commit comments

Comments
 (0)