Skip to content

Commit

Permalink
Add a simple read-only table of rollup jobs and a details panel (#21900)
Browse files Browse the repository at this point in the history
  • Loading branch information
cjcenizal committed Sep 4, 2018
1 parent 44013aa commit df8c245
Show file tree
Hide file tree
Showing 44 changed files with 1,646 additions and 1 deletion.
7 changes: 7 additions & 0 deletions x-pack/plugins/rollup/common/constants/crud_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export const CRUD_APP_BASE_PATH = '/management/elasticsearch/index_rollup_jobs/';
1 change: 1 addition & 0 deletions x-pack/plugins/rollup/common/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
*/

export { PLUGIN } from './plugin';
export { CRUD_APP_BASE_PATH } from './crud_app';
Empty file.
11 changes: 10 additions & 1 deletion x-pack/plugins/rollup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@
import { resolve } from 'path';
import { PLUGIN } from './common/constants';
import { registerLicenseChecker } from './server/lib/register_license_checker';
import { registerIndicesRoute, registerFieldsForWildcardRoute, registerSearchRoute } from './server/routes/api';
import {
registerIndicesRoute,
registerFieldsForWildcardRoute,
registerSearchRoute,
registerJobsRoute,
} from './server/routes/api';

export function rollup(kibana) {
return new kibana.Plugin({
id: PLUGIN.ID,
publicDir: resolve(__dirname, 'public'),
require: ['kibana', 'elasticsearch', 'xpack_main'],
uiExports: {
managementSections: [
'plugins/rollup/crud_app',
],
indexManagement: [
'plugins/rollup/index_pattern_creation',
'plugins/rollup/index_pattern_list',
Expand All @@ -31,6 +39,7 @@ export function rollup(kibana) {
registerIndicesRoute(server);
registerFieldsForWildcardRoute(server);
registerSearchRoute(server);
registerJobsRoute(server);
}
});
}
19 changes: 19 additions & 0 deletions x-pack/plugins/rollup/public/crud_app/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { CRUD_APP_BASE_PATH } from '../../common/constants';
import { JobList } from './sections';

export const App = () => (
<div>
<Switch>
<Route path={CRUD_APP_BASE_PATH} component={JobList} />
</Switch>
</div>
);

72 changes: 72 additions & 0 deletions x-pack/plugins/rollup/public/crud_app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { Provider } from 'react-redux';
import { HashRouter } from 'react-router-dom';
import { management } from 'ui/management';
import routes from 'ui/routes';

import { CRUD_APP_BASE_PATH } from '../../common/constants';
import { setHttpClient } from './services';
import { App } from './app';
import template from './main.html';
import { rollupJobsStore } from './store';

const esSection = management.getSection('elasticsearch');

esSection.register('rollup_jobs', {
visible: true,
display: 'Rollup Jobs',
order: 2,
url: `#${CRUD_APP_BASE_PATH}home`
});

export const manageAngularLifecycle = ($scope, $route, elem) => {
const lastRoute = $route.current;

const deregister = $scope.$on('$locationChangeSuccess', () => {
const currentRoute = $route.current;
if (lastRoute.$$route.template === currentRoute.$$route.template) {
$route.current = lastRoute;
}
});

$scope.$on('$destroy', () => {
deregister && deregister();
elem && unmountComponentAtNode(elem);
});
};

const renderReact = async (elem) => {
render(
<Provider store={rollupJobsStore()}>
<HashRouter>
<App />
</HashRouter>
</Provider>,
elem
);
};

routes.when(`${CRUD_APP_BASE_PATH}:view?`, {
template: template,
controllerAs: 'rollupJobs',
controller: class IndexRollupJobsController {
constructor($scope, $route, $http) {
// NOTE: We depend upon Angular's $http service because it's decorated with interceptors,
// e.g. to check license status per request.
setHttpClient($http);

$scope.$$postDigest(() => {
const elem = document.getElementById('rollupJobsReactRoot');
renderReact(elem);
manageAngularLifecycle($scope, $route, elem);
});
}
}
});
3 changes: 3 additions & 0 deletions x-pack/plugins/rollup/public/crud_app/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<kbn-management-app section="elasticsearch/rollup_jobs">
<div id="rollupJobsReactRoot"></div>
</kbn-management-app>
7 changes: 7 additions & 0 deletions x-pack/plugins/rollup/public/crud_app/sections/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export { JobList } from './job_list';
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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 { connect } from 'react-redux';
import { DetailPanel as DetailPanelView } from './detail_panel';

import {
getDetailPanelType,
getDetailPanelJob,
} from '../../../store/selectors';

import {
closeDetailPanel,
openDetailPanel,
} from '../../../store/actions';

const mapStateToProps = (state) => {
const job = getDetailPanelJob(state);
return {
panelType: getDetailPanelType(state),
job,
};
};

const mapDispatchToProps = (dispatch) => {
return {
closeDetailPanel: () => {
dispatch(closeDetailPanel());
},
openDetailPanel: ({ panelType, job }) => {
dispatch(openDetailPanel({ panelType, job }));
},
};
};

export const DetailPanel = connect(
mapStateToProps,
mapDispatchToProps
)(DetailPanelView);
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React, { Component } from 'react';

import {
EuiFlyout,
EuiFlyoutBody,
EuiFlyoutHeader,
EuiTitle,
EuiTab,
EuiTabs,
EuiSpacer,
} from '@elastic/eui';

import {
TabSummary,
TabTerms,
TabMetrics,
TabJson,
TabHistogram,
} from './tabs';

const tabs = ['Summary', 'Terms', 'Histogram', 'Metrics', 'JSON'];

export class DetailPanel extends Component {
static defaultProps = {
job: {},
}

constructor(props) {
super(props);
}

renderTabs() {
const { panelType, job, openDetailPanel } = this.props;

return tabs.map((tab, index) => {
if (tab === 'Terms' && !job.terms.fields.length) {
return;
}

if (tab === 'Histogram' && !job.histogram.fields.length) {
return;
}

if (tab === 'Metrics' && !job.metrics.length) {
return;
}

const isSelected = tab === panelType;
return (
<EuiTab
onClick={() => openDetailPanel({ panelType: tab, job })}
isSelected={isSelected}
data-test-subj={`detailPanelTab${isSelected ? 'Selected' : ''}`}
key={index}
>
{tab}
</EuiTab>
);
}).filter(tab => tab);
}

render() {
const {
panelType,
closeDetailPanel,
job: {
id,
indexPattern,
rollupIndex,
rollupCron,
rollupInterval,
rollupDelay,
dateHistogramTimeZone,
dateHistogramField,
metrics,
terms,
histogram,
status,
documentsProcessed,
pagesProcessed,
rollupsIndexed,
triggerCount,
json,
},
} = this.props;

if (!panelType) {
return null;
}

const tabToContentMap = {
Summary: (
<TabSummary
id={id}
indexPattern={indexPattern}
rollupIndex={rollupIndex}
rollupCron={rollupCron}
rollupInterval={rollupInterval}
rollupDelay={rollupDelay}
dateHistogramTimeZone={dateHistogramTimeZone}
dateHistogramField={dateHistogramField}
documentsProcessed={documentsProcessed}
pagesProcessed={pagesProcessed}
rollupsIndexed={rollupsIndexed}
triggerCount={triggerCount}
status={status}
/>
),
Terms: (
<TabTerms terms={terms} />
),
Histogram: (
<TabHistogram histogram={histogram} />
),
Metrics: (
<TabMetrics metrics={metrics} />
),
JSON: (
<TabJson json={json} />
),
};

const content = tabToContentMap[panelType];

return (
<EuiFlyout
data-test-subj="indexDetailFlyout"
onClose={closeDetailPanel}
aria-labelledby="rollupJobDetailsFlyoutTitle"
size="m"
maxWidth="520px"
>
<EuiFlyoutHeader>
<EuiTitle size="m" id="rollupJobDetailsFlyoutTitle">
<h2>{id}</h2>
</EuiTitle>

<EuiSpacer size="s" />

<EuiTabs>
{this.renderTabs()}
</EuiTabs>
</EuiFlyoutHeader>

<EuiFlyoutBody>
{content}
</EuiFlyoutBody>
</EuiFlyout>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export { DetailPanel } from './detail_panel.container';
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* 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 { TabSummary } from './tab_summary';
export { TabTerms } from './tab_terms';
export { TabHistogram } from './tab_histogram';
export { TabMetrics } from './tab_metrics';
export { TabJson } from './tab_json';
Loading

0 comments on commit df8c245

Please sign in to comment.