mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 20:51:21 -03:30
Timeout, socket and activity stream changes for workflow pause approve
This commit is contained in:
parent
9186cb23a6
commit
adf621d2cf
@ -10,12 +10,7 @@ export default {
|
||||
name: 'organizations.job_templates',
|
||||
data: {
|
||||
activityStream: true,
|
||||
activityStreamTarget: 'template',
|
||||
socket: {
|
||||
"groups": {
|
||||
"jobs": ["status_changed"]
|
||||
}
|
||||
}
|
||||
activityStreamTarget: 'template'
|
||||
},
|
||||
params: {
|
||||
template_search: {
|
||||
|
||||
@ -13,12 +13,7 @@ export default {
|
||||
},
|
||||
data: {
|
||||
activityStream: true,
|
||||
activityStreamTarget: 'template',
|
||||
socket: {
|
||||
"groups": {
|
||||
"jobs": ["status_changed"]
|
||||
}
|
||||
}
|
||||
activityStreamTarget: 'template'
|
||||
},
|
||||
params: {
|
||||
template_search: {
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
z-index: 1041;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
|
||||
&-drawer {
|
||||
&--drawer {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
@ -19,13 +19,13 @@
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
&-header {
|
||||
&--header {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
&--title {
|
||||
flex: 1 0 auto;
|
||||
color: @default-interface-txt;
|
||||
font-size: 14px;
|
||||
@ -33,7 +33,7 @@
|
||||
width: calc(82%);
|
||||
}
|
||||
|
||||
&-actionRow {
|
||||
&--actionRow {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
@ -44,7 +44,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-exit {
|
||||
&--exit {
|
||||
justify-content: flex-end;
|
||||
display: flex;
|
||||
|
||||
@ -61,4 +61,8 @@
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&--expires {
|
||||
color: @default-err;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
<div class="at-ApprovalsDrawer">
|
||||
<div class="at-ApprovalsDrawer-drawer" ng-if="vm.listLoaded">
|
||||
<div class="at-ApprovalsDrawer-header">
|
||||
<div class="at-ApprovalsDrawer-title">
|
||||
<div class="at-ApprovalsDrawer--drawer" ng-if="vm.listLoaded">
|
||||
<div class="at-ApprovalsDrawer--header">
|
||||
<div class="at-ApprovalsDrawer--title">
|
||||
<span>
|
||||
{{:: vm.strings.get('approvals.NOTIFICATIONS') }}
|
||||
</span>
|
||||
@ -9,7 +9,7 @@
|
||||
{{vm.count}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="at-ApprovalsDrawer-exit">
|
||||
<div class="at-ApprovalsDrawer--exit">
|
||||
<button class="close" ng-click="closeApprovals()">
|
||||
<i class="fa fa-times-circle"></i>
|
||||
</button>
|
||||
@ -39,19 +39,20 @@
|
||||
<at-row-item
|
||||
value-bind-html="{{ approval.created | longDate }}">
|
||||
</at-row-item>
|
||||
<!-- todo: clean this up if it becomes a real thing-->
|
||||
<!-- todo: translate strings -->
|
||||
<at-row-item
|
||||
style="color: red;"
|
||||
value-bind-html="Expires: Never">
|
||||
ng-if="approval.approval_expiration"
|
||||
class="at-ApprovalsDrawer--expires"
|
||||
value-bind-html="{{:: vm.strings.get('approvals.EXPIRES') }} {{ approval.approval_expiration | longDate }}">
|
||||
</at-row-item>
|
||||
<at-row-item
|
||||
ng-if="!approval.approval_expiration"
|
||||
class="at-ApprovalsDrawer--expires"
|
||||
value-bind-html="{{:: vm.strings.get('approvals.EXPIRES_NEVER') }}">
|
||||
</at-row-item>
|
||||
<!-- todo: hook this up when timeout is active-->
|
||||
<!-- <at-row-item
|
||||
style="color: red;"
|
||||
value-bind-html="Expires {{ approval.created | longDate }}">
|
||||
</at-row-item> -->
|
||||
</div>
|
||||
<div class="at-Row-container--wrapped">
|
||||
<div class="at-ApprovalsDrawer-actionRow">
|
||||
<div class="at-Row-container--wrapped" ng-if="approval.can_approve_or_deny">
|
||||
<div class="at-ApprovalsDrawer--actionRow">
|
||||
<div>{{:: vm.strings.get('approvals.CONTINUE') }}</div>
|
||||
<button class="btn at-Button--success"
|
||||
ng-click="vm.approve(approval)"
|
||||
|
||||
@ -126,7 +126,9 @@ function ComponentsStrings (BaseString) {
|
||||
DENY: t.s('DENY'),
|
||||
CONTINUE: t.s('Continue workflow job?'),
|
||||
NOTIFICATIONS: t.s('NOTIFICATIONS'),
|
||||
WORKFLOW_TEMPLATE: t.s('Workflow Template')
|
||||
WORKFLOW_TEMPLATE: t.s('Workflow Template'),
|
||||
EXPIRES: t.s('Expires:'),
|
||||
EXPIRES_NEVER: t.s('Expires: Never')
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -110,5 +110,5 @@
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
||||
</div>
|
||||
<at-approvals-drawer ng-if="vm.showApprovals" close-approvals="vm.closeApprovals()"></at-approvals-drawer>
|
||||
<at-approvals-drawer ng-if="vm.isLoggedIn && vm.showApprovals" close-approvals="vm.closeApprovals()"></at-approvals-drawer>
|
||||
</div>
|
||||
|
||||
@ -93,6 +93,10 @@ export default function BuildAnchor($log, $filter) {
|
||||
case 'o_auth2_application':
|
||||
url += `applications/${obj.id}`;
|
||||
break;
|
||||
case 'workflow_approval':
|
||||
url += `workflows/${activity.summary_fields.workflow_job[0].id}`
|
||||
name = activity.summary_fields.workflow_job[0].name;
|
||||
break;
|
||||
default:
|
||||
url += resource + 's/' + obj.id + '/';
|
||||
}
|
||||
|
||||
@ -124,7 +124,20 @@ export default function BuildDescription(BuildAnchor, $log, i18n) {
|
||||
break;
|
||||
// expected outcome: "operation <object1>"
|
||||
case 'update':
|
||||
activity.description += activity.object1 + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity);
|
||||
if (activity.object1 === 'workflow_approval'
|
||||
&& _.has(activity, 'changes.status')
|
||||
&& activity.changes.status.length === 2
|
||||
) {
|
||||
let operationText = '';
|
||||
if (activity.changes.status[1] === 'successful') {
|
||||
operationText = i18n._('approved');
|
||||
} else if (activity.changes.status[1] === 'failed') {
|
||||
operationText = i18n._('denied');
|
||||
}
|
||||
activity.description = `${operationText} ${activity.object1} ${BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity)}`;
|
||||
} else {
|
||||
activity.description += activity.object1 + BuildAnchor(activity.summary_fields[activity.object1][0], activity.object1, activity);
|
||||
}
|
||||
break;
|
||||
case 'create':
|
||||
activity.description += activity.object1 + BuildAnchor(activity.changes, activity.object1, activity);
|
||||
|
||||
@ -50,11 +50,22 @@ export default ['templateUrl', 'i18n', function(templateUrl, i18n) {
|
||||
}
|
||||
else {
|
||||
let search = {
|
||||
or__object1__in: $scope.streamTarget && $scope.streamTarget === 'template' ? 'job_template,workflow_job_template' : $scope.streamTarget,
|
||||
or__object2__in: $scope.streamTarget && $scope.streamTarget === 'template' ? 'job_template,workflow_job_template' : $scope.streamTarget,
|
||||
or__object1__in: $scope.streamTarget,
|
||||
or__object2__in: $scope.streamTarget,
|
||||
page_size: '20',
|
||||
order_by: '-timestamp'
|
||||
};
|
||||
|
||||
if ($scope.streamTarget && $scope.streamTarget === 'template') {
|
||||
search.or__object1__in = 'job_template,workflow_job_template';
|
||||
search.or__object2__in = 'job_template,workflow_job_template';
|
||||
}
|
||||
|
||||
if ($scope.streamTarget && $scope.streamTarget === 'job') {
|
||||
search.or__object1__in = 'job,workflow_approval';
|
||||
search.or__object2__in = 'job,workflow_approval';
|
||||
}
|
||||
|
||||
// Attach the taget to the query parameters
|
||||
$state.go('activityStream', {target: $scope.streamTarget, id: null, activity_search: search});
|
||||
}
|
||||
|
||||
@ -198,6 +198,10 @@ angular
|
||||
document.title = `Ansible ${$rootScope.BRAND_NAME} ${title}`;
|
||||
});
|
||||
|
||||
$rootScope.$on('ws-approval', () => {
|
||||
fetchApprovalsCount();
|
||||
});
|
||||
|
||||
function activateTab() {
|
||||
// Make the correct tab active
|
||||
var base = $location.path().replace(/^\//, '').split('/')[0];
|
||||
@ -210,6 +214,20 @@ angular
|
||||
}
|
||||
}
|
||||
|
||||
function fetchApprovalsCount() {
|
||||
Rest.setUrl(`${GetBasePath('workflow_approvals')}?status=pending&page_size=1`);
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
$rootScope.pendingApprovalCount = data.count;
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors({}, data, status, null, {
|
||||
hdr: i18n._('Error!'),
|
||||
msg: i18n._('Failed to get workflow jobs pending approval. GET returned status: ') + status
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if ($rootScope.removeConfigReady) {
|
||||
$rootScope.removeConfigReady();
|
||||
}
|
||||
@ -387,18 +405,7 @@ angular
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Rest.setUrl(`${GetBasePath('workflow_approvals')}?status=pending&page_size=1`);
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
$rootScope.pendingApprovalCount = data.count;
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors({}, data, status, null, {
|
||||
hdr: i18n._('Error!'),
|
||||
msg: i18n._('Failed to get workflow jobs pending approval. GET returned status: ') + status
|
||||
});
|
||||
});
|
||||
fetchApprovalsCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -75,11 +75,22 @@ export default
|
||||
stateGoParams.target = streamConfig.activityStreamTarget;
|
||||
let isTemplateTarget = _.includes(['template', 'job_template', 'workflow_job_template'], streamConfig.activityStreamTarget);
|
||||
stateGoParams.activity_search = {
|
||||
or__object1__in: isTemplateTarget ? 'job_template,workflow_job_template' : streamConfig.activityStreamTarget,
|
||||
or__object2__in: isTemplateTarget ? 'job_template,workflow_job_template' : streamConfig.activityStreamTarget,
|
||||
or__object1__in: streamConfig.activityStreamTarget,
|
||||
or__object2__in: streamConfig.activityStreamTarget,
|
||||
order_by: '-timestamp',
|
||||
page_size: '20',
|
||||
};
|
||||
|
||||
if (isTemplateTarget) {
|
||||
stateGoParams.activity_search.or__object1__in = 'job_template,workflow_job_template';
|
||||
stateGoParams.activity_search.or__object2__in = 'job_template,workflow_job_template';
|
||||
}
|
||||
|
||||
if (streamConfig.activityStreamTarget === 'job') {
|
||||
stateGoParams.activity_search.or__object1__in = 'job,workflow_approval';
|
||||
stateGoParams.activity_search.or__object2__in = 'job,workflow_approval';
|
||||
}
|
||||
|
||||
if (streamConfig.activityStreamTarget && streamConfig.activityStreamId && !streamConfig.noActivityStreamID) {
|
||||
stateGoParams.activity_search[streamConfig.activityStreamTarget] = $state.params[streamConfig.activityStreamId];
|
||||
}
|
||||
|
||||
@ -94,9 +94,12 @@
|
||||
<div class="DashboardGraphs-graphContainer" auto-size-module
|
||||
graph-type="jobsStatus"
|
||||
ng-class="{'is-selected': jobStatusSelected }">
|
||||
<job-status-graph class="DashboardGraphs-graph
|
||||
DashboardGraphs-graph--jobStatusGraph"
|
||||
data="graphData.jobStatus" period="month" job-type="all">
|
||||
<job-status-graph
|
||||
class="DashboardGraphs-graph DashboardGraphs-graph--jobStatusGraph"
|
||||
data="graphData.jobStatus"
|
||||
period="graphData.period"
|
||||
job-type="graphData.jobType"
|
||||
status="graphData.status">
|
||||
</job-status-graph>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -18,19 +18,17 @@ function JobStatusGraph($window, adjustGraphSize, templateUrl, i18n, moment, gra
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
data: '='
|
||||
data: '=',
|
||||
period: '=',
|
||||
jobType: '=',
|
||||
status: '='
|
||||
},
|
||||
templateUrl: templateUrl('home/dashboard/graphs/job-status/job_status_graph'),
|
||||
link: link
|
||||
};
|
||||
|
||||
function link(scope, element) {
|
||||
var job_type,
|
||||
job_status_chart = nv.models.lineChart();
|
||||
|
||||
scope.period="month";
|
||||
scope.jobType="all";
|
||||
scope.status="both";
|
||||
var job_status_chart = nv.models.lineChart();
|
||||
|
||||
scope.$watchCollection('data', function(value) {
|
||||
if (value) {
|
||||
@ -129,8 +127,6 @@ function JobStatusGraph($window, adjustGraphSize, templateUrl, i18n, moment, gra
|
||||
|
||||
// when the Period drop down filter is used, create a new graph based on the
|
||||
$('.n').off('click').on("click", function(){
|
||||
period = this.getAttribute("id");
|
||||
|
||||
$('#period-dropdown-display')
|
||||
.html(`
|
||||
<span>${this.text}</span>
|
||||
@ -139,13 +135,11 @@ function JobStatusGraph($window, adjustGraphSize, templateUrl, i18n, moment, gra
|
||||
|
||||
scope.$parent.isFailed = true;
|
||||
scope.$parent.isSuccessful = true;
|
||||
recreateGraph(period, job_type);
|
||||
recreateGraph(this.getAttribute("id"), scope.jobType, scope.status);
|
||||
});
|
||||
|
||||
//On click, update with new data
|
||||
$('.m').off('click').on("click", function(){
|
||||
job_type = this.getAttribute("id");
|
||||
|
||||
$('#type-dropdown-display')
|
||||
.html(`
|
||||
<span>${this.text}</span>
|
||||
@ -154,19 +148,17 @@ function JobStatusGraph($window, adjustGraphSize, templateUrl, i18n, moment, gra
|
||||
|
||||
scope.$parent.isFailed = true;
|
||||
scope.$parent.isSuccessful = true;
|
||||
recreateGraph(period, job_type);
|
||||
recreateGraph(scope.period, this.getAttribute("id"), scope.status);
|
||||
});
|
||||
|
||||
$('.o').off('click').on('click', function() {
|
||||
var job_status = this.getAttribute('id');
|
||||
|
||||
$('#status-dropdown-display')
|
||||
.html(`
|
||||
<span>${this.text}</span>
|
||||
<i class="fa fa-angle-down DashboardGraphs-filterIcon"></i>
|
||||
`);
|
||||
|
||||
recreateGraph(scope.period, scope.jobType, job_status);
|
||||
recreateGraph(scope.period, scope.jobType, this.getAttribute("id"));
|
||||
});
|
||||
|
||||
adjustGraphSize(job_status_chart, element);
|
||||
|
||||
@ -4,95 +4,44 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default
|
||||
["Rest",
|
||||
"GetBasePath",
|
||||
"ProcessErrors",
|
||||
"$rootScope",
|
||||
"$q",
|
||||
"$timeout",
|
||||
JobStatusGraphData];
|
||||
|
||||
function JobStatusGraphData(Rest, getBasePath, processErrors, $rootScope, $q, $timeout) {
|
||||
|
||||
function getData(period, jobType, status) {
|
||||
var url, dash_path = getBasePath('dashboard');
|
||||
if(dash_path === '' ){
|
||||
processErrors(null,
|
||||
null,
|
||||
null,
|
||||
null, {
|
||||
hdr: 'Error!',
|
||||
msg: "There was an error. Please try again."
|
||||
});
|
||||
return;
|
||||
}
|
||||
url = dash_path + 'graphs/jobs/?period='+period+'&job_type='+jobType;
|
||||
Rest.setHeader({'X-WS-Session-Quiet': true});
|
||||
Rest.setUrl(url);
|
||||
return Rest.get()
|
||||
.then(function(value) {
|
||||
if(status === "successful" || status === "failed"){
|
||||
delete value.data.jobs[status];
|
||||
}
|
||||
return value.data;
|
||||
})
|
||||
.catch(function(response) {
|
||||
var errorMessage = 'Failed to get: ' + response.url + ' GET returned: ' + response.status;
|
||||
|
||||
processErrors(null,
|
||||
response.data,
|
||||
response.status,
|
||||
null, {
|
||||
hdr: 'Error!',
|
||||
msg: errorMessage
|
||||
});
|
||||
return $q.reject(response);
|
||||
});
|
||||
}
|
||||
export default ["Rest", "GetBasePath", "ProcessErrors", "$q", JobStatusGraphData];
|
||||
|
||||
function JobStatusGraphData(Rest, getBasePath, processErrors, $q) {
|
||||
return {
|
||||
pendingRefresh: false,
|
||||
refreshTimerRunning: false,
|
||||
refreshTimer: angular.noop,
|
||||
destroyWatcher: angular.noop,
|
||||
setupWatcher: function(period, jobType) {
|
||||
const that = this;
|
||||
that.destroyWatcher =
|
||||
$rootScope.$on('ws-jobs', function() {
|
||||
if (!that.refreshTimerRunning) {
|
||||
that.timebandGetData(period, jobType);
|
||||
} else {
|
||||
that.pendingRefresh = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
timebandGetData: function(period, jobType) {
|
||||
getData(period, jobType).then(function(result) {
|
||||
$rootScope.
|
||||
$broadcast('DataReceived:JobStatusGraph',
|
||||
result);
|
||||
return result;
|
||||
});
|
||||
this.pendingRefresh = false;
|
||||
this.refreshTimerRunning = true;
|
||||
this.refreshTimer = $timeout(() => {
|
||||
if (this.pendingRefresh) {
|
||||
this.timebandGetData(period, jobType);
|
||||
} else {
|
||||
this.refreshTimerRunning = false;
|
||||
}
|
||||
}, 5000);
|
||||
},
|
||||
get: function(period, jobType, status) {
|
||||
|
||||
this.destroyWatcher();
|
||||
$timeout.cancel(this.refreshTimer);
|
||||
this.refreshTimerRunning = false;
|
||||
this.pendingRefresh = false;
|
||||
this.setupWatcher(period, jobType);
|
||||
|
||||
return getData(period, jobType, status);
|
||||
var url, dash_path = getBasePath('dashboard');
|
||||
if(dash_path === '' ){
|
||||
processErrors(null,
|
||||
null,
|
||||
null,
|
||||
null, {
|
||||
hdr: 'Error!',
|
||||
msg: "There was an error. Please try again."
|
||||
});
|
||||
return;
|
||||
}
|
||||
url = dash_path + 'graphs/jobs/?period='+period+'&job_type='+jobType;
|
||||
Rest.setHeader({'X-WS-Session-Quiet': true});
|
||||
Rest.setUrl(url);
|
||||
return Rest.get()
|
||||
.then(function(value) {
|
||||
if(status === "successful" || status === "failed"){
|
||||
delete value.data.jobs[status];
|
||||
}
|
||||
return value.data;
|
||||
})
|
||||
.catch(function(response) {
|
||||
var errorMessage = 'Failed to get: ' + response.url + ' GET returned: ' + response.status;
|
||||
|
||||
processErrors(null,
|
||||
response.data,
|
||||
response.status,
|
||||
null, {
|
||||
hdr: 'Error!',
|
||||
msg: errorMessage
|
||||
});
|
||||
return $q.reject(response);
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default ['$scope', '$rootScope','Wait', '$timeout',
|
||||
export default ['$scope','Wait', '$timeout', 'i18n',
|
||||
'Rest', 'GetBasePath', 'ProcessErrors', 'graphData',
|
||||
function($scope, $rootScope, Wait, $timeout,
|
||||
function($scope, Wait, $timeout, i18n,
|
||||
Rest, GetBasePath, ProcessErrors, graphData) {
|
||||
|
||||
var dataCount = 0;
|
||||
@ -53,16 +53,10 @@ export default ['$scope', '$rootScope','Wait', '$timeout',
|
||||
$scope.removeDashboardReady = $scope.$on('dashboardReady', function (e, data) {
|
||||
$scope.dashboardCountsData = data;
|
||||
$scope.graphData = graphData;
|
||||
$scope.graphData.period = "month";
|
||||
$scope.graphData.jobType = "all";
|
||||
$scope.graphData.status = "both";
|
||||
$scope.$emit('dashboardDataLoadComplete');
|
||||
|
||||
var cleanupJobListener =
|
||||
$rootScope.$on('DataReceived:JobStatusGraph', function(e, data) {
|
||||
$scope.graphData.jobStatus = data;
|
||||
});
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
cleanupJobListener();
|
||||
});
|
||||
});
|
||||
|
||||
if ($scope.removeDashboardJobsListReady) {
|
||||
@ -81,40 +75,6 @@ export default ['$scope', '$rootScope','Wait', '$timeout',
|
||||
$scope.$emit('dashboardDataLoadComplete');
|
||||
});
|
||||
|
||||
$scope.refresh = function () {
|
||||
Wait('start');
|
||||
Rest.setUrl(GetBasePath('dashboard'));
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
$scope.dashboardData = data;
|
||||
$scope.$emit('dashboardReady', data);
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard: ' + status });
|
||||
});
|
||||
Rest.setUrl(GetBasePath("unified_jobs") + "?order_by=-finished&page_size=5&finished__isnull=false&type=workflow_job,job");
|
||||
Rest.setHeader({'X-WS-Session-Quiet': true});
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
data = data.results;
|
||||
$scope.$emit('dashboardJobsListReady', data);
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard jobs list: ' + status });
|
||||
});
|
||||
Rest.setUrl(GetBasePath("unified_job_templates") + "?order_by=-last_job_run&page_size=5&last_job_run__isnull=false&type=workflow_job_template,job_template");
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
data = data.results;
|
||||
$scope.$emit('dashboardJobTemplatesListReady', data);
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard job templates list: ' + status });
|
||||
});
|
||||
};
|
||||
|
||||
$scope.refresh();
|
||||
|
||||
function refreshLists () {
|
||||
Rest.setUrl(GetBasePath('dashboard'));
|
||||
Rest.get()
|
||||
@ -122,7 +82,7 @@ export default ['$scope', '$rootScope','Wait', '$timeout',
|
||||
$scope.dashboardData = data;
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard host graph data: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'), msg: i18n._(`Failed to get dashboard host graph data: ${status}`) });
|
||||
});
|
||||
|
||||
Rest.setUrl(GetBasePath("unified_jobs") + "?order_by=-finished&page_size=5&finished__isnull=false&type=workflow_job,job");
|
||||
@ -132,7 +92,7 @@ export default ['$scope', '$rootScope','Wait', '$timeout',
|
||||
$scope.dashboardJobsListData = data.results;
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard jobs list: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'), msg: i18n._(`Failed to get dashboard jobs list: ${status}`) });
|
||||
});
|
||||
|
||||
Rest.setUrl(GetBasePath("unified_job_templates") + "?order_by=-last_job_run&page_size=5&last_job_run__isnull=false&type=workflow_job_template,job_template");
|
||||
@ -141,8 +101,24 @@ export default ['$scope', '$rootScope','Wait', '$timeout',
|
||||
$scope.dashboardJobTemplatesListData = data.results;
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard jobs list: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'), msg: i18n._(`Failed to get dashboard jobs list: ${status}`) });
|
||||
});
|
||||
|
||||
if ($scope.graphData) {
|
||||
Rest.setUrl(`${GetBasePath('dashboard')}graphs/jobs/?period=${$scope.graphData.period}&job_type=${$scope.graphData.jobType}`);
|
||||
Rest.setHeader({'X-WS-Session-Quiet': true});
|
||||
Rest.get()
|
||||
.then(function(value) {
|
||||
if($scope.graphData.status === "successful" || $scope.graphData.status === "failed"){
|
||||
delete value.data.jobs[$scope.graphData.status];
|
||||
}
|
||||
$scope.graphData.jobStatus = value.data;
|
||||
})
|
||||
.catch(function({data, status}) {
|
||||
processErrors(null, data, status, null, { hdr: i18n._('Error!'), msg: i18n._(`Failed to get dashboard graph data: ${response.status}`)});
|
||||
});
|
||||
}
|
||||
|
||||
pendingRefresh = false;
|
||||
refreshTimerRunning = true;
|
||||
$timeout(() => {
|
||||
@ -154,5 +130,35 @@ export default ['$scope', '$rootScope','Wait', '$timeout',
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
Wait('start');
|
||||
Rest.setUrl(GetBasePath('dashboard'));
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
$scope.dashboardData = data;
|
||||
$scope.$emit('dashboardReady', data);
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'), msg: i18n._(`Failed to get dashboard: ${status}`) });
|
||||
});
|
||||
Rest.setUrl(GetBasePath("unified_jobs") + "?order_by=-finished&page_size=5&finished__isnull=false&type=workflow_job,job");
|
||||
Rest.setHeader({'X-WS-Session-Quiet': true});
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
data = data.results;
|
||||
$scope.$emit('dashboardJobsListReady', data);
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'), msg: i18n._(`Failed to get dashboard jobs list: ${status}`) });
|
||||
});
|
||||
Rest.setUrl(GetBasePath("unified_job_templates") + "?order_by=-last_job_run&page_size=5&last_job_run__isnull=false&type=workflow_job_template,job_template");
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
data = data.results;
|
||||
$scope.$emit('dashboardJobTemplatesListReady', data);
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'), msg: i18n._(`Failed to get dashboard job templates list: ${status}`) });
|
||||
});
|
||||
|
||||
}
|
||||
];
|
||||
|
||||
@ -10,12 +10,7 @@ export default {
|
||||
params: { licenseMissing: null },
|
||||
data: {
|
||||
activityStream: true,
|
||||
refreshButton: true,
|
||||
socket: {
|
||||
"groups": {
|
||||
"jobs": ["status_changed"]
|
||||
}
|
||||
},
|
||||
refreshButton: true
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
label: N_("DASHBOARD")
|
||||
|
||||
@ -175,12 +175,7 @@ let lists = [{
|
||||
},
|
||||
data: {
|
||||
activityStream: true,
|
||||
activityStreamTarget: 'organization',
|
||||
socket: {
|
||||
"groups": {
|
||||
"jobs": ["status_changed"]
|
||||
}
|
||||
},
|
||||
activityStreamTarget: 'organization'
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
parent: "organizations.edit",
|
||||
|
||||
@ -96,6 +96,14 @@ export default
|
||||
$log.debug('Received From Server: ' + e.data);
|
||||
|
||||
var data = JSON.parse(e.data), str = "";
|
||||
|
||||
if (data.group_name === 'jobs'
|
||||
&& 'type' in data
|
||||
&& data.type === 'workflow_approval'
|
||||
) {
|
||||
$rootScope.$broadcast('ws-approval');
|
||||
}
|
||||
|
||||
if(!window.liveUpdates && data.group_name !== "control" && $state.current.name !== "output"){
|
||||
$log.debug('Message from server dropped: ' + e.data);
|
||||
needsRefreshAfterBlur = true;
|
||||
@ -254,21 +262,23 @@ export default
|
||||
// requires a subscribe or an unsubscribe
|
||||
var self = this;
|
||||
return socketPromise.promise.then(function(){
|
||||
if(!state.data || !state.data.socket){
|
||||
_.merge(state.data, {socket: {groups: {}}});
|
||||
self.unsubscribe(state);
|
||||
if (_.get(state, 'data.socket.groups.jobs')) {
|
||||
if (!state.data.socket.groups.jobs.includes("status_changed")) {
|
||||
state.data.socket.groups.jobs.push("status_changed");
|
||||
}
|
||||
}
|
||||
else{
|
||||
["job_events", "ad_hoc_command_events", "workflow_events",
|
||||
else if(!state.data || !state.data.socket){
|
||||
_.merge(state.data, {socket: {groups: {jobs: ["status_changed"]}}});
|
||||
}
|
||||
["job_events", "ad_hoc_command_events", "workflow_events",
|
||||
"project_update_events", "inventory_update_events",
|
||||
"system_job_events"
|
||||
].forEach(function(group) {
|
||||
if(state.data && state.data.socket && state.data.socket.groups.hasOwnProperty(group)){
|
||||
state.data.socket.groups[group] = [id];
|
||||
}
|
||||
});
|
||||
self.subscribe(state);
|
||||
}
|
||||
].forEach(function(group) {
|
||||
if(state.data && state.data.socket && state.data.socket.groups.hasOwnProperty(group)){
|
||||
state.data.socket.groups[group] = [id];
|
||||
}
|
||||
});
|
||||
self.subscribe(state);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@ -608,10 +608,23 @@ export default ['$scope', 'TemplatesService',
|
||||
}
|
||||
} else if ($scope.nodeConfig.mode === "edit") {
|
||||
if (selectedTemplate) {
|
||||
nodeRef[$scope.nodeConfig.nodeId].fullUnifiedJobTemplateObject = selectedTemplate;
|
||||
nodeRef[$scope.nodeConfig.nodeId].unifiedJobTemplate = selectedTemplate;
|
||||
nodeRef[$scope.nodeConfig.nodeId].promptData = _.cloneDeep(promptData);
|
||||
nodeRef[$scope.nodeConfig.nodeId].isEdited = true;
|
||||
if (isPauseNode) {
|
||||
// If it's a _new_ pause node then we'll want to create the new ujt
|
||||
// If it's an existing pause node then we'll want to update the ujt
|
||||
nodeRef[$scope.nodeConfig.nodeId].unifiedJobTemplate = {
|
||||
name: selectedTemplate.name,
|
||||
description: selectedTemplate.description,
|
||||
timeout: selectedTemplate.timeout,
|
||||
unified_job_type: "workflow_approval"
|
||||
};
|
||||
nodeRef[$scope.nodeConfig.nodeId].isEdited = true;
|
||||
} else {
|
||||
nodeRef[$scope.nodeConfig.nodeId].fullUnifiedJobTemplateObject = selectedTemplate;
|
||||
nodeRef[$scope.nodeConfig.nodeId].unifiedJobTemplate = selectedTemplate;
|
||||
nodeRef[$scope.nodeConfig.nodeId].promptData = _.cloneDeep(promptData);
|
||||
nodeRef[$scope.nodeConfig.nodeId].isEdited = true;
|
||||
}
|
||||
|
||||
$scope.graphState.nodeBeingEdited = null;
|
||||
|
||||
$scope.graphState.arrayOfLinksForChart.map( (link) => {
|
||||
@ -622,16 +635,6 @@ export default ['$scope', 'TemplatesService',
|
||||
link.source.unifiedJobTemplate = selectedTemplate;
|
||||
}
|
||||
});
|
||||
} else if (isPauseNode) {
|
||||
// If it's a _new_ pause node then we'll want to create the new ujt
|
||||
// If it's an existing pause node then we'll want to update the ujt
|
||||
nodeRef[$scope.nodeConfig.nodeId].unifiedJobTemplate = {
|
||||
name: selectedTemplate.name,
|
||||
description: selectedTemplate.description,
|
||||
timeout: selectedTemplate.timeout,
|
||||
unified_job_type: "workflow_approval"
|
||||
};
|
||||
nodeRef[$scope.nodeConfig.nodeId].isEdited = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,13 +15,6 @@ export default {
|
||||
parent: 'jobs',
|
||||
label: '{{ workflow.id }} - {{ workflow.name }}'
|
||||
},
|
||||
data: {
|
||||
socket: {
|
||||
"groups":{
|
||||
"jobs": ["status_changed"]
|
||||
}
|
||||
}
|
||||
},
|
||||
templateUrl: templateUrl('workflow-results/workflow-results'),
|
||||
controller: workflowResultsController,
|
||||
resolve: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user