mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Fix Watcher stuck firing state (#138563)
* Update WATCH_STATES by replacing DISABLED with INACTIVE and OK/FIRING with ACTIVE. Update ACTION_STATES by replacing FIRING with OK. - Refactor isAckable logic to directly translate value provided by ES. - Replace WatchStatus component with ActionStateBadge and WatchStateBadge components. * Change WatchListPage 'Last fired' column to 'Condition last met' and 'Last triggered' column to 'Last checked'. - Add tooltips to both. - Add tooltips to State and Comment headers. * Rename Watch Status Model's lastFired -> lastExecution for consistency. Remove unused properties from client WatchStatus model. * Add Condition Met column and tooltips to State and Comment headers on Execution History Panel. * Add tooltip to State header in Execution History flyout. Add Last executed header to Action Statuses Panel and tooltips. Update tests. * Use EUI types instead of hand-rolling them. * Remove unused ACTION_STATES.FIRING and references to WATCH_STATES.FIRING. * Use dots to denote states, similar to Index Management. * Refactor deriveComment to use early exits.
This commit is contained in:
parent
1adabbcb23
commit
f77afae85e
31 changed files with 496 additions and 390 deletions
|
@ -31249,7 +31249,6 @@
|
|||
"xpack.watcher.constants.actionStates.acknowledgedStateText": "Reconnu",
|
||||
"xpack.watcher.constants.actionStates.configErrorStateText": "Erreur de config",
|
||||
"xpack.watcher.constants.actionStates.errorStateText": "Erreur",
|
||||
"xpack.watcher.constants.actionStates.firingStateText": "Déclenchement",
|
||||
"xpack.watcher.constants.actionStates.okStateText": "OK",
|
||||
"xpack.watcher.constants.actionStates.throttledStateText": "Contraint",
|
||||
"xpack.watcher.constants.actionStates.unknownStateText": "Inconnu",
|
||||
|
@ -31259,10 +31258,7 @@
|
|||
"xpack.watcher.constants.watchStateComments.partiallyThrottledStateCommentText": "Partiellement contraint",
|
||||
"xpack.watcher.constants.watchStateComments.throttledStateCommentText": "Contraint",
|
||||
"xpack.watcher.constants.watchStates.configErrorStateText": "Erreur de config",
|
||||
"xpack.watcher.constants.watchStates.disabledStateText": "Désactivé",
|
||||
"xpack.watcher.constants.watchStates.errorStateText": "Erreur",
|
||||
"xpack.watcher.constants.watchStates.firingStateText": "Déclenchement",
|
||||
"xpack.watcher.constants.watchStates.okStateText": "OK",
|
||||
"xpack.watcher.data.parseEsInterval.invalidEsCalendarIntervalErrorMessage": "Intervalle de calendrier non valide : {interval}, la valeur doit être 1",
|
||||
"xpack.watcher.data.parseEsInterval.invalidEsIntervalFormatErrorMessage": "Format d'intervalle non valide : {interval}",
|
||||
"xpack.watcher.deleteSelectedWatchesConfirmModal.cancelButtonLabel": "Annuler",
|
||||
|
|
|
@ -31325,7 +31325,6 @@
|
|||
"xpack.watcher.constants.actionStates.acknowledgedStateText": "承認済み",
|
||||
"xpack.watcher.constants.actionStates.configErrorStateText": "構成エラー",
|
||||
"xpack.watcher.constants.actionStates.errorStateText": "エラー",
|
||||
"xpack.watcher.constants.actionStates.firingStateText": "実行中",
|
||||
"xpack.watcher.constants.actionStates.okStateText": "OK",
|
||||
"xpack.watcher.constants.actionStates.throttledStateText": "スロットル",
|
||||
"xpack.watcher.constants.actionStates.unknownStateText": "不明",
|
||||
|
@ -31335,10 +31334,7 @@
|
|||
"xpack.watcher.constants.watchStateComments.partiallyThrottledStateCommentText": "部分スロットル",
|
||||
"xpack.watcher.constants.watchStateComments.throttledStateCommentText": "スロットル",
|
||||
"xpack.watcher.constants.watchStates.configErrorStateText": "構成エラー",
|
||||
"xpack.watcher.constants.watchStates.disabledStateText": "無効",
|
||||
"xpack.watcher.constants.watchStates.errorStateText": "エラー",
|
||||
"xpack.watcher.constants.watchStates.firingStateText": "実行中",
|
||||
"xpack.watcher.constants.watchStates.okStateText": "OK",
|
||||
"xpack.watcher.data.parseEsInterval.invalidEsCalendarIntervalErrorMessage": "無効なカレンダー間隔:{interval}、1よりも大きな値が必要です",
|
||||
"xpack.watcher.data.parseEsInterval.invalidEsIntervalFormatErrorMessage": "無効な間隔形式:{interval}",
|
||||
"xpack.watcher.deleteSelectedWatchesConfirmModal.cancelButtonLabel": "キャンセル",
|
||||
|
|
|
@ -31354,7 +31354,6 @@
|
|||
"xpack.watcher.constants.actionStates.acknowledgedStateText": "已确认",
|
||||
"xpack.watcher.constants.actionStates.configErrorStateText": "配置错误",
|
||||
"xpack.watcher.constants.actionStates.errorStateText": "错误",
|
||||
"xpack.watcher.constants.actionStates.firingStateText": "正在发送",
|
||||
"xpack.watcher.constants.actionStates.okStateText": "确定",
|
||||
"xpack.watcher.constants.actionStates.throttledStateText": "已限制",
|
||||
"xpack.watcher.constants.actionStates.unknownStateText": "未知",
|
||||
|
@ -31364,10 +31363,7 @@
|
|||
"xpack.watcher.constants.watchStateComments.partiallyThrottledStateCommentText": "已部分限制",
|
||||
"xpack.watcher.constants.watchStateComments.throttledStateCommentText": "已限制",
|
||||
"xpack.watcher.constants.watchStates.configErrorStateText": "配置错误",
|
||||
"xpack.watcher.constants.watchStates.disabledStateText": "已禁用",
|
||||
"xpack.watcher.constants.watchStates.errorStateText": "错误",
|
||||
"xpack.watcher.constants.watchStates.firingStateText": "正在发送",
|
||||
"xpack.watcher.constants.watchStates.okStateText": "确定",
|
||||
"xpack.watcher.data.parseEsInterval.invalidEsCalendarIntervalErrorMessage": "无效的日历时间间隔:{interval},值必须为 1",
|
||||
"xpack.watcher.data.parseEsInterval.invalidEsIntervalFormatErrorMessage": "时间间隔格式无效:{interval}",
|
||||
"xpack.watcher.deleteSelectedWatchesConfirmModal.cancelButtonLabel": "取消",
|
||||
|
|
49
x-pack/plugins/watcher/__fixtures__/get_watch_history.ts
Normal file
49
x-pack/plugins/watcher/__fixtures__/get_watch_history.ts
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import moment, { Moment } from 'moment';
|
||||
import { ACTION_STATES, WATCH_STATES } from '../common/constants';
|
||||
import { ClientWatchStatusModel, ClientActionStatusModel } from '../common/types';
|
||||
|
||||
interface WatchHistory {
|
||||
id: string;
|
||||
watchId: string;
|
||||
startTime: Moment;
|
||||
watchStatus: {
|
||||
state: ClientWatchStatusModel['state'];
|
||||
comment?: string;
|
||||
lastExecution: Moment;
|
||||
actionStatuses?: Array<{
|
||||
id: string;
|
||||
state: ClientActionStatusModel['state'];
|
||||
}>;
|
||||
};
|
||||
details?: object;
|
||||
}
|
||||
|
||||
export const getWatchHistory = ({
|
||||
id,
|
||||
startTime,
|
||||
}: {
|
||||
id: string;
|
||||
startTime: string;
|
||||
}): WatchHistory => ({
|
||||
id,
|
||||
startTime: moment(startTime),
|
||||
watchId: id,
|
||||
watchStatus: {
|
||||
state: WATCH_STATES.OK,
|
||||
lastExecution: moment('2019-06-03T19:44:11.088Z'),
|
||||
actionStatuses: [
|
||||
{
|
||||
id: 'a',
|
||||
state: ACTION_STATES.OK,
|
||||
},
|
||||
],
|
||||
},
|
||||
details: {},
|
||||
});
|
|
@ -6,5 +6,5 @@
|
|||
*/
|
||||
|
||||
export * from './watch';
|
||||
export * from './watch_history';
|
||||
export * from './get_watch_history';
|
||||
export * from './execute_details';
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Moment } from 'moment';
|
||||
import { getRandomString } from '@kbn/test-jest-helpers';
|
||||
import { ClientWatchStatusModel } from '../common/types';
|
||||
import { WATCH_STATES, WATCH_STATE_COMMENTS } from '../common/constants';
|
||||
|
||||
interface Watch {
|
||||
id: string;
|
||||
|
@ -22,14 +23,7 @@ interface Watch {
|
|||
timeWindowUnit?: string;
|
||||
threshold?: number[];
|
||||
isSystemWatch: boolean;
|
||||
watchStatus: {
|
||||
state: 'OK' | 'Firing' | 'Error' | 'Config error' | 'Disabled';
|
||||
comment?: string;
|
||||
lastMetCondition?: Moment;
|
||||
lastChecked?: Moment;
|
||||
isActive: boolean;
|
||||
actionStatuses?: any[];
|
||||
};
|
||||
watchStatus: ClientWatchStatusModel;
|
||||
}
|
||||
|
||||
export const getWatch = ({
|
||||
|
@ -47,8 +41,13 @@ export const getWatch = ({
|
|||
threshold,
|
||||
isSystemWatch = false,
|
||||
watchStatus = {
|
||||
state: 'OK',
|
||||
id: 'a',
|
||||
state: WATCH_STATES.OK,
|
||||
isActive: true,
|
||||
lastChecked: null,
|
||||
lastMetCondition: null,
|
||||
comment: WATCH_STATE_COMMENTS.OK,
|
||||
actionStatuses: [],
|
||||
},
|
||||
}: Partial<Watch> = {}): Watch => ({
|
||||
id,
|
||||
|
|
|
@ -1,39 +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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getRandomString } from '@kbn/test-jest-helpers';
|
||||
|
||||
interface WatchHistory {
|
||||
startTime: string;
|
||||
id: string;
|
||||
watchId: string;
|
||||
watchStatus: {
|
||||
state: 'OK' | 'Firing' | 'Error' | 'Config error' | 'Disabled';
|
||||
comment?: string;
|
||||
actionStatuses?: Array<{
|
||||
id: string;
|
||||
state: 'OK' | 'Firing' | 'Error' | 'Acked' | 'Throttled' | 'Config error';
|
||||
}>;
|
||||
};
|
||||
details?: object;
|
||||
}
|
||||
|
||||
export const getWatchHistory = ({
|
||||
startTime = '2019-06-03T19:44:11.088Z',
|
||||
id = getRandomString(),
|
||||
watchId = getRandomString(),
|
||||
watchStatus = {
|
||||
state: 'OK',
|
||||
},
|
||||
details = {},
|
||||
}: Partial<WatchHistory> = {}): WatchHistory => ({
|
||||
startTime,
|
||||
id,
|
||||
watchId,
|
||||
watchStatus,
|
||||
details,
|
||||
});
|
|
@ -86,17 +86,17 @@ describe('<WatchListPage />', () => {
|
|||
// Expect "watch1" is only visible in the table
|
||||
expect(tableCellsValues.length).toEqual(1);
|
||||
const row = tableCellsValues[0];
|
||||
const { name, id, watchStatus } = watch1;
|
||||
const { name, id } = watch1;
|
||||
|
||||
const expectedRow = [
|
||||
'', // checkbox
|
||||
id,
|
||||
name,
|
||||
watchStatus.state,
|
||||
'', // comment
|
||||
'', // state
|
||||
'', // lastMetCondition
|
||||
'', // lastChecked
|
||||
'', // actions
|
||||
'', // comment
|
||||
'', // row actions
|
||||
];
|
||||
|
||||
expect(row).toEqual(expectedRow);
|
||||
|
@ -128,7 +128,7 @@ describe('<WatchListPage />', () => {
|
|||
const { table } = testBed;
|
||||
const { tableCellsValues } = table.getMetaData('watchesTable');
|
||||
|
||||
const getExpectedValue = (value: any) => (typeof value === 'undefined' ? '' : value);
|
||||
const getExpectedValue = (value: any) => value ?? '';
|
||||
|
||||
tableCellsValues.forEach((row, i) => {
|
||||
const watch = watches[i];
|
||||
|
@ -138,11 +138,11 @@ describe('<WatchListPage />', () => {
|
|||
'',
|
||||
id, // required value
|
||||
getExpectedValue(name),
|
||||
watchStatus.state, // required value
|
||||
getExpectedValue(watchStatus.comment),
|
||||
'', // state
|
||||
getExpectedValue(watchStatus.lastMetCondition),
|
||||
getExpectedValue(watchStatus.lastChecked),
|
||||
'',
|
||||
getExpectedValue(watchStatus.comment),
|
||||
'', // row actions
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,8 +16,8 @@ import { API_BASE_PATH } from '../../common/constants';
|
|||
|
||||
const { setup } = pageHelpers.watchStatusPage;
|
||||
|
||||
const watchHistory1 = getWatchHistory({ startTime: '2019-06-04T01:11:11.294' });
|
||||
const watchHistory2 = getWatchHistory({ startTime: '2019-06-04T01:10:10.987Z' });
|
||||
const watchHistory1 = getWatchHistory({ id: 'a', startTime: '2019-06-04T01:11:11.294' });
|
||||
const watchHistory2 = getWatchHistory({ id: 'b', startTime: '2019-06-04T01:10:10.987Z' });
|
||||
|
||||
const watchHistoryItems = { watchHistoryItems: [watchHistory1, watchHistory2] };
|
||||
|
||||
|
@ -26,13 +26,15 @@ const ACTION_ID = 'my_logging_action_1';
|
|||
const watch = {
|
||||
...WATCH.watch,
|
||||
watchStatus: {
|
||||
state: WATCH_STATES.FIRING,
|
||||
state: WATCH_STATES.ACTIVE,
|
||||
isActive: true,
|
||||
lastExecution: moment('2019-06-03T19:44:11.088Z'),
|
||||
actionStatuses: [
|
||||
{
|
||||
id: ACTION_ID,
|
||||
state: ACTION_STATES.FIRING,
|
||||
state: ACTION_STATES.OK,
|
||||
isAckable: true,
|
||||
lastExecution: moment('2019-06-03T19:44:11.088Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -100,7 +102,8 @@ describe('<WatchStatusPage />', () => {
|
|||
expect(row).toEqual([
|
||||
getExpectedValue(moment(startTime).format()),
|
||||
getExpectedValue(watchStatus.state),
|
||||
getExpectedValue(watchStatus.comment),
|
||||
'',
|
||||
'',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -112,11 +115,11 @@ describe('<WatchStatusPage />', () => {
|
|||
...watchHistory1,
|
||||
watchId: watch.id,
|
||||
watchStatus: {
|
||||
state: WATCH_STATES.FIRING,
|
||||
state: WATCH_STATES.ACTIVE,
|
||||
actionStatuses: [
|
||||
{
|
||||
id: 'my_logging_action_1',
|
||||
state: ACTION_STATES.FIRING,
|
||||
state: ACTION_STATES.OK,
|
||||
isAckable: true,
|
||||
},
|
||||
],
|
||||
|
@ -204,7 +207,7 @@ describe('<WatchStatusPage />', () => {
|
|||
|
||||
httpRequestsMockHelpers.setActivateWatchResponse(WATCH_ID, {
|
||||
watchStatus: {
|
||||
state: WATCH_STATES.FIRING,
|
||||
state: WATCH_STATES.ACTIVE,
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
@ -231,18 +234,22 @@ describe('<WatchStatusPage />', () => {
|
|||
|
||||
tableCellsValues.forEach((row, i) => {
|
||||
const action = watch.watchStatus.actionStatuses[i];
|
||||
const { id, state, isAckable } = action;
|
||||
const { id, state, lastExecution, isAckable } = action;
|
||||
|
||||
expect(row).toEqual([id, state, isAckable ? 'Acknowledge' : '']);
|
||||
expect(row).toEqual([
|
||||
id, // Name
|
||||
state, // State
|
||||
lastExecution.format(), // Last executed
|
||||
isAckable ? 'Acknowledge' : '', // Row actions
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('should allow an action to be acknowledged', async () => {
|
||||
const { actions, table } = testBed;
|
||||
|
||||
httpRequestsMockHelpers.setAcknowledgeWatchResponse(WATCH_ID, ACTION_ID, {
|
||||
const watchHistoryItem = {
|
||||
watchStatus: {
|
||||
state: WATCH_STATES.FIRING,
|
||||
state: WATCH_STATES.ACTIVE,
|
||||
isActive: true,
|
||||
comment: 'Acked',
|
||||
actionStatuses: [
|
||||
|
@ -250,10 +257,13 @@ describe('<WatchStatusPage />', () => {
|
|||
id: ACTION_ID,
|
||||
state: ACTION_STATES.ACKNOWLEDGED,
|
||||
isAckable: false,
|
||||
lastExecution: moment('2019-06-03T19:44:11.088Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
httpRequestsMockHelpers.setAcknowledgeWatchResponse(WATCH_ID, ACTION_ID, watchHistoryItem);
|
||||
|
||||
await actions.clickAcknowledgeButton(0);
|
||||
|
||||
|
@ -268,7 +278,12 @@ describe('<WatchStatusPage />', () => {
|
|||
const { tableCellsValues } = table.getMetaData('watchActionStatusTable');
|
||||
|
||||
tableCellsValues.forEach((row) => {
|
||||
expect(row).toEqual([ACTION_ID, ACTION_STATES.ACKNOWLEDGED, '']);
|
||||
expect(row).toEqual([
|
||||
ACTION_ID, // Name
|
||||
ACTION_STATES.ACKNOWLEDGED, // State
|
||||
watchHistoryItem.watchStatus.actionStatuses[0].lastExecution.format(), // Last executed
|
||||
'', // Row actions
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ export const ACTION_STATES: { [key: string]: string } = {
|
|||
|
||||
// Action has been acknowledged by user
|
||||
ACKNOWLEDGED: i18n.translate('xpack.watcher.constants.actionStates.acknowledgedStateText', {
|
||||
defaultMessage: 'Acked',
|
||||
defaultMessage: 'Acknowledged',
|
||||
}),
|
||||
|
||||
// Action has been throttled (time-based) by the system
|
||||
|
@ -23,11 +23,6 @@ export const ACTION_STATES: { [key: string]: string } = {
|
|||
defaultMessage: 'Throttled',
|
||||
}),
|
||||
|
||||
// Action has been completed
|
||||
FIRING: i18n.translate('xpack.watcher.constants.actionStates.firingStateText', {
|
||||
defaultMessage: 'Firing',
|
||||
}),
|
||||
|
||||
// Action has failed
|
||||
ERROR: i18n.translate('xpack.watcher.constants.actionStates.errorStateText', {
|
||||
defaultMessage: 'Error',
|
||||
|
|
|
@ -27,14 +27,14 @@ export const WATCH_STATE_COMMENTS: { [key: string]: string } = {
|
|||
PARTIALLY_ACKNOWLEDGED: i18n.translate(
|
||||
'xpack.watcher.constants.watchStateComments.partiallyAcknowledgedStateCommentText',
|
||||
{
|
||||
defaultMessage: 'Partially acked',
|
||||
defaultMessage: 'Partially acknowledged',
|
||||
}
|
||||
),
|
||||
|
||||
ACKNOWLEDGED: i18n.translate(
|
||||
'xpack.watcher.constants.watchStateComments.acknowledgedStateCommentText',
|
||||
{
|
||||
defaultMessage: 'Acked',
|
||||
defaultMessage: 'Acknowledged',
|
||||
}
|
||||
),
|
||||
|
||||
|
|
|
@ -8,16 +8,12 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const WATCH_STATES: { [key: string]: string } = {
|
||||
DISABLED: i18n.translate('xpack.watcher.constants.watchStates.disabledStateText', {
|
||||
defaultMessage: 'Disabled',
|
||||
INACTIVE: i18n.translate('xpack.watcher.constants.watchStates.inactiveStateText', {
|
||||
defaultMessage: 'Inactive',
|
||||
}),
|
||||
|
||||
OK: i18n.translate('xpack.watcher.constants.watchStates.okStateText', {
|
||||
defaultMessage: 'OK',
|
||||
}),
|
||||
|
||||
FIRING: i18n.translate('xpack.watcher.constants.watchStates.firingStateText', {
|
||||
defaultMessage: 'Firing',
|
||||
ACTIVE: i18n.translate('xpack.watcher.constants.watchStates.activeStateText', {
|
||||
defaultMessage: 'Active',
|
||||
}),
|
||||
|
||||
ERROR: i18n.translate('xpack.watcher.constants.watchStates.errorStateText', {
|
||||
|
|
|
@ -79,6 +79,6 @@ export interface ClientWatchStatusModel {
|
|||
lastMetCondition: Moment | null;
|
||||
state: keyof typeof WATCH_STATES;
|
||||
comment: keyof typeof WATCH_STATE_COMMENTS;
|
||||
lastFired?: Moment | null;
|
||||
lastExecution?: Moment | null;
|
||||
actionStatuses: ClientActionStatusModel[];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiIcon, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
import type { EuiTextProps } from '@elastic/eui';
|
||||
import { ACTION_STATES } from '../../../common/constants';
|
||||
|
||||
interface Props {
|
||||
state: string;
|
||||
size?: EuiTextProps['size'];
|
||||
}
|
||||
|
||||
const stateToColorMap = {
|
||||
[ACTION_STATES.OK]: 'success',
|
||||
[ACTION_STATES.ACKNOWLEDGED]: 'success',
|
||||
[ACTION_STATES.THROTTLED]: 'warning',
|
||||
[ACTION_STATES.UNKNOWN]: 'subdued',
|
||||
[ACTION_STATES.CONFIG_ERROR]: 'danger',
|
||||
[ACTION_STATES.ERROR]: 'danger',
|
||||
};
|
||||
|
||||
export const ActionStateBadge = ({ state, size = 's' }: Props) => {
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="xs" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="dot" color={stateToColorMap[state]} />
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size={size}>{state}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
|
@ -9,7 +9,8 @@ export { getPageErrorCode, PageError } from './page_error';
|
|||
export { ConfirmWatchesModal } from './confirm_watches_modal';
|
||||
export { DeleteWatchesModal } from './delete_watches_modal';
|
||||
export { ErrableFormRow } from './form_errors';
|
||||
export { WatchStatus } from './watch_status';
|
||||
export { WatchStateBadge } from './watch_state_badge';
|
||||
export { ActionStateBadge } from './action_state_badge';
|
||||
export { SectionLoading } from './section_loading';
|
||||
export type { Error } from './section_error';
|
||||
export { SectionError } from './section_error';
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiIcon, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
import type { EuiTextProps } from '@elastic/eui';
|
||||
import { WATCH_STATES } from '../../../common/constants';
|
||||
|
||||
interface Props {
|
||||
state: string;
|
||||
size?: EuiTextProps['size'];
|
||||
}
|
||||
|
||||
const stateToColorMap = {
|
||||
[WATCH_STATES.ACTIVE]: 'success',
|
||||
[WATCH_STATES.INACTIVE]: 'subdued',
|
||||
[WATCH_STATES.CONFIG_ERROR]: 'subdued',
|
||||
[WATCH_STATES.ERROR]: 'subdued',
|
||||
};
|
||||
|
||||
export const WatchStateBadge = ({ state, size = 's' }: Props) => {
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="xs" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="dot" color={stateToColorMap[state]} />
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size={size}>{state}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
|
@ -1,47 +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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiIcon, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
import { ACTION_STATES, WATCH_STATES } from '../../../common/constants';
|
||||
|
||||
function StatusIcon({ status }: { status: string }) {
|
||||
switch (status) {
|
||||
case WATCH_STATES.FIRING:
|
||||
case ACTION_STATES.FIRING:
|
||||
return <EuiIcon type="play" color="primary" />;
|
||||
case WATCH_STATES.OK:
|
||||
case ACTION_STATES.OK:
|
||||
case ACTION_STATES.ACKNOWLEDGED:
|
||||
return <EuiIcon type="check" color="success" />;
|
||||
case ACTION_STATES.THROTTLED:
|
||||
return <EuiIcon type="clock" color="warning" />;
|
||||
case WATCH_STATES.DISABLED:
|
||||
return <EuiIcon type="minusInCircleFilled" color="subdued" />;
|
||||
case WATCH_STATES.CONFIG_ERROR:
|
||||
case WATCH_STATES.ERROR:
|
||||
case ACTION_STATES.UNKNOWN:
|
||||
return <EuiIcon type="cross" color="subdued" />;
|
||||
case ACTION_STATES.CONFIG_ERROR:
|
||||
case ACTION_STATES.ERROR:
|
||||
return <EuiIcon type="crossInACircleFilled" color="danger" />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function WatchStatus({ status, size = 's' }: { status: string; size?: 'xs' | 's' | 'm' }) {
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="xs" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<StatusIcon status={status} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size={size}>{status}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
|
@ -15,18 +15,10 @@ export class WatchStatus {
|
|||
this.state = get(props, 'state');
|
||||
this.comment = get(props, 'comment');
|
||||
this.isActive = get(props, 'isActive');
|
||||
this.lastFired = getMoment(get(props, 'lastFired'));
|
||||
this.lastExecution = getMoment(get(props, 'lastExecution'));
|
||||
this.lastChecked = getMoment(get(props, 'lastChecked'));
|
||||
this.lastMetCondition = getMoment(get(props, 'lastMetCondition'));
|
||||
|
||||
if (this.lastFired) {
|
||||
this.lastFiredHumanized = this.lastFired.fromNow();
|
||||
}
|
||||
|
||||
if (this.lastChecked) {
|
||||
this.lastCheckedHumanized = this.lastChecked.fromNow();
|
||||
}
|
||||
|
||||
const actionStatuses = get(props, 'actionStatuses', []);
|
||||
this.actionStatuses = actionStatuses.map((actionStatus) =>
|
||||
ActionStatus.fromUpstreamJson(actionStatus)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { Fragment, useContext, useState } from 'react';
|
||||
import React, { Fragment, useContext, useEffect, useState } from 'react';
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
|
@ -67,9 +67,11 @@ export const JsonWatchEditForm = () => {
|
|||
json: hasActionErrors ? [...errors.json, invalidActionMessage] : [...errors.json],
|
||||
};
|
||||
|
||||
if (errors.json.length === 0) {
|
||||
setWatchProperty('watch', JSON.parse(watch.watchString));
|
||||
}
|
||||
useEffect(() => {
|
||||
if (errors.json.length === 0) {
|
||||
setWatchProperty('watch', JSON.parse(watch.watchString));
|
||||
}
|
||||
}, [setWatchProperty, errors, watch]);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
|
||||
import React, { Fragment, useContext } from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import {
|
||||
EuiBasicTable,
|
||||
EuiCodeBlock,
|
||||
|
@ -17,15 +18,14 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
import {
|
||||
ExecutedWatchDetails,
|
||||
ExecutedWatchResults,
|
||||
} from '../../../../../../common/types/watch_types';
|
||||
import { ActionStateBadge, WatchStateBadge, SectionError } from '../../../../components';
|
||||
import { getTypeFromAction } from '../../watch_edit_actions';
|
||||
import { WatchContext } from '../../watch_context';
|
||||
import { WatchStatus, SectionError } from '../../../../components';
|
||||
|
||||
export const SimulateWatchResultsFlyout = ({
|
||||
executeResults,
|
||||
|
@ -104,7 +104,7 @@ export const SimulateWatchResultsFlyout = ({
|
|||
),
|
||||
dataType: 'string' as const,
|
||||
render: (actionState: string, _item: typeof actionsTableData[number]) => (
|
||||
<WatchStatus status={actionState} />
|
||||
<ActionStateBadge state={actionState} />
|
||||
),
|
||||
},
|
||||
{
|
||||
|
@ -171,9 +171,10 @@ export const SimulateWatchResultsFlyout = ({
|
|||
>
|
||||
<EuiFlyoutHeader hasBorder>
|
||||
{flyoutTitle}
|
||||
<EuiSpacer size="xs" />
|
||||
<WatchStatus status={state} size="m" />
|
||||
<EuiSpacer size="s" />
|
||||
<WatchStateBadge state={state} size="m" />
|
||||
</EuiFlyoutHeader>
|
||||
|
||||
<EuiFlyoutBody>
|
||||
{actionsTableData && actionsTableData.length > 0 && (
|
||||
<Fragment>
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
EuiInMemoryTable,
|
||||
EuiIcon,
|
||||
EuiLink,
|
||||
EuiPageContent,
|
||||
EuiSpacer,
|
||||
|
@ -36,7 +37,7 @@ import {
|
|||
getPageErrorCode,
|
||||
PageError,
|
||||
DeleteWatchesModal,
|
||||
WatchStatus,
|
||||
WatchStateBadge,
|
||||
SectionLoading,
|
||||
Error,
|
||||
} from '../../components';
|
||||
|
@ -275,42 +276,99 @@ export const WatchListPage = () => {
|
|||
},
|
||||
{
|
||||
field: 'watchStatus.state',
|
||||
name: i18n.translate('xpack.watcher.sections.watchList.watchTable.stateHeader', {
|
||||
defaultMessage: 'State',
|
||||
}),
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchList.watchTable.stateHeader.tooltipText',
|
||||
{
|
||||
defaultMessage: 'Active, inactive, or error.',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate('xpack.watcher.sections.watchList.watchTable.stateHeader', {
|
||||
defaultMessage: 'State',
|
||||
})}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
width: '130px',
|
||||
render: (state: string) => <WatchStatus status={state} />,
|
||||
render: (state: string) => <WatchStateBadge state={state} />,
|
||||
},
|
||||
{
|
||||
field: 'watchStatus.lastMetCondition',
|
||||
name: i18n.translate('xpack.watcher.sections.watchList.watchTable.lastFiredHeader', {
|
||||
defaultMessage: 'Last fired',
|
||||
}),
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchList.watchTable.lastFiredHeader.tooltipText',
|
||||
{
|
||||
defaultMessage: `The last time the condition was met and action taken.`,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate('xpack.watcher.sections.watchList.watchTable.lastFiredHeader', {
|
||||
defaultMessage: 'Condition last met',
|
||||
})}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
width: '130px',
|
||||
width: '160px',
|
||||
render: (lastMetCondition: Moment) => {
|
||||
return lastMetCondition ? lastMetCondition.fromNow() : lastMetCondition;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'watchStatus.lastChecked',
|
||||
name: i18n.translate('xpack.watcher.sections.watchList.watchTable.lastTriggeredHeader', {
|
||||
defaultMessage: 'Last triggered',
|
||||
}),
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchList.watchTable.lastTriggeredHeader.tooltipText',
|
||||
{
|
||||
defaultMessage: `The last time the condition was checked.`,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate('xpack.watcher.sections.watchList.watchTable.lastTriggeredHeader', {
|
||||
defaultMessage: 'Last checked',
|
||||
})}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
width: '130px',
|
||||
width: '160px',
|
||||
render: (lastChecked: Moment) => {
|
||||
return lastChecked ? lastChecked.fromNow() : lastChecked;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'watchStatus.comment',
|
||||
name: i18n.translate('xpack.watcher.sections.watchList.watchTable.commentHeader', {
|
||||
defaultMessage: 'Comment',
|
||||
}),
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchList.watchTable.commentHeader.tooltipText',
|
||||
{
|
||||
defaultMessage:
|
||||
'Whether any actions have been acknowledged, throttled, or failed to execute.',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate('xpack.watcher.sections.watchList.watchTable.commentHeader', {
|
||||
defaultMessage: 'Comment',
|
||||
})}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
},
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import React, { Fragment, useState, useEffect, useContext } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { Moment } from 'moment';
|
||||
|
||||
import {
|
||||
EuiInMemoryTable,
|
||||
|
@ -18,12 +19,14 @@ import {
|
|||
EuiFlyout,
|
||||
EuiFlyoutHeader,
|
||||
EuiFlyoutBody,
|
||||
EuiIcon,
|
||||
} from '@elastic/eui';
|
||||
import { ackWatchAction } from '../../../lib/api';
|
||||
import { WatchStatus } from '../../../components';
|
||||
|
||||
import { PAGINATION } from '../../../../../common/constants';
|
||||
import { WatchDetailsContext } from '../watch_details_context';
|
||||
import { ackWatchAction } from '../../../lib/api';
|
||||
import { ActionStateBadge } from '../../../components';
|
||||
import { useAppContext } from '../../../app_context';
|
||||
import { WatchDetailsContext } from '../watch_details_context';
|
||||
|
||||
interface ActionError {
|
||||
code: string;
|
||||
|
@ -71,16 +74,56 @@ export const ActionStatusesPanel = () => {
|
|||
defaultMessage: 'Name',
|
||||
}),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
truncateText: false,
|
||||
},
|
||||
{
|
||||
field: 'state',
|
||||
name: i18n.translate('xpack.watcher.sections.watchDetail.watchTable.stateHeader', {
|
||||
defaultMessage: 'State',
|
||||
}),
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchDetail.watchTable.stateHeader.tooltipText',
|
||||
{
|
||||
defaultMessage: 'OK, acknowledged, throttled, or error.',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate('xpack.watcher.sections.watchDetail.watchTable.stateHeader', {
|
||||
defaultMessage: 'State',
|
||||
})}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
render: (state: string) => <WatchStatus status={state} />,
|
||||
render: (state: string) => <ActionStateBadge state={state} />,
|
||||
},
|
||||
{
|
||||
field: 'lastExecution',
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchHistory.watchActionStatusTable.lastExecuted.tooltipText',
|
||||
{
|
||||
defaultMessage: `The last time this action was executed.`,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate(
|
||||
'xpack.watcher.sections.watchHistory.watchActionStatusTable.lastExecuted',
|
||||
{
|
||||
defaultMessage: 'Last executed',
|
||||
}
|
||||
)}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: false,
|
||||
render: (lastExecution?: Moment) => lastExecution?.format() ?? '',
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ import { Moment } from 'moment';
|
|||
import {
|
||||
EuiCodeBlock,
|
||||
EuiFlexGroup,
|
||||
EuiToolTip,
|
||||
EuiIcon,
|
||||
EuiFlexItem,
|
||||
EuiFlyout,
|
||||
EuiFlyoutBody,
|
||||
|
@ -25,7 +27,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
|
||||
import { PAGINATION } from '../../../../../common/constants';
|
||||
import { WatchStatus, SectionError, Error } from '../../../components';
|
||||
import { ActionStateBadge, WatchStateBadge, SectionError, Error } from '../../../components';
|
||||
import { useLoadWatchHistory, useLoadWatchHistoryDetail } from '../../../lib/api';
|
||||
import { WatchDetailsContext } from '../watch_details_context';
|
||||
|
||||
|
@ -120,7 +122,8 @@ export const ExecutionHistoryPanel = () => {
|
|||
defaultMessage: 'Trigger time',
|
||||
}),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
truncateText: false,
|
||||
// TODO: Once we convert the client-side models to TS, this should be a WatchHistoryItemModel.
|
||||
render: (startTime: Moment, item: any) => {
|
||||
const formattedDate = startTime.format();
|
||||
return (
|
||||
|
@ -135,18 +138,79 @@ export const ExecutionHistoryPanel = () => {
|
|||
},
|
||||
{
|
||||
field: 'watchStatus.state',
|
||||
name: i18n.translate('xpack.watcher.sections.watchHistory.watchTable.stateHeader', {
|
||||
defaultMessage: 'State',
|
||||
}),
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchHistory.watchTable.stateHeader.tooltipText',
|
||||
{
|
||||
defaultMessage: 'Active or error state.',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate('xpack.watcher.sections.watchHistory.watchTable.stateHeader', {
|
||||
defaultMessage: 'State',
|
||||
})}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
render: (state: string) => <WatchStatus status={state} />,
|
||||
render: (state: string) => <WatchStateBadge state={state} />,
|
||||
},
|
||||
{
|
||||
field: 'startTime',
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchHistory.watchTable.metConditionHeader.tooltipText',
|
||||
{
|
||||
defaultMessage: 'Whether the condition was met and action taken.',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate('xpack.watcher.sections.watchHistory.watchTable.metConditionHeader', {
|
||||
defaultMessage: 'Condition met',
|
||||
})}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
// TODO: Once we convert the client-side models to TS, this should be a WatchHistoryItemModel.
|
||||
render: (startTime: Moment, item: any) => {
|
||||
const {
|
||||
watchStatus: { lastExecution },
|
||||
} = item;
|
||||
|
||||
if (startTime.isSame(lastExecution)) {
|
||||
return <EuiIcon color="green" type="check" />;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'watchStatus.comment',
|
||||
name: i18n.translate('xpack.watcher.sections.watchHistory.watchTable.commentHeader', {
|
||||
defaultMessage: 'Comment',
|
||||
}),
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchHistory.watchTable.commentHeader.tooltipText',
|
||||
{
|
||||
defaultMessage:
|
||||
'Whether the action was throttled, acknowledged, or failed to execute.',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate('xpack.watcher.sections.watchHistory.watchTable.commentHeader', {
|
||||
defaultMessage: 'Comment',
|
||||
})}{' '}
|
||||
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
},
|
||||
|
@ -202,16 +266,38 @@ export const ExecutionHistoryPanel = () => {
|
|||
defaultMessage: 'Name',
|
||||
}),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
truncateText: false,
|
||||
},
|
||||
{
|
||||
field: 'state',
|
||||
name: i18n.translate('xpack.watcher.sections.watchHistory.watchActionStatusTable.state', {
|
||||
defaultMessage: 'State',
|
||||
}),
|
||||
name: (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.watcher.sections.watchHistory.watchActionStatusTable.state.tooltipText',
|
||||
{
|
||||
defaultMessage: 'OK, acknowledged, throttled, or error.',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
{i18n.translate(
|
||||
'xpack.watcher.sections.watchHistory.watchActionStatusTable.state',
|
||||
{
|
||||
defaultMessage: 'State',
|
||||
}
|
||||
)}{' '}
|
||||
<EuiIcon
|
||||
size="s"
|
||||
color="subdued"
|
||||
type="questionInCircle"
|
||||
className="eui-alignTop"
|
||||
/>
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
render: (state: string) => <WatchStatus status={state} />,
|
||||
render: (state: string) => <ActionStateBadge state={state} />,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -117,25 +117,6 @@ describe('ActionStatusModel states', () => {
|
|||
});
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.ERROR);
|
||||
});
|
||||
|
||||
it(`isn't ackable`, () => {
|
||||
const clientActionStatusModel = createModelWithActions({
|
||||
ack: {
|
||||
state: 'ackable',
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-02T00:00:00.000Z',
|
||||
},
|
||||
last_throttle: {},
|
||||
});
|
||||
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.ERROR);
|
||||
expect(clientActionStatusModel.isAckable).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`ACTION_STATES.OK`, () => {
|
||||
|
@ -148,13 +129,36 @@ describe('ActionStatusModel states', () => {
|
|||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.OK);
|
||||
});
|
||||
|
||||
it(`isn't ackable`, () => {
|
||||
it(`is set when lastSuccessfulExecution is equal to lastExecution`, () => {
|
||||
const clientActionStatusModel = createModelWithActions({
|
||||
ack: { state: 'awaits_successful_execution' },
|
||||
ack: {
|
||||
state: 'ackable',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_throttle: {},
|
||||
});
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.OK);
|
||||
});
|
||||
|
||||
it(`is set when lastSuccessfulExecution is greater than lastExecution`, () => {
|
||||
const clientActionStatusModel = createModelWithActions({
|
||||
ack: {
|
||||
state: 'ackable',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-02T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_throttle: {},
|
||||
});
|
||||
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.OK);
|
||||
expect(clientActionStatusModel.isAckable).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -184,21 +188,6 @@ describe('ActionStatusModel states', () => {
|
|||
});
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.ACKNOWLEDGED);
|
||||
});
|
||||
|
||||
it(`isn't ackable`, () => {
|
||||
const clientActionStatusModel = createModelWithActions({
|
||||
ack: {
|
||||
state: 'acked',
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
});
|
||||
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.ACKNOWLEDGED);
|
||||
expect(clientActionStatusModel.isAckable).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`ACTION_STATES.THROTTLED`, () => {
|
||||
|
@ -231,75 +220,6 @@ describe('ActionStatusModel states', () => {
|
|||
});
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.THROTTLED);
|
||||
});
|
||||
|
||||
it(`is ackable`, () => {
|
||||
const clientActionStatusModel = createModelWithActions({
|
||||
ack: {
|
||||
state: 'ackable',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
});
|
||||
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.THROTTLED);
|
||||
expect(clientActionStatusModel.isAckable).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`ACTION_STATES.FIRING`, () => {
|
||||
it(`is set when lastSuccessfulExecution is equal to lastExecution`, () => {
|
||||
const clientActionStatusModel = createModelWithActions({
|
||||
ack: {
|
||||
state: 'ackable',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_throttle: {},
|
||||
});
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.FIRING);
|
||||
});
|
||||
|
||||
it(`is set when lastSuccessfulExecution is greater than lastExecution`, () => {
|
||||
const clientActionStatusModel = createModelWithActions({
|
||||
ack: {
|
||||
state: 'ackable',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-02T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_throttle: {},
|
||||
});
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.FIRING);
|
||||
});
|
||||
|
||||
it(`is ackable`, () => {
|
||||
const clientActionStatusModel = createModelWithActions({
|
||||
ack: {
|
||||
state: 'ackable',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_throttle: {},
|
||||
});
|
||||
|
||||
expect(clientActionStatusModel.state).toBe(ACTION_STATES.FIRING);
|
||||
expect(clientActionStatusModel.isAckable).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`ACTION_STATES.UNKNOWN`, () => {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
|
||||
import { ActionStatusModelEs, ServerActionStatusModel } from '../../../common/types';
|
||||
import { getMoment } from '../../../common/lib/get_moment';
|
||||
import { deriveState, deriveIsAckable } from './action_status_model_utils';
|
||||
import { deriveState } from './action_status_model_utils';
|
||||
|
||||
export const buildServerActionStatusModel = (
|
||||
actionStatusModelEs: ActionStatusModelEs
|
||||
|
@ -62,7 +62,7 @@ export const buildClientActionStatusModel = (serverActionStatusModel: ServerActi
|
|||
lastSuccessfulExecution,
|
||||
} = serverActionStatusModel;
|
||||
const state = deriveState(serverActionStatusModel);
|
||||
const isAckable = deriveIsAckable(state);
|
||||
const isAckable = serverActionStatusModel.actionStatusJson.ack.state === 'ackable';
|
||||
|
||||
return {
|
||||
id,
|
||||
|
|
|
@ -58,7 +58,7 @@ export const deriveState = (serverActionStatusModel: ServerActionStatusModel) =>
|
|||
if (lastSuccessfulExecution) {
|
||||
// Might be null
|
||||
if (ackState === 'ackable' && lastSuccessfulExecution >= lastExecution) {
|
||||
return ACTION_STATES.FIRING;
|
||||
return ACTION_STATES.OK;
|
||||
}
|
||||
|
||||
if (ackState === 'ackable' && lastSuccessfulExecution < lastExecution) {
|
||||
|
@ -72,11 +72,3 @@ export const deriveState = (serverActionStatusModel: ServerActionStatusModel) =>
|
|||
// missing an action status and the logic to determine it.
|
||||
return ACTION_STATES.UNKNOWN;
|
||||
};
|
||||
|
||||
export const deriveIsAckable = (state: keyof typeof ACTION_STATES) => {
|
||||
if (state === ACTION_STATES.THROTTLED || state === ACTION_STATES.FIRING) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
|
|
@ -98,7 +98,7 @@ describe('watch_history_item', () => {
|
|||
lastChecked: null,
|
||||
lastMetCondition: null,
|
||||
lastFired: undefined,
|
||||
state: 'OK',
|
||||
state: 'Active',
|
||||
},
|
||||
};
|
||||
expect(watchHistoryItem.downstreamJson).toEqual(expected);
|
||||
|
|
|
@ -135,7 +135,7 @@ describe('WatchStatusModel', () => {
|
|||
expect(serverWatchStatusModel.isActive).toBe(clientWatchStatusModel.isActive);
|
||||
expect(serverWatchStatusModel.lastChecked).toBe(clientWatchStatusModel.lastChecked);
|
||||
expect(serverWatchStatusModel.lastMetCondition).toBe(clientWatchStatusModel.lastMetCondition);
|
||||
expect(clientWatchStatusModel.state).toBe(WATCH_STATES.OK);
|
||||
expect(clientWatchStatusModel.state).toBe(WATCH_STATES.ACTIVE);
|
||||
expect(clientWatchStatusModel.comment).toBe(WATCH_STATE_COMMENTS.OK);
|
||||
expect(
|
||||
clientWatchStatusModel.actionStatuses && clientWatchStatusModel.actionStatuses.length
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
} from '../../../common/types';
|
||||
import { getMoment } from '../../../common/lib/get_moment';
|
||||
import { buildServerActionStatusModel, buildClientActionStatusModel } from '../action_status_model';
|
||||
import { deriveState, deriveComment, deriveLastFired } from './watch_status_model_utils';
|
||||
import { deriveState, deriveComment, deriveLastExecution } from './watch_status_model_utils';
|
||||
|
||||
export const buildServerWatchStatusModel = (
|
||||
watchStatusModelEs: WatchStatusModelEs
|
||||
|
@ -80,7 +80,7 @@ export const buildClientWatchStatusModel = (
|
|||
lastMetCondition,
|
||||
state: deriveState(isActive, watchState, clientActionStatuses),
|
||||
comment: deriveComment(isActive, clientActionStatuses),
|
||||
lastFired: deriveLastFired(clientActionStatuses),
|
||||
lastExecution: deriveLastExecution(clientActionStatuses),
|
||||
actionStatuses: clientActionStatuses,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,10 +9,10 @@ import moment from 'moment';
|
|||
|
||||
import { ACTION_STATES, WATCH_STATES, WATCH_STATE_COMMENTS } from '../../../common/constants';
|
||||
import { ClientActionStatusModel } from '../../../common/types';
|
||||
import { deriveState, deriveComment, deriveLastFired } from './watch_status_model_utils';
|
||||
import { deriveState, deriveComment, deriveLastExecution } from './watch_status_model_utils';
|
||||
|
||||
const mockActionStatus = (opts: Partial<ClientActionStatusModel>): ClientActionStatusModel => ({
|
||||
state: ACTION_STATES.OK,
|
||||
state: ACTION_STATES.ACTIVE,
|
||||
id: 'no-id',
|
||||
isAckable: false,
|
||||
lastAcknowledged: null,
|
||||
|
@ -25,13 +25,13 @@ const mockActionStatus = (opts: Partial<ClientActionStatusModel>): ClientActionS
|
|||
});
|
||||
|
||||
describe('WatchStatusModel utils', () => {
|
||||
describe('deriveLastFired', () => {
|
||||
describe('deriveLastExecution', () => {
|
||||
it(`is the latest lastExecution from the client action statuses`, () => {
|
||||
const actionStatuses = [
|
||||
mockActionStatus({ lastExecution: moment('2017-07-05T00:00:00.000Z') }),
|
||||
mockActionStatus({ lastExecution: moment('2015-05-26T18:21:08.630Z') }),
|
||||
];
|
||||
expect(deriveLastFired(actionStatuses)).toEqual(moment('2017-07-05T00:00:00.000Z'));
|
||||
expect(deriveLastExecution(actionStatuses)).toEqual(moment('2017-07-05T00:00:00.000Z'));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -45,8 +45,7 @@ describe('WatchStatusModel utils', () => {
|
|||
const isActive = true;
|
||||
const actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.THROTTLED }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
];
|
||||
expect(deriveComment(isActive, actionStatuses)).toBe(
|
||||
WATCH_STATE_COMMENTS.PARTIALLY_THROTTLED
|
||||
|
@ -67,9 +66,8 @@ describe('WatchStatusModel utils', () => {
|
|||
const isActive = true;
|
||||
const actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.ACKNOWLEDGED }),
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
mockActionStatus({ state: ACTION_STATES.THROTTLED }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
];
|
||||
expect(deriveComment(isActive, actionStatuses)).toBe(
|
||||
WATCH_STATE_COMMENTS.PARTIALLY_ACKNOWLEDGED
|
||||
|
@ -89,10 +87,9 @@ describe('WatchStatusModel utils', () => {
|
|||
it(`is FAILING when one action state is failing`, () => {
|
||||
const isActive = true;
|
||||
const actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACKNOWLEDGED }),
|
||||
mockActionStatus({ state: ACTION_STATES.THROTTLED }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
mockActionStatus({ state: ACTION_STATES.ERROR }),
|
||||
];
|
||||
expect(deriveComment(isActive, actionStatuses)).toBe(WATCH_STATE_COMMENTS.FAILING);
|
||||
|
@ -101,10 +98,9 @@ describe('WatchStatusModel utils', () => {
|
|||
it(`is OK when watch is inactive`, () => {
|
||||
const isActive = false;
|
||||
const actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACKNOWLEDGED }),
|
||||
mockActionStatus({ state: ACTION_STATES.THROTTLED }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
mockActionStatus({ state: ACTION_STATES.ERROR }),
|
||||
];
|
||||
expect(deriveComment(isActive, actionStatuses)).toBe(WATCH_STATE_COMMENTS.OK);
|
||||
|
@ -112,43 +108,37 @@ describe('WatchStatusModel utils', () => {
|
|||
});
|
||||
|
||||
describe('deriveState', () => {
|
||||
it(`is OK there are no actions`, () => {
|
||||
it(`is ACTIVE there are no actions`, () => {
|
||||
const isActive = true;
|
||||
const watchState = 'awaits_execution';
|
||||
expect(deriveState(isActive, watchState, [])).toBe(WATCH_STATES.OK);
|
||||
expect(deriveState(isActive, watchState, [])).toBe(WATCH_STATES.ACTIVE);
|
||||
});
|
||||
|
||||
it(`is FIRING when at least one action state is firing`, () => {
|
||||
it(`is ACTIVE when at least one action state is active`, () => {
|
||||
const isActive = true;
|
||||
const watchState = 'awaits_execution';
|
||||
let actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
];
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.FIRING);
|
||||
let actionStatuses = [mockActionStatus({ state: ACTION_STATES.ACTIVE })];
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.ACTIVE);
|
||||
|
||||
actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
mockActionStatus({ state: ACTION_STATES.THROTTLED }),
|
||||
];
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.FIRING);
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.ACTIVE);
|
||||
|
||||
actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
mockActionStatus({ state: ACTION_STATES.THROTTLED }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACKNOWLEDGED }),
|
||||
];
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.FIRING);
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.ACTIVE);
|
||||
});
|
||||
|
||||
it(`is ERROR when at least one action state is error`, () => {
|
||||
const isActive = true;
|
||||
const watchState = 'awaits_execution';
|
||||
const actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
mockActionStatus({ state: ACTION_STATES.THROTTLED }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACKNOWLEDGED }),
|
||||
mockActionStatus({ state: ACTION_STATES.ERROR }),
|
||||
|
@ -161,23 +151,22 @@ describe('WatchStatusModel utils', () => {
|
|||
const isActive = true;
|
||||
const watchState = 'awaits_execution';
|
||||
const actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
mockActionStatus({ state: ACTION_STATES.CONFIG_ERROR }),
|
||||
];
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.CONFIG_ERROR);
|
||||
});
|
||||
|
||||
it(`is DISABLED when watch is inactive`, () => {
|
||||
it(`is INACTIVE when watch is inactive`, () => {
|
||||
const isActive = false;
|
||||
const watchState = 'awaits_execution';
|
||||
const actionStatuses = [
|
||||
mockActionStatus({ state: ACTION_STATES.OK }),
|
||||
mockActionStatus({ state: ACTION_STATES.FIRING }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACTIVE }),
|
||||
mockActionStatus({ state: ACTION_STATES.THROTTLED }),
|
||||
mockActionStatus({ state: ACTION_STATES.ACKNOWLEDGED }),
|
||||
mockActionStatus({ state: ACTION_STATES.ERROR }),
|
||||
];
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.DISABLED);
|
||||
expect(deriveState(isActive, watchState, actionStatuses)).toBe(WATCH_STATES.INACTIVE);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,7 +28,7 @@ export const deriveActionStatusTotals = (
|
|||
return result;
|
||||
};
|
||||
|
||||
export const deriveLastFired = (actionStatuses: ClientWatchStatusModel['actionStatuses']) => {
|
||||
export const deriveLastExecution = (actionStatuses: ClientWatchStatusModel['actionStatuses']) => {
|
||||
const actionStatus = maxBy(actionStatuses, 'lastExecution');
|
||||
if (actionStatus) {
|
||||
return actionStatus.lastExecution;
|
||||
|
@ -41,7 +41,7 @@ export const deriveState = (
|
|||
actionStatuses: ClientWatchStatusModel['actionStatuses']
|
||||
) => {
|
||||
if (!isActive) {
|
||||
return WATCH_STATES.DISABLED;
|
||||
return WATCH_STATES.INACTIVE;
|
||||
}
|
||||
|
||||
if (watchState === 'failed') {
|
||||
|
@ -58,16 +58,7 @@ export const deriveState = (
|
|||
return WATCH_STATES.CONFIG_ERROR;
|
||||
}
|
||||
|
||||
const firingTotal =
|
||||
totals[ACTION_STATES.FIRING] +
|
||||
totals[ACTION_STATES.ACKNOWLEDGED] +
|
||||
totals[ACTION_STATES.THROTTLED];
|
||||
|
||||
if (firingTotal > 0) {
|
||||
return WATCH_STATES.FIRING;
|
||||
}
|
||||
|
||||
return WATCH_STATES.OK;
|
||||
return WATCH_STATES.ACTIVE;
|
||||
};
|
||||
|
||||
export const deriveComment = (
|
||||
|
@ -76,34 +67,33 @@ export const deriveComment = (
|
|||
) => {
|
||||
const totals = deriveActionStatusTotals(actionStatuses);
|
||||
const totalActions = actionStatuses ? actionStatuses.length : 0;
|
||||
let result = WATCH_STATE_COMMENTS.OK;
|
||||
|
||||
if (totals[ACTION_STATES.THROTTLED] > 0 && totals[ACTION_STATES.THROTTLED] < totalActions) {
|
||||
result = WATCH_STATE_COMMENTS.PARTIALLY_THROTTLED;
|
||||
if (!isActive) {
|
||||
return WATCH_STATE_COMMENTS.OK;
|
||||
}
|
||||
|
||||
if (totals[ACTION_STATES.THROTTLED] > 0 && totals[ACTION_STATES.THROTTLED] === totalActions) {
|
||||
result = WATCH_STATE_COMMENTS.THROTTLED;
|
||||
}
|
||||
|
||||
if (totals[ACTION_STATES.ACKNOWLEDGED] > 0 && totals[ACTION_STATES.ACKNOWLEDGED] < totalActions) {
|
||||
result = WATCH_STATE_COMMENTS.PARTIALLY_ACKNOWLEDGED;
|
||||
if (totals[ACTION_STATES.ERROR] > 0) {
|
||||
return WATCH_STATE_COMMENTS.FAILING;
|
||||
}
|
||||
|
||||
if (
|
||||
totals[ACTION_STATES.ACKNOWLEDGED] > 0 &&
|
||||
totals[ACTION_STATES.ACKNOWLEDGED] === totalActions
|
||||
) {
|
||||
result = WATCH_STATE_COMMENTS.ACKNOWLEDGED;
|
||||
return WATCH_STATE_COMMENTS.ACKNOWLEDGED;
|
||||
}
|
||||
|
||||
if (totals[ACTION_STATES.ERROR] > 0) {
|
||||
result = WATCH_STATE_COMMENTS.FAILING;
|
||||
if (totals[ACTION_STATES.ACKNOWLEDGED] > 0 && totals[ACTION_STATES.ACKNOWLEDGED] < totalActions) {
|
||||
return WATCH_STATE_COMMENTS.PARTIALLY_ACKNOWLEDGED;
|
||||
}
|
||||
|
||||
if (!isActive) {
|
||||
result = WATCH_STATE_COMMENTS.OK;
|
||||
if (totals[ACTION_STATES.THROTTLED] > 0 && totals[ACTION_STATES.THROTTLED] === totalActions) {
|
||||
return WATCH_STATE_COMMENTS.THROTTLED;
|
||||
}
|
||||
|
||||
return result;
|
||||
if (totals[ACTION_STATES.THROTTLED] > 0 && totals[ACTION_STATES.THROTTLED] < totalActions) {
|
||||
return WATCH_STATE_COMMENTS.PARTIALLY_THROTTLED;
|
||||
}
|
||||
|
||||
return WATCH_STATE_COMMENTS.OK;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue