chore: add column `Builtin` to `View` (#101)
* chore: add column `Builtin` to `View` * chore: adjust TopN's UI --------- Co-authored-by: yaojiping <yaojiping@infini.ltd>
This commit is contained in:
parent
6d576a7636
commit
098371729e
|
@ -43,7 +43,7 @@ export class SimpleSavedObject<T = unknown> {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private client: SavedObjectsClientContract,
|
private client: SavedObjectsClientContract,
|
||||||
{ id, type, version, attributes, error, references, migrationVersion, complex_fields }: SavedObjectType<T>
|
{ id, type, version, attributes, error, references, migrationVersion }: SavedObjectType<T>
|
||||||
) {
|
) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -51,7 +51,6 @@ export class SimpleSavedObject<T = unknown> {
|
||||||
this.references = references || [];
|
this.references = references || [];
|
||||||
this._version = version;
|
this._version = version;
|
||||||
this.migrationVersion = migrationVersion;
|
this.migrationVersion = migrationVersion;
|
||||||
this.attributes.complexFields = complex_fields
|
|
||||||
if (error) {
|
if (error) {
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,7 @@ export class IndexPattern implements IIndexPattern {
|
||||||
return this.deserializeFieldFormatMap(mapping);
|
return this.deserializeFieldFormatMap(mapping);
|
||||||
});
|
});
|
||||||
this.viewName = spec.viewName || "";
|
this.viewName = spec.viewName || "";
|
||||||
|
this.builtin = spec.builtin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -440,6 +441,7 @@ export class IndexPattern implements IIndexPattern {
|
||||||
fieldFormatMap,
|
fieldFormatMap,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
typeMeta: this.typeMeta ? JSON.stringify(this.typeMeta) : undefined,
|
typeMeta: this.typeMeta ? JSON.stringify(this.typeMeta) : undefined,
|
||||||
|
builtin: this.builtin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -358,7 +358,8 @@ export class IndexPatternsService {
|
||||||
sourceFilters,
|
sourceFilters,
|
||||||
fieldFormatMap,
|
fieldFormatMap,
|
||||||
typeMeta,
|
typeMeta,
|
||||||
complexFields,
|
complex_fields: complexFields,
|
||||||
|
builtin
|
||||||
},
|
},
|
||||||
type,
|
type,
|
||||||
} = savedObject;
|
} = savedObject;
|
||||||
|
@ -385,7 +386,8 @@ export class IndexPatternsService {
|
||||||
fields: this.fieldArrayToMap(parsedFields),
|
fields: this.fieldArrayToMap(parsedFields),
|
||||||
typeMeta: parsedTypeMeta,
|
typeMeta: parsedTypeMeta,
|
||||||
type,
|
type,
|
||||||
complexFields: parsedComplexFields
|
complexFields: parsedComplexFields,
|
||||||
|
builtin
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,9 @@ const EditIndexPatternCont: React.FC<RouteComponentProps<{ id: string }>> = ({
|
||||||
if (!ip.id) {
|
if (!ip.id) {
|
||||||
ip.id = props.match.params.id;
|
ip.id = props.match.params.id;
|
||||||
}
|
}
|
||||||
|
if (ip.builtin) {
|
||||||
|
props.history.push("");
|
||||||
|
}
|
||||||
setIndexPattern(ip);
|
setIndexPattern(ip);
|
||||||
// setBreadcrumbs(getEditBreadcrumbs(ip));
|
// setBreadcrumbs(getEditBreadcrumbs(ip));
|
||||||
});
|
});
|
||||||
|
|
|
@ -211,11 +211,18 @@ export const IndexPatternTable = ({
|
||||||
dataIndex: "title",
|
dataIndex: "title",
|
||||||
sorter: (a: string, b: string) => sorter.string(a, b, "title"),
|
sorter: (a: string, b: string) => sorter.string(a, b, "title"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: formatMessage({ id: "explore.createview.field.builtin" }),
|
||||||
|
dataIndex: "builtin",
|
||||||
|
render: (val) => {
|
||||||
|
return formatMessage({ id: `explore.createview.field.builtin.${val === true ? "true" : "false"}` });
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: formatMessage({ id: "table.field.actions" }),
|
title: formatMessage({ id: "table.field.actions" }),
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<div>
|
<div>
|
||||||
{canSave ? (
|
{canSave && !record.builtin ? (
|
||||||
<>
|
<>
|
||||||
<a {...reactRouterNavigate(history, `patterns/${record.id}`)}>
|
<a {...reactRouterNavigate(history, `patterns/${record.id}`)}>
|
||||||
{formatMessage({ id: "form.button.edit" })}
|
{formatMessage({ id: "form.button.edit" })}
|
||||||
|
|
|
@ -38,8 +38,8 @@ export async function getIndexPatterns(
|
||||||
const id = pattern.id;
|
const id = pattern.id;
|
||||||
const title = pattern.get('title');
|
const title = pattern.get('title');
|
||||||
const viewName = pattern.get('viewName');
|
const viewName = pattern.get('viewName');
|
||||||
|
const builtin = pattern.get('builtin');
|
||||||
const isDefault = defaultIndex === id;
|
const isDefault = defaultIndex === id;
|
||||||
|
|
||||||
const tags = (indexPatternManagementStart as IndexPatternManagementStart).list.getIndexPatternTags(
|
const tags = (indexPatternManagementStart as IndexPatternManagementStart).list.getIndexPatternTags(
|
||||||
pattern,
|
pattern,
|
||||||
isDefault
|
isDefault
|
||||||
|
@ -55,6 +55,7 @@ export async function getIndexPatterns(
|
||||||
// so the sorting will but the default index on top
|
// so the sorting will but the default index on top
|
||||||
// or on bottom of a the table
|
// or on bottom of a the table
|
||||||
sort: `${isDefault ? '0' : '1'}${title}`,
|
sort: `${isDefault ? '0' : '1'}${title}`,
|
||||||
|
builtin,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
|
|
|
@ -27,6 +27,9 @@ export default {
|
||||||
"explore.createview.field.match_rule": "Match Rule",
|
"explore.createview.field.match_rule": "Match Rule",
|
||||||
"explore.createview.field.match_rule.help":
|
"explore.createview.field.match_rule.help":
|
||||||
'Use (*) to match multiple indices and cannot contain spaces or characters , /, ?, ", <, >, |.',
|
'Use (*) to match multiple indices and cannot contain spaces or characters , /, ?, ", <, >, |.',
|
||||||
|
"explore.createview.field.builtin": "Builtin",
|
||||||
|
"explore.createview.field.builtin.true": "True",
|
||||||
|
"explore.createview.field.builtin.false": "false",
|
||||||
"explore.createview.status.match_index_num": "Matching {length} indices",
|
"explore.createview.status.match_index_num": "Matching {length} indices",
|
||||||
"explore.createview.status.match_special_index":
|
"explore.createview.status.match_special_index":
|
||||||
"The current matching rule did not match the Elasticsearch index.To match the special index, turn on the Include special index switch.",
|
"The current matching rule did not match the Elasticsearch index.To match the special index, turn on the Include special index switch.",
|
||||||
|
|
|
@ -26,6 +26,9 @@ export default {
|
||||||
"explore.createview.field.match_rule": "匹配规则",
|
"explore.createview.field.match_rule": "匹配规则",
|
||||||
"explore.createview.field.match_rule.help":
|
"explore.createview.field.match_rule.help":
|
||||||
'使用 (*) 来匹配多个索引。 不能包含空格或者字符 , /, ?, ", <, >, |.',
|
'使用 (*) 来匹配多个索引。 不能包含空格或者字符 , /, ?, ", <, >, |.',
|
||||||
|
"explore.createview.field.builtin": "是否内置",
|
||||||
|
"explore.createview.field.builtin.true": "是",
|
||||||
|
"explore.createview.field.builtin.false": "否",
|
||||||
"explore.createview.status.match_index_num": "当前匹配到 {length} 个索引",
|
"explore.createview.status.match_index_num": "当前匹配到 {length} 个索引",
|
||||||
"explore.createview.status.match_special_index":
|
"explore.createview.status.match_special_index":
|
||||||
"当前规则没有匹配到任何索引。如需匹配特殊索引,请打开包含特殊索引开关。",
|
"当前规则没有匹配到任何索引。如需匹配特殊索引,请打开包含特殊索引开关。",
|
||||||
|
|
|
@ -36,18 +36,18 @@ export default ({ value = [], onChange, style = {}, className = '' }) => {
|
||||||
{
|
{
|
||||||
value.map((item, index) => (
|
value.map((item, index) => (
|
||||||
<ColorPicker key={index} color={item} onRemove={() => onRemove(index)} onChange={(color) => handleChange(color, index)}>
|
<ColorPicker key={index} color={item} onRemove={() => onRemove(index)} onChange={(color) => handleChange(color, index)}>
|
||||||
<Button style={{ padding: 3, width: 120, marginBottom: 8 }} size="small" >
|
<Button style={{ padding: 3, width: 84, marginBottom: 8 }} size="small" >
|
||||||
<div style={{ background: item, width: '100%', height: 16 }}></div>
|
<div style={{ background: item, width: '100%', height: 16 }}></div>
|
||||||
</Button>
|
</Button>
|
||||||
</ColorPicker>
|
</ColorPicker>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
<ColorPicker onChange={onAdd}>
|
<ColorPicker onChange={onAdd}>
|
||||||
<Button size="small" icon="plus" style={{ width: 120 }}></Button>
|
<Button size="small" icon="plus" style={{ width: 84 }}></Button>
|
||||||
</ColorPicker>
|
</ColorPicker>
|
||||||
</div>
|
</div>
|
||||||
)}>
|
)}>
|
||||||
<div className={className} style={{ padding: '10px 8px', border: '1px solid #d9d9d9', width: 136, height: 32, cursor: 'pointer', ...style }}>
|
<div className={className} style={{ padding: '10px 8px', border: '1px solid #d9d9d9', width: 100, height: 32, cursor: 'pointer', ...style }}>
|
||||||
<div style={{ background, height: 12}}></div>
|
<div style={{ background, height: 12}}></div>
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
:global {
|
:global {
|
||||||
.ant-popover-inner-content {
|
.ant-popover-inner-content {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
max-width: 136px;
|
max-width: 100px;
|
||||||
}
|
}
|
||||||
.ant-popover-arrow {
|
.ant-popover-arrow {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -72,8 +72,7 @@ export default (props) => {
|
||||||
})
|
})
|
||||||
if (res && !res.error && Array.isArray(res.saved_objects) && res.saved_objects[0]) {
|
if (res && !res.error && Array.isArray(res.saved_objects) && res.saved_objects[0]) {
|
||||||
const newView = res.saved_objects[0]
|
const newView = res.saved_objects[0]
|
||||||
let { fieldFormatMap, fields } = newView.attributes || {}
|
let { fieldFormatMap, fields, complex_fields: complexFields } = newView.attributes || {}
|
||||||
let { complex_fields: complexFields } = newView
|
|
||||||
try {
|
try {
|
||||||
fieldFormatMap = JSON.parse(fieldFormatMap) || {}
|
fieldFormatMap = JSON.parse(fieldFormatMap) || {}
|
||||||
fields = JSON.parse(fields) || []
|
fields = JSON.parse(fields) || []
|
||||||
|
@ -413,12 +412,12 @@ export default (props) => {
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
<div className={styles.topn}>
|
<div className={styles.topn}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<Input.Group compact style={{ width: 'auto '}}>
|
<Input.Group compact>
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
value={currentMode}
|
value={currentMode}
|
||||||
onChange={(e) => setCurrentMode(e.target.value)}
|
onChange={(e) => setCurrentMode(e.target.value)}
|
||||||
className={styles.mode}
|
className={styles.mode}
|
||||||
style={{ marginRight: 12, marginBottom: 12 }}
|
style={{ marginRight: 10 }}
|
||||||
>
|
>
|
||||||
<Radio.Button value="treemap">
|
<Radio.Button value="treemap">
|
||||||
<Icon
|
<Icon
|
||||||
|
@ -439,11 +438,11 @@ export default (props) => {
|
||||||
/>
|
/>
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
<div className={styles.label}>
|
<div className={styles.label} title="Top">
|
||||||
Top
|
Top
|
||||||
</div>
|
</div>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
style={{ width: "80px", marginBottom: 12, marginRight: 12 }}
|
style={{ width: "60px", marginRight: 10 }}
|
||||||
className={styles.borderRadiusRight}
|
className={styles.borderRadiusRight}
|
||||||
value={formData.top}
|
value={formData.top}
|
||||||
min={1}
|
min={1}
|
||||||
|
@ -451,13 +450,17 @@ export default (props) => {
|
||||||
precision={0}
|
precision={0}
|
||||||
onChange={(value) => onFormDataChange({ top: value })}
|
onChange={(value) => onFormDataChange({ top: value })}
|
||||||
/>
|
/>
|
||||||
<div className={styles.label}>
|
<div className={styles.label} title={formatMessage({ id: "cluster.monitor.topn.area" })}>
|
||||||
{formatMessage({ id: "cluster.monitor.topn.area" })}
|
{formatMessage({ id: "cluster.monitor.topn.area" })}
|
||||||
</div>
|
</div>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: "150px", marginBottom: 12 }}
|
style={{ flexGrow: 0, flexShrink: 1, overflow: 'hidden' }}
|
||||||
value={formData.sourceArea?.name}
|
value={formData.sourceArea?.name}
|
||||||
dropdownMatchSelectWidth={false}
|
dropdownMatchSelectWidth={false}
|
||||||
|
showSearch
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.props?.children?.toLowerCase().indexOf(input?.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
onChange={(value, option) => {
|
onChange={(value, option) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
const { isComplex } = option?.props?.metric || {}
|
const { isComplex } = option?.props?.metric || {}
|
||||||
|
@ -490,7 +493,7 @@ export default (props) => {
|
||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: "88px", marginBottom: 12, marginRight: 6 }}
|
style={{ width: "70px", marginRight: 6 }}
|
||||||
className={styles.borderRadiusRight}
|
className={styles.borderRadiusRight}
|
||||||
value={formData.statisticArea}
|
value={formData.statisticArea}
|
||||||
dropdownMatchSelectWidth={false}
|
dropdownMatchSelectWidth={false}
|
||||||
|
@ -507,14 +510,18 @@ export default (props) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
<Button style={{ width: 32, marginBottom: 12, padding: 0, marginRight: 6, borderRadius: 4 }} onClick={() => onMetricExchange()}><Icon style={{ fontSize: 16 }} component={ConvertSvg}/></Button>
|
<Button style={{ width: 32, minWidth: 32, padding: 0, marginRight: 6, borderRadius: 4 }} onClick={() => onMetricExchange()}><Icon style={{ fontSize: 16 }} component={ConvertSvg}/></Button>
|
||||||
<div className={styles.label}>
|
<div className={styles.label} title={formatMessage({ id: "cluster.monitor.topn.color" })}>
|
||||||
{formatMessage({ id: "cluster.monitor.topn.color" })}
|
{formatMessage({ id: "cluster.monitor.topn.color" })}
|
||||||
</div>
|
</div>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: "150px", marginBottom: 12 }}
|
style={{ flexGrow: 0, flexShrink: 1, overflow: 'hidden' }}
|
||||||
value={formData.sourceColor?.name}
|
value={formData.sourceColor?.name}
|
||||||
dropdownMatchSelectWidth={false}
|
dropdownMatchSelectWidth={false}
|
||||||
|
showSearch
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.props?.children?.toLowerCase().indexOf(input?.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
onChange={(value, option) => {
|
onChange={(value, option) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
const { isComplex } = option?.props?.metric || {}
|
const { isComplex } = option?.props?.metric || {}
|
||||||
|
@ -548,7 +555,7 @@ export default (props) => {
|
||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: "88px", marginBottom: 12 }}
|
style={{ width: "70px" }}
|
||||||
value={formData.statisticColor}
|
value={formData.statisticColor}
|
||||||
dropdownMatchSelectWidth={false}
|
dropdownMatchSelectWidth={false}
|
||||||
onChange={(value) => onFormDataChange({ statisticColor: value })}
|
onChange={(value) => onFormDataChange({ statisticColor: value })}
|
||||||
|
@ -564,17 +571,17 @@ export default (props) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
<div className={styles.label} style={{ borderTopLeftRadius: 0, borderBottomLeftRadius: 0 }}>
|
<div className={styles.label} title={formatMessage({ id: "cluster.monitor.topn.theme" })} style={{ borderTopLeftRadius: 0, borderBottomLeftRadius: 0 }}>
|
||||||
{formatMessage({ id: "cluster.monitor.topn.theme" })}
|
{formatMessage({ id: "cluster.monitor.topn.theme" })}
|
||||||
</div>
|
</div>
|
||||||
<GradientColorPicker className={styles.borderRadiusRight} style={{ marginRight: 12, marginBottom: 12 }} value={formData.colors || []} onChange={(value) => {
|
<GradientColorPicker className={styles.borderRadiusRight} style={{ marginRight: 10 }} value={formData.colors || []} onChange={(value) => {
|
||||||
onFormDataChange({ colors: value })
|
onFormDataChange({ colors: value })
|
||||||
setConfig({
|
setConfig({
|
||||||
...cloneDeep(config),
|
...cloneDeep(config),
|
||||||
colors: value
|
colors: value
|
||||||
})
|
})
|
||||||
}}/>
|
}}/>
|
||||||
<Button style={{ marginBottom: 12 }} className={styles.borderRadiusLeft} type="primary" onClick={() => fetchData(type, clusterID, timeRange, formData)}>{formatMessage({ id: "form.button.apply" })}</Button>
|
<Button className={styles.borderRadiusLeft} type="primary" onClick={() => fetchData(type, clusterID, timeRange, formData)}>{formatMessage({ id: "form.button.apply" })}</Button>
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,20 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: nowrap;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
:global {
|
:global {
|
||||||
.ant-input-group {
|
.ant-input-group {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
flex-wrap: wrap !important;
|
flex-wrap: nowrap !important;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode {
|
.mode {
|
||||||
width: 84px;
|
width: 84px;
|
||||||
|
min-width: 84px;
|
||||||
:global {
|
:global {
|
||||||
.ant-radio-button-wrapper {
|
.ant-radio-button-wrapper {
|
||||||
width: 42px;
|
width: 42px;
|
||||||
|
@ -34,6 +37,10 @@
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border-top-right-radius: 0px !important;
|
border-top-right-radius: 0px !important;
|
||||||
border-bottom-right-radius: 0px !important;
|
border-bottom-right-radius: 0px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-grow: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue