mirror of
https://github.com/ansible/awx.git
synced 2026-03-21 02:47:35 -02:30
AC-1146 job relaunch fails after 2 or 3 relaunches in a row. Improved Jobs page search, defaulting all search boxes to Name. Enabled searching jobs by Type. Search drop-down box now sorted alphabetically.
This commit is contained in:
@@ -34,7 +34,16 @@ function JobsListController ($scope, $compile, ClearScope, Breadcrumbs, LoadBrea
|
|||||||
$scope.removeBuildJobsList();
|
$scope.removeBuildJobsList();
|
||||||
}
|
}
|
||||||
$scope.removeBuildJobsList = $scope.$on('buildJobsList', function() {
|
$scope.removeBuildJobsList = $scope.$on('buildJobsList', function() {
|
||||||
completed_scope = $scope.$new();
|
if (CompletedJobsList.fields.type) {
|
||||||
|
CompletedJobsList.fields.type.searchOptions = $scope.type_choices;
|
||||||
|
}
|
||||||
|
if (RunningJobsList.fields.type) {
|
||||||
|
RunningJobsList.fields.type.searchOptions = $scope.type_choices;
|
||||||
|
}
|
||||||
|
if (QueuedJobsList.fields.type) {
|
||||||
|
QueuedJobsList.fields.type.searchOptions = $scope.type_choices;
|
||||||
|
}
|
||||||
|
completed_scope = $scope.$new(true);
|
||||||
LoadJobsScope({
|
LoadJobsScope({
|
||||||
parent_scope: $scope,
|
parent_scope: $scope,
|
||||||
scope: completed_scope,
|
scope: completed_scope,
|
||||||
@@ -42,7 +51,7 @@ function JobsListController ($scope, $compile, ClearScope, Breadcrumbs, LoadBrea
|
|||||||
id: 'completed-jobs',
|
id: 'completed-jobs',
|
||||||
url: GetBasePath('unified_jobs') + '?or__status=successful&or__status=failed&or__status=error&or__status=canceled'
|
url: GetBasePath('unified_jobs') + '?or__status=successful&or__status=failed&or__status=error&or__status=canceled'
|
||||||
});
|
});
|
||||||
running_scope = $scope.$new();
|
running_scope = $scope.$new(true);
|
||||||
LoadJobsScope({
|
LoadJobsScope({
|
||||||
parent_scope: $scope,
|
parent_scope: $scope,
|
||||||
scope: running_scope,
|
scope: running_scope,
|
||||||
@@ -50,7 +59,7 @@ function JobsListController ($scope, $compile, ClearScope, Breadcrumbs, LoadBrea
|
|||||||
id: 'active-jobs',
|
id: 'active-jobs',
|
||||||
url: GetBasePath('unified_jobs') + '?status=running'
|
url: GetBasePath('unified_jobs') + '?status=running'
|
||||||
});
|
});
|
||||||
queued_scope = $scope.$new();
|
queued_scope = $scope.$new(true);
|
||||||
LoadJobsScope({
|
LoadJobsScope({
|
||||||
parent_scope: $scope,
|
parent_scope: $scope,
|
||||||
scope: queued_scope,
|
scope: queued_scope,
|
||||||
@@ -58,7 +67,7 @@ function JobsListController ($scope, $compile, ClearScope, Breadcrumbs, LoadBrea
|
|||||||
id: 'queued-jobs',
|
id: 'queued-jobs',
|
||||||
url: GetBasePath('unified_jobs') + '?or__status=pending&or__status=waiting&or__status=new'
|
url: GetBasePath('unified_jobs') + '?or__status=pending&or__status=waiting&or__status=new'
|
||||||
});
|
});
|
||||||
scheduled_scope = $scope.$new();
|
scheduled_scope = $scope.$new(true);
|
||||||
LoadSchedulesScope({
|
LoadSchedulesScope({
|
||||||
parent_scope: $scope,
|
parent_scope: $scope,
|
||||||
scope: scheduled_scope,
|
scope: scheduled_scope,
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parent_scope.$emit(callback, acceptedPasswords);
|
parent_scope.$emit(callback, acceptedPasswords);
|
||||||
|
scope.$destroy();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -147,6 +148,7 @@ function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) {
|
|||||||
$('#password-modal').modal('hide');
|
$('#password-modal').modal('hide');
|
||||||
Alert('Missing Password', 'Required password(s) not provided. Your request will not be submitted.', 'alert-info');
|
Alert('Missing Password', 'Required password(s) not provided. Your request will not be submitted.', 'alert-info');
|
||||||
parent_scope.$emit('PasswordsCanceled');
|
parent_scope.$emit('PasswordsCanceled');
|
||||||
|
scope.$destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
promptPassword();
|
promptPassword();
|
||||||
@@ -223,7 +225,7 @@ function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) {
|
|||||||
if (scope.removeStartPlaybookRun) {
|
if (scope.removeStartPlaybookRun) {
|
||||||
scope.removeStartPlaybookRun();
|
scope.removeStartPlaybookRun();
|
||||||
}
|
}
|
||||||
scope.removeStartJob = scope.$on('StartPlaybookRun', function(e, passwords) {
|
scope.removeStartPlaybookRun = scope.$on('StartPlaybookRun', function(e, passwords) {
|
||||||
LaunchJob({
|
LaunchJob({
|
||||||
scope: scope,
|
scope: scope,
|
||||||
url: launch_url,
|
url: launch_url,
|
||||||
|
|||||||
@@ -57,8 +57,20 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default the search field to 'defaultSearchField', if one exists
|
||||||
|
for (fld in list.fields) {
|
||||||
|
if (list.fields[fld].searchWidget === undefined && widget === 1 ||
|
||||||
|
list.fields[fld].searchWidget === widget) {
|
||||||
|
if (list.fields[fld].defaultSearchField) {
|
||||||
|
scope[iterator + 'SearchField' + modifier] = fld;
|
||||||
|
scope[iterator + 'SearchFieldLabel' + modifier] = list.fields[fld].label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A field marked as key may not be 'searchable', and there might not be a 'defaultSearchField',
|
||||||
|
// so find the first searchable field.
|
||||||
if (Empty(scope[iterator + 'SearchField' + modifier])) {
|
if (Empty(scope[iterator + 'SearchField' + modifier])) {
|
||||||
// A field marked as key may not be 'searchable'. Find the first searchable field.
|
|
||||||
for (fld in list.fields) {
|
for (fld in list.fields) {
|
||||||
if (list.fields[fld].searchWidget === undefined && widget === 1 ||
|
if (list.fields[fld].searchWidget === undefined && widget === 1 ||
|
||||||
list.fields[fld].searchWidget === widget) {
|
list.fields[fld].searchWidget === widget) {
|
||||||
@@ -203,6 +215,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
|||||||
list.fields[fld].searchType === 'select' || list.fields[fld].searchType === 'select_or')) {
|
list.fields[fld].searchType === 'select' || list.fields[fld].searchType === 'select_or')) {
|
||||||
scope[iterator + 'SelectShow' + modifier] = true;
|
scope[iterator + 'SelectShow' + modifier] = true;
|
||||||
scope[iterator + 'SearchSelectOpts' + modifier] = list.fields[fld].searchOptions;
|
scope[iterator + 'SearchSelectOpts' + modifier] = list.fields[fld].searchOptions;
|
||||||
|
scope[iterator + 'SearchType' + modifier] = '';
|
||||||
} else if (list.fields[fld].searchType && list.fields[fld].searchType === 'int') {
|
} else if (list.fields[fld].searchType && list.fields[fld].searchType === 'int') {
|
||||||
//scope[iterator + 'HideSearchType' + modifier] = true;
|
//scope[iterator + 'HideSearchType' + modifier] = true;
|
||||||
scope[iterator + 'SearchType' + modifier] = 'int';
|
scope[iterator + 'SearchType' + modifier] = 'int';
|
||||||
@@ -366,10 +379,12 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
|||||||
// handle fields whose source is a related model e.g. inventories.organization
|
// handle fields whose source is a related model e.g. inventories.organization
|
||||||
scope[iterator + 'SearchParams'] += '&' + list.fields[scope[iterator + 'SearchField' + modifier]].sourceModel + '__' +
|
scope[iterator + 'SearchParams'] += '&' + list.fields[scope[iterator + 'SearchField' + modifier]].sourceModel + '__' +
|
||||||
list.fields[scope[iterator + 'SearchField' + modifier]].sourceField + '__';
|
list.fields[scope[iterator + 'SearchField' + modifier]].sourceField + '__';
|
||||||
} else if ((list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'select') &&
|
} else if ( list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'select' &&
|
||||||
(scope[iterator + 'SearchSelectValue' + modifier].value === '' ||
|
Empty(scope[iterator + 'SearchSelectValue' + modifier].value) ) {
|
||||||
scope[iterator + 'SearchSelectValue' + modifier].value === null)) {
|
|
||||||
scope[iterator + 'SearchParams'] += '&' + scope[iterator + 'SearchField' + modifier] + '__';
|
scope[iterator + 'SearchParams'] += '&' + scope[iterator + 'SearchField' + modifier] + '__';
|
||||||
|
} else if ( list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'select' &&
|
||||||
|
!Empty(scope[iterator + 'SearchSelectValue' + modifier].value) ) {
|
||||||
|
scope[iterator + 'SearchParams'] += '&' + scope[iterator + 'SearchField' + modifier];
|
||||||
} else {
|
} else {
|
||||||
scope[iterator + 'SearchParams'] += '&' + scope[iterator + 'SearchField' + modifier] + '__';
|
scope[iterator + 'SearchParams'] += '&' + scope[iterator + 'SearchField' + modifier] + '__';
|
||||||
}
|
}
|
||||||
@@ -381,10 +396,9 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
|||||||
} else if (list.fields[scope[iterator + 'SearchField' + modifier]].searchType &&
|
} else if (list.fields[scope[iterator + 'SearchField' + modifier]].searchType &&
|
||||||
list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'gtzero') {
|
list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'gtzero') {
|
||||||
scope[iterator + 'SearchParams'] += 'gt=0';
|
scope[iterator + 'SearchParams'] += 'gt=0';
|
||||||
} else if ((list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'select') &&
|
} else if ( (list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'select') &&
|
||||||
(scope[iterator + 'SearchSelectValue' + modifier].value === '' ||
|
Empty(scope[iterator + 'SearchSelectValue' + modifier].value) ) {
|
||||||
scope[iterator + 'SearchSelectValue' + modifier].value === null)) {
|
scope[iterator + 'SearchParams'] += '=iexact=';
|
||||||
scope[iterator + 'SearchParams'] += 'iexact=';
|
|
||||||
} else {
|
} else {
|
||||||
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchType' + modifier] + '=';
|
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchType' + modifier] + '=';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,12 +60,15 @@ angular.module('CompletedJobsDefinition', [])
|
|||||||
link: false,
|
link: false,
|
||||||
columnClass: "col-md-2 hidden-sm hidden-xs",
|
columnClass: "col-md-2 hidden-sm hidden-xs",
|
||||||
columnShow: "showJobType",
|
columnShow: "showJobType",
|
||||||
searchable: false
|
searchable: true,
|
||||||
|
searchType: 'select',
|
||||||
|
searchOptions: [] // populated via GetChoices() in controller
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
columnClass: 'col-md-3 col-xs-5',
|
columnClass: 'col-md-3 col-xs-5',
|
||||||
ngClick: "viewJobLog(completed_job.id, completed_job.nameHref)"
|
ngClick: "viewJobLog(completed_job.id, completed_job.nameHref)",
|
||||||
|
defaultSearchField: true
|
||||||
},
|
},
|
||||||
failed: {
|
failed: {
|
||||||
label: 'Job failed?',
|
label: 'Job failed?',
|
||||||
|
|||||||
@@ -51,12 +51,15 @@ angular.module('QueuedJobsDefinition', [])
|
|||||||
ngBind: 'queued_job.type_label',
|
ngBind: 'queued_job.type_label',
|
||||||
link: false,
|
link: false,
|
||||||
columnClass: "col-md-2 hidden-sm hidden-xs",
|
columnClass: "col-md-2 hidden-sm hidden-xs",
|
||||||
searchable: false
|
searchable: true,
|
||||||
|
searchType: 'select',
|
||||||
|
searchOptions: [] // populated via GetChoices() in controller
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
columnClass: 'col-sm-3 col-xs-5',
|
columnClass: 'col-sm-3 col-xs-5',
|
||||||
ngClick: "viewJobLog(queued_job.id, queued_job.nameHref)"
|
ngClick: "viewJobLog(queued_job.id, queued_job.nameHref)",
|
||||||
|
defaultSearchField: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -51,12 +51,15 @@ angular.module('RunningJobsDefinition', [])
|
|||||||
ngBind: 'running_job.type_label',
|
ngBind: 'running_job.type_label',
|
||||||
link: false,
|
link: false,
|
||||||
columnClass: "col-md-2 hidden-sm hidden-xs",
|
columnClass: "col-md-2 hidden-sm hidden-xs",
|
||||||
searchable: false
|
searchable: true,
|
||||||
|
searchType: 'select',
|
||||||
|
searchOptions: [] // populated via GetChoices() in controller
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
columnClass: 'col-md-3 col-xs-5',
|
columnClass: 'col-md-3 col-xs-5',
|
||||||
ngClick: "viewJobLog(running_job.id, running_job.nameHref)"
|
ngClick: "viewJobLog(running_job.id, running_job.nameHref)",
|
||||||
|
defaultSearchField: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ angular.module('ScheduledJobsDefinition', [])
|
|||||||
sourceField: 'name',
|
sourceField: 'name',
|
||||||
ngClick: "editSchedule(schedule.id)",
|
ngClick: "editSchedule(schedule.id)",
|
||||||
awToolTip: "{{ schedule.nameTip }}",
|
awToolTip: "{{ schedule.nameTip }}",
|
||||||
dataPlacement: "top"
|
dataPlacement: "top",
|
||||||
|
defaultSearchField: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -77,14 +77,14 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
|||||||
*/
|
*/
|
||||||
.factory('Alert', ['$rootScope', '$compile', function ($rootScope, $compile) {
|
.factory('Alert', ['$rootScope', '$compile', function ($rootScope, $compile) {
|
||||||
return function (hdr, msg, cls, action, secondAlert, disableButtons) {
|
return function (hdr, msg, cls, action, secondAlert, disableButtons) {
|
||||||
var scope = $rootScope.$new(), e;
|
var scope = $rootScope.$new(), alertClass, e;
|
||||||
if (secondAlert) {
|
if (secondAlert) {
|
||||||
$('#alert2-modal-msg').attr({ "class": "alert" });
|
|
||||||
scope.alertHeader2 = hdr;
|
|
||||||
scope.alertBody2 = msg;
|
|
||||||
scope.alertClass2 = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger
|
|
||||||
e = angular.element(document.getElementById('alert-modal2'));
|
e = angular.element(document.getElementById('alert-modal2'));
|
||||||
$compile(e)(scope);
|
$compile(e)(scope);
|
||||||
|
scope.alertHeader2 = hdr;
|
||||||
|
scope.alertBody2 = msg;
|
||||||
|
alertClass = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger
|
||||||
|
$('#alert2-modal-msg').attr({ "class": "alert " + alertClass });
|
||||||
$('#alert-modal2').modal({
|
$('#alert-modal2').modal({
|
||||||
show: true,
|
show: true,
|
||||||
keyboard: true,
|
keyboard: true,
|
||||||
@@ -103,12 +103,12 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
$('#alert-modal-msg').attr({ "class": "alert" });
|
|
||||||
scope.alertHeader = hdr;
|
|
||||||
scope.alertBody = msg;
|
|
||||||
scope.alertClass = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger
|
|
||||||
e = angular.element(document.getElementById('alert-modal'));
|
e = angular.element(document.getElementById('alert-modal'));
|
||||||
$compile(e)(scope);
|
$compile(e)(scope);
|
||||||
|
scope.alertHeader = hdr;
|
||||||
|
scope.alertBody = msg;
|
||||||
|
alertClass = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger
|
||||||
|
$('#alert-modal-msg').attr({ "class": "alert " + alertClass });
|
||||||
$('#alert-modal').modal({
|
$('#alert-modal').modal({
|
||||||
show: true,
|
show: true,
|
||||||
keyboard: true,
|
keyboard: true,
|
||||||
|
|||||||
@@ -687,10 +687,31 @@ angular.module('GeneratorHelpers', [])
|
|||||||
form = params.template,
|
form = params.template,
|
||||||
size = params.size,
|
size = params.size,
|
||||||
includeSize = (params.includeSize === undefined) ? true : params.includeSize,
|
includeSize = (params.includeSize === undefined) ? true : params.includeSize,
|
||||||
fld,
|
|
||||||
i, html = '',
|
i, html = '',
|
||||||
modifier,
|
modifier,
|
||||||
searchWidgets = (params.searchWidgets) ? params.searchWidgets : 1;
|
searchWidgets = (params.searchWidgets) ? params.searchWidgets : 1,
|
||||||
|
sortedKeys;
|
||||||
|
|
||||||
|
function addSearchFields(idx) {
|
||||||
|
var html = '';
|
||||||
|
sortedKeys = Object.keys(form.fields).sort();
|
||||||
|
sortedKeys.forEach(function(fld) {
|
||||||
|
if ((form.fields[fld].searchable === undefined || form.fields[fld].searchable === true) &&
|
||||||
|
(((form.fields[fld].searchWidget === undefined || form.fields[fld].searchWidget === 1) && idx === 1) ||
|
||||||
|
(form.fields[fld].searchWidget === idx))) {
|
||||||
|
html += "<li><a href=\"\" ng-click=\"setSearchField('" + iterator + "','";
|
||||||
|
html += fld + "','";
|
||||||
|
if (form.fields[fld].searchLabel) {
|
||||||
|
html += form.fields[fld].searchLabel + "', " + idx + ")\">" +
|
||||||
|
form.fields[fld].searchLabel + "</a></li>\n";
|
||||||
|
} else {
|
||||||
|
html += form.fields[fld].label.replace(/<br \/>/g, ' ') + "', " + idx + ")\">" +
|
||||||
|
form.fields[fld].label.replace(/<br \/>/g, ' ') + "</a></li>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 1; i <= searchWidgets; i++) {
|
for (i = 1; i <= searchWidgets; i++) {
|
||||||
modifier = (i === 1) ? '' : i;
|
modifier = (i === 1) ? '' : i;
|
||||||
@@ -713,21 +734,7 @@ angular.module('GeneratorHelpers', [])
|
|||||||
html += "<span class=\"caret\"></span>\n";
|
html += "<span class=\"caret\"></span>\n";
|
||||||
html += "</button>\n";
|
html += "</button>\n";
|
||||||
html += "<ul class=\"dropdown-menu\" id=\"" + iterator + "SearchDropdown" + modifier + "\">\n";
|
html += "<ul class=\"dropdown-menu\" id=\"" + iterator + "SearchDropdown" + modifier + "\">\n";
|
||||||
for (fld in form.fields) {
|
html += addSearchFields(i);
|
||||||
if ((form.fields[fld].searchable === undefined || form.fields[fld].searchable === true) &&
|
|
||||||
(((form.fields[fld].searchWidget === undefined || form.fields[fld].searchWidget === 1) && i === 1) ||
|
|
||||||
(form.fields[fld].searchWidget === i))) {
|
|
||||||
html += "<li><a href=\"\" ng-click=\"setSearchField('" + iterator + "','";
|
|
||||||
html += fld + "','";
|
|
||||||
if (form.fields[fld].searchLabel) {
|
|
||||||
html += form.fields[fld].searchLabel + "', " + i + ")\">" +
|
|
||||||
form.fields[fld].searchLabel + "</a></li>\n";
|
|
||||||
} else {
|
|
||||||
html += form.fields[fld].label.replace(/<br \/>/g, ' ') + "', " + i + ")\">" +
|
|
||||||
form.fields[fld].label.replace(/<br \/>/g, ' ') + "</a></li>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html += "</ul>\n";
|
html += "</ul>\n";
|
||||||
html += "</div><!-- input-group-btn -->\n";
|
html += "</div><!-- input-group-btn -->\n";
|
||||||
|
|
||||||
|
|||||||
@@ -331,7 +331,7 @@
|
|||||||
<h3 ng-bind="alertHeader"></h3>
|
<h3 ng-bind="alertHeader"></h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div id="alert-modal-msg" class="alert" ng-class="alertClass" ng-bind-html="alertBody"></div>
|
<div id="alert-modal-msg" class="alert" ng-bind-html="alertBody"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a href="#" ng-hide="disableButtons" data-target="#form-modal" data-dismiss="modal" id="alert_ok_btn" class="btn btn-primary">OK</a>
|
<a href="#" ng-hide="disableButtons" data-target="#form-modal" data-dismiss="modal" id="alert_ok_btn" class="btn btn-primary">OK</a>
|
||||||
@@ -349,7 +349,7 @@
|
|||||||
<h3 ng-bind="alertHeader2"></h3>
|
<h3 ng-bind="alertHeader2"></h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div id="alert2-modal-msg" class="alert" ng-class="alertClass2" ng-bind-html="alertBody2"></div>
|
<div id="alert2-modal-msg" class="alert" ng-bind-html="alertBody2"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a href="#" ng-hide="disableButtons2" data-target="#form-modal2" data-dismiss="modal" id="alert2_ok_btn" class="btn btn-primary">OK</a>
|
<a href="#" ng-hide="disableButtons2" data-target="#form-modal2" data-dismiss="modal" id="alert2_ok_btn" class="btn btn-primary">OK</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user