Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workflow default dialog alert #4100

Merged
merged 12 commits into from
Oct 24, 2017
69 changes: 56 additions & 13 deletions app/pages/admin/project-status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,31 @@ import VersionList from './project-status/version-list';
import ExperimentalFeatures from './project-status/experimental-features';
import Toggle from './project-status/toggle';
import RedirectToggle from './project-status/redirect-toggle';
import WorkflowDefaultDialog from './workflow-default-dialog';

class ProjectStatus extends Component {
constructor(props) {
super(props);
this.onChangeWorkflowLevel = this.onChangeWorkflowLevel.bind(this);
this.getWorkflows = this.getWorkflows.bind(this);
this.forceUpdate = this.forceUpdate.bind(this);
this.renderError = this.renderError.bind(this);
this.renderWorkflows = this.renderWorkflows.bind(this);
this.handleToggle = this.handleToggle.bind(this);
this.getProjectAndWorkflows = this.getProjectAndWorkflows.bind(this);
this.handleDialogCancel = this.handleDialogCancel.bind(this);
this.handleDialogSuccess = this.handleDialogSuccess.bind(this);

this.state = {
project: null,
dialogIsOpen: false,
error: null,
project: null,
usedWorkflowLevels: [],
workflows: []
};
}

componentDidMount() {
this.getProject().then(() => this.getWorkflows());
this.getProjectAndWorkflows();
}

componentWillUnmount() {
Expand Down Expand Up @@ -58,6 +62,10 @@ class ProjectStatus extends Component {
});
}

getProjectAndWorkflows() {
this.getProject().then(() => this.getWorkflows());
}

getUsedWorkflowLevels(workflows) {
return workflows
.map(workflow => workflow.configuration.level)
Expand All @@ -73,18 +81,44 @@ class ProjectStatus extends Component {
.catch(error => this.setState({ error }));
}

handleDialogCancel() {
this.setState({ dialogIsOpen: false });
}

handleDialogSuccess() {
const defaultWorkflow = this.state.workflows.filter(workflow =>
workflow.id === this.state.project.configuration.default_workflow
);
this.state.project.update({ 'configuration.default_workflow': undefined }).save()
.then(() => {
defaultWorkflow[0].update({ active: false }).save()
.then(() => {
this.getProjectAndWorkflows();
})
.catch(error => this.setState({ error }));
})
.then(() => {
this.setState({
dialogIsOpen: false
});
})
.catch(error => this.setState({ error }));
}

handleToggle(event, workflow) {
this.setState({ error: null });
const checked = event.target.checked;
const isChecked = event.target.checked;
const defaultWorkflowId = this.state.project.configuration.default_workflow;

return workflow.update({ 'active': checked }).save()
.then(() => this.getWorkflows())
.catch(error => this.setState({ error }))
}
if (defaultWorkflowId === workflow.id && workflow.active) {
this.setState({
dialogIsOpen: true
});
}

renderError() {
if (this.state.error) {
return <div>{this.state.error}</div>;
if ((defaultWorkflowId !== workflow.id) || (defaultWorkflowId === workflow.id && !workflow.active)) {
workflow.update({ active: isChecked }).save()
.catch(error => this.setState({ error }));
}
}

Expand All @@ -98,12 +132,18 @@ class ProjectStatus extends Component {
{this.state.workflows.map((workflow) => {
return (
<li key={workflow.id} className="section-list__item">
{this.state.project.configuration.default_workflow === workflow.id ? ' * ' : ''}
<WorkflowToggle
workflow={workflow}
name="active"
checked={workflow.active}
handleToggle={(event) => this.handleToggle(event, workflow)}
handleToggle={event => this.handleToggle(event, workflow)}
/>{' | '}
{this.state.dialogIsOpen &&
<WorkflowDefaultDialog
onCancel={this.handleDialogCancel}
onSuccess={this.handleDialogSuccess}
/>}
<label>
Level:{' '}
<select
Expand Down Expand Up @@ -164,7 +204,10 @@ class ProjectStatus extends Component {
<div className="project-status__section">
<h4>Workflow Settings</h4>
<small>The workflow level dropdown is for the workflow assignment experimental feature.</small>
{this.renderError()}
<br />
<small>An asterisk (*) denotes a default workflow.</small>
{this.state.error &&
`Error ${this.state.error.status}: ${this.state.error.message}`}
{this.renderWorkflows()}
</div>
<hr />
Expand Down
36 changes: 36 additions & 0 deletions app/pages/admin/workflow-default-dialog.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import Dialog from 'modal-form/dialog';

const WorkflowDefaultDialog = ({ onSuccess, onCancel }) => (
<Dialog tag="div" closeButton={true} onCancel={onCancel}>
<p>
You are about to make the default workflow inactive,
which will remove the default workflow setting from this project.
The default workflow can be set in the edit workflows page of the project builder.
</p>
<button
type="button"
onClick={onSuccess}
>
ok
</button>
<button
type="button"
onClick={onCancel}
>
cancel
</button>
</Dialog>
);

WorkflowDefaultDialog.defaultProps = {
onCancel: () => {},
onSuccess: () => {}
};

WorkflowDefaultDialog.propTypes = {
onCancel: React.PropTypes.func,
onSuccess: React.PropTypes.func
};

export default WorkflowDefaultDialog;
32 changes: 32 additions & 0 deletions app/pages/admin/workflow-default-dialog.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import assert from 'assert';
import { shallow } from 'enzyme';
import sinon from 'sinon';
import WorkflowDefaultDialog from './workflow-default-dialog';

describe('WorkflowDefaultDialog', () => {
let wrapper;
let onSuccessSpy;
let onCancelSpy;

before(() => {
onSuccessSpy = sinon.spy();
onCancelSpy = sinon.spy();
wrapper = shallow(<WorkflowDefaultDialog onSuccess={onSuccessSpy} onCancel={onCancelSpy}/>);
});

it('renders without crashing', () => {
const WorkflowDefaultDialogContainer = wrapper.find('div').first();
assert.equal(WorkflowDefaultDialogContainer.length, 1);
});

it('calls the onSuccess handler', () => {
wrapper.find('button').first().simulate('click');
sinon.assert.calledOnce(onSuccessSpy);
});

it('calls the onCancel handler', () => {
wrapper.find('button').last().simulate('click');
sinon.assert.calledOnce(onCancelSpy);
});
});