Skip to content

Commit

Permalink
Watcher history page: port to react (#33047)
Browse files Browse the repository at this point in the history
Get watch detail page ported to react.
  • Loading branch information
Paul Sanwald authored Apr 12, 2019
1 parent d22e9c2 commit 0078417
Show file tree
Hide file tree
Showing 9 changed files with 569 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const DeleteWatchesModal = ({
'xpack.watcher.deleteSelectedWatchesConfirmModal.descriptionText',
{
defaultMessage:
'This will permanently delete {numWatchesToDelete, plural, one {a watch} other {# watches}}. Are you sure?',
'This will permanently delete {numWatchesToDelete, plural, one {a watch} other {# watches}}. You can’t recover a deleted watch.',
values: { numWatchesToDelete },
}
);
Expand Down
47 changes: 47 additions & 0 deletions x-pack/plugins/watcher/public/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Watch } from 'plugins/watcher/models/watch';
import { WatchHistoryItem } from 'plugins/watcher/models/watch_history_item';
import { WatchStatus } from 'plugins/watcher/models/watch_status';

import { __await } from 'tslib';
import chrome from 'ui/chrome';
import { ROUTES } from '../../common/constants';
Expand All @@ -25,6 +28,35 @@ export const fetchWatches = async () => {
return Watch.fromUpstreamJson(watch);
});
};

export const fetchWatchDetail = async (id: string) => {
const {
data: { watch },
} = await getHttpClient().get(`${basePath}/watch/${id}`);
return Watch.fromUpstreamJson(watch);
};

export const fetchWatchHistoryDetail = async (id: string) => {
const {
data: { watchHistoryItem },
} = await getHttpClient().get(`${basePath}/history/${id}`);
const item = WatchHistoryItem.fromUpstreamJson(watchHistoryItem);
return item;
};

export const fetchWatchHistory = async (id: string, startTime: string) => {
let url = `${basePath}/watch/${id}/history`;
if (startTime) {
url += `?startTime=${startTime}`;
}
const result: any = await getHttpClient().get(url);
const items: any = result.data.watchHistoryItems;
return items.map((historyItem: any) => {
const item = WatchHistoryItem.fromUpstreamJson(historyItem);
return item;
});
};

export const deleteWatches = async (watchIds: string[]) => {
const body = {
watchIds,
Expand All @@ -34,6 +66,21 @@ export const deleteWatches = async (watchIds: string[]) => {
} = await getHttpClient().post(`${basePath}/watches/delete`, body);
return results;
};

export const deactivateWatch = async (id: string) => {
const {
data: { watchStatus },
} = await getHttpClient().put(`${basePath}/watch/${id}/deactivate`, null);
return WatchStatus.fromUpstreamJson(watchStatus);
};

export const activateWatch = async (id: string) => {
const {
data: { watchStatus },
} = await getHttpClient().put(`${basePath}/watch/${id}/activate`, null);
return WatchStatus.fromUpstreamJson(watchStatus);
};

export const fetchWatch = async (watchId: string) => {
const body = {
watchId,
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/watcher/public/models/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ declare module 'plugins/watcher/models/watch_history_item' {
export const WatchHistoryItem: any;
}

declare module 'plugins/watcher/models/watch_status' {
export const WatchStatus: any;
}
// TODO: Remove once typescript definitions are in EUI
declare module '@elastic/eui' {
export const EuiCodeEditor: React.SFC<any>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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 { InjectedIntl, injectI18n } from '@kbn/i18n/react';
import React from 'react';
import { EuiIcon } from '@elastic/eui';
import { WATCH_STATES } from '../../../../../common/constants/watch_states';

const WatchActionStatusUi = ({ intl, watchState }: { intl: InjectedIntl; watchState: string }) => {
const stateToIcon: { [key: string]: JSX.Element } = {
[WATCH_STATES.OK]: <EuiIcon type="check" color="green" />,
[WATCH_STATES.DISABLED]: <EuiIcon type="minusInCircle" color="grey" />,
[WATCH_STATES.FIRING]: <EuiIcon type="play" color="primary" />,
[WATCH_STATES.ERROR]: <EuiIcon type="crossInACircleFilled" color="red" />,
[WATCH_STATES.CONFIG_ERROR]: <EuiIcon type="crossInACircleFilled" color="red" />,
};

return <div>{stateToIcon[watchState]}</div>;
};

export const WatchActionStatus = injectI18n(WatchActionStatusUi);
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* 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 {
EuiFlexGroup,
EuiFlexItem,
EuiInMemoryTable,
EuiSpacer,
EuiText,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
import React, { Fragment, useEffect, useState } from 'react';
import { fetchWatchDetail } from '../../../../lib/api';
import { WatchActionStatus } from './watch_action_status';

const WatchDetailUi = ({ intl, watchId }: { intl: InjectedIntl; watchId: string }) => {
const [isWatchesLoading, setIsWatchesLoading] = useState<boolean>(true);
const [actions, setWatchActions] = useState([]);

const pagination = {
initialPageSize: 10,
pageSizeOptions: [10, 50, 100],
};

const columns = [
{
field: 'id',
name: i18n.translate('xpack.watcher.sections.watchDetail.watchTable.actionHeader', {
defaultMessage: 'Action',
}),
sortable: true,
truncateText: true,
render: (action: string) => {
return <EuiText>{action}</EuiText>;
},
},
{
field: 'state',
name: i18n.translate('xpack.watcher.sections.watchDetail.watchTable.stateHeader', {
defaultMessage: 'State',
}),
sortable: true,
truncateText: true,
render: (state: string) => {
return (
<EuiFlexGroup gutterSize="xs" alignItems="center">
<EuiFlexItem grow={false}>
<WatchActionStatus watchState={state} />
</EuiFlexItem>
<EuiFlexItem grow={false} className="watchState__message">
<EuiText>{state}</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
);
},
},
];
const loadWatchActions = async () => {
const loadedWatchActions = await fetchWatchDetail(watchId);
setWatchActions(loadedWatchActions.watchStatus.actionStatuses);
setIsWatchesLoading(false);
};
useEffect(() => {
loadWatchActions();
// only run the first time the component loads
}, []);

return (
<Fragment>
<EuiTitle size="m">
<h1>
<FormattedMessage
id="xpack.watcher.sections.watchDetail.header"
defaultMessage="Current status"
/>
</h1>
</EuiTitle>
<EuiSpacer size="s" />
<EuiInMemoryTable
items={actions}
itemId="id"
columns={columns}
pagination={pagination}
sorting={true}
loading={isWatchesLoading}
message={
<FormattedMessage
id="xpack.watcher.sections.watchDetail.watchTable.noWatchesMessage"
defaultMessage="No current status"
/>
}
/>
</Fragment>
);
};

export const WatchDetail = injectI18n(WatchDetailUi);
Loading

0 comments on commit 0078417

Please sign in to comment.