mirror of
https://github.com/ansible/awx.git
synced 2026-05-17 06:17:36 -02:30
job template labels ui implementation
This commit is contained in:
@@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
.RoleList-deleteContainer {
|
.RoleList-deleteContainer {
|
||||||
border: 1px solid @default-second-border;
|
border: 1px solid @default-second-border;
|
||||||
|
border-left-color: @default-bg;
|
||||||
|
background-color: @default-bg;
|
||||||
border-top-right-radius: 5px;
|
border-top-right-radius: 5px;
|
||||||
border-bottom-right-radius: 5px;
|
border-bottom-right-radius: 5px;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
|
|||||||
@@ -189,6 +189,18 @@ export default
|
|||||||
dataPlacement: "right",
|
dataPlacement: "right",
|
||||||
dataContainer: "body"
|
dataContainer: "body"
|
||||||
},
|
},
|
||||||
|
labels: {
|
||||||
|
label: 'Labels',
|
||||||
|
type: 'select',
|
||||||
|
ngOptions: 'label.label for label in labelOptions track by label.value',
|
||||||
|
multiSelect: true,
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
dataTitle: 'Labels',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
awPopOver: 'You can add labels to a job template to aid in filtering',
|
||||||
|
dataContainer: 'body'
|
||||||
|
},
|
||||||
variables: {
|
variables: {
|
||||||
label: 'Extra Variables',
|
label: 'Extra Variables',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
|
|||||||
@@ -11,14 +11,14 @@
|
|||||||
'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList',
|
'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList',
|
||||||
'LookUpInit', 'md5Setup', 'ParseTypeChange', 'Wait', 'Empty', 'ToJSON',
|
'LookUpInit', 'md5Setup', 'ParseTypeChange', 'Wait', 'Empty', 'ToJSON',
|
||||||
'CallbackHelpInit', 'initSurvey', 'Prompt', 'GetChoices', '$state',
|
'CallbackHelpInit', 'initSurvey', 'Prompt', 'GetChoices', '$state',
|
||||||
'CreateSelect2',
|
'CreateSelect2', '$q',
|
||||||
function(
|
function(
|
||||||
Refresh, $filter, $scope, $rootScope, $compile,
|
Refresh, $filter, $scope, $rootScope, $compile,
|
||||||
$location, $log, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
$location, $log, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
||||||
ProcessErrors, ReturnToCaller, ClearScope, GetBasePath, InventoryList,
|
ProcessErrors, ReturnToCaller, ClearScope, GetBasePath, InventoryList,
|
||||||
CredentialList, ProjectList, LookUpInit, md5Setup, ParseTypeChange, Wait,
|
CredentialList, ProjectList, LookUpInit, md5Setup, ParseTypeChange, Wait,
|
||||||
Empty, ToJSON, CallbackHelpInit, SurveyControllerInit, Prompt, GetChoices,
|
Empty, ToJSON, CallbackHelpInit, SurveyControllerInit, Prompt, GetChoices,
|
||||||
$state, CreateSelect2
|
$state, CreateSelect2, $q
|
||||||
) {
|
) {
|
||||||
|
|
||||||
ClearScope();
|
ClearScope();
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
}
|
}
|
||||||
$scope.removeChoicesReady = $scope.$on('choicesReadyVerbosity', function () {
|
$scope.removeChoicesReady = $scope.$on('choicesReadyVerbosity', function () {
|
||||||
selectCount++;
|
selectCount++;
|
||||||
if (selectCount === 2) {
|
if (selectCount === 3) {
|
||||||
var verbosity;
|
var verbosity;
|
||||||
// this sets the default options for the selects as specified by the controller.
|
// this sets the default options for the selects as specified by the controller.
|
||||||
for (verbosity in $scope.verbosity_options) {
|
for (verbosity in $scope.verbosity_options) {
|
||||||
@@ -145,7 +145,11 @@
|
|||||||
element:'#job_templates_job_type',
|
element:'#job_templates_job_type',
|
||||||
multiple: false
|
multiple: false
|
||||||
});
|
});
|
||||||
|
CreateSelect2({
|
||||||
|
element:'#job_templates_labels',
|
||||||
|
multiple: true,
|
||||||
|
addNew: true
|
||||||
|
});
|
||||||
CreateSelect2({
|
CreateSelect2({
|
||||||
element:'#playbook-select',
|
element:'#playbook-select',
|
||||||
multiple: false
|
multiple: false
|
||||||
@@ -178,6 +182,21 @@
|
|||||||
callback: 'choicesReadyVerbosity'
|
callback: 'choicesReadyVerbosity'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Rest.setUrl('api/v1/labels');
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
$scope.labelOptions = data.results
|
||||||
|
.map((i) => ({label: i.name, value: i.id}));
|
||||||
|
$scope.$emit("choicesReadyVerbosity");
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, form, {
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to get labels. GET returned ' +
|
||||||
|
'status: ' + status
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Update playbook select whenever project value changes
|
// Update playbook select whenever project value changes
|
||||||
selectPlaybook = function (oldValue, newValue) {
|
selectPlaybook = function (oldValue, newValue) {
|
||||||
var url;
|
var url;
|
||||||
@@ -265,12 +284,6 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// $scope.selectPlaybookUnregister = $scope.$watch('project_name', function (newval, oldval) {
|
|
||||||
// selectPlaybook(oldval, newval);
|
|
||||||
// checkSCMStatus(oldval, newval);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Register a watcher on project_name
|
// Register a watcher on project_name
|
||||||
if ($scope.selectPlaybookUnregister) {
|
if ($scope.selectPlaybookUnregister) {
|
||||||
$scope.selectPlaybookUnregister();
|
$scope.selectPlaybookUnregister();
|
||||||
@@ -311,14 +324,126 @@
|
|||||||
}
|
}
|
||||||
$scope.removeTemplateSaveSuccess = $scope.$on('templateSaveSuccess', function(e, data) {
|
$scope.removeTemplateSaveSuccess = $scope.$on('templateSaveSuccess', function(e, data) {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
if (data.related && data.related.callback) {
|
if (data.related &&
|
||||||
Alert('Callback URL', '<p>Host callbacks are enabled for this template. The callback URL is:</p>'+
|
data.related.callback) {
|
||||||
'<p style="padding: 10px 0;"><strong>' + $scope.callback_server_path + data.related.callback + '</strong></p>'+
|
Alert('Callback URL',
|
||||||
'<p>The host configuration key is: <strong>' + $filter('sanitize')(data.host_config_key) + '</strong></p>', 'alert-info', saveCompleted, null, null, null, true);
|
`
|
||||||
}
|
<p>Host callbacks are enabled for this template. The callback URL is:</p>
|
||||||
else {
|
<p style=\"padding: 10px 0;\">
|
||||||
saveCompleted();
|
<strong>
|
||||||
|
${$scope.callback_server_path}
|
||||||
|
${data.related.callback}
|
||||||
|
</string>
|
||||||
|
</p>
|
||||||
|
<p>The host configuration key is:
|
||||||
|
<strong>
|
||||||
|
${$filter('sanitize')(data.host_config_key)}
|
||||||
|
</string>
|
||||||
|
</p>
|
||||||
|
`,
|
||||||
|
'alert-info', saveCompleted, null, null,
|
||||||
|
null, true);
|
||||||
}
|
}
|
||||||
|
var orgDefer = $q.defer();
|
||||||
|
var associationDefer = $q.defer();
|
||||||
|
|
||||||
|
Rest.setUrl(data.related.labels);
|
||||||
|
|
||||||
|
var currentLabels = Rest.get()
|
||||||
|
.then(function(data) {
|
||||||
|
return data.data.results
|
||||||
|
.map(val => val.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
currentLabels.then(function (current) {
|
||||||
|
var labelsToAdd = $scope.labels
|
||||||
|
.map(val => val.value);
|
||||||
|
var labelsToDisassociate = current
|
||||||
|
.filter(val => labelsToAdd
|
||||||
|
.indexOf(val) === -1)
|
||||||
|
.map(val => ({id: val, disassociate: true}));
|
||||||
|
var labelsToAssociate = labelsToAdd
|
||||||
|
.filter(val => current
|
||||||
|
.indexOf(val) === -1)
|
||||||
|
.map(val => ({id: val, associate: true}));
|
||||||
|
var pass = labelsToDisassociate
|
||||||
|
.concat(labelsToAssociate);
|
||||||
|
associationDefer.resolve(pass);
|
||||||
|
});
|
||||||
|
|
||||||
|
Rest.setUrl(GetBasePath("organizations"));
|
||||||
|
Rest.get()
|
||||||
|
.success(function(data) {
|
||||||
|
orgDefer.resolve(data.results[0].id);
|
||||||
|
});
|
||||||
|
|
||||||
|
orgDefer.promise.then(function(orgId) {
|
||||||
|
var toPost = [];
|
||||||
|
$scope.newLabels = $scope.newLabels
|
||||||
|
.map(function(i, val) {
|
||||||
|
val.organization = orgId;
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.newLabels.each(function(i, val) {
|
||||||
|
toPost.push(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
associationDefer.promise.then(function(arr) {
|
||||||
|
toPost = toPost
|
||||||
|
.concat(arr);
|
||||||
|
|
||||||
|
Rest.setUrl(data.related.labels);
|
||||||
|
|
||||||
|
var defers = [];
|
||||||
|
for (var i = 0; i < toPost.length; i++) {
|
||||||
|
defers.push(Rest.post(toPost[i]));
|
||||||
|
}
|
||||||
|
$q.all(defers)
|
||||||
|
.then(function() {
|
||||||
|
$scope.addedItem = data.id;
|
||||||
|
|
||||||
|
Refresh({
|
||||||
|
scope: $scope,
|
||||||
|
set: 'job_templates',
|
||||||
|
iterator: 'job_template',
|
||||||
|
url: $scope.current_url
|
||||||
|
});
|
||||||
|
|
||||||
|
if($scope.survey_questions &&
|
||||||
|
$scope.survey_questions.length > 0){
|
||||||
|
//once the job template information
|
||||||
|
// is saved we submit the survey
|
||||||
|
// info to the correct endpoint
|
||||||
|
var url = data.url+ 'survey_spec/';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.post({ name: $scope.survey_name,
|
||||||
|
description: $scope.survey_description,
|
||||||
|
spec: $scope.survey_questions })
|
||||||
|
.success(function () {
|
||||||
|
Wait('stop');
|
||||||
|
})
|
||||||
|
.error(function (data,
|
||||||
|
status) {
|
||||||
|
ProcessErrors(
|
||||||
|
$scope,
|
||||||
|
data,
|
||||||
|
status,
|
||||||
|
form,
|
||||||
|
{
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to add new ' +
|
||||||
|
'survey. Post returned ' +
|
||||||
|
'status: ' +
|
||||||
|
status
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
saveCompleted();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
@@ -327,11 +452,13 @@
|
|||||||
$scope.invalid_survey = false;
|
$scope.invalid_survey = false;
|
||||||
|
|
||||||
// users can't save a survey with a scan job
|
// users can't save a survey with a scan job
|
||||||
if($scope.job_type.value === "scan" && $scope.survey_enabled === true){
|
if($scope.job_type.value === "scan" &&
|
||||||
|
$scope.survey_enabled === true){
|
||||||
$scope.survey_enabled = false;
|
$scope.survey_enabled = false;
|
||||||
}
|
}
|
||||||
// Can't have a survey enabled without a survey
|
// Can't have a survey enabled without a survey
|
||||||
if($scope.survey_enabled === true && $scope.survey_exists!==true){
|
if($scope.survey_enabled === true &&
|
||||||
|
$scope.survey_exists!==true){
|
||||||
$scope.survey_enabled = false;
|
$scope.survey_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,70 +468,61 @@
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
for (fld in form.fields) {
|
for (fld in form.fields) {
|
||||||
if (form.fields[fld].type === 'select' && fld !== 'playbook') {
|
if (form.fields[fld].type === 'select' &&
|
||||||
|
fld !== 'playbook') {
|
||||||
data[fld] = $scope[fld].value;
|
data[fld] = $scope[fld].value;
|
||||||
} else {
|
} else {
|
||||||
if (fld !== 'variables' && fld !== 'survey') {
|
if (fld !== 'variables' &&
|
||||||
|
fld !== 'survey') {
|
||||||
data[fld] = $scope[fld];
|
data[fld] = $scope[fld];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.extra_vars = ToJSON($scope.parseType, $scope.variables, true);
|
data.extra_vars = ToJSON($scope.parseType,
|
||||||
if(data.job_type === 'scan' && $scope.default_scan === true){
|
$scope.variables, true);
|
||||||
|
if(data.job_type === 'scan' &&
|
||||||
|
$scope.default_scan === true){
|
||||||
data.project = "";
|
data.project = "";
|
||||||
data.playbook = "";
|
data.playbook = "";
|
||||||
}
|
}
|
||||||
// We only want to set the survey_enabled flag to true for this job template if a survey exists
|
// We only want to set the survey_enabled flag to
|
||||||
// and it's been enabled. By default, survey_enabled is explicitly set to true but if no survey
|
// true for this job template if a survey exists
|
||||||
// is created then we don't want it enabled.
|
// and it's been enabled. By default,
|
||||||
data.survey_enabled = ($scope.survey_enabled && $scope.survey_exists) ? $scope.survey_enabled : false;
|
// survey_enabled is explicitly set to true but
|
||||||
|
// if no survey is created then we don't want
|
||||||
|
// it enabled.
|
||||||
|
data.survey_enabled = ($scope.survey_enabled &&
|
||||||
|
$scope.survey_exists) ? $scope.survey_enabled : false;
|
||||||
|
|
||||||
|
$scope.newLabels = $("#job_templates_labels > option")
|
||||||
|
.filter("[data-select2-tag=true]")
|
||||||
|
.map((i, val) => ({name: $(val).text()}));
|
||||||
|
|
||||||
Rest.setUrl(defaultUrl);
|
Rest.setUrl(defaultUrl);
|
||||||
Rest.post(data)
|
Rest.post(data)
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
$scope.$emit('templateSaveSuccess', data);
|
$scope.$emit('templateSaveSuccess',
|
||||||
|
data);
|
||||||
$scope.addedItem = data.id;
|
|
||||||
|
|
||||||
Refresh({
|
|
||||||
scope: $scope,
|
|
||||||
set: 'job_templates',
|
|
||||||
iterator: 'job_template',
|
|
||||||
url: $scope.current_url
|
|
||||||
});
|
|
||||||
|
|
||||||
if($scope.survey_questions && $scope.survey_questions.length > 0){
|
|
||||||
//once the job template information is saved we submit the survey info to the correct endpoint
|
|
||||||
var url = data.url+ 'survey_spec/';
|
|
||||||
Rest.setUrl(url);
|
|
||||||
Rest.post({ name: $scope.survey_name, description: $scope.survey_description, spec: $scope.survey_questions })
|
|
||||||
.success(function () {
|
|
||||||
Wait('stop');
|
|
||||||
|
|
||||||
})
|
|
||||||
.error(function (data, status) {
|
|
||||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
|
||||||
msg: 'Failed to add new survey. Post returned status: ' + status });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
ProcessErrors($scope, data, status, form,
|
||||||
msg: 'Failed to add new job template. POST returned status: ' + status
|
{
|
||||||
});
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to add new job ' +
|
||||||
|
'template. POST returned status: ' +
|
||||||
|
status
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
Alert("Error", "Error parsing extra variables. Parser returned: " + err);
|
Alert("Error", "Error parsing extra variables. " +
|
||||||
|
"Parser returned: " + err);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.formCancel = function () {
|
$scope.formCancel = function () {
|
||||||
$state.transitionTo('jobTemplates');
|
$state.transitionTo('jobTemplates');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default
|
|||||||
'SchedulesControllerInit', 'JobsControllerInit', 'JobsListUpdate',
|
'SchedulesControllerInit', 'JobsControllerInit', 'JobsListUpdate',
|
||||||
'GetChoices', 'SchedulesListInit', 'SchedulesList', 'CallbackHelpInit',
|
'GetChoices', 'SchedulesListInit', 'SchedulesList', 'CallbackHelpInit',
|
||||||
'PlaybookRun' , 'initSurvey', '$state', 'CreateSelect2',
|
'PlaybookRun' , 'initSurvey', '$state', 'CreateSelect2',
|
||||||
'ToggleNotification', 'NotificationsListInit',
|
'ToggleNotification', 'NotificationsListInit', '$q',
|
||||||
function(
|
function(
|
||||||
$filter, $scope, $rootScope, $compile,
|
$filter, $scope, $rootScope, $compile,
|
||||||
$location, $log, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
$location, $log, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
||||||
@@ -31,7 +31,7 @@ export default
|
|||||||
Empty, Prompt, ParseVariableString, ToJSON, SchedulesControllerInit,
|
Empty, Prompt, ParseVariableString, ToJSON, SchedulesControllerInit,
|
||||||
JobsControllerInit, JobsListUpdate, GetChoices, SchedulesListInit,
|
JobsControllerInit, JobsListUpdate, GetChoices, SchedulesListInit,
|
||||||
SchedulesList, CallbackHelpInit, PlaybookRun, SurveyControllerInit, $state,
|
SchedulesList, CallbackHelpInit, PlaybookRun, SurveyControllerInit, $state,
|
||||||
CreateSelect2, ToggleNotification, NotificationsListInit
|
CreateSelect2, ToggleNotification, NotificationsListInit, $q
|
||||||
) {
|
) {
|
||||||
|
|
||||||
ClearScope();
|
ClearScope();
|
||||||
@@ -232,11 +232,6 @@ export default
|
|||||||
multiple: false
|
multiple: false
|
||||||
});
|
});
|
||||||
|
|
||||||
CreateSelect2({
|
|
||||||
element:'#job_templates_verbosity',
|
|
||||||
multiple: false
|
|
||||||
});
|
|
||||||
|
|
||||||
for (var set in relatedSets) {
|
for (var set in relatedSets) {
|
||||||
$scope.search(relatedSets[set].iterator);
|
$scope.search(relatedSets[set].iterator);
|
||||||
}
|
}
|
||||||
@@ -353,7 +348,7 @@ export default
|
|||||||
}
|
}
|
||||||
$scope.removeChoicesReady = $scope.$on('choicesReady', function() {
|
$scope.removeChoicesReady = $scope.$on('choicesReady', function() {
|
||||||
choicesCount++;
|
choicesCount++;
|
||||||
if (choicesCount === 4) {
|
if (choicesCount === 5) {
|
||||||
$scope.$emit('LoadJobs');
|
$scope.$emit('LoadJobs');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -392,6 +387,41 @@ export default
|
|||||||
callback: 'choicesReady'
|
callback: 'choicesReady'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Rest.setUrl('api/v1/labels');
|
||||||
|
Wait("start");
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
$scope.labelOptions = data.results
|
||||||
|
.map((i) => ({label: i.name, value: i.id}));
|
||||||
|
$scope.$emit("choicesReady");
|
||||||
|
Rest.setUrl(defaultUrl + $state.params.template_id +
|
||||||
|
"/labels");
|
||||||
|
Rest.get()
|
||||||
|
.success(function(data) {
|
||||||
|
var opts = data.results
|
||||||
|
.map(i => ({id: i.id + "",
|
||||||
|
test: i.name}));
|
||||||
|
CreateSelect2({
|
||||||
|
element:'#job_templates_labels',
|
||||||
|
multiple: true,
|
||||||
|
addNew: true,
|
||||||
|
opts: opts
|
||||||
|
});
|
||||||
|
Wait("stop");
|
||||||
|
});
|
||||||
|
CreateSelect2({
|
||||||
|
element:'#job_templates_verbosity',
|
||||||
|
multiple: false
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, form, {
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to get labels. GET returned ' +
|
||||||
|
'status: ' + status
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function saveCompleted() {
|
function saveCompleted() {
|
||||||
$state.go('jobTemplates', null, {reload: true});
|
$state.go('jobTemplates', null, {reload: true});
|
||||||
}
|
}
|
||||||
@@ -401,34 +431,105 @@ export default
|
|||||||
}
|
}
|
||||||
$scope.removeTemplateSaveSuccess = $scope.$on('templateSaveSuccess', function(e, data) {
|
$scope.removeTemplateSaveSuccess = $scope.$on('templateSaveSuccess', function(e, data) {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
if ($scope.allow_callbacks && ($scope.host_config_key !== master.host_config_key || $scope.callback_url !== master.callback_url)) {
|
if (data.related &&
|
||||||
if (data.related && data.related.callback) {
|
data.related.callback) {
|
||||||
Alert('Callback URL', '<p>Host callbacks are enabled for this template. The callback URL is:</p>'+
|
Alert('Callback URL',
|
||||||
'<p style="padding: 10px 0;"><strong>' + $scope.callback_server_path + data.related.callback + '</strong></p>'+
|
`
|
||||||
'<p>The host configuration key is: <strong>' + $filter('sanitize')(data.host_config_key) + '</strong></p>', 'alert-info', saveCompleted, null, null, null, true);
|
<p>Host callbacks are enabled for this template. The callback URL is:</p>
|
||||||
}
|
<p style=\"padding: 10px 0;\">
|
||||||
else {
|
<strong>
|
||||||
saveCompleted();
|
${$scope.callback_server_path}
|
||||||
}
|
${data.related.callback}
|
||||||
}
|
</string>
|
||||||
else {
|
</p>
|
||||||
saveCompleted();
|
<p>The host configuration key is:
|
||||||
|
<strong>
|
||||||
|
${$filter('sanitize')(data.host_config_key)}
|
||||||
|
</string>
|
||||||
|
</p>
|
||||||
|
`,
|
||||||
|
'alert-info', saveCompleted, null, null,
|
||||||
|
null, true);
|
||||||
}
|
}
|
||||||
|
var orgDefer = $q.defer();
|
||||||
|
var associationDefer = $q.defer();
|
||||||
|
|
||||||
|
Rest.setUrl(data.related.labels);
|
||||||
|
|
||||||
|
var currentLabels = Rest.get()
|
||||||
|
.then(function(data) {
|
||||||
|
return data.data.results
|
||||||
|
.map(val => val.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
currentLabels.then(function (current) {
|
||||||
|
var labelsToAdd = $scope.labels
|
||||||
|
.map(val => val.value);
|
||||||
|
var labelsToDisassociate = current
|
||||||
|
.filter(val => labelsToAdd
|
||||||
|
.indexOf(val) === -1)
|
||||||
|
.map(val => ({id: val, disassociate: true}));
|
||||||
|
var labelsToAssociate = labelsToAdd
|
||||||
|
.filter(val => current
|
||||||
|
.indexOf(val) === -1)
|
||||||
|
.map(val => ({id: val, associate: true}));
|
||||||
|
var pass = labelsToDisassociate
|
||||||
|
.concat(labelsToAssociate);
|
||||||
|
associationDefer.resolve(pass);
|
||||||
|
});
|
||||||
|
|
||||||
|
Rest.setUrl(GetBasePath("organizations"));
|
||||||
|
Rest.get()
|
||||||
|
.success(function(data) {
|
||||||
|
orgDefer.resolve(data.results[0].id);
|
||||||
|
});
|
||||||
|
|
||||||
|
orgDefer.promise.then(function(orgId) {
|
||||||
|
var toPost = [];
|
||||||
|
$scope.newLabels = $scope.newLabels
|
||||||
|
.map(function(i, val) {
|
||||||
|
val.organization = orgId;
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.newLabels.each(function(i, val) {
|
||||||
|
toPost.push(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
associationDefer.promise.then(function(arr) {
|
||||||
|
toPost = toPost
|
||||||
|
.concat(arr);
|
||||||
|
|
||||||
|
Rest.setUrl(data.related.labels);
|
||||||
|
|
||||||
|
var defers = [];
|
||||||
|
for (var i = 0; i < toPost.length; i++) {
|
||||||
|
defers.push(Rest.post(toPost[i]));
|
||||||
|
}
|
||||||
|
$q.all(defers)
|
||||||
|
.then(function() {
|
||||||
|
saveCompleted();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Save changes to the parent
|
// Save changes to the parent
|
||||||
|
// Save
|
||||||
$scope.formSave = function () {
|
$scope.formSave = function () {
|
||||||
var fld, data = {};
|
var fld, data = {};
|
||||||
$scope.invalid_survey = false;
|
$scope.invalid_survey = false;
|
||||||
|
|
||||||
// users can't save a survey with a scan job
|
// users can't save a survey with a scan job
|
||||||
if($scope.job_type.value === "scan" && $scope.survey_enabled === true){
|
if($scope.job_type.value === "scan" &&
|
||||||
|
$scope.survey_enabled === true){
|
||||||
$scope.survey_enabled = false;
|
$scope.survey_enabled = false;
|
||||||
}
|
}
|
||||||
// Can't have a survey enabled without a survey
|
// Can't have a survey enabled without a survey
|
||||||
if($scope.survey_enabled === true && $scope.survey_exists!==true){
|
if($scope.survey_enabled === true &&
|
||||||
|
$scope.survey_exists!==true){
|
||||||
$scope.survey_enabled = false;
|
$scope.survey_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,21 +538,38 @@ export default
|
|||||||
Wait('start');
|
Wait('start');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Make sure we have valid variable data
|
|
||||||
data.extra_vars = ToJSON($scope.parseType, $scope.variables, true);
|
|
||||||
if(data.extra_vars === undefined ){
|
|
||||||
throw 'undefined variables';
|
|
||||||
}
|
|
||||||
for (fld in form.fields) {
|
for (fld in form.fields) {
|
||||||
if (form.fields[fld].type === 'select' && fld !== 'playbook') {
|
if (form.fields[fld].type === 'select' &&
|
||||||
|
fld !== 'playbook') {
|
||||||
data[fld] = $scope[fld].value;
|
data[fld] = $scope[fld].value;
|
||||||
} else {
|
} else {
|
||||||
if (fld !== 'variables' && fld !== 'callback_url') {
|
if (fld !== 'variables' &&
|
||||||
|
fld !== 'survey') {
|
||||||
data[fld] = $scope[fld];
|
data[fld] = $scope[fld];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rest.setUrl(defaultUrl + id + '/');
|
data.extra_vars = ToJSON($scope.parseType,
|
||||||
|
$scope.variables, true);
|
||||||
|
if(data.job_type === 'scan' &&
|
||||||
|
$scope.default_scan === true){
|
||||||
|
data.project = "";
|
||||||
|
data.playbook = "";
|
||||||
|
}
|
||||||
|
// We only want to set the survey_enabled flag to
|
||||||
|
// true for this job template if a survey exists
|
||||||
|
// and it's been enabled. By default,
|
||||||
|
// survey_enabled is explicitly set to true but
|
||||||
|
// if no survey is created then we don't want
|
||||||
|
// it enabled.
|
||||||
|
data.survey_enabled = ($scope.survey_enabled &&
|
||||||
|
$scope.survey_exists) ? $scope.survey_enabled : false;
|
||||||
|
|
||||||
|
$scope.newLabels = $("#job_templates_labels > option")
|
||||||
|
.filter("[data-select2-tag=true]")
|
||||||
|
.map((i, val) => ({name: $(val).text()}));
|
||||||
|
|
||||||
|
Rest.setUrl(defaultUrl + $state.params.template_id);
|
||||||
Rest.put(data)
|
Rest.put(data)
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
$scope.$emit('templateSaveSuccess', data);
|
$scope.$emit('templateSaveSuccess', data);
|
||||||
@@ -460,12 +578,11 @@ export default
|
|||||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
||||||
msg: 'Failed to update job template. PUT returned status: ' + status });
|
msg: 'Failed to update job template. PUT returned status: ' + status });
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
Alert("Error", "Error parsing extra variables. Parser returned: " + err);
|
Alert("Error", "Error parsing extra variables. " +
|
||||||
|
"Parser returned: " + err);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.formCancel = function () {
|
$scope.formCancel = function () {
|
||||||
@@ -474,7 +591,7 @@ export default
|
|||||||
var defaultUrl = GetBasePath('job_templates') + $state.params.template_id;
|
var defaultUrl = GetBasePath('job_templates') + $state.params.template_id;
|
||||||
Rest.setUrl(defaultUrl);
|
Rest.setUrl(defaultUrl);
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function(res){
|
.success(function(){
|
||||||
$state.go('jobTemplates', null, {reload: true, notify:true});
|
$state.go('jobTemplates', null, {reload: true, notify:true});
|
||||||
})
|
})
|
||||||
.error(function(res, status){
|
.error(function(res, status){
|
||||||
|
|||||||
74
awx/ui/client/src/job-templates/labels/labelsList.block.less
Normal file
74
awx/ui/client/src/job-templates/labels/labelsList.block.less
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/** @define LabelList */
|
||||||
|
@import "../shared/branding/colors.default.less";
|
||||||
|
|
||||||
|
.LabelList {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-tagContainer {
|
||||||
|
display: flex;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-tag {
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 2px 10px;
|
||||||
|
margin: 4px 0px;
|
||||||
|
border: 1px solid @default-second-border;
|
||||||
|
font-size: 12px;
|
||||||
|
color: @default-interface-txt;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background-color: @default-bg;
|
||||||
|
margin-right: 5px;
|
||||||
|
max-width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-tag--deletable {
|
||||||
|
margin-right: 0px;
|
||||||
|
border-top-right-radius: 0px;
|
||||||
|
border-bottom-right-radius: 0px;
|
||||||
|
border-right: 0;
|
||||||
|
max-wdith: ~"calc(100% - 23px)";
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-deleteContainer {
|
||||||
|
border: 1px solid @default-second-border;
|
||||||
|
border-left-color: @default-bg;
|
||||||
|
background-color: @default-bg;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin: 4px 0px;
|
||||||
|
margin-right: 5px;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-tagDelete {
|
||||||
|
font-size: 13px;
|
||||||
|
color: @default-icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-name {
|
||||||
|
flex: initial;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-tag--deletable > .LabelList-name {
|
||||||
|
max-width: ~"calc(100% - 23px)";
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-deleteContainer:hover, {
|
||||||
|
border-color: @default-err;
|
||||||
|
background-color: @default-err;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LabelList-deleteContainer:hover > .LabelList-tagDelete {
|
||||||
|
color: @default-bg;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/* jshint unused: vars */
|
||||||
|
export default
|
||||||
|
[ 'templateUrl',
|
||||||
|
'Wait',
|
||||||
|
'Rest',
|
||||||
|
'GetBasePath',
|
||||||
|
'ProcessErrors',
|
||||||
|
'Prompt',
|
||||||
|
function(templateUrl, Wait, Rest, GetBasePath, ProcessErrors, Prompt) {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
scope: false,
|
||||||
|
templateUrl: templateUrl('job-templates/labels/labelsList'),
|
||||||
|
link: function(scope, element, attrs) {
|
||||||
|
scope.labels = scope.
|
||||||
|
job_template.summary_fields.labels;
|
||||||
|
|
||||||
|
scope.deleteLabel = function(templateId, templateName, labelId, labelName) {
|
||||||
|
var action = function () {
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
Wait('start');
|
||||||
|
var url = GetBasePath("job_templates") + templateId + "/labels/";
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.post({"disassociate": true, "id": labelId})
|
||||||
|
.success(function () {
|
||||||
|
Wait('stop');
|
||||||
|
scope.search("job_template");
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Could not disacssociate label from JT. Call to ' + url + ' failed. DELETE returned status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Prompt({
|
||||||
|
hdr: 'Remove Label from ' + templateName,
|
||||||
|
body: '<div class="Prompt-bodyQuery">Confirm the removal of the <span class="Prompt-emphasis">' + labelName + '</span> label.</div>',
|
||||||
|
action: action,
|
||||||
|
actionText: 'REMOVE'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<div class="LabelList-tagContainer"
|
||||||
|
ng-repeat="label in labels">
|
||||||
|
<div class="LabelList-tag LabelList-tag--deletable">
|
||||||
|
<span class="LabelList-name">{{ label.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="LabelList-deleteContainer"
|
||||||
|
ng-click="deleteLabel(job_template.id, job_template.name, label.id, label.name)">
|
||||||
|
<i class="fa fa-times LabelList-tagDelete"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
11
awx/ui/client/src/job-templates/labels/main.js
Normal file
11
awx/ui/client/src/job-templates/labels/main.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2015 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
import labelsList from './labelsList.directive';
|
||||||
|
|
||||||
|
export default
|
||||||
|
angular.module('labels', [])
|
||||||
|
.directive('labelsList', labelsList);
|
||||||
@@ -11,9 +11,10 @@ import jobTemplatesList from './list/main';
|
|||||||
import jobTemplatesAdd from './add/main';
|
import jobTemplatesAdd from './add/main';
|
||||||
import jobTemplatesEdit from './edit/main';
|
import jobTemplatesEdit from './edit/main';
|
||||||
import jobTemplatesCopy from './copy/main';
|
import jobTemplatesCopy from './copy/main';
|
||||||
|
import labels from './labels/main';
|
||||||
|
|
||||||
export default
|
export default
|
||||||
angular.module('jobTemplates',
|
angular.module('jobTemplates',
|
||||||
[surveyMaker.name, jobTemplatesList.name, jobTemplatesAdd.name,
|
[surveyMaker.name, jobTemplatesList.name, jobTemplatesAdd.name,
|
||||||
jobTemplatesEdit.name, jobTemplatesCopy.name])
|
jobTemplatesEdit.name, jobTemplatesCopy.name, labels.name])
|
||||||
.service('deleteJobTemplate', deleteJobTemplate);
|
.service('deleteJobTemplate', deleteJobTemplate);
|
||||||
|
|||||||
@@ -23,19 +23,28 @@ export default
|
|||||||
name: {
|
name: {
|
||||||
key: true,
|
key: true,
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
columnClass: 'col-lg-3 col-md-3 col-sm-4 col-xs-4'
|
columnClass: 'col-lg-2 col-md-2 col-sm-4 col-xs-9'
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
label: 'Description',
|
label: 'Description',
|
||||||
columnClass: 'col-lg-3 col-md-3 hidden-sm hidden-xs'
|
columnClass: 'col-lg-2 hidden-md hidden-sm hidden-xs'
|
||||||
},
|
},
|
||||||
smart_status: {
|
smart_status: {
|
||||||
label: 'Activity',
|
label: 'Activity',
|
||||||
columnClass: 'List-tableCell col-lg-4 col-md-4 col-sm-5 col-xs-5',
|
columnClass: 'List-tableCell col-lg-3 col-md-4 hidden-sm hidden-xs',
|
||||||
searchable: false,
|
searchable: false,
|
||||||
nosort: true,
|
nosort: true,
|
||||||
ngInclude: "'/static/partials/job-template-smart-status.html'",
|
ngInclude: "'/static/partials/job-template-smart-status.html'",
|
||||||
type: 'template'
|
type: 'template'
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
label: 'Labels',
|
||||||
|
type: 'labels',
|
||||||
|
nosort: true,
|
||||||
|
columnClass: 'List-tableCell col-lg-3 col-md-3 hidden-sm hidden-xs',
|
||||||
|
searchType: 'related',
|
||||||
|
sourceModel: 'labels',
|
||||||
|
sourceField: 'name'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -52,7 +61,7 @@ export default
|
|||||||
|
|
||||||
fieldActions: {
|
fieldActions: {
|
||||||
|
|
||||||
columnClass: 'col-lg-2 col-md-2 col-sm-3 col-xs-3',
|
columnClass: 'col-lg-2 col-md-3 col-sm-3 col-xs-3',
|
||||||
|
|
||||||
submit: {
|
submit: {
|
||||||
label: 'Launch',
|
label: 'Launch',
|
||||||
|
|||||||
@@ -196,6 +196,8 @@
|
|||||||
|
|
||||||
.TagSearch-deleteContainer {
|
.TagSearch-deleteContainer {
|
||||||
border: 1px solid @default-second-border;
|
border: 1px solid @default-second-border;
|
||||||
|
border-left-color: @default-bg;
|
||||||
|
background-color: @default-bg;
|
||||||
border-top-right-radius: 5px;
|
border-top-right-radius: 5px;
|
||||||
border-bottom-right-radius: 5px;
|
border-bottom-right-radius: 5px;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
|
|||||||
@@ -3,9 +3,13 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', function(R
|
|||||||
// parse the field config object to return
|
// parse the field config object to return
|
||||||
// one of the searchTypes (for the left dropdown)
|
// one of the searchTypes (for the left dropdown)
|
||||||
this.buildType = function (field, key, id) {
|
this.buildType = function (field, key, id) {
|
||||||
|
var obj = {};
|
||||||
// build the value (key)
|
// build the value (key)
|
||||||
var value;
|
var value;
|
||||||
if (typeof(field.key) === String) {
|
if (field.sourceModel && field.sourceField) {
|
||||||
|
value = field.sourceModel + '__' + field.sourceField;
|
||||||
|
obj.related = true;
|
||||||
|
} else if (typeof(field.key) === String) {
|
||||||
value = field.key;
|
value = field.key;
|
||||||
} else {
|
} else {
|
||||||
value = key;
|
value = key;
|
||||||
@@ -27,23 +31,19 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', function(R
|
|||||||
type = 'text';
|
type = 'text';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj.id = id;
|
||||||
|
obj.value = value;
|
||||||
|
obj.label = label;
|
||||||
|
obj.type = type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return the built option
|
// return the built option
|
||||||
if (type === 'select') {
|
if (type === 'select') {
|
||||||
return {
|
obj.typeOptions = typeOptions;
|
||||||
id: id,
|
|
||||||
value: value,
|
|
||||||
label: label,
|
|
||||||
type: type,
|
|
||||||
typeOptions: typeOptions
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
id: id,
|
|
||||||
value: value,
|
|
||||||
label: label,
|
|
||||||
type: type
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
// given the fields that are searchable,
|
// given the fields that are searchable,
|
||||||
@@ -116,6 +116,45 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', function(R
|
|||||||
|
|
||||||
// returns the url with filter params
|
// returns the url with filter params
|
||||||
this.updateFilteredUrl = function(basePath, tags, pageSize) {
|
this.updateFilteredUrl = function(basePath, tags, pageSize) {
|
||||||
|
// remove the chain directive from all the urls that might have
|
||||||
|
// been added previously
|
||||||
|
tags = (tags || []).map(function(val) {
|
||||||
|
if (val.url.indexOf("chain__") !== -1) {
|
||||||
|
val.url = val.url.substring(("chain__").length);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
|
||||||
|
// separate those tags with the related: true attribute
|
||||||
|
var separateRelated = _.partition(tags, function(i) {
|
||||||
|
return i.related;
|
||||||
|
});
|
||||||
|
|
||||||
|
var relatedTags = separateRelated[0];
|
||||||
|
var nonRelatedTags = separateRelated[1];
|
||||||
|
|
||||||
|
if (relatedTags.length > 1) {
|
||||||
|
// separate query params that need the change directive
|
||||||
|
// but have different keys
|
||||||
|
var chainGroups = _.groupBy(relatedTags, function(i) {
|
||||||
|
return i.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// iterate over those groups and add the "chain__" to the
|
||||||
|
// beginning of all but the first of each url
|
||||||
|
relatedTags = _.flatten(_.map(chainGroups, function(group) {
|
||||||
|
return group.map(function(val, i) {
|
||||||
|
if (i !== 0) {
|
||||||
|
val.url = "chain__" + val.url;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
// combine the related and non related tags after chainifying
|
||||||
|
tags = relatedTags.concat(nonRelatedTags);
|
||||||
|
}
|
||||||
|
|
||||||
return basePath + "?" +
|
return basePath + "?" +
|
||||||
(tags || []).map(function (t) {
|
(tags || []).map(function (t) {
|
||||||
return t.url;
|
return t.url;
|
||||||
|
|||||||
@@ -616,7 +616,8 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
|
|||||||
options = params.opts,
|
options = params.opts,
|
||||||
multiple = (params.multiple!==undefined) ? params.multiple : true,
|
multiple = (params.multiple!==undefined) ? params.multiple : true,
|
||||||
placeholder = params.placeholder,
|
placeholder = params.placeholder,
|
||||||
customDropdownAdapter = (params.customDropdownAdapter!==undefined) ? params.customDropdownAdapter : true;
|
customDropdownAdapter = (params.customDropdownAdapter!==undefined) ? params.customDropdownAdapter : true,
|
||||||
|
addNew = params.addNew;
|
||||||
|
|
||||||
$.fn.select2.amd.require([
|
$.fn.select2.amd.require([
|
||||||
'select2/utils',
|
'select2/utils',
|
||||||
@@ -624,11 +625,12 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
|
|||||||
'select2/dropdown/search',
|
'select2/dropdown/search',
|
||||||
'select2/dropdown/attachContainer',
|
'select2/dropdown/attachContainer',
|
||||||
'select2/dropdown/closeOnSelect',
|
'select2/dropdown/closeOnSelect',
|
||||||
'select2/dropdown/minimumResultsForSearch'
|
'select2/dropdown/minimumResultsForSearch',
|
||||||
], function (Utils, Dropdown, Search, AttachContainer, CloseOnSelect, MinimumResultsForSearch) {
|
'select2/data/tokenizer'
|
||||||
|
], function (Utils, Dropdown, Search, AttachContainer, CloseOnSelect, MinimumResultsForSearch, Tokenizer) {
|
||||||
|
|
||||||
var CustomAdapter =
|
var CustomAdapter =
|
||||||
_.reduce([Search, AttachContainer, CloseOnSelect, MinimumResultsForSearch],
|
_.reduce([Search, AttachContainer, CloseOnSelect, MinimumResultsForSearch, Tokenizer],
|
||||||
function(Adapter, Decorator) {
|
function(Adapter, Decorator) {
|
||||||
return Utils.Decorate(Adapter, Decorator);
|
return Utils.Decorate(Adapter, Decorator);
|
||||||
}, Dropdown);
|
}, Dropdown);
|
||||||
@@ -639,14 +641,20 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
|
|||||||
containerCssClass: 'Form-dropDown',
|
containerCssClass: 'Form-dropDown',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
minimumResultsForSearch: Infinity,
|
minimumResultsForSearch: Infinity,
|
||||||
}
|
};
|
||||||
|
|
||||||
// multiple-choice directive calls select2 but needs to do so without this custom adapter
|
// multiple-choice directive calls select2 but needs to do so without this custom adapter
|
||||||
// to allow the element to be draggable on survey preview.
|
// to allow the element to be draggable on survey preview.
|
||||||
if(customDropdownAdapter) {
|
if (customDropdownAdapter) {
|
||||||
config.dropdownAdapter = CustomAdapter;
|
config.dropdownAdapter = CustomAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addNew) {
|
||||||
|
$(element).prepend("<option></option>");
|
||||||
|
config.tags = true;
|
||||||
|
config.tokenSeparators = [];
|
||||||
|
}
|
||||||
|
|
||||||
$(element).select2(config);
|
$(element).select2(config);
|
||||||
|
|
||||||
if(options){
|
if(options){
|
||||||
@@ -884,7 +892,7 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
.factory('ParamPass', function() {
|
.factory('ParamPass', function() {
|
||||||
var savedData = undefined;
|
var savedData;
|
||||||
|
|
||||||
function set(data) {
|
function set(data) {
|
||||||
savedData = data;
|
savedData = data;
|
||||||
@@ -899,5 +907,5 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
|
|||||||
return {
|
return {
|
||||||
set: set,
|
set: set,
|
||||||
get: get
|
get: get
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -448,12 +448,29 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
|||||||
options = params.options,
|
options = params.options,
|
||||||
base = params.base,
|
base = params.base,
|
||||||
field = list.fields[fld],
|
field = list.fields[fld],
|
||||||
html = '';
|
html = '',
|
||||||
|
classList;
|
||||||
|
|
||||||
if (field.type !== undefined && field.type === 'DropDown') {
|
if (field.type !== undefined && field.type === 'DropDown') {
|
||||||
html = DropDown(params);
|
html = DropDown(params);
|
||||||
} else if (field.type === 'role') {
|
} else if (field.type === 'role') {
|
||||||
html += "<td class=\"List-tableCell\"><role-list class=\"RoleList\"></role-list></td>";
|
classList = (field.columnClass) ?
|
||||||
|
Attr(field, 'columnClass') : "";
|
||||||
|
html += `
|
||||||
|
<td ${classList}>
|
||||||
|
<role-list class=\"RoleList\">
|
||||||
|
</role-list>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
} else if (field.type === 'labels') {
|
||||||
|
classList = (field.columnClass) ?
|
||||||
|
Attr(field, 'columnClass') : "";
|
||||||
|
html += `
|
||||||
|
<td ${classList}>
|
||||||
|
<labels-list class=\"LabelList\">
|
||||||
|
</labels-list>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
} else if (field.type === 'badgeCount') {
|
} else if (field.type === 'badgeCount') {
|
||||||
html = BadgeCount(params);
|
html = BadgeCount(params);
|
||||||
} else if (field.type === 'badgeOnly') {
|
} else if (field.type === 'badgeOnly') {
|
||||||
|
|||||||
Reference in New Issue
Block a user