mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[ML] Hide inference stats for PyTorch models (#160599)
## Summary Resolves https://github.com/elastic/kibana/issues/157385 Hides inference stats for the PyTorch models. - The salient information (`inference_count`, `timestamp`) is a repeat of what is already displayed in the Deployment Stats section. - `missing_all_fields_count` is confusing as the PyTorch models take a single input field rather than multiple fields as DFA models do, hence omitted. - The deployment stats have an [error_count](https://www.elastic.co/guide/en/elasticsearch/reference/current/get-trained-models-stats.html) field, hence it has been added to the Deployment Stats and `failure_count` has been removed. - Displays the stats tab by default for expanded rows if the model has started deployments
This commit is contained in:
parent
6db22e3e2a
commit
4064e2b7d4
5 changed files with 260 additions and 235 deletions
|
@ -61,12 +61,8 @@ export const ELASTIC_MODEL_DEFINITIONS = {
|
|||
|
||||
export const MODEL_STATE = {
|
||||
...DEPLOYMENT_STATE,
|
||||
DOWNLOADING: i18n.translate('xpack.ml.trainedModels.modelsList.downloadingStateLabel', {
|
||||
defaultMessage: 'downloading',
|
||||
}),
|
||||
DOWNLOADED: i18n.translate('xpack.ml.trainedModels.modelsList.downloadedStateLabel', {
|
||||
defaultMessage: 'downloaded',
|
||||
}),
|
||||
DOWNLOADING: 'downloading',
|
||||
DOWNLOADED: 'downloaded',
|
||||
} as const;
|
||||
|
||||
export type ModelState = typeof MODEL_STATE[keyof typeof MODEL_STATE];
|
||||
export type ModelState = typeof MODEL_STATE[keyof typeof MODEL_STATE] | null;
|
||||
|
|
|
@ -202,6 +202,7 @@ export interface AllocatedModel {
|
|||
throughput_last_minute: number;
|
||||
number_of_allocations: number;
|
||||
threads_per_allocation: number;
|
||||
error_count?: number;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -220,6 +220,16 @@ export const AllocatedModels: FC<AllocatedModelsProps> = ({
|
|||
return v.node.number_of_pending_requests;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: i18n.translate('xpack.ml.trainedModels.nodesList.modelsList.errorCountHeader', {
|
||||
defaultMessage: 'Errors',
|
||||
}),
|
||||
width: '60px',
|
||||
'data-test-subj': 'mlAllocatedModelsTableErrorCount',
|
||||
render: (v: AllocatedModel) => {
|
||||
return v.node.error_count ?? 0;
|
||||
},
|
||||
},
|
||||
].filter((v) => !hideColumns.includes(v.id!));
|
||||
|
||||
return (
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, useMemo, useCallback } from 'react';
|
||||
import React, { type FC, useCallback, useMemo } from 'react';
|
||||
import { omit, pick } from 'lodash';
|
||||
import {
|
||||
EuiBadge,
|
||||
|
@ -27,7 +27,6 @@ import { FIELD_FORMAT_IDS } from '@kbn/field-formats-plugin/common';
|
|||
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
|
||||
import { isDefined } from '@kbn/ml-is-defined';
|
||||
import { TRAINED_MODEL_TYPE } from '@kbn/ml-trained-models-utils';
|
||||
import type { PartialBy } from '../../../common/types/common';
|
||||
import type { ModelItemFull } from './models_list';
|
||||
import { ModelPipelines } from './pipelines';
|
||||
import { AllocatedModels } from '../memory_usage/nodes_overview/allocated_models';
|
||||
|
@ -132,30 +131,34 @@ export const ExpandedRow: FC<ExpandedRowProps> = ({ item }) => {
|
|||
description,
|
||||
} = item;
|
||||
|
||||
const inferenceStats = useMemo(() => {
|
||||
if (!isPopulatedObject(stats.inference_stats)) return;
|
||||
const inferenceStats = useMemo<TrainedModelStat['inference_stats']>(() => {
|
||||
if (!isPopulatedObject(stats.inference_stats) || item.model_type === TRAINED_MODEL_TYPE.PYTORCH)
|
||||
return;
|
||||
|
||||
const result = { ...stats.inference_stats } as PartialBy<
|
||||
Exclude<TrainedModelStat['inference_stats'], undefined>,
|
||||
'cache_miss_count'
|
||||
>;
|
||||
if (item.model_type === TRAINED_MODEL_TYPE.PYTORCH) {
|
||||
delete result.cache_miss_count;
|
||||
}
|
||||
return result;
|
||||
return stats.inference_stats;
|
||||
}, [stats.inference_stats, item.model_type]);
|
||||
|
||||
const { analytics_config: analyticsConfig, ...restMetaData } = metadata ?? {};
|
||||
|
||||
const details = {
|
||||
const details = useMemo(() => {
|
||||
return {
|
||||
description,
|
||||
tags,
|
||||
version,
|
||||
estimated_operations,
|
||||
estimated_heap_memory_usage_bytes,
|
||||
default_field_map,
|
||||
license_level,
|
||||
};
|
||||
}, [
|
||||
default_field_map,
|
||||
description,
|
||||
estimated_heap_memory_usage_bytes,
|
||||
estimated_operations,
|
||||
license_level,
|
||||
tags,
|
||||
version,
|
||||
estimated_operations,
|
||||
estimated_heap_memory_usage_bytes,
|
||||
default_field_map,
|
||||
license_level,
|
||||
};
|
||||
]);
|
||||
|
||||
const deploymentStatItems: AllocatedModel[] = useMemo<AllocatedModel[]>(() => {
|
||||
const deploymentStats = stats.deployment_stats;
|
||||
|
@ -181,6 +184,7 @@ export const ExpandedRow: FC<ExpandedRowProps> = ({ item }) => {
|
|||
'throughput_last_minute',
|
||||
'number_of_allocations',
|
||||
'threads_per_allocation',
|
||||
'error_count',
|
||||
]),
|
||||
name: nodeName,
|
||||
} as AllocatedModel['node'],
|
||||
|
@ -191,46 +195,28 @@ export const ExpandedRow: FC<ExpandedRowProps> = ({ item }) => {
|
|||
return items;
|
||||
}, [stats]);
|
||||
|
||||
const tabs: EuiTabbedContentTab[] = [
|
||||
{
|
||||
id: 'details',
|
||||
'data-test-subj': 'mlTrainedModelDetails',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.detailsTabLabel"
|
||||
defaultMessage="Details"
|
||||
/>
|
||||
),
|
||||
content: (
|
||||
<div data-test-subj={'mlTrainedModelDetailsContent'}>
|
||||
<EuiSpacer size={'s'} />
|
||||
<EuiFlexGrid columns={2} gutterSize={'m'}>
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.detailsTitle"
|
||||
defaultMessage="Details"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(details)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
{isPopulatedObject(restMetaData) ? (
|
||||
const tabs = useMemo<EuiTabbedContentTab[]>(() => {
|
||||
return [
|
||||
{
|
||||
id: 'details',
|
||||
'data-test-subj': 'mlTrainedModelDetails',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.detailsTabLabel"
|
||||
defaultMessage="Details"
|
||||
/>
|
||||
),
|
||||
content: (
|
||||
<div data-test-subj={'mlTrainedModelDetailsContent'}>
|
||||
<EuiSpacer size={'s'} />
|
||||
<EuiFlexGrid columns={2} gutterSize={'m'}>
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.metadataTitle"
|
||||
defaultMessage="Metadata"
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.detailsTitle"
|
||||
defaultMessage="Details"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
|
@ -238,192 +224,224 @@ export const ExpandedRow: FC<ExpandedRowProps> = ({ item }) => {
|
|||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(restMetaData)}
|
||||
listItems={formatToListItems(details)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
</EuiFlexGrid>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
...(inferenceConfig
|
||||
? [
|
||||
{
|
||||
id: 'config',
|
||||
'data-test-subj': 'mlTrainedModelInferenceConfig',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.configTabLabel"
|
||||
defaultMessage="Config"
|
||||
/>
|
||||
),
|
||||
content: (
|
||||
<div data-test-subj={'mlTrainedModelInferenceConfigContent'}>
|
||||
<EuiSpacer size={'s'} />
|
||||
<EuiFlexGrid columns={2} gutterSize={'m'}>
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.inferenceConfigTitle"
|
||||
defaultMessage="Inference configuration"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(
|
||||
inferenceConfig[Object.keys(inferenceConfig)[0]]
|
||||
)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
{analyticsConfig && (
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.analyticsConfigTitle"
|
||||
defaultMessage="Analytics configuration"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(analyticsConfig)}
|
||||
{isPopulatedObject(restMetaData) ? (
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.metadataTitle"
|
||||
defaultMessage="Metadata"
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGrid>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(isPopulatedObject(omit(stats, ['pipeline_count', 'ingest']))
|
||||
? [
|
||||
{
|
||||
id: 'stats',
|
||||
'data-test-subj': 'mlTrainedModelStats',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.statsTabLabel"
|
||||
defaultMessage="Stats"
|
||||
/>
|
||||
),
|
||||
content: (
|
||||
<div data-test-subj={'mlTrainedModelStatsContent'}>
|
||||
<EuiSpacer size={'s'} />
|
||||
|
||||
{!!deploymentStatItems?.length ? (
|
||||
<>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.deploymentStatsTitle"
|
||||
defaultMessage="Deployment stats"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<AllocatedModels models={deploymentStatItems} hideColumns={['model_id']} />
|
||||
</EuiPanel>
|
||||
<EuiSpacer size={'s'} />
|
||||
</>
|
||||
) : null}
|
||||
|
||||
<EuiFlexGrid columns={2} gutterSize={'m'}>
|
||||
{inferenceStats ? (
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.inferenceStatsTitle"
|
||||
defaultMessage="Inference stats"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(inferenceStats)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
{isPopulatedObject(stats.model_size_stats) &&
|
||||
!isPopulatedObject(inferenceStats) ? (
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.modelSizeStatsTitle"
|
||||
defaultMessage="Model size stats"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(stats.model_size_stats)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
</EuiFlexGrid>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...((isPopulatedObject(pipelines) && Object.keys(pipelines).length > 0) || stats.ingest
|
||||
? [
|
||||
{
|
||||
id: 'pipelines',
|
||||
'data-test-subj': 'mlTrainedModelPipelines',
|
||||
name: (
|
||||
<>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(restMetaData)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
</EuiFlexGrid>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
...(inferenceConfig
|
||||
? [
|
||||
{
|
||||
id: 'config',
|
||||
'data-test-subj': 'mlTrainedModelInferenceConfig',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.pipelinesTabLabel"
|
||||
defaultMessage="Pipelines"
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.configTabLabel"
|
||||
defaultMessage="Config"
|
||||
/>
|
||||
{isPopulatedObject(pipelines) ? (
|
||||
<EuiNotificationBadge>{Object.keys(pipelines).length}</EuiNotificationBadge>
|
||||
) : null}
|
||||
</>
|
||||
),
|
||||
content: (
|
||||
<div data-test-subj={'mlTrainedModelPipelinesContent'}>
|
||||
<EuiSpacer size={'s'} />
|
||||
<ModelPipelines pipelines={pipelines!} ingestStats={stats.ingest} />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
),
|
||||
content: (
|
||||
<div data-test-subj={'mlTrainedModelInferenceConfigContent'}>
|
||||
<EuiSpacer size={'s'} />
|
||||
<EuiFlexGrid columns={2} gutterSize={'m'}>
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.inferenceConfigTitle"
|
||||
defaultMessage="Inference configuration"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(
|
||||
inferenceConfig[Object.keys(inferenceConfig)[0]]
|
||||
)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
{analyticsConfig && (
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.analyticsConfigTitle"
|
||||
defaultMessage="Analytics configuration"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(analyticsConfig)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGrid>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(isPopulatedObject(omit(stats, ['pipeline_count', 'ingest']))
|
||||
? [
|
||||
{
|
||||
id: 'stats',
|
||||
'data-test-subj': 'mlTrainedModelStats',
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.statsTabLabel"
|
||||
defaultMessage="Stats"
|
||||
/>
|
||||
),
|
||||
content: (
|
||||
<div data-test-subj={'mlTrainedModelStatsContent'}>
|
||||
<EuiSpacer size={'s'} />
|
||||
|
||||
{!!deploymentStatItems?.length ? (
|
||||
<>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.deploymentStatsTitle"
|
||||
defaultMessage="Deployment stats"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<AllocatedModels models={deploymentStatItems} hideColumns={['model_id']} />
|
||||
</EuiPanel>
|
||||
<EuiSpacer size={'s'} />
|
||||
</>
|
||||
) : null}
|
||||
|
||||
<EuiFlexGrid columns={2} gutterSize={'m'}>
|
||||
{inferenceStats ? (
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.inferenceStatsTitle"
|
||||
defaultMessage="Inference stats"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(inferenceStats)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
{isPopulatedObject(stats.model_size_stats) &&
|
||||
!isPopulatedObject(inferenceStats) ? (
|
||||
<EuiFlexItem>
|
||||
<EuiPanel>
|
||||
<EuiTitle size={'xs'}>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.modelSizeStatsTitle"
|
||||
defaultMessage="Model size stats"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size={'m'} />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="column"
|
||||
listItems={formatToListItems(stats.model_size_stats)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
</EuiFlexGrid>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...((isPopulatedObject(pipelines) && Object.keys(pipelines).length > 0) || stats.ingest
|
||||
? [
|
||||
{
|
||||
id: 'pipelines',
|
||||
'data-test-subj': 'mlTrainedModelPipelines',
|
||||
name: (
|
||||
<>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.trainedModels.modelsList.expandedRow.pipelinesTabLabel"
|
||||
defaultMessage="Pipelines"
|
||||
/>
|
||||
{isPopulatedObject(pipelines) ? (
|
||||
<EuiNotificationBadge>{Object.keys(pipelines).length}</EuiNotificationBadge>
|
||||
) : null}
|
||||
</>
|
||||
),
|
||||
content: (
|
||||
<div data-test-subj={'mlTrainedModelPipelinesContent'}>
|
||||
<EuiSpacer size={'s'} />
|
||||
<ModelPipelines pipelines={pipelines!} ingestStats={stats.ingest} />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
}, [
|
||||
analyticsConfig,
|
||||
deploymentStatItems,
|
||||
details,
|
||||
formatToListItems,
|
||||
inferenceConfig,
|
||||
inferenceStats,
|
||||
pipelines,
|
||||
restMetaData,
|
||||
stats,
|
||||
]);
|
||||
|
||||
const initialSelectedTab =
|
||||
item.state === 'started' ? tabs.find((t) => t.id === 'stats') : tabs[0];
|
||||
|
||||
return (
|
||||
<EuiTabbedContent
|
||||
size="s"
|
||||
style={{ width: '100%' }}
|
||||
css={{ width: '100%' }}
|
||||
tabs={tabs}
|
||||
initialSelectedTab={tabs[0]}
|
||||
initialSelectedTab={initialSelectedTab}
|
||||
autoFocus="selected"
|
||||
onTabClick={(tab) => {}}
|
||||
data-test-subj={'mlTrainedModelRowDetails'}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -283,7 +283,7 @@ export const ModelsList: FC<Props> = ({
|
|||
(v) => v.state === DEPLOYMENT_STATE.STARTED
|
||||
)
|
||||
? DEPLOYMENT_STATE.STARTED
|
||||
: '';
|
||||
: null;
|
||||
});
|
||||
|
||||
const elasticModels = models.filter((model) =>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue