Skip to content

Commit

Permalink
[ML] Adding permission checks to jobs list (elastic#20487) (elastic#2…
Browse files Browse the repository at this point in the history
…0511)

* [ML] Adding permission checks to jobs list

* adding comment

* removing horizontal line

* changes based on review
  • Loading branch information
jgowdyelastic authored Jul 6, 2018
1 parent 92ed457 commit abbfb03
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,103 +4,73 @@
* you may not use this file except in compliance with the Elastic License.
*/


import React from 'react';

import {
EuiText,
EuiIcon,
} from '@elastic/eui';
import { checkPermission } from 'plugins/ml/privilege/check_privilege';
import { mlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';

import {
stopDatafeeds,
cloneJob } from '../utils';
cloneJob,
isStartable,
isStoppable,
} from '../utils';

export function actionsMenuContent(showEditJobFlyout, showDeleteJobModal, showStartDatafeedModal, refreshJobs) {
return [{
render: (item) => {
return (
getStartStop(item, showStartDatafeedModal, refreshJobs)
);
}
}, {
render: (item) => {
return (
<MLText onClick={() => cloneJob(item.id)}>
<EuiIcon type="copy" />
Clone job
</MLText>
);
}
}, {
render: (item) => {
return (
<MLText onClick={() => {
showEditJobFlyout(item);
closeMenu();
}}
>
<EuiIcon type="copy" />
Edit job
</MLText>
);
}
}, {
render: (item) => {
return (
<MLText
color="danger"
onClick={() => {
showDeleteJobModal([item]);
closeMenu();
}}
>
<EuiIcon type="trash" />
Delete job
</MLText>
);
}
}];
}

const canCreateJob = (checkPermission('canCreateJob') && mlNodesAvailable());
const canUpdateJob = checkPermission('canUpdateJob');
const canDeleteJob = checkPermission('canDeleteJob');
const canUpdateDatafeed = checkPermission('canUpdateDatafeed');
const canStartStopDatafeed = (checkPermission('canStartStopDatafeed') && mlNodesAvailable());

function getStartStop(item, showStartDatafeedModal, refreshJobs) {
if (item.datafeedState === 'stopped') {
return (
<MLText onClick={() => {
return [
{
name: 'Start datafeed',
description: 'Start datafeed',
icon: 'play',
enabled: () => (canStartStopDatafeed),
available: (item) => (isStartable([item])),
onClick: (item) => {
showStartDatafeedModal([item]);
closeMenu();
}}
>
<EuiIcon type="play" />
Start datafeed
</MLText>
);
}

if (item.datafeedState === 'started') {
return (
<MLText onClick={() => {
}
}, {
name: 'Stop datafeed',
description: 'Stop datafeed',
icon: 'stop',
enabled: () => (canStartStopDatafeed),
available: (item) => (isStoppable([item])),
onClick: (item) => {
stopDatafeeds([item], refreshJobs);
closeMenu(true);
}}
>
<EuiIcon type="stop" />
Stop datafeed
</MLText>
);
}
}

// EuiText wrapper to stop event propagation so the menu items don't fire twice.
// this appears to be an issue with the EuiBasicTable actions col when specifying
// a custom render function which contains its own onClick
function MLText({ onClick, ...rest }) {
const click = (e) => {
e.stopPropagation();
onClick();
};
return <EuiText onClick={click} {...rest} />;
}
}, {
name: 'Clone job',
description: 'Clone job',
icon: 'copy',
enabled: () => (canCreateJob),
onClick: (item) => {
cloneJob(item.id);
}
}, {
name: 'Edit job',
description: 'Edit job',
icon: 'copy',
enabled: () => (canUpdateJob && canUpdateDatafeed),
onClick: (item) => {
showEditJobFlyout(item);
closeMenu();
}
}, {
name: 'Delete job',
description: 'Delete job',
icon: 'trash',
color: 'danger',
enabled: () => (canDeleteJob),
onClick: (item) => {
showDeleteJobModal([item]);
closeMenu();
}
}
];
}

function closeMenu(now = false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,16 @@
opacity: 1;
}

