[ML] Add the job message tab to data frame analytics (#50468)
* [ML] get analytics job messages from ml-notifications * [ML] remove commented import * [ML] add job_type filter for anomaly_detector * [ML] job messages component * [ML] update styles * [ML] update job messages container for anomaly detection with async await * [ML] fix passing a prop * [ML] fix types and error message * [ML] fix i18n * [ML] fix text alignment * [ML] remove duplicated copyright comment
This commit is contained in:
parent
1a8bb3a223
commit
0c42aa8a58
|
@ -10,4 +10,3 @@ export const ML_ANNOTATIONS_INDEX_PATTERN = '.ml-annotations-6';
|
|||
|
||||
export const ML_RESULTS_INDEX_PATTERN = '.ml-anomalies-*';
|
||||
export const ML_NOTIFICATION_INDEX_PATTERN = '.ml-notifications*';
|
||||
export const ML_DF_NOTIFICATION_INDEX_PATTERN = '.data-frame-notifications-1';
|
||||
|
|
|
@ -12,10 +12,6 @@ export interface AuditMessageBase {
|
|||
text?: string;
|
||||
}
|
||||
|
||||
export interface AnalyticsMessage extends AuditMessageBase {
|
||||
analytics_id: string;
|
||||
}
|
||||
|
||||
export interface JobMessage extends AuditMessageBase {
|
||||
job_id: string;
|
||||
}
|
||||
|
|
|
@ -4,5 +4,4 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
|
||||
export { JobIcon } from './job_message_icon';
|
|
@ -11,7 +11,7 @@ import { AuditMessageBase } from '../../../common/types/audit_message';
|
|||
|
||||
interface Props {
|
||||
message: AuditMessageBase;
|
||||
showTooltip: boolean;
|
||||
showTooltip?: boolean;
|
||||
}
|
||||
|
||||
const [INFO, WARNING, ERROR] = ['info', 'warning', 'error'];
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { JobMessages } from './job_messages';
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 React, { FC } from 'react';
|
||||
|
||||
import { EuiSpacer, EuiBasicTable } from '@elastic/eui';
|
||||
// @ts-ignore
|
||||
import { formatDate } from '@elastic/eui/lib/services/format';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import theme from '@elastic/eui/dist/eui_theme_light.json';
|
||||
|
||||
import { JobMessage } from '../../../common/types/audit_message';
|
||||
import { JobIcon } from '../job_message_icon';
|
||||
|
||||
const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
|
||||
|
||||
interface JobMessagesProps {
|
||||
messages: JobMessage[];
|
||||
loading: boolean;
|
||||
error: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component for rendering job messages for anomaly detection
|
||||
* and data frame analytics jobs.
|
||||
*/
|
||||
export const JobMessages: FC<JobMessagesProps> = ({ messages, loading, error }) => {
|
||||
const columns = [
|
||||
{
|
||||
name: '',
|
||||
render: (message: JobMessage) => <JobIcon message={message} />,
|
||||
width: `${theme.euiSizeL}`,
|
||||
},
|
||||
{
|
||||
name: i18n.translate('xpack.ml.jobMessages.timeLabel', {
|
||||
defaultMessage: 'Time',
|
||||
}),
|
||||
render: (message: any) => formatDate(message.timestamp, TIME_FORMAT),
|
||||
width: '120px',
|
||||
},
|
||||
{
|
||||
field: 'node_name',
|
||||
name: i18n.translate('xpack.ml.jobMessages.nodeLabel', {
|
||||
defaultMessage: 'Node',
|
||||
}),
|
||||
width: '150px',
|
||||
},
|
||||
{
|
||||
field: 'message',
|
||||
name: i18n.translate('xpack.ml.jobMessages.messageLabel', {
|
||||
defaultMessage: 'Message',
|
||||
}),
|
||||
width: '50%',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiBasicTable
|
||||
className="job-messages-table"
|
||||
items={messages}
|
||||
columns={columns}
|
||||
compressed={true}
|
||||
loading={loading}
|
||||
error={error}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -27,7 +27,7 @@ import {
|
|||
} from '../../../../common';
|
||||
import { isCompletedAnalyticsJob } from './common';
|
||||
import { isRegressionAnalysis } from '../../../../common/analytics';
|
||||
// import { ExpandedRowMessagesPane } from './expanded_row_messages_pane';
|
||||
import { ExpandedRowMessagesPane } from './expanded_row_messages_pane';
|
||||
|
||||
function getItemDescription(value: any) {
|
||||
if (typeof value === 'object') {
|
||||
|
@ -235,19 +235,16 @@ export const ExpandedRow: FC<Props> = ({ item }) => {
|
|||
name: 'JSON',
|
||||
content: <ExpandedRowJsonPane json={item.config} />,
|
||||
},
|
||||
// Audit messages are not yet supported by the analytics API.
|
||||
/*
|
||||
{
|
||||
id: 'ml-analytics-job-messages',
|
||||
name: i18n.translate(
|
||||
'xpack.ml.dataframe.analyticsList.analyticsDetails.tabs.analyticsMessagesLabel',
|
||||
{
|
||||
defaultMessage: 'Messages',
|
||||
defaultMessage: 'Job messages',
|
||||
}
|
||||
),
|
||||
content: <ExpandedRowMessagesPane analyticsId={item.id} />,
|
||||
},
|
||||
*/
|
||||
];
|
||||
|
||||
// Using `expand=false` here so the tabs themselves don't spread
|
||||
|
|
|
@ -4,27 +4,19 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { Fragment, FC, useState } from 'react';
|
||||
|
||||
import { EuiSpacer, EuiBasicTable } from '@elastic/eui';
|
||||
// @ts-ignore
|
||||
import { formatDate } from '@elastic/eui/lib/services/format';
|
||||
import React, { FC, useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import theme from '@elastic/eui/dist/eui_theme_light.json';
|
||||
import { ml } from '../../../../../services/ml_api_service';
|
||||
// @ts-ignore
|
||||
import { JobIcon } from '../../../../../components/job_message_icon';
|
||||
import { AnalyticsMessage } from '../../../../../../common/types/audit_message';
|
||||
import { useRefreshAnalyticsList } from '../../../../common';
|
||||
|
||||
const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
|
||||
import { JobMessages } from '../../../../../components/job_messages';
|
||||
import { JobMessage } from '../../../../../../common/types/audit_message';
|
||||
|
||||
interface Props {
|
||||
analyticsId: string;
|
||||
}
|
||||
|
||||
export const ExpandedRowMessagesPane: FC<Props> = ({ analyticsId }) => {
|
||||
const [messages, setMessages] = useState([]);
|
||||
const [messages, setMessages] = useState<JobMessage[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [errorMessage, setErrorMessage] = useState('');
|
||||
|
||||
|
@ -63,43 +55,5 @@ export const ExpandedRowMessagesPane: FC<Props> = ({ analyticsId }) => {
|
|||
|
||||
useRefreshAnalyticsList({ onRefresh: getMessagesFactory() });
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: '',
|
||||
render: (message: AnalyticsMessage) => <JobIcon message={message} />,
|
||||
width: `${theme.euiSizeXL}px`,
|
||||
},
|
||||
{
|
||||
name: i18n.translate('xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.timeLabel', {
|
||||
defaultMessage: 'Time',
|
||||
}),
|
||||
render: (message: any) => formatDate(message.timestamp, TIME_FORMAT),
|
||||
},
|
||||
{
|
||||
field: 'node_name',
|
||||
name: i18n.translate('xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.nodeLabel', {
|
||||
defaultMessage: 'Node',
|
||||
}),
|
||||
},
|
||||
{
|
||||
field: 'message',
|
||||
name: i18n.translate('xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.messageLabel', {
|
||||
defaultMessage: 'Message',
|
||||
}),
|
||||
width: '50%',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiBasicTable
|
||||
items={messages}
|
||||
columns={columns}
|
||||
compressed={true}
|
||||
loading={isLoading}
|
||||
error={errorMessage}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
return <JobMessages messages={messages} loading={isLoading} error={errorMessage} />;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
.tab-contents {
|
||||
margin: -$euiSizeS;
|
||||
padding: $euiSizeS;
|
||||
|
@ -69,27 +68,13 @@
|
|||
.json-textarea {
|
||||
height: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
// SASSTODO: This needs to be rewritten. A lot of this should be done with the JS props
|
||||
.job-messages-table {
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
text-align: left;
|
||||
|
||||
.euiTable {
|
||||
font-size: 12px;
|
||||
|
||||
th:nth-child(1) {
|
||||
width: $euiSizeXL;
|
||||
}
|
||||
th:nth-child(2) {
|
||||
width: 150px;
|
||||
}
|
||||
th:nth-child(3) {
|
||||
width: 120px;
|
||||
}
|
||||
th:nth-child(4) {
|
||||
width: auto;
|
||||
}
|
||||
tr:last-child {
|
||||
td {
|
||||
border-bottom: none;
|
||||
|
@ -100,5 +85,3 @@
|
|||
background-color: $euiColorEmptyShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ class JobDetailsUI extends Component {
|
|||
id: 'xpack.ml.jobsList.jobDetails.tabs.jobMessagesLabel',
|
||||
defaultMessage: 'Job messages'
|
||||
}),
|
||||
content: <JobMessagesPane job={job} />,
|
||||
content: <JobMessagesPane jobId={job.job_id} />,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* 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 PropTypes from 'prop-types';
|
||||
import React, {
|
||||
Component
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
EuiSpacer,
|
||||
EuiBasicTable,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { formatDate } from '@elastic/eui/lib/services/format';
|
||||
import { ml } from 'plugins/ml/services/ml_api_service';
|
||||
import { JobIcon } from '../../../../components/job_message_icon';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
|
||||
|
||||
class JobMessagesPaneUI extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
messages: []
|
||||
};
|
||||
this.jobId = props.job.job_id;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
ml.jobs.jobAuditMessages(this.jobId)
|
||||
.then((messages) => {
|
||||
this.setState({ messages });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('Job messages could not be loaded', error);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { messages } = this.state;
|
||||
const { intl } = this.props;
|
||||
const columns = [{
|
||||
name: '',
|
||||
render: item => (<JobIcon message={item} />)
|
||||
}, {
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.ml.jobsList.jobDetails.messagesPane.timeLabel',
|
||||
defaultMessage: 'Time'
|
||||
}),
|
||||
render: item => formatDate(item.timestamp, TIME_FORMAT)
|
||||
}, {
|
||||
field: 'node_name',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.ml.jobsList.jobDetails.messagesPane.nodeLabel',
|
||||
defaultMessage: 'Node'
|
||||
}),
|
||||
}, {
|
||||
field: 'message',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.ml.jobsList.jobDetails.messagesPane.messageLabel',
|
||||
defaultMessage: 'Message'
|
||||
}),
|
||||
}
|
||||
];
|
||||
return (
|
||||
<React.Fragment>
|
||||
<EuiSpacer size="s" />
|
||||
<div className="job-messages-table">
|
||||
<EuiBasicTable
|
||||
items={messages}
|
||||
columns={columns}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
JobMessagesPaneUI.propTypes = {
|
||||
job: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export const JobMessagesPane = injectI18n(JobMessagesPaneUI);
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 React, { FC, useEffect, useState } from 'react';
|
||||
|
||||
import { ml } from '../../../../services/ml_api_service';
|
||||
import { JobMessages } from '../../../../components/job_messages';
|
||||
import { JobMessage } from '../../../../../common/types/audit_message';
|
||||
|
||||
interface JobMessagesPaneProps {
|
||||
jobId: string;
|
||||
}
|
||||
|
||||
export const JobMessagesPane: FC<JobMessagesPaneProps> = ({ jobId }) => {
|
||||
const [messages, setMessages] = useState<JobMessage[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [errorMessage, setErrorMessage] = useState('');
|
||||
|
||||
const fetchMessages = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
setMessages(await ml.jobs.jobAuditMessages(jobId));
|
||||
setIsLoading(false);
|
||||
} catch (e) {
|
||||
setIsLoading(false);
|
||||
setErrorMessage(e);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Job messages could not be loaded', e);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchMessages();
|
||||
}, []);
|
||||
|
||||
return <JobMessages messages={messages} loading={isLoading} error={errorMessage} />;
|
||||
};
|
|
@ -69,27 +69,13 @@
|
|||
.json-textarea {
|
||||
height: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
// SASSTODO: This needs to be rewritten. A lot of this should be done with the JS props
|
||||
.job-messages-table {
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
text-align: left;
|
||||
|
||||
.euiTable {
|
||||
font-size: 12px;
|
||||
|
||||
th:nth-child(1) {
|
||||
width: $euiSizeXL;
|
||||
}
|
||||
th:nth-child(2) {
|
||||
width: 150px;
|
||||
}
|
||||
th:nth-child(3) {
|
||||
width: 120px;
|
||||
}
|
||||
th:nth-child(4) {
|
||||
width: auto;
|
||||
}
|
||||
tr:last-child {
|
||||
td {
|
||||
border-bottom: none;
|
||||
|
@ -100,5 +86,3 @@
|
|||
background-color: $euiColorEmptyShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { MlSummaryJobs } from '../../../common/types/jobs';
|
|||
import { MlServerDefaults, MlServerLimits } from '../../services/ml_server_info';
|
||||
import { ES_AGGREGATION } from '../../../common/constants/aggregation_types';
|
||||
import { DataFrameAnalyticsStats } from '../../data_frame_analytics/pages/analytics_management/components/analytics_list/common';
|
||||
import { JobMessage } from '../../../common/types/audit_message';
|
||||
|
||||
// TODO This is not a complete representation of all methods of `ml.*`.
|
||||
// It just satisfies needs for other parts of the code area which use
|
||||
|
@ -117,7 +118,7 @@ declare interface Ml {
|
|||
stopDatafeeds(datafeedIds: string[]): Promise<object>;
|
||||
deleteJobs(jobIds: string[]): Promise<object>;
|
||||
closeJobs(jobIds: string[]): Promise<object>;
|
||||
jobAuditMessages(jobId: string, from: string): Promise<object>;
|
||||
jobAuditMessages(jobId: string, from?: string): Promise<JobMessage[]>;
|
||||
deletingJobTasks(): Promise<object>;
|
||||
newJobCaps(indexPatternTitle: string, isRollup: boolean): Promise<object>;
|
||||
newJobLineChart(
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { ML_DF_NOTIFICATION_INDEX_PATTERN } from '../../../common/constants/index_patterns';
|
||||
import { callWithRequestType } from '../../../common/types/kibana';
|
||||
import { AnalyticsMessage } from '../../../common/types/audit_message';
|
||||
import { ML_NOTIFICATION_INDEX_PATTERN } from '../../../common/constants/index_patterns';
|
||||
import { JobMessage } from '../../../common/types/audit_message';
|
||||
|
||||
const SIZE = 50;
|
||||
|
||||
|
@ -15,7 +15,7 @@ interface Message {
|
|||
_type: string;
|
||||
_id: string;
|
||||
_score: null | number;
|
||||
_source: AnalyticsMessage;
|
||||
_source: JobMessage;
|
||||
sort?: any;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,11 @@ export function analyticsAuditMessagesProvider(callWithRequest: callWithRequestT
|
|||
level: 'activity',
|
||||
},
|
||||
},
|
||||
must: {
|
||||
term: {
|
||||
job_type: 'data_frame_analytics',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -50,12 +55,12 @@ export function analyticsAuditMessagesProvider(callWithRequest: callWithRequestT
|
|||
should: [
|
||||
{
|
||||
term: {
|
||||
analytics_id: '', // catch system messages
|
||||
job_id: '', // catch system messages
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
analytics_id: analyticsId, // messages for specified analyticsId
|
||||
job_id: analyticsId, // messages for specified analyticsId
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -65,12 +70,12 @@ export function analyticsAuditMessagesProvider(callWithRequest: callWithRequestT
|
|||
|
||||
try {
|
||||
const resp = await callWithRequest('search', {
|
||||
index: ML_DF_NOTIFICATION_INDEX_PATTERN,
|
||||
index: ML_NOTIFICATION_INDEX_PATTERN,
|
||||
ignore_unavailable: true,
|
||||
rest_total_hits_as_int: true,
|
||||
size: SIZE,
|
||||
body: {
|
||||
sort: [{ timestamp: { order: 'desc' } }, { analytics_id: { order: 'asc' } }],
|
||||
sort: [{ timestamp: { order: 'desc' } }, { job_id: { order: 'asc' } }],
|
||||
query,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -48,6 +48,11 @@ export function jobAuditMessagesProvider(callWithRequest) {
|
|||
term: {
|
||||
level: 'activity'
|
||||
}
|
||||
},
|
||||
must: {
|
||||
term: {
|
||||
job_type: 'anomaly_detector'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -6130,9 +6130,6 @@
|
|||
"xpack.ml.jobsList.jobDetails.forecastsTable.viewLabel": "表示",
|
||||
"xpack.ml.jobsList.jobDetails.generalTitle": "一般",
|
||||
"xpack.ml.jobsList.jobDetails.influencersTitle": "影響",
|
||||
"xpack.ml.jobsList.jobDetails.messagesPane.messageLabel": "メッセージ",
|
||||
"xpack.ml.jobsList.jobDetails.messagesPane.nodeLabel": "ノード",
|
||||
"xpack.ml.jobsList.jobDetails.messagesPane.timeLabel": "時間",
|
||||
"xpack.ml.jobsList.jobDetails.modelSizeStatsTitle": "モデルサイズ統計",
|
||||
"xpack.ml.jobsList.jobDetails.nodeTitle": "ノード",
|
||||
"xpack.ml.jobsList.jobDetails.noPermissionToViewDatafeedPreviewTitle": "データフィードのプレビューを表示するパーミッションがありません",
|
||||
|
@ -6610,9 +6607,6 @@
|
|||
"xpack.ml.datavisualizer.searchPanel.sampleLabel": "サンプル",
|
||||
"xpack.ml.datavisualizer.searchPanel.sampleSizeAriaLabel": "サンプリングするドキュメント数を選択してください",
|
||||
"xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.errorMessage": "メッセージを読み込めませんでした",
|
||||
"xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.messageLabel": "メッセージ",
|
||||
"xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.nodeLabel": "ノード",
|
||||
"xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.timeLabel": "時間",
|
||||
"xpack.ml.fieldDataCard.cardBoolean.documentsCountDescription": "{count, plural, zero {# document} one {# document} other {# documents}} ({docsPercent}%)",
|
||||
"xpack.ml.fieldDataCard.cardDate.documentsCountDescription": "{count, plural, zero {# document} one {# document} other {# documents}} ({docsPercent}%)",
|
||||
"xpack.ml.fieldDataCard.cardDate.earliestDescription": "最も古い {earliestFormatted}",
|
||||
|
|
|
@ -6131,9 +6131,6 @@
|
|||
"xpack.ml.jobsList.jobDetails.forecastsTable.viewLabel": "查看",
|
||||
"xpack.ml.jobsList.jobDetails.generalTitle": "常规",
|
||||
"xpack.ml.jobsList.jobDetails.influencersTitle": "影响因素",
|
||||
"xpack.ml.jobsList.jobDetails.messagesPane.messageLabel": "消息",
|
||||
"xpack.ml.jobsList.jobDetails.messagesPane.nodeLabel": "节点",
|
||||
"xpack.ml.jobsList.jobDetails.messagesPane.timeLabel": "时间",
|
||||
"xpack.ml.jobsList.jobDetails.modelSizeStatsTitle": "模型大小统计",
|
||||
"xpack.ml.jobsList.jobDetails.nodeTitle": "节点",
|
||||
"xpack.ml.jobsList.jobDetails.noPermissionToViewDatafeedPreviewTitle": "您无权查看数据馈送预览",
|
||||
|
@ -6703,9 +6700,6 @@
|
|||
"xpack.ml.datavisualizer.searchPanel.sampleLabel": "采样",
|
||||
"xpack.ml.datavisualizer.searchPanel.sampleSizeAriaLabel": "选择要采样的文档数目",
|
||||
"xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.errorMessage": "无法加载消息",
|
||||
"xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.messageLabel": "消息",
|
||||
"xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.nodeLabel": "节点",
|
||||
"xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.timeLabel": "时间",
|
||||
"xpack.ml.fieldDataCard.cardBoolean.documentsCountDescription": "{count, plural, zero {# 个文档} one {# 个文档} other {# 个文档}} ({docsPercent}%)",
|
||||
"xpack.ml.fieldDataCard.cardDate.documentsCountDescription": "{count, plural, zero {# 个文档} one {# 个文档} other {# 个文档}} ({docsPercent}%)",
|
||||
"xpack.ml.fieldDataCard.cardDate.earliestDescription": "最早的 {earliestFormatted}",
|
||||
|
|
Loading…
Reference in a new issue