foreman_remote_execution 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.babelrc +9 -0
- data/.eslintignore +3 -0
- data/.eslintrc +49 -0
- data/.gitignore +1 -0
- data/.hound.yml +5 -0
- data/.rubocop.yml +4 -1
- data/.rubocop_todo.yml +63 -35
- data/.travis.yml +6 -0
- data/app/assets/javascripts/foreman_remote_execution/template_invocation.js +1 -1
- data/app/assets/stylesheets/foreman_remote_execution/job_invocations.css.scss +0 -14
- data/app/controllers/job_invocations_controller.rb +18 -0
- data/app/helpers/job_invocations_chart_helper.rb +77 -0
- data/app/helpers/job_invocations_helper.rb +79 -0
- data/app/helpers/remote_execution_helper.rb +10 -50
- data/app/models/job_invocation.rb +4 -0
- data/app/models/remote_execution_provider.rb +4 -0
- data/app/views/job_invocations/_card_results.html.erb +11 -0
- data/app/views/job_invocations/_card_schedule.html.erb +32 -0
- data/app/views/job_invocations/_card_target_hosts.html.erb +33 -0
- data/app/views/job_invocations/_card_user_input.html.erb +16 -0
- data/app/views/job_invocations/_tab_hosts.html.erb +1 -1
- data/app/views/job_invocations/_tab_overview.html.erb +25 -55
- data/app/views/job_invocations/_tab_preview_templates.html.erb +20 -0
- data/app/views/job_invocations/_user_input.html.erb +21 -0
- data/app/views/job_invocations/show.html.erb +14 -8
- data/app/views/job_invocations/show.js.erb +3 -6
- data/config/routes.rb +1 -0
- data/lib/foreman_remote_execution/engine.rb +2 -2
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/package.json +62 -0
- data/test/unit/job_invocation_test.rb +15 -0
- data/webpack/index.js +29 -0
- data/webpack/react_app/components/jobInvocations/AggregateStatus/index.js +34 -0
- data/webpack/react_app/components/jobInvocations/AggregateStatus/index.test.js +36 -0
- data/webpack/react_app/components/jobInvocations/index.js +58 -0
- data/webpack/react_app/redux/actions/jobInvocations/index.js +74 -0
- data/webpack/react_app/redux/consts.js +6 -0
- data/webpack/react_app/redux/reducers/index.js +6 -0
- data/webpack/react_app/redux/reducers/jobInvocations/index.fixtures.js +78 -0
- data/webpack/react_app/redux/reducers/jobInvocations/index.js +32 -0
- data/webpack/react_app/redux/reducers/jobInvocations/index.test.js +37 -0
- data/webpack/test_setup.js +11 -0
- metadata +26 -2
@@ -1,24 +1,30 @@
|
|
1
1
|
<% title @job_invocation.description, trunc_with_tooltip(@job_invocation.description, 120) %>
|
2
2
|
<% stylesheet 'foreman_remote_execution/job_invocations' %>
|
3
3
|
<% javascript 'charts', 'foreman_remote_execution/template_invocation' %>
|
4
|
+
<%= javascript_include_tag *webpack_asset_paths('remoteexecution', :extension => 'js'), "data-turbolinks-track" => true, 'defer' => 'defer' %>
|
4
5
|
|
5
6
|
<% if @job_invocation.task %>
|
6
7
|
<% title_actions(button_group(job_invocation_task_buttons(@job_invocation.task))) %>
|
7
8
|
<% end %>
|
8
9
|
|
9
10
|
<ul class="nav nav-tabs" data-tabs="tabs">
|
10
|
-
<li class="
|
11
|
-
|
12
|
-
|
11
|
+
<li class="active">
|
12
|
+
<a href="#primary" data-toggle="tab"><%= _('Overview') %></a>
|
13
|
+
</li>
|
14
|
+
<li>
|
15
|
+
<a href="#preview_templates" data-toggle="tab"><%= _('Preview templates') %></a>
|
16
|
+
</li>
|
17
|
+
<% if @job_invocation.recurring_logic.present? %>
|
18
|
+
<li><a href="#recurring_logic" data-toggle="tab"><%= _('Recurring logic') %></a></li>
|
19
|
+
<% end %>
|
13
20
|
</ul>
|
14
21
|
|
15
22
|
<div class="tab-content">
|
16
|
-
<div class="tab-pane
|
17
|
-
<%= render 'tab_overview', :job_invocation => @job_invocation %>
|
23
|
+
<div class="tab-pane active" id="primary">
|
24
|
+
<%= render 'tab_overview', :job_invocation => @job_invocation, :hosts => @hosts %>
|
18
25
|
</div>
|
19
|
-
|
20
|
-
|
21
|
-
<%= render 'tab_hosts', :job_invocation => @job_invocation, :hosts => @hosts %>
|
26
|
+
<div class="tab-pane" id="preview_templates">
|
27
|
+
<%= render 'tab_preview_templates', :job_invocation => @job_invocation %>
|
22
28
|
</div>
|
23
29
|
|
24
30
|
<% unless @job_invocation.recurring_logic.nil? %>
|
@@ -1,11 +1,8 @@
|
|
1
1
|
$('div#title_action div.btn-group').html('<%= button_group(job_invocation_task_buttons(@job_invocation.task)).html_safe %>');
|
2
|
-
$('div#status_chart').html('<%=j job_invocation_chart(@job_invocation) %>');
|
3
|
-
$('div#status').flot_pie();
|
4
|
-
|
5
2
|
<% if params[:hosts_needs_refresh] == 'true' && @job_invocation.resolved? %>
|
6
|
-
var
|
7
|
-
|
8
|
-
|
3
|
+
var hosts_table = $('div#hosts');
|
4
|
+
hosts_table.html('<%=j render('tab_hosts', :job_invocation => @job_invocation, :hosts => @hosts) %>');
|
5
|
+
hosts_table.data('refresh_required', '');
|
9
6
|
<% end %>
|
10
7
|
|
11
8
|
<% ['name', 'status', 'actions', 'provider'].each do |attribute| %>
|
data/config/routes.rb
CHANGED
@@ -31,7 +31,7 @@ module ForemanRemoteExecution
|
|
31
31
|
|
32
32
|
initializer 'foreman_remote_execution.register_plugin', before: :finisher_hook do |_app|
|
33
33
|
Foreman::Plugin.register :foreman_remote_execution do
|
34
|
-
requires_foreman '>= 1.
|
34
|
+
requires_foreman '>= 1.18'
|
35
35
|
|
36
36
|
apipie_documented_controllers ["#{ForemanRemoteExecution::Engine.root}/app/controllers/api/v2/*.rb"]
|
37
37
|
|
@@ -54,7 +54,7 @@ module ForemanRemoteExecution
|
|
54
54
|
permission :lock_job_templates, { :job_templates => [:lock, :unlock] }, :resource_type => 'JobTemplate'
|
55
55
|
permission :create_job_invocations, { :job_invocations => [:new, :create, :refresh, :rerun, :preview_hosts],
|
56
56
|
'api/v2/job_invocations' => [:create, :rerun] }, :resource_type => 'JobInvocation'
|
57
|
-
permission :view_job_invocations, { :job_invocations => [:index, :show, :auto_complete_search], :template_invocations => [:show],
|
57
|
+
permission :view_job_invocations, { :job_invocations => [:index, :chart, :show, :auto_complete_search], :template_invocations => [:show],
|
58
58
|
'api/v2/job_invocations' => [:index, :show, :output] }, :resource_type => 'JobInvocation'
|
59
59
|
permission :create_template_invocations, {}, :resource_type => 'TemplateInvocation'
|
60
60
|
permission :cancel_job_invocations, { :job_invocations => [:cancel], 'api/v2/job_invocations' => [:cancel] }, :resource_type => 'JobInvocation'
|
data/package.json
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
{
|
2
|
+
"name": "foreman_remote_execution",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"license": "GPL-3.0",
|
5
|
+
"scripts": {
|
6
|
+
"lint": "./node_modules/.bin/eslint -c .eslintrc webpack/ script/ || exit 0",
|
7
|
+
"test": "node node_modules/.bin/jest webpack",
|
8
|
+
"test:watch": "node node_modules/.bin/jest webpack --watchAll",
|
9
|
+
"test:current": "node node_modules/.bin/jest webpack --watch"
|
10
|
+
},
|
11
|
+
"jest": {
|
12
|
+
"verbose": true,
|
13
|
+
"moduleDirectories": [
|
14
|
+
"node_modules",
|
15
|
+
"webpack"
|
16
|
+
],
|
17
|
+
"setupFiles": [
|
18
|
+
"raf/polyfill",
|
19
|
+
"./webpack/test_setup.js"
|
20
|
+
],
|
21
|
+
"testPathIgnorePatterns": [
|
22
|
+
"/node_modules/",
|
23
|
+
"<rootDir>/foreman/"
|
24
|
+
]
|
25
|
+
},
|
26
|
+
"repository": {
|
27
|
+
"type": "git",
|
28
|
+
"url": "git+https://github.com/foreman_remote_execution/foreman_remote_execution.git"
|
29
|
+
},
|
30
|
+
"bugs": {
|
31
|
+
"url": "http://projects.theforeman.org/projects/foreman_remote_execution/issues"
|
32
|
+
},
|
33
|
+
"devDependencies": {
|
34
|
+
"babel-eslint": "^8.2.1",
|
35
|
+
"babel-preset-env": "^1.6.0",
|
36
|
+
"babel-preset-react": "^6.24.1",
|
37
|
+
"babel-plugin-lodash": "^3.3.2",
|
38
|
+
"babel-plugin-transform-object-assign": "^6.22.0",
|
39
|
+
"babel-plugin-transform-class-properties": "^6.24.1",
|
40
|
+
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
41
|
+
"enzyme": "^3.2.0",
|
42
|
+
"enzyme-adapter-react-16": "^1.1.0",
|
43
|
+
"enzyme-to-json": "^3.1.2",
|
44
|
+
"eslint": "^4.10.0",
|
45
|
+
"eslint-config-airbnb": "^16.0.0",
|
46
|
+
"eslint-plugin-import": "^2.8.0",
|
47
|
+
"eslint-plugin-jest": "^21.2.0",
|
48
|
+
"eslint-plugin-jsx-a11y": "^6.0.2",
|
49
|
+
"eslint-plugin-react": "^7.4.0",
|
50
|
+
"jest": "^21.2.1"
|
51
|
+
},
|
52
|
+
"dependencies": {
|
53
|
+
"babel-polyfill": "^6.26.0",
|
54
|
+
"prop-types": "^15.6.0",
|
55
|
+
"react": "^16.2.0",
|
56
|
+
"react-dom": "^16.2.0",
|
57
|
+
"react-redux": "^5.0.6",
|
58
|
+
"redux": "^3.7.2",
|
59
|
+
"seamless-immutable": "^7.1.3",
|
60
|
+
"urijs": "^1.19.0"
|
61
|
+
}
|
62
|
+
}
|
@@ -173,4 +173,19 @@ class JobInvocationTest < ActiveSupport::TestCase
|
|
173
173
|
end
|
174
174
|
end
|
175
175
|
|
176
|
+
describe '#finished?' do
|
177
|
+
let(:task) { ForemanTasks::Task.new }
|
178
|
+
before { job_invocation.task = task }
|
179
|
+
|
180
|
+
it 'returns false if task state is pending' do
|
181
|
+
job_invocation.task.expects(:pending?).returns(true)
|
182
|
+
refute job_invocation.finished?
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'returns true if task is not pending' do
|
186
|
+
job_invocation.task.expects(:pending?).returns(false)
|
187
|
+
assert job_invocation.finished?
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
176
191
|
end
|
data/webpack/index.js
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
import URI from 'urijs';
|
2
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
3
|
+
import { mount, registerReducer } from 'foremanReact/common/MountingService';
|
4
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
5
|
+
import componentRegistry from 'foremanReact/components/componentRegistry';
|
6
|
+
import JobInvocationContainer from './react_app/components/jobInvocations';
|
7
|
+
import rootReducer from './react_app/redux/reducers';
|
8
|
+
|
9
|
+
componentRegistry.register({
|
10
|
+
name: 'JobInvocationContainer',
|
11
|
+
type: JobInvocationContainer,
|
12
|
+
});
|
13
|
+
|
14
|
+
registerReducer('foremanRemoteExecutionReducers', rootReducer);
|
15
|
+
|
16
|
+
if (window.location.href.match(/job_invocations/)) {
|
17
|
+
const jobInvocationId = parseInt(
|
18
|
+
new URI(window.location.href).filename(),
|
19
|
+
10,
|
20
|
+
);
|
21
|
+
|
22
|
+
const mountJobInvocationContainer = () => {
|
23
|
+
mount('JobInvocationContainer', '#status_chart', {
|
24
|
+
url: `/job_invocations/chart?id=${jobInvocationId}`,
|
25
|
+
});
|
26
|
+
};
|
27
|
+
|
28
|
+
document.addEventListener('page:change', mountJobInvocationContainer);
|
29
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
const AggregateStatus = ({ statuses }) => (
|
4
|
+
<div id="aggregate_statuses">
|
5
|
+
<p className="card-pf-aggregate-status-notifications">
|
6
|
+
<span className="card-pf-aggregate-status-notification">
|
7
|
+
<span id="success_count">
|
8
|
+
<span className="pficon pficon-ok" />
|
9
|
+
{statuses.success}
|
10
|
+
</span>
|
11
|
+
</span>
|
12
|
+
<span className="card-pf-aggregate-status-notification">
|
13
|
+
<span id="failed_count">
|
14
|
+
<span className="pficon pficon-error-circle-o" />
|
15
|
+
{statuses.failed}
|
16
|
+
</span>
|
17
|
+
</span>
|
18
|
+
<span className="card-pf-aggregate-status-notification">
|
19
|
+
<span id="pending_count">
|
20
|
+
<span className="pficon pficon-running" />
|
21
|
+
{statuses.pending}
|
22
|
+
</span>
|
23
|
+
</span>
|
24
|
+
<span className="card-pf-aggregate-status-notification">
|
25
|
+
<span id="cancelled_count">
|
26
|
+
<span className="pficon pficon-close" />
|
27
|
+
{statuses.cancelled}
|
28
|
+
</span>
|
29
|
+
</span>
|
30
|
+
</p>
|
31
|
+
</div>
|
32
|
+
);
|
33
|
+
|
34
|
+
export default AggregateStatus;
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { shallow } from 'enzyme';
|
3
|
+
import AggregateStatus from './index.js';
|
4
|
+
|
5
|
+
jest.unmock('./index.js');
|
6
|
+
|
7
|
+
describe('AggregateStatus', () => {
|
8
|
+
describe('has no data', () => {
|
9
|
+
it('renders cards with no data', () => {
|
10
|
+
const chartNumbers = shallow(<AggregateStatus statuses={{}} />);
|
11
|
+
const success = chartNumbers.find('#success_count').text();
|
12
|
+
const failed = chartNumbers.find('#failed_count').text();
|
13
|
+
const pending = chartNumbers.find('#pending_count').text();
|
14
|
+
const cancelled = chartNumbers.find('#cancelled_count').text();
|
15
|
+
expect(success).toBe('');
|
16
|
+
expect(failed).toBe('');
|
17
|
+
expect(cancelled).toBe('');
|
18
|
+
expect(pending).toBe('');
|
19
|
+
});
|
20
|
+
|
21
|
+
it('renders cards with props passed', () => {
|
22
|
+
const statuses = {
|
23
|
+
success: 19, failed: 20, cancelled: 31, pending: 3,
|
24
|
+
};
|
25
|
+
const chartNumbers = shallow(<AggregateStatus statuses={statuses} />);
|
26
|
+
const success = chartNumbers.find('#success_count').text();
|
27
|
+
const failed = chartNumbers.find('#failed_count').text();
|
28
|
+
const pending = chartNumbers.find('#pending_count').text();
|
29
|
+
const cancelled = chartNumbers.find('#cancelled_count').text();
|
30
|
+
expect(success).toBe(statuses.success.toString());
|
31
|
+
expect(failed).toBe(statuses.failed.toString());
|
32
|
+
expect(cancelled).toBe(statuses.cancelled.toString());
|
33
|
+
expect(pending).toBe(statuses.pending.toString());
|
34
|
+
});
|
35
|
+
});
|
36
|
+
});
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import { connect } from 'react-redux';
|
2
|
+
import React from 'react';
|
3
|
+
import Immutable from 'seamless-immutable';
|
4
|
+
import PropTypes from 'prop-types';
|
5
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
6
|
+
import DonutChart from 'foremanReact/components/common/charts/DonutChart';
|
7
|
+
import AggregateStatus from './AggregateStatus/index.js';
|
8
|
+
import * as JobInvocationActions from '../../redux/actions/jobInvocations';
|
9
|
+
|
10
|
+
class JobInvocationContainer extends React.Component {
|
11
|
+
componentDidMount() {
|
12
|
+
const { startJobInvocationsPolling, data: { url } } = this.props;
|
13
|
+
|
14
|
+
startJobInvocationsPolling(url);
|
15
|
+
}
|
16
|
+
|
17
|
+
render() {
|
18
|
+
const { jobInvocations, statuses } = this.props;
|
19
|
+
|
20
|
+
return (
|
21
|
+
<div id="job_invocations_chart_container">
|
22
|
+
<DonutChart data={Immutable.asMutable(jobInvocations)} />
|
23
|
+
<AggregateStatus statuses={statuses} />
|
24
|
+
</div>
|
25
|
+
);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
const mapStateToProps = (state) => {
|
30
|
+
const {
|
31
|
+
jobInvocations,
|
32
|
+
statuses,
|
33
|
+
} = state.foremanRemoteExecutionReducers.jobInvocations;
|
34
|
+
|
35
|
+
return {
|
36
|
+
jobInvocations,
|
37
|
+
statuses,
|
38
|
+
};
|
39
|
+
};
|
40
|
+
|
41
|
+
JobInvocationContainer.propTypes = {
|
42
|
+
startJobInvocationsPolling: PropTypes.func,
|
43
|
+
data: PropTypes.string,
|
44
|
+
jobInvocations: PropTypes.arrayOf(PropTypes.arrayOf(
|
45
|
+
PropTypes.string,
|
46
|
+
PropTypes.number,
|
47
|
+
PropTypes.string,
|
48
|
+
)),
|
49
|
+
statuses: PropTypes.shape({}),
|
50
|
+
};
|
51
|
+
|
52
|
+
JobInvocationContainer.defaultProps = {
|
53
|
+
startJobInvocationsPolling: JobInvocationActions.startJobInvocationsPolling,
|
54
|
+
data: '',
|
55
|
+
jobInvocations: [['property', 3, 'color']],
|
56
|
+
statuses: {},
|
57
|
+
};
|
58
|
+
export default connect(mapStateToProps, JobInvocationActions)(JobInvocationContainer);
|
@@ -0,0 +1,74 @@
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
2
|
+
import API from 'foremanReact/API';
|
3
|
+
|
4
|
+
import {
|
5
|
+
JOB_INVOCATIONS_GET_JOB_INVOCATIONS,
|
6
|
+
JOB_INVOCATIONS_POLLING_STARTED,
|
7
|
+
JOB_INVOCATIONS_JOB_FINISHED,
|
8
|
+
} from '../../consts';
|
9
|
+
|
10
|
+
const defaultJobInvocationsPollingInterval = 1000;
|
11
|
+
const jobInvocationsInterval = process.env.JOB_INVOCATIONS_POLLING ||
|
12
|
+
defaultJobInvocationsPollingInterval;
|
13
|
+
|
14
|
+
const getJobInvocations = url => (dispatch, getState) => {
|
15
|
+
function onGetJobInvocationsSuccess({ data }) {
|
16
|
+
// If the job has finished, stop polling
|
17
|
+
if (data.finished) {
|
18
|
+
dispatch({
|
19
|
+
type: JOB_INVOCATIONS_JOB_FINISHED,
|
20
|
+
payload: {
|
21
|
+
jobInvocations: data,
|
22
|
+
},
|
23
|
+
});
|
24
|
+
} else {
|
25
|
+
dispatch({
|
26
|
+
type: JOB_INVOCATIONS_GET_JOB_INVOCATIONS,
|
27
|
+
payload: {
|
28
|
+
jobInvocations: data,
|
29
|
+
},
|
30
|
+
});
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
function onGetJobInvocationsFailed(error) {
|
35
|
+
if (error.response.status === 401) {
|
36
|
+
window.location.replace('/users/login');
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
function triggerPolling() {
|
41
|
+
if (jobInvocationsInterval) {
|
42
|
+
setTimeout(
|
43
|
+
() => dispatch(getJobInvocations(url)),
|
44
|
+
jobInvocationsInterval,
|
45
|
+
);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
const isDocumentVisible =
|
50
|
+
document.visibilityState === 'visible' ||
|
51
|
+
document.visibilityState === 'prerender';
|
52
|
+
|
53
|
+
if (getState().foremanRemoteExecutionReducers.jobInvocations.isPolling) {
|
54
|
+
if (isDocumentVisible) {
|
55
|
+
API.get(url)
|
56
|
+
.then(onGetJobInvocationsSuccess)
|
57
|
+
.catch(onGetJobInvocationsFailed)
|
58
|
+
.then(triggerPolling);
|
59
|
+
} else {
|
60
|
+
// document is not visible, keep polling without api call
|
61
|
+
triggerPolling();
|
62
|
+
}
|
63
|
+
}
|
64
|
+
};
|
65
|
+
|
66
|
+
export const startJobInvocationsPolling = url => (dispatch, getState) => {
|
67
|
+
if (getState().foremanRemoteExecutionReducers.jobInvocations.isPolling) {
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
dispatch({
|
71
|
+
type: JOB_INVOCATIONS_POLLING_STARTED,
|
72
|
+
});
|
73
|
+
dispatch(getJobInvocations(url));
|
74
|
+
};
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import Immutable from 'seamless-immutable';
|
2
|
+
|
3
|
+
export const initialState = Immutable({
|
4
|
+
isPolling: false,
|
5
|
+
jobInvocations: [],
|
6
|
+
statuses: [],
|
7
|
+
});
|
8
|
+
|
9
|
+
export const pollingStarted = Immutable({
|
10
|
+
isPolling: true,
|
11
|
+
jobInvocations: [],
|
12
|
+
statuses: [],
|
13
|
+
});
|
14
|
+
|
15
|
+
export const jobInvocationsPayload = Immutable({
|
16
|
+
jobInvocations: {
|
17
|
+
job_invocations: [
|
18
|
+
[
|
19
|
+
'Success',
|
20
|
+
100,
|
21
|
+
'#B7312D',
|
22
|
+
],
|
23
|
+
[
|
24
|
+
'Failed',
|
25
|
+
20,
|
26
|
+
'#B7312D',
|
27
|
+
],
|
28
|
+
[
|
29
|
+
'Pending',
|
30
|
+
40,
|
31
|
+
'#B7312D',
|
32
|
+
],
|
33
|
+
[
|
34
|
+
'Cancelled',
|
35
|
+
0,
|
36
|
+
'#B7312D',
|
37
|
+
],
|
38
|
+
],
|
39
|
+
statuses: {
|
40
|
+
cancelled: 0,
|
41
|
+
failed: 0,
|
42
|
+
pending: 0,
|
43
|
+
success: 1,
|
44
|
+
},
|
45
|
+
},
|
46
|
+
});
|
47
|
+
|
48
|
+
export const jobInvocationsReceived = Immutable({
|
49
|
+
isPolling: true,
|
50
|
+
jobInvocations: [
|
51
|
+
[
|
52
|
+
'Success',
|
53
|
+
100,
|
54
|
+
'#B7312D',
|
55
|
+
],
|
56
|
+
[
|
57
|
+
'Failed',
|
58
|
+
20,
|
59
|
+
'#B7312D',
|
60
|
+
],
|
61
|
+
[
|
62
|
+
'Pending',
|
63
|
+
40,
|
64
|
+
'#B7312D',
|
65
|
+
],
|
66
|
+
[
|
67
|
+
'Cancelled',
|
68
|
+
0,
|
69
|
+
'#B7312D',
|
70
|
+
],
|
71
|
+
],
|
72
|
+
statuses: {
|
73
|
+
cancelled: 0,
|
74
|
+
failed: 0,
|
75
|
+
pending: 0,
|
76
|
+
success: 1,
|
77
|
+
},
|
78
|
+
});
|