.euiContextMenuPanel .euiContextMenuItem {
white-space: nowrap;
.euiContextMenuPanel {
.euiContextMenuItem {
white-space: nowrap;
}
.euiContextMenuItem:last-child:not(.euiContextMenuItem-isDisabled) {
color: #A30000
}
}


.euiTableCellContent .euiLink {
margin-right: 10px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/


import { checkPermission } from 'plugins/ml/privilege/check_privilege';
import { mlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
import PropTypes from 'prop-types';
import React, {
Component,
Expand All @@ -29,6 +31,9 @@ export class MultiJobActionsMenu extends Component {
this.state = {
isOpen: false,
};

this.canDeleteJob = checkPermission('canDeleteJob');
this.canStartStopDatafeed = (checkPermission('canStartStopDatafeed') && mlNodesAvailable());
}

onButtonClick = () => {
Expand All @@ -51,6 +56,7 @@ export class MultiJobActionsMenu extends Component {
iconType="gear"
aria-label="Next"
color="text"
disabled={(this.canDeleteJob === false && this.canStartStopDatafeed === false)}
/>
);

Expand All @@ -60,6 +66,7 @@ export class MultiJobActionsMenu extends Component {
<EuiContextMenuItem
key="delete"
icon="trash"
disabled={(this.canDeleteJob === false)}
onClick={() => { this.props.showDeleteJobModal(this.props.jobs); this.closePopover(); }}
>
Delete job{s}
Expand All @@ -72,6 +79,7 @@ export class MultiJobActionsMenu extends Component {
<EuiContextMenuItem
key="stop datafeed"
icon="stop"
disabled={(this.canStartStopDatafeed === false)}
onClick={() => { stopDatafeeds(this.props.jobs, this.props.refreshJobs); this.closePopover(); }}
>
Stop datafeed{s}
Expand All @@ -84,6 +92,7 @@ export class MultiJobActionsMenu extends Component {
<EuiContextMenuItem
key="start datafeed"
icon="play"
disabled={(this.canStartStopDatafeed === false)}
onClick={() => { this.props.showStartDatafeedModal(this.props.jobs); this.closePopover(); }}
>
Start datafeed{s}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
white-space: nowrap;
}

.euiContextMenuItem:last-child {
.euiContextMenuItem:last-child:not(.euiContextMenuItem-isDisabled) {
color: #A30000
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@



import { checkPermission } from 'plugins/ml/privilege/check_privilege';
import { mlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';

import React from 'react';
import './styles/main.less';

Expand All @@ -18,10 +21,12 @@ function newJob() {
}

export function NewJobButton() {
const buttonEnabled = (checkPermission('canCreateJob') && mlNodesAvailable());
return (
<EuiButton
onClick={newJob}
size="s"
disabled={(buttonEnabled === false)}
fill
>
<i className="new-job-button fa fa-plus" />
Expand Down
37 changes: 34 additions & 3 deletions x-pack/plugins/ml/public/jobs/jobs_list_new/jobs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,57 @@
import './styles/main.less';
import { NewJobButton } from './components/new_job_button';
import { JobsListView } from './components/jobs_list_view';
import { mlNodesAvailable, permissionToViewMlNodeCount } from 'plugins/ml/ml_nodes_check/check_ml_nodes';

import React, {
Component
} from 'react';

import {
EuiHorizontalRule,
EuiCallOut,
EuiLink,
EuiSpacer,
} from '@elastic/eui';

function NodeAvailableWarning() {
const isCloud = false; // placeholder for future specific cloud functionality
if ((mlNodesAvailable() === true) || (permissionToViewMlNodeCount() === false)) {
return (<span />);
} else {
return (
<React.Fragment>
<EuiCallOut
title="No ML nodes available"
color="warning"
iconType="alert"
>
<p>
There are no ML nodes available.<br />
You will not be able to create or run jobs.
{isCloud &&
<span ng-if="isCloud">
&nbsp;This can be configured in Cloud <EuiLink href="#">here</EuiLink>.
</span>
}
</p>
</EuiCallOut>
<EuiSpacer size="m" />
</React.Fragment>
);
}
}

export class JobsPage extends Component {
constructor(props) {
super(props);

this.state = {
};
}

render() {
return (
<div className="job-management">
<NodeAvailableWarning />
<header>
<div className="new-job-button-container">
<NewJobButton />
Expand All @@ -36,7 +67,7 @@ export class JobsPage extends Component {

<div className="clear" />

<EuiHorizontalRule margin="m" />
<EuiSpacer size="s" />

<JobsListView />
</div>
Expand Down

0 comments on commit abbfb03

Please sign in to comment.