Skip to content

Commit

Permalink
port advanced watcher to react (#34188)
Browse files Browse the repository at this point in the history
* port advanced watcher to react

* fix i18n

* update execute trigger override text fields to number input and select fields

* fix page title for edit mode

* remove todo comments

* add license validity check; pass kbnUrl service as prop

* address review comments
  • Loading branch information
alisonelizabeth committed Apr 4, 2019
1 parent c3700b3 commit 081bb7c
Show file tree
Hide file tree
Showing 24 changed files with 1,400 additions and 45 deletions.
1 change: 1 addition & 0 deletions x-pack/plugins/watcher/common/constants/index.ts
Expand Up @@ -23,3 +23,4 @@ export { WATCH_HISTORY } from './watch_history';
export { WATCH_STATES } from './watch_states';
export { WATCH_TYPES } from './watch_types';
export { ERROR_CODES } from './error_codes';
export { WATCH_TABS, WATCH_TAB_ID_EDIT, WATCH_TAB_ID_SIMULATE } from './watch_tabs';
1 change: 1 addition & 0 deletions x-pack/plugins/watcher/common/constants/time_units.ts
Expand Up @@ -5,6 +5,7 @@
*/

export const TIME_UNITS: { [key: string]: string } = {
MILLISECOND: 'ms',
SECOND: 's',
MINUTE: 'm',
HOUR: 'h',
Expand Down
30 changes: 30 additions & 0 deletions x-pack/plugins/watcher/common/constants/watch_tabs.ts
@@ -0,0 +1,30 @@
/*
* 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 { i18n } from '@kbn/i18n';

export const WATCH_TAB_ID_EDIT = 'watchEditTab';
export const WATCH_TAB_ID_SIMULATE = 'watchSimulateTab';

interface WatchTab {
id: string;
name: string;
}

export const WATCH_TABS: WatchTab[] = [
{
id: WATCH_TAB_ID_EDIT,
name: i18n.translate('xpack.watcher.sections.watchEdit.json.editTabLabel', {
defaultMessage: 'Edit',
}),
},
{
id: WATCH_TAB_ID_SIMULATE,
name: i18n.translate('xpack.watcher.sections.watchEdit.json.simulateTabLabel', {
defaultMessage: 'Simulate',
}),
},
];
Expand Up @@ -4,14 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { keys, values, intersection } from 'lodash';
import { intersection, keys, values } from 'lodash';
import { ACTION_TYPES } from '../../constants';

export function getActionType(action) {
const type = intersection(
keys(action),
values(ACTION_TYPES)
)[0] || ACTION_TYPES.UNKNOWN;
export function getActionType(action: { [key: string]: { [key: string]: any } }) {
const type = intersection(keys(action), values(ACTION_TYPES))[0] || ACTION_TYPES.UNKNOWN;

return type;
}
57 changes: 57 additions & 0 deletions x-pack/plugins/watcher/common/types/watch_types.ts
@@ -0,0 +1,57 @@
/*
* 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 interface ExecutedWatchResults {
id: string;
watchId: string;
details: any;
startTime: Date;
watchStatus: {
state: string;
actionStatuses: Array<{ state: string; lastExecutionReason: string }>;
};
}

export interface ExecutedWatchDetails {
triggerData: {
triggeredTime: Date;
scheduledTime: Date;
};
ignoreCondition: boolean;
alternativeInput: any;
actionModes: {
[key: string]: string;
};
recordExecution: boolean;
upstreamJson: any;
}

export interface BaseWatch {
id: string;
type: string;
isNew: boolean;
name: string;
isSystemWatch: boolean;
watchStatus: any;
watchErrors: any;
typeName: string;
displayName: string;
upstreamJson: any;
resetActions: () => void;
createAction: (type: string, actionProps: {}) => void;
validate: () => { warning: { message: string } };
actions: [
{
id: string;
type: string;
}
];
watch: {
actions: {
[key: string]: { [key: string]: any };
};
};
}
44 changes: 44 additions & 0 deletions x-pack/plugins/watcher/public/components/confirm_watches_modal.tsx
@@ -0,0 +1,44 @@
/*
* 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 { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';

export const ConfirmWatchesModal = ({
modalOptions,
callback,
}: {
modalOptions: { message: string } | null;
callback: (isConfirmed?: boolean) => void;
}) => {
if (!modalOptions) {
return null;
}
return (
<EuiOverlayMask>
<EuiConfirmModal
buttonColor="danger"
title={i18n.translate('xpack.watcher.sections.watchEdit.json.saveConfirmModal.title', {
defaultMessage: 'Confirm save',
})}
onCancel={() => callback()}
onConfirm={() => {
callback(true);
}}
cancelButtonText={i18n.translate(
'xpack.watcher.sections.watchEdit.json.saveConfirmModal.cancelButtonLabel',
{ defaultMessage: 'Cancel' }
)}
confirmButtonText={i18n.translate(
'xpack.watcher.sections.watchEdit.json.saveConfirmModal.saveButtonLabel',
{ defaultMessage: 'Save' }
)}
>
{modalOptions.message}
</EuiConfirmModal>
</EuiOverlayMask>
);
};
13 changes: 13 additions & 0 deletions x-pack/plugins/watcher/public/lib/api.ts
Expand Up @@ -7,6 +7,8 @@ import { Watch } from 'plugins/watcher/models/watch';
import { __await } from 'tslib';
import chrome from 'ui/chrome';
import { ROUTES } from '../../common/constants';
import { BaseWatch, ExecutedWatchDetails } from '../../common/types/watch_types';

let httpClient: ng.IHttpService;
export const setHttpClient = (anHttpClient: ng.IHttpService) => {
httpClient = anHttpClient;
Expand Down Expand Up @@ -63,3 +65,14 @@ export const fetchFields = async (indexes: string[]) => {
} = await getHttpClient().post(`${basePath}/fields`, { indexes });
return fields;
};
export const createWatch = async (watch: BaseWatch) => {
const { data } = await getHttpClient().put(`${basePath}/watch/${watch.id}`, watch.upstreamJson);
return data;
};
export const executeWatch = async (executeWatchDetails: ExecutedWatchDetails, watch: BaseWatch) => {
const { data } = await getHttpClient().put(`${basePath}/watch/execute`, {
executeDetails: executeWatchDetails.upstreamJson,
watch: watch.upstreamJson,
});
return data;
};
Expand Up @@ -8,6 +8,8 @@ import { makeDocumentationLink } from './make_documentation_link';

export const documentationLinks = {
watcher: {
putWatchApi: makeDocumentationLink('{baseUrl}guide/en/elasticsearch/reference/{urlVersion}/watcher-api-put-watch.html')
}
putWatchApi: makeDocumentationLink(
'{baseUrl}guide/en/elasticsearch/reference/{urlVersion}/watcher-api-put-watch.html'
),
},
};
Expand Up @@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/

export { documentationLinks } from './documentation_links.js';
export { documentationLinks } from './documentation_links';
Expand Up @@ -13,13 +13,6 @@ const minor = semver.minor(metadata.version);
const urlVersion = `${major}.${minor}`;
const baseUrl = 'https://www.elastic.co/';

/**
*
* @param {string} linkTemplate Link template containing {baseUrl} and {urlVersion} placeholders
* @return {string} Actual link, with placeholders in template replaced
*/
export function makeDocumentationLink(linkTemplate) {
return linkTemplate
.replace('{baseUrl}', baseUrl)
.replace('{urlVersion}', urlVersion);
export function makeDocumentationLink(linkTemplate: string) {
return linkTemplate.replace('{baseUrl}', baseUrl).replace('{urlVersion}', urlVersion);
}
Expand Up @@ -4,24 +4,52 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { TIME_UNITS } from '../../../common/constants';
import moment from 'moment';

export class ExecuteDetails {
constructor(props = {}) {
this.triggeredTime = props.triggeredTime;
this.triggeredTimeValue = props.triggeredTimeValue;
this.triggeredTimeUnit = props.triggeredTimeUnit;
this.scheduledTimeValue = props.scheduledTimeValue;
this.scheduledTimeUnit = props.scheduledTimeUnit;
this.scheduledTime = props.scheduledTime;
this.ignoreCondition = props.ignoreCondition;
this.alternativeInput = props.alternativeInput;
this.actionModes = props.actionModes;
this.recordExecution = props.recordExecution;
}

formatTime(timeUnit, value) {
let timeValue = moment();
switch (timeUnit) {
case TIME_UNITS.SECOND:
timeValue = timeValue.add(value, 'seconds');
break;
case TIME_UNITS.MINUTE:
timeValue = timeValue.add(value, 'minutes');
break;
case TIME_UNITS.HOUR:
timeValue = timeValue.add(value, 'hours');
break;
case TIME_UNITS.MILLISECOND:
timeValue = timeValue.add(value, 'milliseconds');
break;
}
return timeValue.format();
}

get upstreamJson() {
const hasTriggerTime = this.triggeredTimeValue !== '';
const hasScheduleTime = this.scheduledTimeValue !== '';
const formattedTriggerTime = hasTriggerTime ? this.formatTime(this.triggeredTimeUnit, this.triggeredTimeValue) : undefined;
const formattedScheduleTime = hasScheduleTime ? this.formatTime(this.scheduledTimeUnit, this.scheduledTimeValue) : undefined;
const triggerData = {
triggeredTime: this.triggeredTime,
scheduledTime: this.scheduledTime,
triggeredTime: formattedTriggerTime,
scheduledTime: formattedScheduleTime,
};

return {
triggerData: triggerData,
triggerData,
ignoreCondition: this.ignoreCondition,
alternativeInput: this.alternativeInput,
actionModes: this.actionModes,
Expand Down
17 changes: 17 additions & 0 deletions x-pack/plugins/watcher/public/models/index.d.ts
Expand Up @@ -9,3 +9,20 @@ declare module 'plugins/watcher/models/watch' {
declare module 'plugins/watcher/models/watch/threshold_watch' {
export const ThresholdWatch: any;
}
declare module 'plugins/watcher/models/watch/json_watch' {
export const JsonWatch: any;
}

declare module 'plugins/watcher/models/execute_details/execute_details' {
export const ExecuteDetails: any;
}

declare module 'plugins/watcher/models/watch_history_item' {
export const WatchHistoryItem: any;
}

// TODO: Remove once typescript definitions are in EUI
declare module '@elastic/eui' {
export const EuiCodeEditor: React.SFC<any>;
export const EuiDescribedFormGroup: React.SFC<any>;
}
2 changes: 1 addition & 1 deletion x-pack/plugins/watcher/public/models/watch/base_watch.js
Expand Up @@ -25,7 +25,7 @@ export class BaseWatch {
* @param {array} props.actions Action definitions
*/
constructor(props = {}) {
this.id = get(props, 'id');
this.id = get(props, 'id', '');
this.type = get(props, 'type');
this.isNew = get(props, 'isNew', true);

Expand Down

0 comments on commit 081bb7c

Please sign in to comment.