write index management
This commit is contained in:
parent
05d5acd62c
commit
24bf26498a
|
@ -92,4 +92,19 @@ func (handler APIHandler) HandleUpdateSettingsAction(w http.ResponseWriter, req
|
||||||
}
|
}
|
||||||
resBody["payload"] = true
|
resBody["payload"] = true
|
||||||
handler.WriteJSON(w, resBody, http.StatusOK)
|
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler APIHandler) HandleDeleteIndexAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
client := elastic.GetClient(handler.Config.Elasticsearch)
|
||||||
|
indexName := ps.ByName("index")
|
||||||
|
resBody := newResponseBody()
|
||||||
|
err := client.DeleteIndex(indexName)
|
||||||
|
if err != nil {
|
||||||
|
resBody["status"] = false
|
||||||
|
resBody["error"] = err
|
||||||
|
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resBody["payload"] = true
|
||||||
|
handler.WriteJSON(w, resBody, http.StatusOK)
|
||||||
}
|
}
|
|
@ -33,6 +33,7 @@ func Init(cfg *config.AppConfig) {
|
||||||
ui.HandleUIMethod(api.GET, pathPrefix+"index/:index/_mappings", handler.HandleGetMappingsAction)
|
ui.HandleUIMethod(api.GET, pathPrefix+"index/:index/_mappings", handler.HandleGetMappingsAction)
|
||||||
ui.HandleUIMethod(api.GET, pathPrefix+"index/:index/_settings", handler.HandleGetSettingsAction)
|
ui.HandleUIMethod(api.GET, pathPrefix+"index/:index/_settings", handler.HandleGetSettingsAction)
|
||||||
ui.HandleUIMethod(api.PUT, pathPrefix+"index/:index/_settings", handler.HandleUpdateSettingsAction)
|
ui.HandleUIMethod(api.PUT, pathPrefix+"index/:index/_settings", handler.HandleUpdateSettingsAction)
|
||||||
|
ui.HandleUIMethod(api.DELETE, pathPrefix+"index/:index", handler.HandleDeleteIndexAction)
|
||||||
|
|
||||||
task.RegisterScheduleTask(task.ScheduleTask{
|
task.RegisterScheduleTask(task.ScheduleTask{
|
||||||
Description: "sync reindex task result to index infinireindex",
|
Description: "sync reindex task result to index infinireindex",
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default [
|
||||||
authority: ['admin', 'user'],
|
authority: ['admin', 'user'],
|
||||||
routes: [
|
routes: [
|
||||||
// dashboard
|
// dashboard
|
||||||
{ path: '/', redirect: '/platform/cluster' },
|
{ path: '/', redirect: '/platform/clusterlist' },
|
||||||
{
|
{
|
||||||
path: '/platform',
|
path: '/platform',
|
||||||
name: 'platform',
|
name: 'platform',
|
||||||
|
|
|
@ -648,10 +648,10 @@ const mappings = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
'get /_search-center/_cat/indices': function(req, res){
|
// 'get /_search-center/_cat/indices': function(req, res){
|
||||||
res.send(data)
|
// res.send(data)
|
||||||
},
|
// },
|
||||||
'get /_search-center/index/:index/_mappings': function(req, res){
|
// 'get /_search-center/index/:index/_mappings': function(req, res){
|
||||||
res.send(mappings)
|
// res.send(mappings)
|
||||||
}
|
// }
|
||||||
}
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {flattenObject} from '@/lib/flatten_object';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export const readOnlySettings = [
|
||||||
|
'index.creation_date',
|
||||||
|
'index.number_of_shards',
|
||||||
|
'index.provided_name',
|
||||||
|
'index.uuid',
|
||||||
|
'index.version.created',
|
||||||
|
'index.compound_format',
|
||||||
|
'index.data_path',
|
||||||
|
'index.format',
|
||||||
|
'index.number_of_routing_shards',
|
||||||
|
'index.sort.field',
|
||||||
|
'index.sort.missing',
|
||||||
|
'index.sort.mode',
|
||||||
|
'index.sort.order',
|
||||||
|
'index.routing_partition_size',
|
||||||
|
'index.store.type',
|
||||||
|
];
|
||||||
|
export const settingsToDisplay = [
|
||||||
|
'index.number_of_replicas',
|
||||||
|
'index.blocks.read_only_allow_delete',
|
||||||
|
'index.codec',
|
||||||
|
'index.priority',
|
||||||
|
'index.query.default_field',
|
||||||
|
'index.refresh_interval',
|
||||||
|
'index.write.wait_for_active_shards',
|
||||||
|
];
|
||||||
|
|
||||||
|
//API expects settings in flattened dotted form,
|
||||||
|
//whereas they come back as nested objects from ES
|
||||||
|
export function transformSettingsForApi(data, isOpen) {
|
||||||
|
const { defaults, settings } = data;
|
||||||
|
//settings user has actually set
|
||||||
|
const flattenedSettings = flattenObject(settings);
|
||||||
|
//settings with their defaults
|
||||||
|
const flattenedDefaults = flattenObject(defaults);
|
||||||
|
const filteredDefaults = _.pick(flattenedDefaults, settingsToDisplay);
|
||||||
|
const newSettings = { ...filteredDefaults, ...flattenedSettings };
|
||||||
|
readOnlySettings.forEach((e) => delete newSettings[e]);
|
||||||
|
//can't change codec on open index
|
||||||
|
if (isOpen) {
|
||||||
|
delete newSettings['index.codec'];
|
||||||
|
}
|
||||||
|
return newSettings;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export const flattenObject = (nestedObj, flattenArrays) => {
|
||||||
|
const stack = []; // track key stack
|
||||||
|
const flatObj = {};
|
||||||
|
const dot = '.';
|
||||||
|
(function flattenObj(obj) {
|
||||||
|
_.keys(obj).forEach(function (key) {
|
||||||
|
stack.push(key);
|
||||||
|
if (!flattenArrays && Array.isArray(obj[key])) flatObj[stack.join(dot)] = obj[key];
|
||||||
|
else if (_.isObject(obj[key])) flattenObj(obj[key]);
|
||||||
|
else flatObj[stack.join(dot)] = obj[key];
|
||||||
|
stack.pop();
|
||||||
|
});
|
||||||
|
})(nestedObj);
|
||||||
|
return flatObj;
|
||||||
|
};
|
|
@ -1,5 +1,6 @@
|
||||||
import React, { PureComponent, Fragment } from 'react';
|
import React, { PureComponent, Fragment } from 'react';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
|
import {Link} from 'umi';
|
||||||
import {
|
import {
|
||||||
Row,
|
Row,
|
||||||
Col,
|
Col,
|
||||||
|
@ -14,14 +15,14 @@ import {
|
||||||
Tabs,
|
Tabs,
|
||||||
Descriptions,
|
Descriptions,
|
||||||
Menu,
|
Menu,
|
||||||
|
Table,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
Icon
|
Icon, Popconfirm
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import StandardTable from '@/components/StandardTable';
|
import Editor from '@monaco-editor/react';
|
||||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
|
||||||
|
|
||||||
import styles from '../List/TableList.less';
|
import styles from '../List/TableList.less';
|
||||||
import JSONPretty from 'react-json-prettify';
|
import {transformSettingsForApi} from '@/lib/elasticsearch/edit_settings';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
|
@ -132,9 +133,8 @@ const UpdateForm = Form.create()(props => {
|
||||||
});
|
});
|
||||||
|
|
||||||
/* eslint react/no-multi-comp:0 */
|
/* eslint react/no-multi-comp:0 */
|
||||||
@connect(({ pipeline, loading }) => ({
|
@connect(({ index }) => ({
|
||||||
pipeline,
|
index
|
||||||
loading: loading.models.pipeline,
|
|
||||||
}))
|
}))
|
||||||
@Form.create()
|
@Form.create()
|
||||||
class Index extends PureComponent {
|
class Index extends PureComponent {
|
||||||
|
@ -142,14 +142,12 @@ class Index extends PureComponent {
|
||||||
modalVisible: false,
|
modalVisible: false,
|
||||||
updateModalVisible: false,
|
updateModalVisible: false,
|
||||||
expandForm: false,
|
expandForm: false,
|
||||||
selectedRows: [],
|
|
||||||
formValues: {},
|
formValues: {},
|
||||||
updateFormValues: {},
|
updateFormValues: {},
|
||||||
drawerVisible: false,
|
drawerVisible: false,
|
||||||
editingIndex:{},
|
editingIndex:{},
|
||||||
|
indexActiveKey: '1',
|
||||||
};
|
};
|
||||||
datasource = `[{"health":"green","status":"open","index":"blogs_fixed","uuid":"Q6zngGf9QVaWqpV0lF-0nw","pri":"1","rep":"1","docs.count":"1594","docs.deleted":"594","store.size":"17.9mb","pri.store.size":"8.9mb"},{"health":"red","status":"open","index":"elastic_qa","uuid":"_qkVlQ5LRoOKffV-nFj8Uw","pri":"1","rep":"1","docs.count":null,"docs.deleted":null,"store.size":null,"pri.store.size":null},{"health":"green","status":"open","index":".kibana-event-log-7.9.0-000001","uuid":"fgTtyl62Tc6F1ddJfPwqHA","pri":"1","rep":"1","docs.count":"20","docs.deleted":"0","store.size":"25kb","pri.store.size":"12.5kb"},{"health":"green","status":"open","index":"blogs","uuid":"Mb2n4wnNQSKqSToI_QO0Yg","pri":"1","rep":"1","docs.count":"1594","docs.deleted":"0","store.size":"11mb","pri.store.size":"5.5mb"},{"health":"green","status":"open","index":".kibana-event-log-7.9.0-000002","uuid":"8GpbwnDXR2KJUsw6srLnWw","pri":"1","rep":"1","docs.count":"9","docs.deleted":"0","store.size":"96.9kb","pri.store.size":"48.4kb"},{"health":"green","status":"open","index":".apm-agent-configuration","uuid":"vIaV9k2VS-W48oUOe2xNWA","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":"logs_server1","uuid":"u56jv2AyR2KOkruOfxIAnA","pri":"1","rep":"1","docs.count":"5386","docs.deleted":"0","store.size":"5.1mb","pri.store.size":"2.5mb"},{"health":"green","status":"open","index":".kibana_1","uuid":"dBCrfVblRPGVlYAIlP_Duw","pri":"1","rep":"1","docs.count":"3187","docs.deleted":"50","store.size":"24.8mb","pri.store.size":"12.4mb"},{"health":"green","status":"open","index":".tasks","uuid":"3RafayGeSNiqglO2BHof9Q","pri":"1","rep":"1","docs.count":"3","docs.deleted":"0","store.size":"39.9kb","pri.store.size":"19.9kb"},{"health":"green","status":"open","index":"filebeat-7.9.0-elastic_qa","uuid":"tktSYU14S3CrsrJb0ybpSQ","pri":"1","rep":"1","docs.count":"3009880","docs.deleted":"0","store.size":"1.6gb","pri.store.size":"850.1mb"},{"health":"green","status":"open","index":"analysis_test","uuid":"6ZHEAW1ST_qfg7mo4Bva4w","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":".apm-custom-link","uuid":"Y4N2TeVERrGacEGwY-NPAQ","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"416b","pri.store.size":"208b"},{"health":"green","status":"open","index":"kibana_sample_data_ecommerce","uuid":"4FIWJKhGSr6bE72R0xEQyA","pri":"1","rep":"1","docs.count":"4675","docs.deleted":"0","store.size":"9.2mb","pri.store.size":"4.6mb"},{"health":"green","status":"open","index":".kibana_task_manager_1","uuid":"9afyndU_Q26oqOiEIoqRJw","pri":"1","rep":"1","docs.count":"6","docs.deleted":"2","store.size":"378.8kb","pri.store.size":"12.5kb"},{"health":"green","status":"open","index":".async-search","uuid":"2VbJgnN7SsqC-DWN64yXUQ","pri":"1","rep":"1","docs.count":"0","docs.deleted":"0","store.size":"3.9kb","pri.store.size":"3.7kb"}]`;
|
|
||||||
|
|
||||||
columns = [
|
columns = [
|
||||||
{
|
{
|
||||||
title: '索引名称',
|
title: '索引名称',
|
||||||
|
@ -165,19 +163,15 @@ class Index extends PureComponent {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '文档数',
|
title: '文档数',
|
||||||
dataIndex: 'docs.count',
|
dataIndex: 'docs_count',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '主分片数',
|
title: '主分片数',
|
||||||
dataIndex: 'pri'
|
dataIndex: 'shards'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '从分片数',
|
title: '从分片数',
|
||||||
dataIndex: 'rep'
|
dataIndex: 'replicas'
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '存储大小',
|
|
||||||
dataIndex: 'store.size'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
|
@ -185,15 +179,11 @@ class Index extends PureComponent {
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{/* <a onClick={() => this.handleUpdateModalVisible(true, record)}>设置</a>
|
{/* <a onClick={() => this.handleUpdateModalVisible(true, record)}>设置</a>
|
||||||
<Divider type="vertical" /> */}
|
<Divider type="vertical" /> */}
|
||||||
<a onClick={() => {
|
<Popconfirm title="Sure to delete?" onConfirm={() => this.handleDeleteClick(record.index)}>
|
||||||
this.state.selectedRows.push(record);
|
<a>删除</a>
|
||||||
this.handleDeleteClick();
|
</Popconfirm>
|
||||||
}}>删除</a>
|
|
||||||
<Divider type="vertical" />
|
<Divider type="vertical" />
|
||||||
<a onClick={() => {
|
<Link to={"/data/doc?index=" + record.index}>文档管理</Link>
|
||||||
this.state.selectedRows.push(record);
|
|
||||||
this.handleDeleteClick();
|
|
||||||
}}>文档管理</a>
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -201,36 +191,13 @@ class Index extends PureComponent {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
// dispatch({
|
|
||||||
// type: 'pipeline/fetch',
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
handleStandardTableChange = (pagination, filtersArg, sorter) => {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
const { formValues } = this.state;
|
|
||||||
|
|
||||||
const filters = Object.keys(filtersArg).reduce((obj, key) => {
|
|
||||||
const newObj = { ...obj };
|
|
||||||
newObj[key] = getValue(filtersArg[key]);
|
|
||||||
return newObj;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
currentPage: pagination.current,
|
|
||||||
pageSize: pagination.pageSize,
|
|
||||||
...formValues,
|
|
||||||
...filters,
|
|
||||||
};
|
|
||||||
if (sorter.field) {
|
|
||||||
params.sorter = `${sorter.field}_${sorter.order}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'pipeline/fetch',
|
type: 'index/fetchIndices',
|
||||||
payload: params,
|
payload: {
|
||||||
|
cluster: 'single-es'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
handleFormReset = () => {
|
handleFormReset = () => {
|
||||||
const { form, dispatch } = this.props;
|
const { form, dispatch } = this.props;
|
||||||
|
@ -244,50 +211,25 @@ class Index extends PureComponent {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleDeleteClick = e => {
|
handleDeleteClick = (indexName) => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
const { selectedRows } = this.state;
|
dispatch({
|
||||||
|
type: 'index/removeIndex',
|
||||||
if (!selectedRows) return;
|
payload: {
|
||||||
dispatch({
|
index: indexName
|
||||||
type: 'pipeline/delete',
|
}
|
||||||
payload: {
|
|
||||||
key: selectedRows.map(row => row.name),
|
|
||||||
},
|
|
||||||
callback: () => {
|
|
||||||
this.setState({
|
|
||||||
selectedRows: [],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSelectRows = rows => {
|
|
||||||
this.setState({
|
|
||||||
selectedRows: rows,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSearch = e => {
|
handleSearch = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const { dispatch, form } = this.props;
|
const { dispatch, form } = this.props;
|
||||||
|
|
||||||
form.validateFields((err, fieldsValue) => {
|
form.validateFields((err, fieldsValue) => {
|
||||||
if (err) return;
|
if (err) return;
|
||||||
|
|
||||||
const values = {
|
|
||||||
...fieldsValue,
|
|
||||||
updatedAt: fieldsValue.updatedAt && fieldsValue.updatedAt.valueOf(),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
formValues: values,
|
searchKey: fieldsValue.name,
|
||||||
});
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: 'rule/fetch',
|
|
||||||
payload: values,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -366,14 +308,63 @@ class Index extends PureComponent {
|
||||||
return this.renderSimpleForm();
|
return this.renderSimpleForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleIndexTabChanged = (activeKey, indexName) => {
|
||||||
|
this.setState({
|
||||||
|
indexActiveKey: activeKey,
|
||||||
|
})
|
||||||
|
const {dispatch} = this.props;
|
||||||
|
if(activeKey == '2'){
|
||||||
|
if(this.props.index.mappings[indexName]){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dispatch({
|
||||||
|
type: 'index/fetchMappings',
|
||||||
|
payload: {
|
||||||
|
index: indexName,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else if(activeKey == '4'){
|
||||||
|
if(this.props.index.settings[indexName]){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dispatch({
|
||||||
|
type: 'index/fetchSettings',
|
||||||
|
payload: {
|
||||||
|
index: indexName,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleEditorDidMount = (_valueGetter)=>{
|
||||||
|
this.indexSettingsGetter = _valueGetter;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleIndexSettingsSaveClick = (indexName)=>{
|
||||||
|
let settings = this.indexSettingsGetter();
|
||||||
|
settings = JSON.parse(settings);
|
||||||
|
const {dispatch} = this.props;
|
||||||
|
dispatch({
|
||||||
|
type: 'index/saveSettings',
|
||||||
|
payload: {
|
||||||
|
index: indexName,
|
||||||
|
settings: settings.settings,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const data = {
|
const {clusterIndices, settings} = this.props.index;
|
||||||
list: JSON.parse(this.datasource),
|
let indices = [];
|
||||||
pagination: {
|
for(let key in clusterIndices) {
|
||||||
pageSize: 5,
|
if(this.state.searchKey){
|
||||||
},
|
if(key.indexOf(this.state.searchKey) > -1){
|
||||||
};
|
indices.push(clusterIndices[key]);
|
||||||
const { selectedRows, modalVisible, updateModalVisible, updateFormValues,editingIndex, drawerVisible } = this.state;
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
indices.push(clusterIndices[key]);
|
||||||
|
}
|
||||||
|
const { modalVisible, updateModalVisible, updateFormValues,editingIndex, drawerVisible } = this.state;
|
||||||
const parentMethods = {
|
const parentMethods = {
|
||||||
handleAdd: this.handleAdd,
|
handleAdd: this.handleAdd,
|
||||||
handleModalVisible: this.handleModalVisible,
|
handleModalVisible: this.handleModalVisible,
|
||||||
|
@ -382,6 +373,10 @@ class Index extends PureComponent {
|
||||||
handleUpdateModalVisible: this.handleUpdateModalVisible,
|
handleUpdateModalVisible: this.handleUpdateModalVisible,
|
||||||
handleUpdate: this.handleUpdate,
|
handleUpdate: this.handleUpdate,
|
||||||
};
|
};
|
||||||
|
let newSettings = {};
|
||||||
|
if(settings && settings[editingIndex.index]){
|
||||||
|
newSettings = transformSettingsForApi(settings[editingIndex.index], editingIndex.status === 'open')
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
@ -392,18 +387,14 @@ class Index extends PureComponent {
|
||||||
<Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
|
<Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
|
||||||
新建
|
新建
|
||||||
</Button>
|
</Button>
|
||||||
{selectedRows.length > 0 && (
|
|
||||||
<span>
|
|
||||||
<Button onClick={() => this.handleDeleteClick()}>删除</Button>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<StandardTable
|
<Table bordered
|
||||||
selectedRows={selectedRows}
|
dataSource={indices}
|
||||||
data={data}
|
rowKey='index'
|
||||||
|
pagination={
|
||||||
|
{pageSize: 5,}
|
||||||
|
}
|
||||||
columns={this.columns}
|
columns={this.columns}
|
||||||
onSelectRow={this.handleSelectRows}
|
|
||||||
onChange={this.handleStandardTableChange}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -420,20 +411,21 @@ class Index extends PureComponent {
|
||||||
onClose={()=>{
|
onClose={()=>{
|
||||||
this.setState({
|
this.setState({
|
||||||
drawerVisible: false,
|
drawerVisible: false,
|
||||||
|
indexActiveKey: '1',
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
width={640}
|
width={720}
|
||||||
>
|
>
|
||||||
<Tabs defaultActiveKey="1" onChange={()=>{}}>
|
<Tabs activeKey={this.state.indexActiveKey} onChange={(activeKey)=>{this.handleIndexTabChanged(activeKey, editingIndex.index)}}>
|
||||||
<TabPane tab="Summary" key="1">
|
<TabPane tab="Summary" key="1">
|
||||||
<Descriptions title="General" column={2}>
|
<Descriptions title="General" column={2}>
|
||||||
<Descriptions.Item label="Health">green</Descriptions.Item>
|
<Descriptions.Item label="Health">{editingIndex.health}</Descriptions.Item>
|
||||||
<Descriptions.Item label="Status">open</Descriptions.Item>
|
<Descriptions.Item label="Status">{editingIndex.status}</Descriptions.Item>
|
||||||
<Descriptions.Item label="Primaries">1</Descriptions.Item>
|
<Descriptions.Item label="Primaries">{editingIndex.shards}</Descriptions.Item>
|
||||||
<Descriptions.Item label="Replicas">0</Descriptions.Item>
|
<Descriptions.Item label="Replicas">{editingIndex.replicas}</Descriptions.Item>
|
||||||
<Descriptions.Item label="Docs Count">5</Descriptions.Item>
|
<Descriptions.Item label="Docs Count">{editingIndex.docs_count}</Descriptions.Item>
|
||||||
<Descriptions.Item label="Docs Deleted">0</Descriptions.Item>
|
<Descriptions.Item label="Docs Deleted">{editingIndex.docs_deleted}</Descriptions.Item>
|
||||||
<Descriptions.Item label="Storage Size">115.3kb</Descriptions.Item>
|
<Descriptions.Item label="Storage Size"></Descriptions.Item>
|
||||||
<Descriptions.Item label="Primary Storage Size"></Descriptions.Item>
|
<Descriptions.Item label="Primary Storage Size"></Descriptions.Item>
|
||||||
<Descriptions.Item label="Alias">
|
<Descriptions.Item label="Alias">
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
|
@ -441,140 +433,38 @@ class Index extends PureComponent {
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tab="Mappings" key="2">
|
<TabPane tab="Mappings" key="2">
|
||||||
<JSONWrapper>
|
<JSONWrapper>
|
||||||
<JSONPretty json={JSON.parse(`{
|
<div style={{background:'#F5F7FA', color:'#343741', padding:10}}>
|
||||||
"mappings": {
|
<pre className="language-json">{JSON.stringify(this.props.index.mappings[editingIndex.index], null, 2)}</pre>
|
||||||
"_doc": {
|
</div>
|
||||||
"dynamic": "strict",
|
</JSONWrapper>
|
||||||
"_meta": {
|
|
||||||
"migrationMappingPropertyHashes": {
|
|
||||||
"migrationVersion": "4a1746014a75ade3a714e1db5763276f",
|
|
||||||
"originId": "2f4316de49999235636386fe51dc06c1",
|
|
||||||
"task": "235412e52d09e7165fac8a67a43ad6b4",
|
|
||||||
"updated_at": "00da57df13e94e9d98437d13ace4bfe0",
|
|
||||||
"references": "7997cf5a56cc02bdc9c93361bde732b0",
|
|
||||||
"namespace": "2f4316de49999235636386fe51dc06c1",
|
|
||||||
"type": "2f4316de49999235636386fe51dc06c1",
|
|
||||||
"namespaces": "2f4316de49999235636386fe51dc06c1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"migrationVersion": {
|
|
||||||
"dynamic": "true",
|
|
||||||
"properties": {
|
|
||||||
"task": {
|
|
||||||
"type": "text",
|
|
||||||
"fields": {
|
|
||||||
"keyword": {
|
|
||||||
"type": "keyword",
|
|
||||||
"ignore_above": 256
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"namespace": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"namespaces": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"originId": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"references": {
|
|
||||||
"type": "nested",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "keyword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"task": {
|
|
||||||
"properties": {
|
|
||||||
"attempts": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"ownerId": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"params": {
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
"retryAt": {
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
"runAt": {
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
"schedule": {
|
|
||||||
"properties": {
|
|
||||||
"interval": {
|
|
||||||
"type": "keyword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"scheduledAt": {
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
"scope": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"startedAt": {
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"taskType": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"type": "keyword"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "date"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
`)} theme={{
|
|
||||||
background: '#F5F7FA',
|
|
||||||
brace: '#343741',
|
|
||||||
keyQuotes: '#343741',
|
|
||||||
valueQuotes: '#343741',
|
|
||||||
colon: '#343741',
|
|
||||||
comma: '#343741',
|
|
||||||
key: '#343741',
|
|
||||||
value: {
|
|
||||||
string: '#343741',
|
|
||||||
null: '#343741',
|
|
||||||
number: '#343741',
|
|
||||||
boolean: '#343741',
|
|
||||||
},
|
|
||||||
bracket: '#343741',
|
|
||||||
}} /></JSONWrapper>
|
|
||||||
</TabPane>
|
|
||||||
<TabPane tab="Stats" key="3">
|
|
||||||
Content of Tab Pane 3
|
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
{/*<TabPane tab="Stats" key="3">*/}
|
||||||
|
{/* Content of Tab Pane 3*/}
|
||||||
|
{/*</TabPane>*/}
|
||||||
<TabPane tab="Edit settings" key="4">
|
<TabPane tab="Edit settings" key="4">
|
||||||
Content of Tab Pane 3
|
<div style={{textAlign:'right', marginBottom: 10}}>
|
||||||
|
<span style={{marginRight: 30}}>Edit, then save your JSON</span>
|
||||||
|
<Button type='primary' onClick={
|
||||||
|
()=>{
|
||||||
|
this.handleIndexSettingsSaveClick(editingIndex.index)
|
||||||
|
}
|
||||||
|
}>Save</Button></div>
|
||||||
|
<div style={{border: '1px solid rgb(232, 232, 232)'}}>
|
||||||
|
<Editor
|
||||||
|
height="300px"
|
||||||
|
language="json"
|
||||||
|
theme="light"
|
||||||
|
value={JSON.stringify(newSettings, null, 2)}
|
||||||
|
options={{
|
||||||
|
minimap: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
tabSize: 2,
|
||||||
|
wordBasedSuggestions: true,
|
||||||
|
}}
|
||||||
|
editorDidMount={this.handleEditorDidMount}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div style={{position:'absolute', bottom: 10}}>
|
<div style={{position:'absolute', bottom: 10}}>
|
||||||
|
@ -586,10 +476,10 @@ class Index extends PureComponent {
|
||||||
<Icon type="delete" />
|
<Icon type="delete" />
|
||||||
Delete
|
Delete
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="2">
|
{/*<Menu.Item key="2">*/}
|
||||||
<Icon type="edit" />
|
{/* <Icon type="edit" />*/}
|
||||||
Edit
|
{/* Edit*/}
|
||||||
</Menu.Item>
|
{/*</Menu.Item>*/}
|
||||||
<Menu.Item key="3">
|
<Menu.Item key="3">
|
||||||
<Icon type="close" />
|
<Icon type="close" />
|
||||||
Close
|
Close
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
import { getIndices,getMappings, getSettings, deleteIndex,
|
||||||
|
updateSettings} from '@/services/indices';
|
||||||
|
import { message } from 'antd';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespace: 'index',
|
||||||
|
state: {
|
||||||
|
clusterIndices: [],
|
||||||
|
mappings: {},
|
||||||
|
settings: {}
|
||||||
|
},
|
||||||
|
effects:{
|
||||||
|
*fetchIndices({payload}, {call, put}){
|
||||||
|
let resp = yield call(getIndices)
|
||||||
|
if(resp.status === false){
|
||||||
|
message.warn("获取数据失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
clusterIndices: resp.payload,
|
||||||
|
cluster: payload.cluster,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
*fetchMappings({payload}, {call, put}){
|
||||||
|
let resp = yield call(getMappings, payload);
|
||||||
|
if(resp.status === false){
|
||||||
|
message.warn("get mappings failed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
mappings: resp.payload,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
*fetchSettings({payload}, {call, put}){
|
||||||
|
let resp = yield call(getSettings, payload);
|
||||||
|
if(resp.status === false){
|
||||||
|
message.warn("get settings failed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
settings: resp.payload,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
*saveSettings({payload}, {call, put, select}){
|
||||||
|
let resp = yield call(updateSettings, payload);
|
||||||
|
if(resp.status === false){
|
||||||
|
message.warn("save settings failed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let {settings} = yield select(state=>state.index);
|
||||||
|
settings[payload.index] = payload.settings;
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
settings
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
*removeIndex({payload}, {call, put, select}){
|
||||||
|
let resp = yield call(deleteIndex, payload);
|
||||||
|
if(resp.status === false){
|
||||||
|
message.warn("get mappings failed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let {clusterIndices} = yield select(state=>state.index);
|
||||||
|
delete clusterIndices[payload.index];
|
||||||
|
yield put({
|
||||||
|
type: 'saveData',
|
||||||
|
payload: {
|
||||||
|
clusterIndices: clusterIndices,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reducers:{
|
||||||
|
saveData(state, {payload}){
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,9 +10,34 @@ export async function getMappings(payload){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getSettings(payload){
|
||||||
|
let index = payload.index || '*'
|
||||||
|
let url = `${pathPrefix}/index/${index}/_settings`;
|
||||||
|
return request(url,{
|
||||||
|
method: 'GET',
|
||||||
|
expirys: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateSettings(payload){
|
||||||
|
let index = payload.index
|
||||||
|
let url = `${pathPrefix}/index/${index}/_settings`;
|
||||||
|
return request(url,{
|
||||||
|
method: 'PUT',
|
||||||
|
body: payload.settings,
|
||||||
|
expirys: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function getIndices(params) {
|
export async function getIndices(params) {
|
||||||
return request(`${pathPrefix}/_cat/indices`, {
|
return request(`${pathPrefix}/_cat/indices`, {
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteIndex(params) {
|
||||||
|
let index = params.index;
|
||||||
|
return request(`${pathPrefix}/index/${index}`, {
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
}
|
}
|
Loading…
Reference in New Issue