mirror of
https://github.com/ansible/awx.git
synced 2026-01-22 15:08:03 -03:30
Create/edit survey re-work
This commit is contained in:
parent
2d31021296
commit
0f2d924adb
@ -2058,7 +2058,8 @@ tr td button i {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.select2-container--disabled,.select2-container--disabled .select2-selection--single{
|
||||
/* Overwrite select2 base styles for single/multiple selects so that match up with other form elements. Also overwrite disabled styles. */
|
||||
.select2-container--disabled,.select2-container--disabled .select2-selection--single,.select2-container--disabled .select2-selection--multiple {
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
@ -2066,6 +2067,19 @@ tr td button i {
|
||||
opacity: .35;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single {
|
||||
background-color: @field-secondary-bg;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--multiple {
|
||||
background-color: @field-secondary-bg;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
body.is-modalOpen {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@ -30,6 +30,12 @@
|
||||
min-height: 45px;
|
||||
}
|
||||
|
||||
.Form-secondaryTitle{
|
||||
color: @default-icon;
|
||||
padding-bottom: 20px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.Form-title--is_superuser{
|
||||
height:15px;
|
||||
color: @btn-txt;
|
||||
@ -136,7 +142,7 @@
|
||||
|
||||
.Form-formGroup {
|
||||
flex: 1 0 auto;
|
||||
margin-bottom: 25px;
|
||||
margin-bottom: 20px;
|
||||
width: 33%;
|
||||
padding-right: 50px;
|
||||
}
|
||||
@ -226,7 +232,6 @@
|
||||
|
||||
.Form-dropDown {
|
||||
height: 30px !important;
|
||||
background-color: @field-secondary-bg!important;
|
||||
border-radius: 5px !important;
|
||||
border:1px solid @field-border!important;
|
||||
color: @field-input-text!important;
|
||||
@ -431,6 +436,25 @@ input[type='radio']:checked:before {
|
||||
color: @btn-txt;
|
||||
}
|
||||
|
||||
.Form-surveyButton {
|
||||
background-color: @default-link;
|
||||
margin-right: 20px;
|
||||
color: @default-bg;
|
||||
text-transform: uppercase;
|
||||
padding-left:15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.Form-surveyButton:hover{
|
||||
background-color: @default-link-hov;
|
||||
color: @default-bg;
|
||||
}
|
||||
|
||||
.Form-formGroup--singleColumn {
|
||||
width: 100%;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 650px) {
|
||||
.Form-formGroup {
|
||||
flex: 1 0 auto;
|
||||
|
||||
@ -28,8 +28,15 @@ table.ui-datepicker-calendar {
|
||||
font-weight: bold;
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
line-height: 1;
|
||||
opacity: .7;
|
||||
opacity: 1;
|
||||
text-shadow: 0 1px 0 @white;
|
||||
color:@default-second-border;
|
||||
}
|
||||
.close:hover{
|
||||
color:@default-icon;
|
||||
}
|
||||
.ui-widget {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
.ui-widget-header {
|
||||
border-radius: 0;
|
||||
|
||||
@ -49,7 +49,6 @@ export default
|
||||
variables: {
|
||||
label: 'Variables',
|
||||
type: 'textarea',
|
||||
'class': 'Form-textArea',
|
||||
addRequired: false,
|
||||
editRequird: false,
|
||||
rows: 6,
|
||||
|
||||
@ -276,8 +276,8 @@ export default
|
||||
type: 'custom',
|
||||
column: 2,
|
||||
ngHide: "job_type.value === 'scan'" ,
|
||||
control: '<button type="button" class="btn btn-sm Form-buttonDefault" id="job_templates_create_survey_btn" ng-show="!survey_exists" ng-click="addSurvey()">ADD SURVEY</button>'+
|
||||
'<button type="button" class="btn btn-sm Form-buttonDefault" id="job_templates_edit_survey_btn" ng-show="survey_exists" ng-click="editSurvey()">EDIT SURVEY</button>'
|
||||
control: '<button type="button" class="btn btn-sm Form-surveyButton" id="job_templates_create_survey_btn" ng-show="!survey_exists" ng-click="addSurvey()">ADD SURVEY</button>'+
|
||||
'<button type="button" class="btn btn-sm Form-surveyButton" id="job_templates_edit_survey_btn" ng-show="survey_exists" ng-click="editSurvey()">EDIT SURVEY</button>'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ angular.module('JobTemplatesHelper', ['Utilities'])
|
||||
.success(function (data) {
|
||||
var fld, i;
|
||||
for (fld in form.fields) {
|
||||
if (fld !== 'variables' && data[fld] !== null && data[fld] !== undefined) {
|
||||
if (fld !== 'variables' && fld !== 'survey' && data[fld] !== null && data[fld] !== undefined) {
|
||||
if (form.fields[fld].type === 'select') {
|
||||
if (scope[fld + '_options'] && scope[fld + '_options'].length > 0) {
|
||||
for (i = 0; i < scope[fld + '_options'].length; i++) {
|
||||
@ -91,10 +91,8 @@ angular.module('JobTemplatesHelper', ['Utilities'])
|
||||
}
|
||||
} else {
|
||||
scope[fld] = data[fld];
|
||||
if(fld ==='survey_enabled'){
|
||||
if(!Empty(data.summary_fields.survey)) {
|
||||
scope.survey_exists = true;
|
||||
}
|
||||
if(!Empty(data.summary_fields.survey)) {
|
||||
scope.survey_exists = true;
|
||||
}
|
||||
}
|
||||
master[fld] = scope[fld];
|
||||
@ -114,6 +112,8 @@ angular.module('JobTemplatesHelper', ['Utilities'])
|
||||
Wait('stop');
|
||||
scope.url = data.url;
|
||||
|
||||
scope.survey_enabled = data.survey_enabled;
|
||||
|
||||
scope.ask_variables_on_launch = (data.ask_variables_on_launch) ? 'true' : 'false';
|
||||
master.ask_variables_on_launch = scope.ask_variables_on_launch;
|
||||
|
||||
|
||||
@ -337,16 +337,20 @@
|
||||
if (form.fields[fld].type === 'select' && fld !== 'playbook') {
|
||||
data[fld] = $scope[fld].value;
|
||||
} else {
|
||||
if (fld !== 'variables') {
|
||||
if (fld !== 'variables' && fld !== 'survey') {
|
||||
data[fld] = $scope[fld];
|
||||
}
|
||||
}
|
||||
}
|
||||
data.extra_vars = ToJSON($scope.parseType, $scope.variables, true);
|
||||
if(data.job_type === 'scan' && $scope.default_scan === true){
|
||||
data.project = "";
|
||||
data.playbook = "";
|
||||
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;
|
||||
Rest.setUrl(defaultUrl);
|
||||
Rest.post(data)
|
||||
.success(function(data) {
|
||||
@ -361,7 +365,7 @@
|
||||
url: $scope.current_url
|
||||
});
|
||||
|
||||
if(data.survey_enabled===true){
|
||||
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);
|
||||
@ -413,19 +417,12 @@
|
||||
if($scope.job_type.value === "scan" && $scope.survey_enabled === true){
|
||||
$scope.survey_enabled = false;
|
||||
}
|
||||
// Can't have a survey enabled without a survey
|
||||
if($scope.survey_enabled === true && $scope.survey_exists!==true){
|
||||
// $scope.$emit("PromptForSurvey");
|
||||
|
||||
// The original design for this was a pop up that would prompt the user if they wanted to create a
|
||||
// survey, because they had enabled one but not created it yet. We switched this for now so that
|
||||
// an error message would be displayed by the survey buttons that tells the user to add a survey or disabled
|
||||
// surveys.
|
||||
$scope.invalid_survey = true;
|
||||
return;
|
||||
} else {
|
||||
$scope.$emit("GatherFormFields");
|
||||
$scope.survey_enabled = false;
|
||||
}
|
||||
|
||||
$scope.$emit("GatherFormFields");
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<div class="tab-pane" id="job_templates_create">
|
||||
<div ui-view></div>
|
||||
<div ng-cloak id="htmlTemplate" class="Panel"></div>
|
||||
<div id="survey-modal-dialog"></div>
|
||||
<div ng-include="'/static/partials/survey-maker-modal.html'"></div>
|
||||
</div>
|
||||
|
||||
@ -307,27 +307,6 @@ export default
|
||||
|
||||
Wait('start');
|
||||
|
||||
if ($scope.removeEnableSurvey) {
|
||||
$scope.removeEnableSurvey();
|
||||
}
|
||||
$scope.removeEnableSurvey = $scope.$on('EnableSurvey', function(fld) {
|
||||
|
||||
$('#job_templates_survey_enabled_chbox').attr('checked', $scope[fld]);
|
||||
Rest.setUrl(defaultUrl + id+ '/survey_spec/');
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
if(data && data.name){
|
||||
$scope.survey_exists = true;
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, form, {
|
||||
hdr: 'Error!',
|
||||
msg: 'Failed to retrieve job template: ' + $stateParams.template_id + '. GET status: ' + status
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if ($scope.removeSurveySaved) {
|
||||
$scope.rmoveSurveySaved();
|
||||
}
|
||||
@ -506,7 +485,7 @@ export default
|
||||
.error(function(res, status){
|
||||
ProcessErrors($rootScope, res, status, null, {hdr: 'Error!',
|
||||
msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status});
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
$state.go('jobTemplates');
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<div class="tab-pane" id="job_templates_edit">
|
||||
<div ui-view></div>
|
||||
<div ng-cloak id="htmlTemplate" class="Panel"></div>
|
||||
<div id="survey-modal-dialog"></div>
|
||||
<div ng-include="'/static/partials/survey-maker-modal.html'"></div>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export default
|
||||
function EditQuestion(GetBasePath, Rest, Wait, ProcessErrors, $compile, GenerateForm, SurveyQuestionForm) {
|
||||
function EditQuestion(GetBasePath, Rest, Wait, ProcessErrors, $compile, GenerateForm, SurveyQuestionForm, CreateSelect2) {
|
||||
return function(params) {
|
||||
|
||||
var scope = params.scope,
|
||||
@ -7,16 +7,12 @@ export default
|
||||
element,
|
||||
tmpVar,
|
||||
i,
|
||||
question = params.question, //scope.survey_questions[index],
|
||||
question = params.question,
|
||||
form = SurveyQuestionForm;
|
||||
|
||||
$('#survey-save-button').attr('disabled', 'disabled');
|
||||
angular.element('#survey_question_question_cancel_btn').trigger('click');
|
||||
$('#add_question_btn').hide();
|
||||
// $('#new_question .aw-form-well').remove();
|
||||
element = $('.question_final:eq('+index+')');
|
||||
element.css('opacity', 1.0);
|
||||
element.empty();
|
||||
// Update the index so that we know which question is being edited.
|
||||
scope.editQuestionIndex = index;
|
||||
|
||||
scope.text_min = null;
|
||||
scope.text_max = null;
|
||||
scope.int_min = null;
|
||||
@ -70,6 +66,16 @@ export default
|
||||
else if ( question.type === 'multiselect'){
|
||||
scope.default_multiselect = question.default;
|
||||
}
|
||||
|
||||
// After we populate the form with data, need to call CreateSelect2 again
|
||||
// to get the dropdown to show the selected item.
|
||||
CreateSelect2({
|
||||
element:'#survey_question_type',
|
||||
multiple: false
|
||||
});
|
||||
|
||||
// Set the form to dirty. This lets the cancel button know that it should become enabled.
|
||||
scope.survey_question_form.$setDirty();
|
||||
});
|
||||
|
||||
if (scope.removeGenerateForm) {
|
||||
@ -77,7 +83,7 @@ export default
|
||||
}
|
||||
scope.removeGenerateForm = scope.$on('GenerateForm', function() {
|
||||
tmpVar = scope.mode;
|
||||
GenerateForm.inject(form, { id: 'question_'+index, mode: 'edit' , related: false, scope:scope });
|
||||
GenerateForm.inject(form, { id: 'survey_maker_question_form', mode: 'edit', related: false, scope:scope });
|
||||
scope.mode = tmpVar;
|
||||
scope.$emit('FillQuestionForm');
|
||||
});
|
||||
@ -95,5 +101,6 @@ EditQuestion.$inject =
|
||||
'ProcessErrors',
|
||||
'$compile',
|
||||
'GenerateForm',
|
||||
'questionDefinitionForm'
|
||||
'questionDefinitionForm',
|
||||
'CreateSelect2'
|
||||
];
|
||||
|
||||
@ -1,193 +0,0 @@
|
||||
/**
|
||||
* Takes a finalized question and displays it on the survey maker page
|
||||
*
|
||||
* FinalizeQuestion({
|
||||
* scope: $scope containing list of survey form fields
|
||||
* question: question object that was submitted by the question form
|
||||
* id: id of job template that survey is attached to
|
||||
* callback: $scope.$emit label to call when delete is completed
|
||||
* })
|
||||
*
|
||||
*/
|
||||
|
||||
export default
|
||||
function FinalizeQuestion(GetBasePath, Rest, Wait, ProcessErrors, $compile, Empty, $filter, questionScope) {
|
||||
return function(params) {
|
||||
|
||||
var question = params.question,
|
||||
scope = questionScope(question, params.scope),
|
||||
index = params.index,
|
||||
required,
|
||||
element,
|
||||
max,
|
||||
min,
|
||||
defaultValue,
|
||||
html = "";
|
||||
|
||||
question.index = index;
|
||||
question.question_name = $filter('sanitize')(question.question_name);
|
||||
question.question_description = (question.question_description) ? $filter('sanitize')(question.question_description) : undefined;
|
||||
|
||||
|
||||
if(!$('#question_'+question.index+':eq(0)').is('div')){
|
||||
html+='<div id="question_'+question.index+'" class="question_final row"></div>';
|
||||
$('#finalized_questions').append(html);
|
||||
}
|
||||
|
||||
required = (question.required===true) ? "prepend-asterisk" : "";
|
||||
html = '<div class="question_title col-xs-12">';
|
||||
html += '<label for="'+question.variable+'"><span class="label-text '+required+'"> '+question.question_name+'</span></label>';
|
||||
html += '</div>';
|
||||
|
||||
if(!Empty(question.question_description)){
|
||||
html += '<div class="col-xs-12 description"><i>'+question.question_description+'</i></div>\n';
|
||||
}
|
||||
|
||||
if(question.type === 'text' ){
|
||||
defaultValue = (question.default) ? question.default : "";
|
||||
defaultValue = $filter('sanitize')(defaultValue);
|
||||
defaultValue = scope.serialize(defaultValue);
|
||||
html+='<div class="row">'+
|
||||
'<div class="col-xs-8">'+
|
||||
'<input type="text" placeholder="'+defaultValue+'" class="form-control ng-pristine ng-invalid-required ng-invalid final" required="" readonly>'+
|
||||
'</div></div>';
|
||||
}
|
||||
if(question.type === "textarea"){
|
||||
defaultValue = (question.default) ? question.default : (question.default_textarea) ? question.default_textarea: "" ;
|
||||
defaultValue = $filter('sanitize')(defaultValue);
|
||||
defaultValue = scope.serialize(defaultValue);
|
||||
html+='<div class="row">'+
|
||||
'<div class="col-xs-8 input_area">'+
|
||||
'<textarea class="form-control ng-pristine ng-invalid-required ng-invalid final" required="" rows="3" readonly>'+defaultValue+'</textarea>'+
|
||||
'</div></div>';
|
||||
}
|
||||
if(question.type === 'multiplechoice' || question.type === "multiselect"){
|
||||
|
||||
question.default = question.default_multiselect || question.default;
|
||||
|
||||
var defaultScopePropertyName =
|
||||
question.variable + '_default';
|
||||
|
||||
if (question.default) {
|
||||
if (question.type === 'multiselect' && typeof question.default.split === 'function') {
|
||||
scope[defaultScopePropertyName] = question.default.split('\n');
|
||||
} else if (question.type !== 'multiselect') {
|
||||
scope[defaultScopePropertyName] = question.default;
|
||||
}
|
||||
} else {
|
||||
scope[defaultScopePropertyName] = '';
|
||||
}
|
||||
|
||||
html += '<div class="row">';
|
||||
html += '<div class="col-xs-8">';
|
||||
html += '<div class="SurveyControls-selectWrapper">';
|
||||
html += '<survey-question type="' + question.type + '" question="question" ng-required="' + question.required + '" ng-model="' + defaultScopePropertyName + '" ng-disabled=true></survey-question>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
if(question.type === 'password'){
|
||||
defaultValue = (question.default) ? question.default : "";
|
||||
defaultValue = $filter('sanitize')(defaultValue);
|
||||
defaultValue = scope.serialize(defaultValue);
|
||||
html+='<div class="row">'+
|
||||
' <div class="col-xs-8 input_area input-group">'+
|
||||
'<span class="input-group-btn">'+
|
||||
'<button class="btn btn-default survey-maker-password show_input_button" id="'+question.variable+'_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="toggleInput("#'+question.variable+'")" data-original-title="" title="">ABC</button>'+
|
||||
'</span>'+
|
||||
'<input id="'+ question.variable +'" type="password" ng-model="default_password" name="'+ question.variable +'" class="form-control ng-pristine ng-valid-api-error ng-invalid" autocomplete="false" readonly>'+
|
||||
'</div>'+
|
||||
'</div>';
|
||||
}
|
||||
|
||||
if(question.type === 'integer'){
|
||||
min = (!Empty(question.min)) ? question.min : "";
|
||||
max = (!Empty(question.max)) ? question.max : "" ;
|
||||
defaultValue = (!Empty(question.default)) ? question.default : (!Empty(question.default_int)) ? question.default_int : "" ;
|
||||
html+='<div class="row">'+
|
||||
'<div class="col-xs-8 input_area">'+
|
||||
'<input type="number" class="final form-control" name="'+question.variable+'" min="'+min+'" max="'+max+'" value="'+defaultValue+'" readonly>'+
|
||||
'</div></div>';
|
||||
|
||||
}
|
||||
if(question.type === "float"){
|
||||
min = (!Empty(question.min)) ? question.min : "";
|
||||
max = (!Empty(question.max)) ? question.max : "" ;
|
||||
defaultValue = (!Empty(question.default)) ? question.default : (!Empty(question.default_float)) ? question.default_float : "" ;
|
||||
html+='<div class="row">'+
|
||||
'<div class="col-xs-8 input_area">'+
|
||||
'<input type="number" class="final form-control" name="'+question.variable+'" min="'+min+'" max="'+max+'" value="'+defaultValue+'" readonly>'+
|
||||
'</div></div>';
|
||||
|
||||
}
|
||||
html += '<div class="col-xs-12 text-right question_actions">';
|
||||
html += '<a id="edit-question_'+question.index+'" data-placement="top" aw-tool-tip="Edit question" data-original-title="" title=""><i class="fa fa-pencil"></i> </a>';
|
||||
html += '<a id="delete-question_'+question.index+'" data-placement="top" aw-tool-tip="Delete question" data-original-title="" title=""><i class="fa fa-trash-o"></i> </a>';
|
||||
html += '<a id="question-up_'+question.index+'" data-placement="top" aw-tool-tip="Move up" data-original-title="" title=""><i class="fa fa-arrow-up"></i> </a>';
|
||||
html += '<a id="question-down_'+question.index+'" data-placement="top" aw-tool-tip="Move down" data-original-title="" title=""><i class="fa fa-arrow-down"></i> </a>';
|
||||
html+='</div></div>';
|
||||
|
||||
$('#question_'+question.index).append(html);
|
||||
|
||||
element = angular.element(document.getElementById('question_'+question.index));
|
||||
// // element.html(html);
|
||||
//element.css('opacity', 0.7);
|
||||
|
||||
$compile(element)(scope);
|
||||
|
||||
$('#add_question_btn').show();
|
||||
$('#add_question_btn').removeAttr('disabled');
|
||||
$('#add_question_btn').focus();
|
||||
$('#survey_maker_save_btn').removeAttr('disabled');
|
||||
|
||||
// Sometimes the $event.target returns the anchor element that wraps the icon, and sometimes the icon itself
|
||||
// is returned. So for each icon click event we check to see which target the user clicked, and depending no which one
|
||||
// they clicked, we move up the dom hierarchy to get the index on the question. Ultimatley the object that is passed to
|
||||
// each one of these functions should be the index of the question that the user is trying to perform an action on.
|
||||
$('#delete-question_'+question.index+'').on('click', function($event){
|
||||
if($event.target.nodeName==="A"){
|
||||
scope.deleteQuestion($event.target.parentElement.parentElement.id.split('_')[1]);
|
||||
}
|
||||
else if($event.target.nodeName === "I"){
|
||||
scope.deleteQuestion($event.target.parentElement.parentElement.parentElement.id.split('_')[1]);
|
||||
}
|
||||
});
|
||||
$('#edit-question_'+question.index+'').on('click', function($event){
|
||||
if($event.target.nodeName==="A"){
|
||||
scope.editQuestion($event.target.parentElement.parentElement.id.split('_')[1]);
|
||||
}
|
||||
else if($event.target.nodeName === "I"){
|
||||
scope.editQuestion($event.target.parentElement.parentElement.parentElement.id.split('_')[1]);
|
||||
}
|
||||
});
|
||||
$('#question-up_'+question.index+'').on('click', function($event){
|
||||
if($event.target.nodeName==="A"){
|
||||
scope.questionUp($event.target.parentElement.parentElement.id.split('_')[1]);
|
||||
}
|
||||
else if($event.target.nodeName === "I"){
|
||||
scope.questionUp($event.target.parentElement.parentElement.parentElement.id.split('_')[1]);
|
||||
}
|
||||
});
|
||||
$('#question-down_'+question.index+'').on('click', function($event){
|
||||
if($event.target.nodeName==="A"){
|
||||
scope.questionDown($event.target.parentElement.parentElement.id.split('_')[1]);
|
||||
}
|
||||
else if($event.target.nodeName === "I"){
|
||||
scope.questionDown($event.target.parentElement.parentElement.parentElement.id.split('_')[1]);
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
FinalizeQuestion.$inject =
|
||||
[ 'GetBasePath',
|
||||
'Rest',
|
||||
'Wait',
|
||||
'ProcessErrors',
|
||||
'$compile',
|
||||
'Empty',
|
||||
'$filter',
|
||||
'questionScope'
|
||||
];
|
||||
@ -1,9 +1,7 @@
|
||||
import questionScope from './question-scope.factory';
|
||||
import finalize from './finalize.factory';
|
||||
import edit from './edit.factory';
|
||||
|
||||
export default
|
||||
angular.module('jobTemplates.surveyMaker.questions', [])
|
||||
.factory('finalizeQuestion', finalize)
|
||||
.factory('questionScope', questionScope)
|
||||
.factory('editQuestion', edit);
|
||||
|
||||
@ -1,43 +1,31 @@
|
||||
/* jshint unused: vars */
|
||||
import {templateUrl} from '../../../shared/template-url/template-url.factory';
|
||||
|
||||
function link($timeout, scope, element, attrs, ngModel) {
|
||||
attrs.width = attrs.width || '100%';
|
||||
function link($timeout, CreateSelect2, scope, element, attrs, ngModel) {
|
||||
|
||||
$timeout(function() {
|
||||
|
||||
$.fn.select2.amd.require(
|
||||
[ 'select2/utils',
|
||||
'select2/dropdown',
|
||||
'select2/dropdown/search',
|
||||
'select2/dropdown/attachContainer',
|
||||
'select2/dropdown/closeOnSelect',
|
||||
'select2/dropdown/minimumResultsForSearch'
|
||||
],
|
||||
function(Utils, Dropdown, Search, AttachContainer, CloseOnSelect, MinimumResultsForSearch) {
|
||||
|
||||
var CustomAdapter =
|
||||
_.reduce([Search, AttachContainer, CloseOnSelect, MinimumResultsForSearch],
|
||||
function(Adapter, Decorator) {
|
||||
return Utils.Decorate(Adapter, Decorator);
|
||||
}, Dropdown);
|
||||
|
||||
element.find('select').select2(
|
||||
{ multiple: scope.isMultipleSelect(),
|
||||
minimumResultsForSearch: Infinity,
|
||||
theme: 'bootstrap',
|
||||
width: attrs.width,
|
||||
dropdownAdapter: CustomAdapter
|
||||
});
|
||||
});
|
||||
// select2-ify the dropdown. If the preview flag is passed here
|
||||
// and it's true then we don't want to use a custom dropdown adapter.
|
||||
// The reason for this is that the custom dropdown adapter breaks
|
||||
// the draggability of this element. We're able to get away with this
|
||||
// in preview mode (survey create/edit) because the element is disabled
|
||||
// and we don't actually need the dropdown portion. Note that the custom
|
||||
// dropdown adapter is used to get the dropdown contents to show up in
|
||||
// a modal.
|
||||
CreateSelect2({
|
||||
element: element.find('select'),
|
||||
multiple: scope.isMultipleSelect(),
|
||||
customDropdownAdapter: scope.preview ? false : true
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export default
|
||||
[ '$timeout',
|
||||
function($timeout) {
|
||||
[ '$timeout', 'CreateSelect2',
|
||||
function($timeout, CreateSelect2) {
|
||||
var directive =
|
||||
{ restrict: 'E',
|
||||
require: 'ngModel',
|
||||
@ -47,10 +35,11 @@ export default
|
||||
question: '=',
|
||||
isRequired: '=ngRequired',
|
||||
selectedValue: '=ngModel',
|
||||
isDisabled: '=ngDisabled'
|
||||
isDisabled: '=ngDisabled',
|
||||
preview: '='
|
||||
},
|
||||
templateUrl: templateUrl('job-templates/survey-maker/render/multiple-choice'),
|
||||
link: _.partial(link, $timeout)
|
||||
link: _.partial(link, $timeout, CreateSelect2)
|
||||
};
|
||||
return directive;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<select class="form-control" ng-model="selectedValue" multi-select ng-required="isRequired" ng-disabled="isDisabled">
|
||||
<select class="form-control SurveyMaker-previewSelect" ng-model="selectedValue" multi-select ng-required="isRequired" ng-disabled="isDisabled">
|
||||
<option ng-repeat="choice in choices" value="{{choice}}" ng-selected="selectedValue.indexOf(choice) !== -1">{{choice}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@ -23,31 +23,104 @@ function findQuestionByIndex(questions, index) {
|
||||
});
|
||||
}
|
||||
|
||||
function link(scope, element, attrs) {
|
||||
function link($sce, $filter, Empty, scope, element, attrs) {
|
||||
|
||||
function serialize(expression) {
|
||||
return $sce.getTrustedHtml(expression);
|
||||
}
|
||||
|
||||
function sanitizeDefault() {
|
||||
|
||||
var defaultValue = "";
|
||||
|
||||
if(scope.question.type === 'text'|| scope.question.type === "password" ){
|
||||
defaultValue = (scope.question.default) ? scope.question.default : "";
|
||||
defaultValue = $filter('sanitize')(defaultValue);
|
||||
defaultValue = serialize(defaultValue);
|
||||
}
|
||||
|
||||
if(scope.question.type === "textarea"){
|
||||
defaultValue = (scope.question.default) ? scope.question.default : (scope.question.default_textarea) ? scope.question.default_textarea: "" ;
|
||||
defaultValue = $filter('sanitize')(defaultValue);
|
||||
defaultValue = serialize(defaultValue);
|
||||
}
|
||||
|
||||
if(scope.question.type === 'multiplechoice' || scope.question.type === "multiselect"){
|
||||
|
||||
scope.question.default = scope.question.default_multiselect || scope.question.default;
|
||||
|
||||
if (scope.question.default) {
|
||||
if (scope.question.type === 'multiselect' && typeof scope.question.default.split === 'function') {
|
||||
defaultValue = scope.question.default.split('\n');
|
||||
} else if (scope.question.type !== 'multiselect') {
|
||||
defaultValue = scope.question.default;
|
||||
}
|
||||
} else {
|
||||
defaultValue = '';
|
||||
}
|
||||
}
|
||||
|
||||
if(scope.question.type === 'integer'){
|
||||
var min = (!Empty(scope.question.min)) ? scope.question.min : "";
|
||||
var max = (!Empty(scope.question.max)) ? scope.question.max : "" ;
|
||||
defaultValue = (!Empty(scope.question.default)) ? scope.question.default : (!Empty(scope.question.default_int)) ? scope.question.default_int : "" ;
|
||||
|
||||
}
|
||||
if(scope.question.type === "float"){
|
||||
var min = (!Empty(scope.question.min)) ? scope.question.min : "";
|
||||
var max = (!Empty(scope.question.max)) ? scope.question.max : "" ;
|
||||
defaultValue = (!Empty(scope.question.default)) ? scope.question.default : (!Empty(scope.question.default_float)) ? scope.question.default_float : "" ;
|
||||
|
||||
}
|
||||
|
||||
scope.defaultValue = defaultValue;
|
||||
|
||||
}
|
||||
|
||||
//for toggling the input on password inputs
|
||||
scope.toggleInput = function(id) {
|
||||
var buttonId = id + "_show_input_button",
|
||||
inputId = id,
|
||||
buttonInnerHTML = $(buttonId).html();
|
||||
if (buttonInnerHTML.indexOf("SHOW") > -1) {
|
||||
$(buttonId).html("HIDE");
|
||||
$(inputId).attr("type", "text");
|
||||
} else {
|
||||
$(buttonId).html("SHOW");
|
||||
$(inputId).attr("type", "password");
|
||||
}
|
||||
};
|
||||
|
||||
if (!scope.question) {
|
||||
scope.question = findQuestionByIndex(scope.surveyQuestions, Number(attrs.index));
|
||||
}
|
||||
|
||||
// Split out choices to be consumed by the multiple-choice directive
|
||||
if (!_.isUndefined(scope.question.choices)) {
|
||||
scope.choices = scope.question.choices.split('\n');
|
||||
}
|
||||
|
||||
sanitizeDefault();
|
||||
|
||||
}
|
||||
|
||||
export default
|
||||
function() {
|
||||
var directive =
|
||||
{ restrict: 'E',
|
||||
scope:
|
||||
{ question: '=',
|
||||
selectedValue: '=ngModel',
|
||||
surveyQuestions: '=',
|
||||
isRequired: '@ngRequired',
|
||||
isDisabled: '@ngDisabled'
|
||||
},
|
||||
templateUrl: templateUrl('job-templates/survey-maker/render/survey-question'),
|
||||
link: link
|
||||
};
|
||||
[
|
||||
'$sce', '$filter', 'Empty',
|
||||
function($sce, $filter, Empty) {
|
||||
var directive =
|
||||
{ restrict: 'E',
|
||||
scope:
|
||||
{ question: '=',
|
||||
surveyQuestions: '=',
|
||||
isRequired: '@ngRequired',
|
||||
isDisabled: '@ngDisabled',
|
||||
preview: '='
|
||||
},
|
||||
templateUrl: templateUrl('job-templates/survey-maker/render/survey-question'),
|
||||
link: _.partial(link, $sce, $filter, Empty)
|
||||
};
|
||||
|
||||
return directive;
|
||||
}
|
||||
return directive;
|
||||
}
|
||||
];
|
||||
|
||||
@ -1,8 +1,30 @@
|
||||
<multiple-choice
|
||||
multi-select="question.type === 'multiselect'"
|
||||
question="question"
|
||||
choices="choices"
|
||||
ng-required="isRequired === 'true'"
|
||||
ng-model="selectedValue"
|
||||
ng-disabled="isDisabled === 'true'">
|
||||
</multiple-choice>
|
||||
<div ng-if="question.type === 'text'">
|
||||
<input type="text" ng-model="defaultValue" class="form-control ng-pristine ng-invalid-required ng-invalid final" required="" readonly>
|
||||
</div>
|
||||
<div ng-if="question.type === 'textarea'" class="input_area">
|
||||
<textarea class="form-control ng-pristine ng-invalid-required ng-invalid final" required="" rows="3" readonly>{{defaultValue}}</textarea>
|
||||
</div>
|
||||
<div ng-if="question.type === 'multiplechoice' || question.type === 'multiselect'" class="SurveyMaker-previewInput">
|
||||
<multiple-choice
|
||||
multi-select="question.type === 'multiselect'"
|
||||
question="question"
|
||||
choices="choices"
|
||||
ng-required="isRequired === 'true'"
|
||||
ng-model="defaultValue"
|
||||
ng-disabled="isDisabled === 'true'"
|
||||
preview="preview">
|
||||
</multiple-choice>
|
||||
</div>
|
||||
<div ng-if="question.type === 'password'" class="input_area input-group">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default SurveyMaker-previewPasswordButton" id="{{ question.variable + '_show_input_button' }}" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="toggleInput('#' + question.variable)" data-original-title="" title="">SHOW</button>
|
||||
</span>
|
||||
<input id="{{question.variable}}" type="password" name="" class="form-control ng-pristine ng-valid-api-error ng-invalid" autocomplete="false" ng-model="defaultValue" readonly>
|
||||
</div>
|
||||
|
||||
<div ng-if="question.type === 'integer'" class="input_area">
|
||||
<input type="number" class="final form-control" name="" min="question.min" max="question.max" ng-value="defaultValue" readonly>
|
||||
</div>
|
||||
<div ng-if="question.type === 'float'" class="input_area">
|
||||
<input type="number" class="final form-control" name="" min="question.min" max="question.max" ng-value="defaultValue" readonly>
|
||||
</div>
|
||||
|
||||
@ -15,10 +15,11 @@ export default
|
||||
|
||||
addTitle: 'Add Question',
|
||||
editTitle: 'Edit Question',
|
||||
titleClass: 'Form-secondaryTitle',
|
||||
base: 'survey_question',
|
||||
name: 'survey_question',
|
||||
well: true,
|
||||
twoColumns: true,
|
||||
cancelButton: false,
|
||||
|
||||
fields: {
|
||||
question_name: {
|
||||
@ -28,7 +29,8 @@ export default
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 1,
|
||||
awSurveyQuestion: true
|
||||
awSurveyQuestion: true,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
question_description: {
|
||||
realName: 'question_description',
|
||||
@ -36,16 +38,17 @@ export default
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
column: 1
|
||||
column: 1,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
variable: {
|
||||
ealName: 'variable',
|
||||
type: 'custom',
|
||||
control:'<label for="variable"><span class="label-text prepend-asterisk"> Answer Variable Name</span>'+
|
||||
control:'<label for="variable"><span class="Form-inputLabel prepend-asterisk"> ANSWER VARIABLE NAME</span>'+
|
||||
'<a id="awp-variable" href="" aw-pop-over="<p>The suggested format for variable names is lowercase and underscore-separated. Also note that this field cannot accept variable names with spaces.</p><p>For example: <br>foo_bar<br>'+
|
||||
'user_id<br>host_name<br><div class="popover-footer"><span class="key">esc</span> or click to close</div>" '+
|
||||
'data-placement="right" data-container="body" data-title="Answer Variable Name" class="help-link" data-original-title="" title="" tabindex="-1"><i class="fa fa-question-circle"></i></a> </label>'+
|
||||
'<div><input type="text" ng-model="variable" name="variable" id="survey_question_variable" class="form-control ng-pristine ng-invalid ng-invalid-required" required="" aw-survey-variable-name>'+
|
||||
'<div><input type="text" ng-model="variable" name="variable" id="survey_question_variable" class="form-control Form-textInput ng-pristine ng-invalid ng-invalid-required" required="" aw-survey-variable-name>'+
|
||||
'<div class="error ng-hide" id="survey_question-variable-required-error" ng-show="survey_question_form.variable.$dirty && survey_question_form.variable.$error.required">Please enter an answer variable name.</div>'+
|
||||
'<div class="error ng-hide" id="survey_question-variable-variable-error" ng-show="survey_question_form.variable.$dirty && survey_question_form.variable.$error.variable">Please remove the illegal character from the survey question variable name.</div>'+
|
||||
'<div class="error ng-hide" id=survey_question-variable-duplicate-error" ng-show="duplicate">This question variable is already in use. Please enter a different variable name.</div>' +
|
||||
@ -53,7 +56,8 @@ export default
|
||||
'</div>',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 1
|
||||
column: 1,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
type: {
|
||||
realName: 'answer_type',
|
||||
@ -64,7 +68,8 @@ export default
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 2,
|
||||
ngChange: 'typeChange()'
|
||||
ngChange: 'typeChange()',
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
choices: {
|
||||
realName: 'answer_options',
|
||||
@ -81,20 +86,21 @@ export default
|
||||
dataTitle: 'Multiple Choice Options',
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
column: 2
|
||||
column: 2,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
text_options: {
|
||||
realName: 'answer_options',
|
||||
type: 'custom',
|
||||
control:'<div class="row">'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="text_min"><span class="label-text">Minimum Length</span></label><input id="text_min" type="number" name="text_min" ng-model="text_min" min=0 aw-min="0" aw-max="text_max" class="form-control" integer />'+
|
||||
'<label for="text_min"><span class="Form-inputLabel">Minimum Length</span></label><input id="text_min" name="text_min" ng-model="text_min" min=0 aw-min="0" aw-max="text_max" aw-spinner="text_min" integer>'+
|
||||
'<div class="error" ng-show="survey_question_form.text_min.$error.integer || survey_question_form.text_min.$error.number">The minimum length you entered is not a valid number. Please enter a whole number.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.text_min.$error.awMax">The minimium length is too high. Please enter a lower number.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.text_min.$error.awMin">The minimum length is too low. Please enter a positive number.</div>'+
|
||||
'</div>'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="text_max"><span class="label-text">Maximum Length</span></label><input id="text_max" type="number" name="text_max" ng-model="text_max" aw-min="text_min || 0" min=0 class="form-control" integer >'+
|
||||
'<label for="text_max"><span class="Form-inputLabel">Maximum Length</span></label><input id="text_max" name="text_max" ng-model="text_max" aw-min="text_min || 0" min=0 aw-spinner="text_max" integer>'+
|
||||
'<div class="error" ng-show="survey_question_form.text_max.$error.integer || survey_question_form.text_max.$error.number">The maximum length you entered is not a valid number. Please enter a whole nnumber.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.text_max.$error.awMin">The maximum length is too low. Please enter a number larger than the minimum length you set.</div>'+
|
||||
'</div>'+
|
||||
@ -102,20 +108,21 @@ export default
|
||||
ngShow: 'type.type==="text" ',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 2
|
||||
column: 2,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
textarea_options: {
|
||||
realName: 'answer_options',
|
||||
type: 'custom',
|
||||
control:'<div class="row">'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="textarea_min"><span class="label-text">Minimum Length</span></label><input id="textarea_min" type="number" name="textarea_min" ng-model="textarea_min" min=0 aw-min="0" aw-max="textarea_max" class="form-control" integer />'+
|
||||
'<label for="textarea_min"><span class="Form-inputLabel">Minimum Length</span></label><input id="textarea_min" type="number" name="textarea_min" ng-model="textarea_min" min=0 aw-min="0" aw-max="textarea_max" class="form-control Form-textInput" integer />'+
|
||||
'<div class="error" ng-show="survey_question_form.textarea_min.$error.integer || survey_question_form.textarea_min.$error.number">The minimum length you entered is not a valid number. Please enter a whole number.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.textarea_min.$error.awMax">The minimium length is too high. Please enter a lower number.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.textarea_min.$error.awMin">The minimum length is too low. Please enter a positive number.</div>'+
|
||||
'</div>'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="textarea_max"><span class="label-text">Maximum Length</span></label><input id="textarea_max" type="number" name="textarea_max" ng-model="textarea_max" aw-min="textarea_min || 0" min=0 class="form-control" integer >'+
|
||||
'<label for="textarea_max"><span class="Form-inputLabel">Maximum Length</span></label><input id="textarea_max" type="number" name="textarea_max" ng-model="textarea_max" aw-min="textarea_min || 0" min=0 class="form-control Form-textInput" integer >'+
|
||||
'<div class="error" ng-show="survey_question_form.textarea_max.$error.integer || survey_question_form.textarea_max.$error.number">The maximum length you entered is not a valid number. Please enter a whole number.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.textarea_max.$error.awMin">The maximum length is too low. Please enter a number larger than the minimum length you set.</div>'+
|
||||
'</div>'+
|
||||
@ -123,20 +130,21 @@ export default
|
||||
ngShow: 'type.type==="textarea" ',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 2
|
||||
column: 2,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
password_options: {
|
||||
realName: 'answer_options',
|
||||
type: 'custom',
|
||||
control:'<div class="row">'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="password_min"><span class="label-text">Minimum Length</span></label><input id="password_min" type="number" name="password_min" ng-model="password_min" min=0 aw-min="0" aw-max="password_max" class="form-control" integer />'+
|
||||
'<label for="password_min"><span class="Form-inputLabel">Minimum Length</span></label><input id="password_min" type="number" name="password_min" ng-model="password_min" min=0 aw-min="0" aw-max="password_max" class="form-control Form-textInput" integer />'+
|
||||
'<div class="error" ng-show="survey_question_form.password_min.$error.integer || survey_question_form.password_min.$error.number">The minimum length you entered is not a valid number. Please enter a whole number.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.password_min.$error.awMax">The minimium length is too high. Please enter a lower number.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.password_min.$error.awMin">The minimum length is too low. Please enter a positive number.</div>'+
|
||||
'</div>'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="password_max"><span class="label-text">Maximum Length</span></label><input id="password_max" type="number" name="password_max" ng-model="password_max" aw-min="password_min || 0" min=0 class="form-control" integer >'+
|
||||
'<label for="password_max"><span class="Form-inputLabel">Maximum Length</span></label><input id="password_max" type="number" name="password_max" ng-model="password_max" aw-min="password_min || 0" min=0 class="form-control Form-textInput" integer >'+
|
||||
'<div class="error" ng-show="survey_question_form.password_max.$error.integer || survey_question_form.password_max.$error.number">The maximum length you entered is not a valid number. Please enter a whole number.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.password_max.$error.awMin">The maximum length is too low. Please enter a number larger than the minimum length you set.</div>'+
|
||||
'</div>'+
|
||||
@ -144,19 +152,20 @@ export default
|
||||
ngShow: 'type.type==="password" ',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 2
|
||||
column: 2,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
int_options: {
|
||||
realName: 'answer_options',
|
||||
type: 'custom',
|
||||
control:'<div class="row">'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="minimum"><span class="label-text">Minimum</span></label><input id="int_min" type="number" name="int_min" ng-model="int_min" aw-max="int_max" class="form-control" integer >'+
|
||||
'<label for="minimum"><span class="Form-inputLabel">Minimum</span></label><input id="int_min" type="number" name="int_min" ng-model="int_min" aw-max="int_max" class="form-control Form-textInput" integer >'+
|
||||
'<div class="error" ng-show="survey_question_form.int_min.$error.integer || survey_question_form.int_min.$error.number">Please enter a valid integer.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.int_min.$error.awMax">Please enter a smaller integer.</div>'+
|
||||
'</div>'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="minimum"><span class="label-text">Maximum</span></label><input id="int_max" type="number" name="int_max" ng-model="int_max" aw-min="int_min" class="form-control" integer >'+
|
||||
'<label for="minimum"><span class="Form-inputLabel">Maximum</span></label><input id="int_max" type="number" name="int_max" ng-model="int_max" aw-min="int_min" class="form-control Form-textInput" integer >'+
|
||||
'<div class="error" ng-show="survey_question_form.int_max.$error.integer || survey_question_form.int_max.$error.number">Please enter a valid integer.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.int_max.$error.awMin">Please enter a larger integer.</div>'+
|
||||
'</div>'+
|
||||
@ -164,19 +173,20 @@ export default
|
||||
ngShow: 'type.type==="integer" ',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 2
|
||||
column: 2,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
float_options: {
|
||||
realName: 'answer_options',
|
||||
type: 'custom',
|
||||
control: '<div class="row">'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="minimum"><span class="label-text">Minimum</span></label><input id="float_min" type="number" name="float_min" ng-model="float_min" class="form-control" smart-float aw-max="float_max">'+
|
||||
'<label for="minimum"><span class="Form-inputLabel">Minimum</span></label><input id="float_min" type="number" name="float_min" ng-model="float_min" class="form-control Form-textInput" smart-float aw-max="float_max">'+
|
||||
'<div class="error" ng-show="survey_question_form.float_min.$error.float || survey_question_form.float_min.$error.number">Please enter a valid float.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.float_min.$error.awMax">Please enter a smaller float.</div>'+
|
||||
'</div>'+
|
||||
'<div class="col-xs-6">'+
|
||||
'<label for="maximum"><span class="label-text">Maximum</span></label><input id="float_max" type="number" name="float_max" ng-model="float_max" class="form-control" smart-float aw-min="float_min">'+
|
||||
'<label for="maximum"><span class="Form-inputLabel">Maximum</span></label><input id="float_max" type="number" name="float_max" ng-model="float_max" class="form-control Form-textInput" smart-float aw-min="float_min">'+
|
||||
'<div class="error" ng-show="survey_question_form.float_max.$error.float">Please enter a valid float.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.float_max.$error.awMin">Please enter a larger float.</div>'+
|
||||
|
||||
@ -185,15 +195,16 @@ export default
|
||||
ngShow: 'type.type==="float" ',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 2
|
||||
column: 2,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
default:{
|
||||
realName: 'default_answer',
|
||||
type: 'custom' ,
|
||||
control: '<div class="form-group" >'+
|
||||
'<label for="default"><span class="label-text">Default Answer</span></label>'+
|
||||
'<label for="default"><span class="Form-inputLabel">Default Answer</span></label>'+
|
||||
'<div>'+
|
||||
'<input type="text" ng-model="default" name="default" id="default" class="form-control">'+
|
||||
'<input type="text" ng-model="default" name="default" id="default" class="form-control Form-textInput">'+
|
||||
'<div class="error ng-hide" id=survey_question-default-duplicate-error" ng-show="invalidChoice">Please enter an answer from the choices listed.</div>' +
|
||||
'<div class="error ng-hide" id=survey_question-default-duplicate-error" ng-show="minTextError">The answer is shorter than the minimium length. Please make the answer longer. </div>' +
|
||||
'<div class="error ng-hide" id=survey_question-default-duplicate-error" ng-show="maxTextError">The answer is longer than the maximum length. Please make the answer shorter. </div>' +
|
||||
@ -201,72 +212,77 @@ export default
|
||||
'</div>'+
|
||||
'</div>',
|
||||
column: 2,
|
||||
ngShow: 'type.type === "text" || type.type === "multiplechoice" '
|
||||
ngShow: 'type.type === "text" || type.type === "multiplechoice" ',
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
default_multiselect: {
|
||||
realName: 'default_answer' ,
|
||||
type: 'custom',
|
||||
control: '<div class="form-group">'+
|
||||
'<label for="default_multiselect"><span class="label-text">Default Answer</span></label>'+
|
||||
'<label for="default_multiselect"><span class="Form-inputLabel">Default Answer</span></label>'+
|
||||
'<div>'+
|
||||
'<textarea rows="3" ng-model="default_multiselect" name="default_multiselect" class="form-control ng-pristine ng-valid" id="default_multiselect" aw-watch=""></textarea>'+
|
||||
'<textarea rows="3" ng-model="default_multiselect" name="default_multiselect" class="form-control Form-textArea ng-pristine ng-valid" id="default_multiselect" aw-watch=""></textarea>'+
|
||||
'<div class="error ng-hide" id=survey_question-default_multiselect-duplicate-error" ng-show="invalidChoice">Please enter an answer/answers from the choices listed.</div>' +
|
||||
'<div class="error api-error ng-binding" id="survey_question-default_multiselect-api-error" ng-bind="default_multiselect_api_error"></div>'+
|
||||
'</div>'+
|
||||
'</div>',
|
||||
column: 2,
|
||||
ngShow: 'type.type==="multiselect" '
|
||||
ngShow: 'type.type==="multiselect" ',
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
default_int: {
|
||||
realName: 'default_answer',
|
||||
type: 'custom',
|
||||
control: '<div>'+
|
||||
'<label for="default_int"><span class="label-text">Default Answer</span></label>'+
|
||||
'<input type="number" ng-model="default_int" name="default_int" aw-min="int_min" aw-max="int_max" class="form-control" integer />'+
|
||||
'<label for="default_int"><span class="Form-inputLabel">Default Answer</span></label>'+
|
||||
'<input type="number" ng-model="default_int" name="default_int" aw-min="int_min" aw-max="int_max" class="form-control Form-textInput" integer />'+
|
||||
'<div class="error" ng-show="survey_question_form.default_int.$error.number || survey_question_form.default_int.$error.integer">Please enter a valid integer.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.default_int.$error.awMin || survey_question_form.default_int.$error.awMax"> Please enter a value in the range of {{int_min}} to {{int_max}}.</div>'+
|
||||
'</div>',
|
||||
column: 2,
|
||||
ngShow: 'type.type === "integer" '
|
||||
ngShow: 'type.type === "integer" ',
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
default_float: {
|
||||
realName: 'default_answer',
|
||||
type: 'custom',
|
||||
control: '<div>'+
|
||||
'<label for="default_float"><span class="label-text">Default Answer</span></label>'+
|
||||
'<input type="number" ng-model="default_float" name="default_float" aw-min="float_min" aw-max="float_max" class="form-control" />'+
|
||||
'<label for="default_float"><span class="Form-inputLabel">Default Answer</span></label>'+
|
||||
'<input type="number" ng-model="default_float" name="default_float" aw-min="float_min" aw-max="float_max" class="form-control Form-textInput" />'+
|
||||
'<div class="error" ng-show="survey_question_form.default_float.$error.number || survey_question_form.default_float.$error.float">Please enter a valid float.</div>'+
|
||||
'<div class="error" ng-show="survey_question_form.default_float.$error.awMin || survey_question_form.default_float.$error.awMax"> Please enter a value in the range of {{float_min}} to {{float_max}}!</div>'+
|
||||
'</div>',
|
||||
column: 2,
|
||||
ngShow: 'type.type=== "float" '
|
||||
ngShow: 'type.type=== "float" ',
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
default_textarea: {
|
||||
realName: "default_answer" ,
|
||||
type: 'custom',
|
||||
control: '<div class="form-group">'+
|
||||
'<label for="default_textarea"><span class="label-text">Default Answer</span></label>'+
|
||||
control: '<div class="form-group Form-formGroup Form-formGroup--singleColumn">'+
|
||||
'<label for="default_textarea"><span class="Form-inputLabel">Default Answer</span></label>'+
|
||||
'<div>'+
|
||||
'<textarea rows="3" ng-model="default_textarea" name="default_textarea" class="form-control ng-valid ng-dirty" id="default_textarea"></textarea>'+
|
||||
'<textarea rows="3" ng-model="default_textarea" name="default_textarea" class="form-control Form-textArea ng-valid ng-dirty" id="default_textarea"></textarea>'+
|
||||
'<div class="error ng-hide" id=survey_question-default-duplicate-error" ng-show="minTextError">The answer is shorter than the minimium length. Please make the answer longer. </div>' +
|
||||
'<div class="error ng-hide" id=survey_question-default-duplicate-error" ng-show="maxTextError">The answer is longer than the maximum length. Please make the answer shorter. </div>' +
|
||||
'<div class="error api-error ng-binding" id="survey_question-default_textarea-api-error" ng-bind="default_textarea_api_error"></div>'+
|
||||
'</div>'+
|
||||
'</div>',
|
||||
column : 2,
|
||||
ngShow: 'type.type === "textarea" '
|
||||
column : 2,
|
||||
ngShow: 'type.type === "textarea" ',
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
default_password: {
|
||||
realName: 'default_answer' ,
|
||||
type: 'custom' ,
|
||||
control: '<div class="form-group">'+
|
||||
'<label for="default_password"><span class="label-text">Default Answer</span></label>'+
|
||||
'<label for="default_password"><span class="Form-inputLabel">Default Answer</span></label>'+
|
||||
'<div>'+
|
||||
'<div class="input-group">'+
|
||||
'<span class="input-group-btn">'+
|
||||
'<button class="btn btn-default show_input_button" id="default_password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="toggleInput("#default_password")" data-original-title="" title="">Show</button>'+
|
||||
'</span>'+
|
||||
'<input id="default_password" type="password" ng-model="default_password" name="default_password" class="form-control ng-pristine ng-valid-api-error ng-invalid" autocomplete="false">'+
|
||||
'<input id="default_password" type="password" ng-model="default_password" name="default_password" class="form-control Form-textInput ng-pristine ng-valid-api-error ng-invalid" autocomplete="false">'+
|
||||
'</div>'+
|
||||
'<div class="error ng-hide" id=survey_question-default-duplicate-error" ng-show="minTextError">The answer is shorter than the minimium length. Please make the answer longer. </div>' +
|
||||
'<div class="error ng-hide" id=survey_question-default-password-duplicate-error" ng-show="maxTextError">The answer is longer than the maximum length. Please make the answer shorter. </div>' +
|
||||
@ -274,7 +290,8 @@ export default
|
||||
'</div>'+
|
||||
'</div>',
|
||||
column: 2,
|
||||
ngShow: 'type.type === "password" '
|
||||
ngShow: 'type.type === "password" ',
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
},
|
||||
required: {
|
||||
realName: 'required_answer',
|
||||
@ -282,20 +299,22 @@ export default
|
||||
type: 'checkbox',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
column: 2
|
||||
column: 2,
|
||||
class: 'Form-formGroup--singleColumn'
|
||||
}
|
||||
},
|
||||
buttons: {
|
||||
question_cancel : {
|
||||
label: 'Cancel',
|
||||
'class' : 'btn btn-default',
|
||||
ngClick: 'cancelQuestion($event)'
|
||||
},
|
||||
submit_question: {
|
||||
ngClick: 'submitQuestion($event)',
|
||||
ngDisabled: true,
|
||||
'class': 'btn btn-sm btn-primary',
|
||||
label: 'Add Question'
|
||||
'class': 'btn btn-sm Form-saveButton',
|
||||
label: '{{editQuestionIndex === null ? "ADD" : "UPDATE"}}'
|
||||
},
|
||||
question_cancel : {
|
||||
label: 'Cancel',
|
||||
'class' : 'btn btn-default Form-cancelButton',
|
||||
ngClick: 'generateAddQuestionForm()',
|
||||
ngDisabled: 'survey_question_form.$pristine'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,212 @@
|
||||
@import "awx/ui/client/src/shared/branding/colors.default.less";
|
||||
|
||||
.SurveyMaker-dialog {
|
||||
padding: 0px;
|
||||
|
||||
.ui-dialog-buttonpane, .ui-dialog-titlebar {
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
.SurveyMaker-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.SurveyMaker-title {
|
||||
align-items: center;
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
}
|
||||
.SurveyMaker-titleText {
|
||||
color: @list-title-txt;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.SurveyMaker-titleLockup {
|
||||
margin-left: 4px;
|
||||
margin-right: 6px;
|
||||
display: inline-block;
|
||||
margin-top: 0px;
|
||||
padding-bottom: 2px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.SurveyMaker-titleLockup:before {
|
||||
content: "\007C";
|
||||
color: @default-icon-hov;
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
}
|
||||
.SurveyMaker-close {
|
||||
justify-content: flex-end;
|
||||
display: flex;
|
||||
}
|
||||
.SurveyMaker-exit{
|
||||
cursor:pointer;
|
||||
padding:0px;
|
||||
border: none;
|
||||
height:20px;
|
||||
font-size: 20px;
|
||||
background-color:@default-bg;
|
||||
color:@default-second-border;
|
||||
transition: color 0.2s;
|
||||
line-height:1;
|
||||
}
|
||||
.SurveyMaker-exit:hover{
|
||||
color:@default-icon;
|
||||
}
|
||||
.SurveyMaker-content {
|
||||
display: flex;
|
||||
margin-top: 25px;
|
||||
}
|
||||
.SurveyMaker-questionPanel {
|
||||
display: flex;
|
||||
flex: 0 0 475px;
|
||||
}
|
||||
.SurveyMaker-previewPanel {
|
||||
display: flex;
|
||||
flex: 0 0 637px;
|
||||
}
|
||||
.SurveyMaker-separatorPanel {
|
||||
display: flex;
|
||||
flex: 0 0 51px;
|
||||
}
|
||||
.SurveyMaker-contentSeparator {
|
||||
width: 1px;
|
||||
background-color: @default-list-header-bg;
|
||||
margin: 0px 25px;
|
||||
}
|
||||
.SurveyMaker-panelHeader {
|
||||
color: @default-icon;
|
||||
padding-bottom: 20px;
|
||||
min-height: 40px;
|
||||
flex: 0 0 auto;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.SurveyMaker-panelBody {
|
||||
flex: 1 0 auto;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.SurveyMaker-panelFooter {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.SurveyMaker-noQuestions {
|
||||
color: @default-icon;
|
||||
}
|
||||
.SurveyMaker-deleteButton {
|
||||
font-size: 16px;
|
||||
height: 30px;
|
||||
min-width: 30px;
|
||||
color: @list-action-icon;
|
||||
background-color: @list-actn-bg;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.SurveyMaker-deleteButton:hover {
|
||||
background-color: @list-actn-del-bg-hov !important;
|
||||
color: @list-actn-icn-hov;
|
||||
}
|
||||
.SurveyMaker-previewLabel {
|
||||
text-transform: uppercase;
|
||||
color: @default-interface-txt;
|
||||
font-weight: normal;
|
||||
font-size: small;
|
||||
width: 100%;
|
||||
}
|
||||
.SurveyMaker-deleteOverlay {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0,0,0,0.3);
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.SurveyMaker-deleteModal {
|
||||
height: 200px;
|
||||
width: 600px;
|
||||
background-color: @default-bg;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.SurveyMaker-previewInputRow {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.SurveyMaker-previewInput {
|
||||
flex: 1 0 523px;
|
||||
max-width: 523px;
|
||||
}
|
||||
.SurveyMaker-previewActions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.SurveyMaker-previewActions--selected {
|
||||
background-color: @default-link !important;
|
||||
color: @default-bg;
|
||||
}
|
||||
.SurveyMaker-previewRows {
|
||||
position: relative;
|
||||
min-height: 42px;
|
||||
padding-left: 0px;
|
||||
|
||||
/* These classes are dynamically added via the angular-drag-and-drop-lists directive */
|
||||
.dndPlaceholder {
|
||||
display: block;
|
||||
background-color: @default-tertiary-bg;
|
||||
padding: 10px 15px;
|
||||
min-height: 42px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 4px;
|
||||
color: @default-interface-txt;
|
||||
}
|
||||
|
||||
.dndDraggingSource {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.SurveyMaker-previewRow {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
||||
/* Disable text selection if item is not draggable */
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.SurveyMaker-reorderButton {
|
||||
color: @default-icon;
|
||||
margin-right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: -moz-grab;
|
||||
cursor: -webkit-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.SurveyMaker-reorderButton:hover {
|
||||
color: @default-interface-txt;
|
||||
}
|
||||
.SurveyMaker-previewPasswordButton {
|
||||
padding: 7px 15px!important;
|
||||
}
|
||||
.SurveyMaker-previewInput {
|
||||
.select2-container--disabled {
|
||||
opacity: inherit!important;
|
||||
}
|
||||
}
|
||||
.SurveyMaker-previewMultiSelect {
|
||||
background-color: #EEEEEE!important;
|
||||
cursor: not-allowed!important;
|
||||
}
|
||||
@ -3,17 +3,19 @@ export default
|
||||
return function(params) {
|
||||
var scope = params.scope;
|
||||
|
||||
// This variable controls the survey on/off toggle beside the create survey
|
||||
// modal title. We want this toggle to be on by default
|
||||
scope.survey_enabled = true;
|
||||
|
||||
if (scope.removeDialogReady) {
|
||||
scope.removeDialogReady();
|
||||
}
|
||||
scope.removeDialogReady = scope.$on('DialogReady', function() {
|
||||
$('#survey-modal-dialog').dialog('open');
|
||||
scope.addQuestion();
|
||||
scope.generateAddQuestionForm();
|
||||
});
|
||||
Wait('start');
|
||||
$('#form-container').empty();
|
||||
scope.resetForm();
|
||||
ShowSurveyModal({ title: "Add Survey", scope: scope, callback: 'DialogReady' });
|
||||
ShowSurveyModal({ scope: scope, callback: 'DialogReady' });
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
* DeleteSurvey({
|
||||
* scope: $scope containing list of survey form fields
|
||||
* id: id of job template that survey is attached to
|
||||
* callback: $scope.$emit label to call when delete is completed
|
||||
* })
|
||||
*
|
||||
*/
|
||||
@ -14,7 +13,6 @@ export default
|
||||
|
||||
var scope = params.scope,
|
||||
id = params.id,
|
||||
// callback = params.callback,
|
||||
url;
|
||||
|
||||
|
||||
@ -25,11 +23,9 @@ export default
|
||||
scope.survey_name = "";
|
||||
scope.survey_description = "";
|
||||
scope.survey_questions = [];
|
||||
scope.closeSurvey('survey-modal-dialog');
|
||||
Wait('stop');
|
||||
scope.survey_exists = false;
|
||||
$('#job_templates_delete_survey_btn').hide();
|
||||
$('#job_templates_edit_survey_btn').hide();
|
||||
$('#job_templates_create_survey_btn').show();
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
export default
|
||||
function EditFactory($stateParams, SchedulerInit, ShowSurveyModal, Wait, Rest, ProcessErrors, GetBasePath, GenerateForm,
|
||||
Empty, AddSurvey) {
|
||||
function EditFactory(ShowSurveyModal, Wait, Rest, ProcessErrors, GetBasePath, Empty, AddSurvey) {
|
||||
return function(params) {
|
||||
var scope = params.scope,
|
||||
id = params.id,
|
||||
tempSurv = {},
|
||||
url = GetBasePath('job_templates') + id + '/survey_spec/', i;
|
||||
|
||||
if (scope.removeDialogReady) {
|
||||
@ -12,24 +10,13 @@ export default
|
||||
}
|
||||
scope.removeDialogReady = scope.$on('DialogReady', function() {
|
||||
$('#survey-modal-dialog').dialog('open');
|
||||
scope.generateAddQuestionForm();
|
||||
});
|
||||
|
||||
scope.resetForm();
|
||||
Wait('start');
|
||||
//for adding a job template:
|
||||
if(scope.mode === 'add'){
|
||||
tempSurv.survey_name = scope.survey_name;
|
||||
tempSurv.survey_description = scope.survey_description;
|
||||
tempSurv.survey_questions = scope.survey_questions;
|
||||
|
||||
ShowSurveyModal({ title: "Edit Survey", scope: scope, callback: 'DialogReady' });
|
||||
|
||||
// scope.survey_name = tempSurv.survey_name;
|
||||
// scope.survey_description = tempSurv.survey_description;
|
||||
|
||||
for(i=0; i<tempSurv.survey_questions.length; i++){
|
||||
scope.finalizeQuestion(tempSurv.survey_questions[i], i);
|
||||
}
|
||||
}
|
||||
//editing an existing job template:
|
||||
else{
|
||||
@ -39,14 +26,9 @@ export default
|
||||
.success(function (data) {
|
||||
if(!Empty(data)){
|
||||
ShowSurveyModal({ title: "Edit Survey", scope: scope, callback: 'DialogReady' });
|
||||
|
||||
scope.survey_name = data.name;
|
||||
scope.survey_description = data.description;
|
||||
scope.survey_questions = data.spec;
|
||||
for(i=0; i<scope.survey_questions.length; i++){
|
||||
scope.finalizeQuestion(scope.survey_questions[i], i);
|
||||
}
|
||||
// scope.addQuestion();
|
||||
Wait('stop');
|
||||
} else {
|
||||
AddSurvey({
|
||||
@ -66,15 +48,11 @@ export default
|
||||
|
||||
|
||||
EditFactory.$inject =
|
||||
[ '$stateParams',
|
||||
'SchedulerInit',
|
||||
'showSurvey',
|
||||
[ 'showSurvey',
|
||||
'Wait',
|
||||
'Rest',
|
||||
'ProcessErrors',
|
||||
'GetBasePath',
|
||||
'GenerateForm',
|
||||
'Empty',
|
||||
'addSurvey'
|
||||
];
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
export default
|
||||
function Init($location, DeleteSurvey, EditSurvey, AddSurvey, GenerateForm, SurveyQuestionForm, Wait, Alert,
|
||||
GetBasePath, Rest, ProcessErrors, $compile, FinalizeQuestion, EditQuestion, $sce) {
|
||||
function Init(DeleteSurvey, EditSurvey, AddSurvey, GenerateForm, SurveyQuestionForm, Wait, Alert,
|
||||
GetBasePath, Rest, ProcessErrors, $compile, EditQuestion, CreateSelect2) {
|
||||
return function(params) {
|
||||
var scope = params.scope,
|
||||
id = params.id,
|
||||
@ -20,230 +20,183 @@ export default
|
||||
{name: 'Float', type: 'float'}
|
||||
];
|
||||
|
||||
scope.serialize = function(expression){
|
||||
return $sce.getTrustedHtml(expression);
|
||||
};
|
||||
|
||||
scope.deleteSurvey = function() {
|
||||
DeleteSurvey({
|
||||
scope: scope,
|
||||
id: id,
|
||||
// callback: 'SchedulesRefresh'
|
||||
});
|
||||
};
|
||||
|
||||
scope.editSurvey = function() {
|
||||
if(scope.mode==='add'){
|
||||
for(i=0; i<scope.survey_questions.length; i++){
|
||||
questions.push(scope.survey_questions[i]);
|
||||
}
|
||||
}
|
||||
EditSurvey({
|
||||
scope: scope,
|
||||
id: id,
|
||||
// callback: 'SchedulesRefresh'
|
||||
});
|
||||
};
|
||||
/* SURVEY RELATED FUNCTIONS */
|
||||
|
||||
// Called when a job template does not have a saved survey. This simply sets some
|
||||
// default variables and fills the add question form via form generator.
|
||||
scope.addSurvey = function() {
|
||||
AddSurvey({
|
||||
scope: scope
|
||||
});
|
||||
};
|
||||
|
||||
scope.cancelSurvey = function(me){
|
||||
if(scope.mode === 'add'){
|
||||
questions = [];
|
||||
// Called when a job template (new or existing) already has a "saved" survey
|
||||
// In the case where a job template has not yet been created but a survey has
|
||||
// been the data is just pulled out of the scope rather than from the server.
|
||||
// (this is dictated by scope.mode)
|
||||
scope.editSurvey = function() {
|
||||
// Goes out and fetches the existing survey and populates the preview
|
||||
EditSurvey({
|
||||
scope: scope,
|
||||
id: id
|
||||
});
|
||||
};
|
||||
|
||||
// This gets called after a user confirms survey deletion
|
||||
scope.deleteSurvey = function() {
|
||||
// Hide the delete overlay
|
||||
scope.hideDeleteOverlay();
|
||||
// Show the loading spinner
|
||||
Wait('start');
|
||||
// Call the delete survey factory which handles making the rest call
|
||||
// and closing the modal after success
|
||||
DeleteSurvey({
|
||||
scope: scope,
|
||||
id: id
|
||||
});
|
||||
};
|
||||
|
||||
// Called when the user hits cancel/close on the survey modal. This function
|
||||
// goes out and cleans up the survey_questions on scope before destroying
|
||||
// the modal.
|
||||
scope.closeSurvey = function(id) {
|
||||
if(scope.mode === 'add') {
|
||||
// Clear out any "unsaved" survey questions
|
||||
for (var i = scope.survey_questions.length - 1; i >= 0; i--) {
|
||||
if (scope.survey_questions[i].new_question) {
|
||||
scope.survey_questions.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Clear out the whole array, this data gets pulled in each time the modal is opened
|
||||
scope.survey_questions = [];
|
||||
}
|
||||
$(me).dialog('close');
|
||||
$('#' + id).dialog('destroy');
|
||||
}
|
||||
|
||||
// Gets called when a user actually hits the save button. Functionality differs
|
||||
// based on the mode. scope.mode="add" cleans up scope.survey_questions and
|
||||
// destroys the modal, holding the survey questions in memory. scope.mode="edit"
|
||||
// actually fires off the necessary server call(s) to add/update a survey.
|
||||
scope.saveSurvey = function() {
|
||||
Wait('start');
|
||||
if(scope.mode ==="add"){
|
||||
// Loop across the survey questions and remove any new_question flags
|
||||
angular.forEach(scope.survey_questions, function(question, key) {
|
||||
delete question['new_question'];
|
||||
});
|
||||
|
||||
$('#survey-modal-dialog').dialog('destroy');
|
||||
scope.survey_name = "";
|
||||
scope.survey_description = "";
|
||||
scope.$emit('SurveySaved');
|
||||
}
|
||||
else {
|
||||
|
||||
scope.survey_name = "";
|
||||
scope.survey_description = "";
|
||||
|
||||
var updateSurveyQuestions = function() {
|
||||
Rest.setUrl(GetBasePath('job_templates') + id + '/survey_spec/');
|
||||
return Rest.post({name: scope.survey_name, description: scope.survey_description, spec: scope.survey_questions })
|
||||
.success(function (data) {
|
||||
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to add new survey. POST returned status: ' + status });
|
||||
});
|
||||
}
|
||||
|
||||
var updateSurveyEnabled = function() {
|
||||
Rest.setUrl(GetBasePath('job_templates') + id+ '/');
|
||||
return Rest.patch({"survey_enabled": scope.survey_enabled})
|
||||
.success(function (data) {
|
||||
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors(scope, data, status, form, {
|
||||
hdr: 'Error!',
|
||||
msg: 'Failed to retrieve save survey_enabled: ' + $routeParams.template_id + '. GET status: ' + status
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
updateSurveyQuestions()
|
||||
.then(function() {
|
||||
return updateSurveyEnabled();
|
||||
})
|
||||
.then(function() {
|
||||
scope.closeSurvey('survey-modal-dialog');
|
||||
scope.$emit('SurveySaved');
|
||||
})
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
scope.addQuestion = function(){
|
||||
// Gets called when the user clicks the on/off toggle beside the survey modal title.
|
||||
scope.toggleSurveyEnabled = function() {
|
||||
scope.survey_enabled = !scope.survey_enabled;
|
||||
};
|
||||
|
||||
/* END SURVEY RELATED FUNCTIONS */
|
||||
|
||||
/* QUESTION RELATED FUNCTIONS */
|
||||
|
||||
// This injects the Add Question form into survey_maker_question_form
|
||||
scope.generateAddQuestionForm = function(){
|
||||
// This tmpMode logic is necessary because form generator seems to set scope.mode to match the mode that you pass it.
|
||||
// So if a user is editing a job template (scope.mode='edit') but the JT doesn't have a survey then when we open the
|
||||
// modal we need to make sure that scope.mode is still 'edit' after the Add Question form is injected.
|
||||
// To avoid having to do this we'd need to track the job template mode in a variable other than scope.mode.
|
||||
var tmpMode = scope.mode;
|
||||
GenerateForm.inject(form, { id:'new_question', mode: 'add' , scope: scope, related: false});
|
||||
GenerateForm.inject(form, { id:'survey_maker_question_form', mode: 'add' , scope: scope, related: false});
|
||||
scope.mode = tmpMode;
|
||||
scope.required = true; //set the required checkbox to true via the ngmodel attached to scope.required.
|
||||
scope.text_min = null;
|
||||
scope.text_max = null;
|
||||
scope.int_min = null;
|
||||
scope.int_max = null;
|
||||
scope.float_min = null;
|
||||
scope.float_max = null;
|
||||
scope.duplicate = false;
|
||||
scope.invalidChoice = false;
|
||||
scope.minTextError = false;
|
||||
scope.maxTextError = false;
|
||||
scope.clearQuestion();
|
||||
};
|
||||
|
||||
scope.addNewQuestion = function(){
|
||||
// $('#add_question_btn').on("click" , function(){
|
||||
scope.addQuestion();
|
||||
$('#survey_question_question_name').focus();
|
||||
$('#add_question_btn').attr('disabled', 'disabled');
|
||||
$('#add_question_btn').hide();
|
||||
$('#survey-save-button').attr('disabled' , 'disabled');
|
||||
// });
|
||||
};
|
||||
// This gets called when a users clicks the pencil icon beside a question preview in order to edit it.
|
||||
scope.editQuestion = function(index){
|
||||
scope.duplicate = false;
|
||||
// The edit question factory injects the edit form and fills the form with the question data from memory.
|
||||
EditQuestion({
|
||||
index: index,
|
||||
scope: scope,
|
||||
question: (scope.mode==='add') ? questions[index] : scope.survey_questions[index]
|
||||
question: scope.survey_questions[index]
|
||||
});
|
||||
};
|
||||
|
||||
// Gets called when a user clicks the delete icon on a question in the survey preview
|
||||
scope.showDeleteQuestion = function(deleteIndex) {
|
||||
// Keep track of the question to be deleted on scope
|
||||
scope.questionToBeDeleted = deleteIndex;
|
||||
// Show the delete overlay with mode='question'
|
||||
scope.showDeleteOverlay('question');
|
||||
}
|
||||
|
||||
// Called after a user confirms question deletion (hitting the DELETE button on the delete question overlay).
|
||||
scope.deleteQuestion = function(index){
|
||||
element = $('.question_final:eq('+index+')');
|
||||
element.remove();
|
||||
if(scope.mode === 'add'){
|
||||
questions.splice(index, 1);
|
||||
scope.reorder();
|
||||
if(questions.length<1){
|
||||
$('#survey-save-button').attr('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
else {
|
||||
scope.survey_questions.splice(index, 1);
|
||||
scope.reorder();
|
||||
if(scope.survey_questions.length<1){
|
||||
$('#survey-save-button').attr('disabled', 'disabled');
|
||||
// Move the edit question index down by one if this question came before the
|
||||
// one being edited in the array. This makes sure that our pointer to the question
|
||||
// currently being edited gets updated independently from a deleted question.
|
||||
if(GenerateForm.mode === 'edit' && !isNaN(scope.editQuestionIndex)){
|
||||
if(scope.editQuestionIndex == index) {
|
||||
// The user is deleting the question being edited - need to roll back to Add Question mode
|
||||
scope.editQuestionIndex = null;
|
||||
scope.generateAddQuestionForm();
|
||||
}
|
||||
else if(scope.editQuestionIndex > index) {
|
||||
scope.editQuestionIndex--;
|
||||
}
|
||||
}
|
||||
// Remove the question from the array
|
||||
scope.survey_questions.splice(index, 1);
|
||||
// Hide the delete overlay
|
||||
scope.hideDeleteOverlay();
|
||||
};
|
||||
|
||||
scope.cancelQuestion = function(event){
|
||||
var elementID, key;
|
||||
if(event.target.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.id==="new_question"){
|
||||
$('#new_question .aw-form-well').remove();
|
||||
$('#add_question_btn').show();
|
||||
$('#add_question_btn').removeAttr('disabled');
|
||||
if(scope.mode === 'add' && questions.length>0){
|
||||
$('#survey-save-button').removeAttr('disabled');
|
||||
}
|
||||
if(scope.mode === 'edit' && scope.survey_questions.length>0 && scope.can_edit===true){
|
||||
$('#survey-save-button').removeAttr('disabled');
|
||||
}
|
||||
|
||||
} else {
|
||||
elementID = event.target.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.id;
|
||||
key = elementID.split('_')[1];
|
||||
$('#'+elementID).empty();
|
||||
if(scope.mode === 'add'){
|
||||
if(questions.length>0){
|
||||
$('#survey-save-button').removeAttr('disabled');
|
||||
}
|
||||
scope.finalizeQuestion(questions[key], Number(key));
|
||||
}
|
||||
else if(scope.mode=== 'edit' ){
|
||||
if(scope.survey_questions.length>0 && scope.can_edit === true){
|
||||
$('#survey-save-button').removeAttr('disabled');
|
||||
}
|
||||
scope.finalizeQuestion(scope.survey_questions[key] , Number(key));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
scope.questionUp = function(index){
|
||||
var animating = false,
|
||||
clickedDiv = $('#question_'+index),
|
||||
prevDiv = clickedDiv.prev(),
|
||||
distance = clickedDiv.outerHeight();
|
||||
|
||||
if (animating) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (prevDiv.length) {
|
||||
animating = true;
|
||||
$.when(clickedDiv.animate({
|
||||
top: -distance
|
||||
}, 600),
|
||||
prevDiv.animate({
|
||||
top: distance
|
||||
}, 600)).done(function () {
|
||||
prevDiv.css('top', '0px');
|
||||
clickedDiv.css('top', '0px');
|
||||
clickedDiv.insertBefore(prevDiv);
|
||||
animating = false;
|
||||
if ( scope.mode === 'add'){
|
||||
i = questions[index];
|
||||
questions[index] = questions[index-1];
|
||||
questions[index-1] = i;
|
||||
} else {
|
||||
i = scope.survey_questions[index];
|
||||
scope.survey_questions[index] = scope.survey_questions[index-1];
|
||||
scope.survey_questions[index-1] = i;
|
||||
}
|
||||
scope.reorder();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
scope.questionDown = function(index){
|
||||
var clickedDiv = $('#question_'+index),
|
||||
nextDiv = clickedDiv.next(),
|
||||
distance = clickedDiv.outerHeight(),
|
||||
animating = false;
|
||||
|
||||
if (animating) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextDiv.length) {
|
||||
animating = true;
|
||||
$.when(clickedDiv.animate({
|
||||
top: distance
|
||||
}, 600),
|
||||
nextDiv.animate({
|
||||
top: -distance
|
||||
}, 600)).done(function () {
|
||||
nextDiv.css('top', '0px');
|
||||
clickedDiv.css('top', '0px');
|
||||
nextDiv.insertBefore(clickedDiv);
|
||||
animating = false;
|
||||
if(scope.mode === 'add'){
|
||||
i = questions[index];
|
||||
questions[index] = questions[Number(index)+1];
|
||||
questions[Number(index)+1] = i;
|
||||
} else {
|
||||
i = scope.survey_questions[index];
|
||||
scope.survey_questions[index] = scope.survey_questions[Number(index)+1];
|
||||
scope.survey_questions[Number(index)+1] = i;
|
||||
}
|
||||
scope.reorder();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
scope.reorder = function(){
|
||||
if(scope.mode==='add'){
|
||||
for(i=0; i<questions.length; i++){
|
||||
questions[i].index=i;
|
||||
$('.question_final:eq('+i+')').attr('id', 'question_'+i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i=0; i<scope.survey_questions.length; i++){
|
||||
scope.survey_questions[i].index=i;
|
||||
$('.question_final:eq('+i+')').attr('id', 'question_'+i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
scope.finalizeQuestion= function(data, index){
|
||||
FinalizeQuestion({
|
||||
scope: scope,
|
||||
question: data,
|
||||
id: id,
|
||||
index: index
|
||||
});
|
||||
};
|
||||
|
||||
scope.typeChange = function() {
|
||||
function clearTypeSpecificFields() {
|
||||
scope.minTextError = false;
|
||||
scope.maxTextError = false;
|
||||
scope.default = "";
|
||||
@ -263,6 +216,34 @@ export default
|
||||
scope.int_max = "";
|
||||
scope.float_min = "";
|
||||
scope.float_max = "";
|
||||
}
|
||||
|
||||
// Sets all of our scope variables used for adding/editing a question back to a clean state
|
||||
scope.clearQuestion = function(){
|
||||
clearTypeSpecificFields();
|
||||
scope.editQuestionIndex = null;
|
||||
scope.question_name = null;
|
||||
scope.question_description = null;
|
||||
scope.variable = null;
|
||||
scope.required = true; //set the required checkbox to true via the ngmodel attached to scope.required.
|
||||
scope.duplicate = false;
|
||||
scope.invalidChoice = false;
|
||||
scope.type = "";
|
||||
|
||||
// Make sure that the select2 dropdown for question type is clean
|
||||
CreateSelect2({
|
||||
element:'#survey_question_type',
|
||||
multiple: false
|
||||
});
|
||||
|
||||
// Set the whole form to pristine
|
||||
scope.survey_question_form.$setPristine();
|
||||
}
|
||||
|
||||
// Gets called when the "type" dropdown value changes. In that case, we want to clear out
|
||||
// all the "type" specific fields/errors and start fresh.
|
||||
scope.typeChange = function() {
|
||||
clearTypeSpecificFields();
|
||||
scope.survey_question_form.default.$setPristine();
|
||||
scope.survey_question_form.default_multiselect.$setPristine();
|
||||
scope.survey_question_form.default_float.$setPristine();
|
||||
@ -274,6 +255,9 @@ export default
|
||||
scope.survey_question_form.int_max.$setPristine();
|
||||
};
|
||||
|
||||
// Function that gets called when a user hits ADD/UPDATE on the survey question form. This
|
||||
// function handles some validation as well as eventually adding the question to the
|
||||
// scope.survey_questions array.
|
||||
scope.submitQuestion = function(event){
|
||||
var data = {},
|
||||
fld, i,
|
||||
@ -340,36 +324,18 @@ export default
|
||||
|
||||
// validate that there aren't any questions using this var name.
|
||||
if(GenerateForm.mode === 'add'){
|
||||
if(scope.mode === 'add'){
|
||||
for(fld in questions){
|
||||
if(questions[fld].variable === scope.variable){
|
||||
scope.duplicate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (scope.mode === 'edit'){
|
||||
for(fld in scope.survey_questions){
|
||||
if(scope.survey_questions[fld].variable === scope.variable){
|
||||
scope.duplicate = true;
|
||||
}
|
||||
for(fld in scope.survey_questions){
|
||||
if(scope.survey_questions[fld].variable === scope.variable){
|
||||
scope.duplicate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(GenerateForm.mode === 'edit'){
|
||||
elementID = event.target.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.id;
|
||||
key = elementID.split('_')[1];
|
||||
if(scope.mode==='add'){
|
||||
for(fld in questions){
|
||||
if(questions[fld].variable === scope.variable && fld!==key){
|
||||
scope.duplicate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(scope.mode === 'edit'){
|
||||
for(fld in scope.survey_questions){
|
||||
if(scope.survey_questions[fld].variable === scope.variable && fld!==key){
|
||||
scope.duplicate = true;
|
||||
}
|
||||
// Loop across the survey questions and see if a different question already has
|
||||
// the same variable name
|
||||
for(var i=0; i<scope.survey_questions.length; i++){
|
||||
if(scope.survey_questions[i].variable === scope.variable && i!==scope.editQuestionIndex){
|
||||
scope.duplicate = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,38 +406,22 @@ export default
|
||||
}
|
||||
|
||||
Wait('stop');
|
||||
if(scope.mode === 'add' || scope.mode==="edit" && scope.can_edit === true){
|
||||
$('#survey-save-button').removeAttr('disabled');
|
||||
}
|
||||
|
||||
if(GenerateForm.mode === 'add'){
|
||||
if(scope.mode === 'add'){
|
||||
questions.push(data);
|
||||
$('#new_question .aw-form-well').remove();
|
||||
$('#add_question_btn').show();
|
||||
scope.finalizeQuestion(data , questions.length-1);
|
||||
}
|
||||
else if (scope.mode === 'edit'){
|
||||
scope.survey_questions.push(data);
|
||||
$('#new_question .aw-form-well').remove();
|
||||
$('#add_question_btn').show();
|
||||
scope.finalizeQuestion(data , scope.survey_questions.length-1);
|
||||
}
|
||||
// Flag this question as new
|
||||
data.new_question = true;
|
||||
|
||||
scope.survey_questions.push(data);
|
||||
$('#new_question .aw-form-well').remove();
|
||||
$('#add_question_btn').show();
|
||||
}
|
||||
if(GenerateForm.mode === 'edit'){
|
||||
elementID = event.target.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.id;
|
||||
key = elementID.split('_')[1];
|
||||
if(scope.mode==='add'){
|
||||
questions[key] = data;
|
||||
}
|
||||
else if(scope.mode === 'edit'){
|
||||
scope.survey_questions[key] = data;
|
||||
}
|
||||
$('#'+elementID).empty();
|
||||
scope.finalizeQuestion(data , Number(key));
|
||||
// Overwrite the survey question with the new data
|
||||
scope.survey_questions[scope.editQuestionIndex] = data;
|
||||
}
|
||||
|
||||
// Throw the user back to the "add question" form
|
||||
scope.generateAddQuestionForm();
|
||||
|
||||
|
||||
} catch (err) {
|
||||
@ -479,71 +429,109 @@ export default
|
||||
Alert("Error", "Error parsing extra variables. Parser returned: " + err);
|
||||
}
|
||||
};
|
||||
scope.resetForm = function(){
|
||||
html = '<div class="row">'+
|
||||
'<div class="col-sm-12">'+
|
||||
'<label for="survey"><span class="label-text prepend-asterisk"> Questions</span></label>'+
|
||||
'<div id="survey_maker_question_area"></div>'+
|
||||
'<div id="finalized_questions"></div>'+
|
||||
'<button style="display:none" type="button" class="btn btn-sm btn-primary" id="add_question_btn" ng-click="addNewQuestion()" aw-tool-tip="Create a new question" data-placement="top" data-original-title="" title="" disabled><i class="fa fa-plus fa-lg"></i> New Question</button>'+
|
||||
'<div id="new_question"></div>'+
|
||||
'</div>'+
|
||||
'</div>';
|
||||
$('#survey-modal-dialog').html(html);
|
||||
element = angular.element(document.getElementById('add_question_btn'));
|
||||
$compile(element)(scope);
|
||||
};
|
||||
|
||||
scope.saveSurvey = function() {
|
||||
Wait('start');
|
||||
if(scope.mode ==="add"){
|
||||
$('#survey-modal-dialog').dialog('close');
|
||||
if(questions.length>0){
|
||||
scope.survey_questions = questions;
|
||||
// This function is bound to the dnd-drop directive. When a question is dragged and
|
||||
// dropped, this is the function that gets called.
|
||||
scope.surveyQuestionDropped = function(dropIndex, question) {
|
||||
|
||||
// Handle moving the question to its new slot in scope.survey_questions
|
||||
for(var i=0; i<scope.survey_questions.length; i++) {
|
||||
|
||||
if(angular.equals(scope.survey_questions[i], question)) {
|
||||
|
||||
// Check to make sure that the survey question was actually moved
|
||||
if(i !== dropIndex) {
|
||||
// Since the suvey question being "moved" is still technically in the array
|
||||
// we need to adjust the drop index when moving a question down in the array
|
||||
// See: https://github.com/marceljuenemann/angular-drag-and-drop-lists/issues/54#issuecomment-125487293
|
||||
if(i < dropIndex) {
|
||||
dropIndex--;
|
||||
}
|
||||
// Remove this survey question from its original position
|
||||
scope.survey_questions.splice(i, 1);
|
||||
|
||||
// Add this survey question to its new position
|
||||
scope.survey_questions.splice(dropIndex, 0, question);
|
||||
|
||||
// Update the editQuestionIndex if applicable
|
||||
if(typeof scope.editQuestionIndex === "number") {
|
||||
// A question is being edited - lets see if we need to adjust the index
|
||||
if(scope.editQuestionIndex === i) {
|
||||
// The edited question was moved
|
||||
scope.editQuestionIndex = dropIndex;
|
||||
}
|
||||
else if(scope.editQuestionIndex < i && dropIndex <= scope.editQuestionIndex) {
|
||||
// An element that was behind the edit question is now ahead of it
|
||||
scope.editQuestionIndex++;
|
||||
}
|
||||
else if(scope.editQuestionIndex > i && dropIndex >= scope.editQuestionIndex) {
|
||||
// An element that was ahead of the edit question is now behind it
|
||||
scope.editQuestionIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Break out of the for loop
|
||||
break;
|
||||
}
|
||||
scope.survey_name = "";
|
||||
scope.survey_description = "";
|
||||
questions = [] ;
|
||||
scope.$emit('SurveySaved');
|
||||
}
|
||||
else{
|
||||
scope.survey_name = "";
|
||||
scope.survey_description = "";
|
||||
url = GetBasePath('job_templates') + id + '/survey_spec/';
|
||||
Rest.setUrl(url);
|
||||
Rest.post({ name: scope.survey_name, description: scope.survey_description, spec: scope.survey_questions })
|
||||
.success(function () {
|
||||
// Wait('stop');
|
||||
$('#survey-modal-dialog').dialog('close');
|
||||
scope.$emit('SurveySaved');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to add new survey. POST returned status: ' + status });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//for toggling the input on password inputs
|
||||
};
|
||||
|
||||
// return true here signals that the drop is allowed, but that we've already taken care of inserting the element
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gets called when a user is creating/editing a question that has a password
|
||||
// field. The password field in the form has a SHOW/HIDE button that calls this.
|
||||
scope.toggleInput = function(id) {
|
||||
// Note that the id string passed into this function will have a "#" prepended
|
||||
var buttonId = id + "_show_input_button",
|
||||
inputId = id,
|
||||
buttonInnerHTML = $(buttonId).html();
|
||||
if (buttonInnerHTML.indexOf("Show") > -1) {
|
||||
$(buttonId).html("Hide");
|
||||
if (buttonInnerHTML.indexOf("SHOW") > -1) {
|
||||
$(buttonId).html("HIDE");
|
||||
$(inputId).attr("type", "text");
|
||||
} else {
|
||||
$(buttonId).html("Show");
|
||||
$(buttonId).html("SHOW");
|
||||
$(inputId).attr("type", "password");
|
||||
}
|
||||
};
|
||||
|
||||
/* END QUESTION RELATED FUNCTIONS */
|
||||
|
||||
/* DELETE OVERLAY RELATED FUNCTIONS */
|
||||
|
||||
// This handles setting the delete mode and flipping the boolean used to show the delete overlay
|
||||
scope.showDeleteOverlay = function(mode) {
|
||||
// Set the delete mode (question or survey) so that the overlay knows
|
||||
// how to phrase the prompt
|
||||
scope.deleteMode = mode;
|
||||
// Flip the deleteOverlayVisible flag so that the overlay becomes visible via ng-show
|
||||
scope.deleteOverlayVisible = true;
|
||||
}
|
||||
|
||||
// Called by the cancel/close buttons on the delete overlay. Also called after deletion has been confirmed.
|
||||
scope.hideDeleteOverlay = function() {
|
||||
// Clear out the delete mode for next time
|
||||
scope.deleteMode = null;
|
||||
// Clear out the index variable for next time
|
||||
scope.questionToBeDeleted = null;
|
||||
// Hide the delete overlay
|
||||
scope.deleteOverlayVisible = false;
|
||||
}
|
||||
|
||||
/* END DELETE OVERLAY RELATED FUNCTIONS */
|
||||
|
||||
// Watcher that updates the survey enabled/disabled tooltip based on scope.survey_enabled
|
||||
scope.$watch('survey_enabled', function(newVal, oldVal) {
|
||||
scope.surveyEnabledTooltip = (newVal) ? "Disable survey" : "Enable survey";
|
||||
})
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
Init.$inject =
|
||||
[ '$location',
|
||||
'deleteSurvey',
|
||||
[ 'deleteSurvey',
|
||||
'editSurvey',
|
||||
'addSurvey',
|
||||
'GenerateForm',
|
||||
@ -554,7 +542,6 @@ Init.$inject =
|
||||
'Rest',
|
||||
'ProcessErrors',
|
||||
'$compile',
|
||||
'finalizeQuestion',
|
||||
'editQuestion',
|
||||
'$sce'
|
||||
'CreateSelect2'
|
||||
];
|
||||
|
||||
@ -8,60 +8,26 @@ export default
|
||||
mode = (params.mode) ? params.mode : "survey-maker",
|
||||
title = params.title,
|
||||
element,
|
||||
target = (mode==='survey-taker') ? 'password-modal' : "survey-modal-dialog",
|
||||
buttons = [{
|
||||
"label": "Cancel",
|
||||
"onClick": function() {
|
||||
scope.cancelSurvey(this);
|
||||
},
|
||||
"icon": "fa-times",
|
||||
"class": "btn btn-default",
|
||||
"id": "survey-close-button"
|
||||
},{
|
||||
"label": (mode==='survey-taker') ? "Launch" : "Save" ,
|
||||
"onClick": function() {
|
||||
setTimeout(function(){
|
||||
scope.$apply(function(){
|
||||
if(mode==='survey-taker'){
|
||||
scope.$emit('SurveyTakerCompleted');
|
||||
} else{
|
||||
scope.saveSurvey();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
"icon": (mode==='survey-taker') ? "fa-rocket" : "fa-check",
|
||||
"class": "btn btn-primary",
|
||||
"id": "survey-save-button"
|
||||
}];
|
||||
target = (mode==='survey-taker') ? 'password-modal' : "survey-modal-dialog";
|
||||
|
||||
CreateDialog({
|
||||
id: target,
|
||||
title: title,
|
||||
scope: scope,
|
||||
buttons: buttons,
|
||||
width: 700,
|
||||
height: 725,
|
||||
width: 1200,
|
||||
minWidth: 400,
|
||||
draggable: false,
|
||||
dialogClass: 'SurveyMaker-dialog',
|
||||
onClose: function() {
|
||||
$('#'+target).empty();
|
||||
},
|
||||
onOpen: function() {
|
||||
Wait('stop');
|
||||
if(mode!=="survey-taker"){
|
||||
// if(scope.mode === 'add'){
|
||||
// $('#survey-save-button').attr('disabled' , true);
|
||||
// } else
|
||||
if(scope.can_edit === false){
|
||||
$('#survey-save-button').attr('disabled', "disabled");
|
||||
}
|
||||
else {
|
||||
$('#survey-save-button').attr('ng-disabled', "survey_questions.length<1 ");
|
||||
}
|
||||
element = angular.element(document.getElementById('survey-save-button'));
|
||||
$compile(element)(scope);
|
||||
|
||||
}
|
||||
// Let the modal height be variable based on the content
|
||||
// and set a uniform padding
|
||||
$('#'+target).css({'height': 'auto', 'padding': '20px'});
|
||||
|
||||
if(mode==="survey-taker"){
|
||||
$('#survey-save-button').attr('ng-disabled', "survey_taker_form.$invalid");
|
||||
element = angular.element(document.getElementById('survey-save-button'));
|
||||
|
||||
95
awx/ui/client/src/partials/survey-maker-modal.html
Normal file
95
awx/ui/client/src/partials/survey-maker-modal.html
Normal file
@ -0,0 +1,95 @@
|
||||
<div id="survey-modal-dialog" style="display: none;">
|
||||
<div class="SurveyMaker-deleteOverlay" ng-show="deleteOverlayVisible">
|
||||
<div class="Modal-content modal-content">
|
||||
<div class="Modal-header">
|
||||
<div class="Modal-title" ng-bind="deleteMode === 'survey' ? 'Delete Survey' : (deleteMode === 'question' ? 'Delete Question' : '')"></div>
|
||||
<div class="Modal-exitHolder">
|
||||
<button class="close Modal-exit" ng-click="hideDeleteOverlay()">
|
||||
<i class="fa fa-times-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Modal-body ng-binding">
|
||||
<div class="Prompt-bodyQuery">Are you sure you want to delete this {{deleteMode}}?</div>
|
||||
<div class="Prompt-bodyTarget">{{survey_questions[questionToBeDeleted].question_name}}</div>
|
||||
</div>
|
||||
<div class="Modal-footer">
|
||||
<button ng-click="deleteMode === 'survey' ? deleteSurvey() : (deleteMode === 'question' ? deleteQuestion(questionToBeDeleted) : '')" class="btn Modal-footerButton ng-binding Modal-errorButton">DELETE</a>
|
||||
<button ng-click="hideDeleteOverlay()" class="btn Modal-defaultButton Modal-footerButton">CANCEL</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="SurveyMaker-header">
|
||||
<div class="SurveyMaker-title">
|
||||
<div class="SurveyMaker-titleText">{{name || "New Job Template"}}<div class="SurveyMaker-titleLockup"></div>SURVEY</div>
|
||||
<div class="ScheduleToggle" ng-class="{'is-on': survey_enabled}" aw-tool-tip="surveyEnabledTooltip" data-placement="right" data-tip-watch="surveyEnabledTooltip">
|
||||
<div ng-show="survey_enabled" class="ScheduleToggle-switch is-on" ng-click="toggleSurveyEnabled()">ON</div>
|
||||
<div ng-show="!survey_enabled" class="ScheduleToggle-switch" ng-click="toggleSurveyEnabled()">OFF</div>
|
||||
</div>
|
||||
</div>
|
||||
<button id="delete-survey" class="SurveyMaker-deleteButton" data-placement="top" ng-show="survey_exists" ng-click="showDeleteOverlay('survey')" aw-tool-tip="Delete survey" data-original-title="" title="">
|
||||
<i class="fa fa-trash-o"></i>
|
||||
</button>
|
||||
<div class="SurveyMaker-close">
|
||||
<button class="SurveyMaker-exit" ng-click="closeSurvey('survey-modal-dialog')"><i class="fa fa-times-circle"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="SurveyMaker-content">
|
||||
<div class="SurveyMaker-questionPanel">
|
||||
<div id="survey_maker_question_form"></div>
|
||||
</div>
|
||||
<div class="SurveyMaker-separatorPanel">
|
||||
<div class="SurveyMaker-contentSeparator">
|
||||
</div>
|
||||
</div>
|
||||
<div class="SurveyMaker-previewPanel">
|
||||
<div style="display: flex; flex-direction: column; width: 100%;">
|
||||
<div class="SurveyMaker-panelHeader">PREVIEW</div>
|
||||
<div class="SurveyMaker-panelBody">
|
||||
<div ng-if="survey_questions.length < 1" class="SurveyMaker-noQuestions">PLEASE ADD A QUESTION ON THE LEFT</div>
|
||||
<ul dnd-list="survey_questions" class="SurveyMaker-previewRows" dnd-drop="surveyQuestionDropped(index, item)">
|
||||
<li ng-repeat="question in survey_questions" dnd-draggable="question" dnd-effect-allowed="move" class="SurveyMaker-previewRow">
|
||||
<dnd-nodrag>
|
||||
<div>
|
||||
<label class="SurveyMaker-previewLabel" for="question.variable">
|
||||
<span class="label-text" ng-class="{'prepend-asterisk': question.required}"> {{question.question_name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div ng-if="question.question_description" class="col-xs-12 description">
|
||||
<i>{{question.question_description}}</i>
|
||||
</div>
|
||||
<div class="SurveyMaker-previewInputRow">
|
||||
<span dnd-handle class="SurveyMaker-reorderButton" data-placement="top" aw-tool-tip="Drag to reorder question" data-original-title="" title="">
|
||||
<i class="fa fa-ellipsis-v"></i>
|
||||
<span> </span>
|
||||
<i class="fa fa-ellipsis-v"></i>
|
||||
</span>
|
||||
<survey-question class="SurveyMaker-previewInput" preview="true" question="question" ng-required="question.required" ng-disabled=true></survey-question>
|
||||
<div class="SurveyMaker-previewActions">
|
||||
<button class="List-actionButton" data-placement="top" ng-class="{'SurveyMaker-previewActions--selected' : editQuestionIndex == $index}" ng-click="editQuestion($index)" aw-tool-tip="Edit question" data-original-title="" title="">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</button>
|
||||
<button class="List-actionButton List-actionButton--delete" data-placement="top" ng-click="showDeleteQuestion($index)" aw-tool-tip="Delete question" data-original-title="" title="">
|
||||
<i class="fa fa-trash-o"></i>
|
||||
</button>
|
||||
</div>
|
||||
</dnd-nodrag>
|
||||
</div>
|
||||
</li>
|
||||
<li class="SurveyMaker-previewRow dndPlaceholder">
|
||||
Drop question here to reorder
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="SurveyMaker-panelFooter">
|
||||
<div class="Form-buttons">
|
||||
<button id="survey-save-button" class="btn btn-sm Form-saveButton" ng-click="saveSurvey()" ng-disabled="survey_questions.length < 1 || !can_edit || editQuestionIndex !== null">SAVE</button>
|
||||
<button id="survey-close-button" class="btn btn-sm Form-buttonDefault" ng-click="closeSurvey('survey-modal-dialog')">CANCEL</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1,6 +0,0 @@
|
||||
<!-- <div class="tab-pane" id="survey_maker"> -->
|
||||
<div class="tab-pane" id="survey-modal-dailog">
|
||||
<survey-maker ng-if="isModalReady"></survey-maker>
|
||||
<div id="htmlTemplate" class="ng-scope"></div>
|
||||
<!-- <div id="survey-modal-dialog" title="Add Survey"></div> -->
|
||||
</div>
|
||||
@ -60,6 +60,8 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper'])
|
||||
beforeDestroy = params.beforeDestroy,
|
||||
closeOnEscape = (params.closeOnEscape === undefined) ? false : params.closeOnEscape,
|
||||
resizable = (params.resizable === undefined) ? true : params.resizable,
|
||||
draggable = (params.draggable === undefined) ? true : params.draggable,
|
||||
dialogClass = params.dialogClass,
|
||||
forms = _.chain([params.form]).flatten().compact().value(),
|
||||
buttons,
|
||||
id = params.id,
|
||||
@ -104,6 +106,8 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper'])
|
||||
title: title,
|
||||
closeOnEscape: closeOnEscape,
|
||||
resizable: resizable,
|
||||
draggable: draggable,
|
||||
dialogClass: dialogClass,
|
||||
create: function () {
|
||||
// Fix the close button
|
||||
$('.ui-dialog[aria-describedby="' + id + '"]').find('.ui-dialog-titlebar button').empty().attr({'class': 'close'}).html('<i class="fa fa-times-circle"></i>');
|
||||
|
||||
@ -615,7 +615,8 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
|
||||
var element = params.element,
|
||||
options = params.opts,
|
||||
multiple = (params.multiple!==undefined) ? params.multiple : true,
|
||||
placeholder = params.placeholder;
|
||||
placeholder = params.placeholder,
|
||||
customDropdownAdapter = (params.customDropdownAdapter!==undefined) ? params.customDropdownAdapter : true;
|
||||
|
||||
$.fn.select2.amd.require([
|
||||
'select2/utils',
|
||||
@ -632,14 +633,22 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
|
||||
return Utils.Decorate(Adapter, Decorator);
|
||||
}, Dropdown);
|
||||
|
||||
$(element).select2({
|
||||
var config = {
|
||||
placeholder: placeholder,
|
||||
multiple: multiple,
|
||||
containerCssClass: 'Form-dropDown',
|
||||
width: '100%',
|
||||
minimumResultsForSearch: Infinity,
|
||||
dropdownAdapter: CustomAdapter
|
||||
});
|
||||
}
|
||||
|
||||
// multiple-choice directive calls select2 but needs to do so without this custom adapter
|
||||
// to allow the element to be draggable on survey preview.
|
||||
if(customDropdownAdapter) {
|
||||
config.dropdownAdapter = CustomAdapter;
|
||||
}
|
||||
|
||||
$(element).select2(config);
|
||||
|
||||
if(options){
|
||||
for (var d = 0; d < $(element + " option").length; d++) {
|
||||
var item = $(element + " option")[d];
|
||||
|
||||
@ -261,7 +261,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
$('.form-control[required], input[type="radio"][required]').each(function () {
|
||||
var label, span;
|
||||
if (Empty($(this).attr('aw-required-when'))) {
|
||||
label = $(this).parent().parent().find('label').first();
|
||||
label = $(this).closest('.form-group').find('label').first();
|
||||
if ($(this).attr('type') === 'radio') {
|
||||
label = $(this).parent().parent().parent().find('label').first();
|
||||
}
|
||||
@ -568,7 +568,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
}
|
||||
html += "<input type=\"text\" name=\"" + fld + "\" ";
|
||||
html += "ng-model=\"" + fld + "\" ";
|
||||
html += (field['class']) ? Attr(field, "class") : "";
|
||||
html += " readonly />\n";
|
||||
return html;
|
||||
},
|
||||
@ -674,7 +673,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += "id=\"" + form.name + "_" + fld + "_chbox\" ";
|
||||
html += (idx !== undefined) ? "_" + idx : "";
|
||||
html += "class=\"";
|
||||
html += (field['class']) ? field['class'] + " " : "";
|
||||
html += "\"";
|
||||
html += (field.trueValue !== undefined) ? Attr(field, 'trueValue') : "";
|
||||
html += (field.falseValue !== undefined) ? Attr(field, 'falseValue') : "";
|
||||
@ -737,7 +735,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += "\">\n";
|
||||
html += "<div class=\"alert";
|
||||
html += (field.closeable === undefined || field.closeable === true) ? " alert-dismissable" : "";
|
||||
html += (field['class']) ? " " + field['class'] : "";
|
||||
html += "\" ";
|
||||
html += (field.ngShow) ? this.attr(field, 'ngShow') : "";
|
||||
html += ">\n";
|
||||
@ -783,7 +780,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += buildId(field, fld, this.form);
|
||||
html += (field.controlNGClass) ? "ng-class=\"" + field.controlNGClass + "\" " : "";
|
||||
html += "class=\"form-control Form-textInput ";
|
||||
html += (field['class']) ? " " + this.attr(field, 'class') : "";
|
||||
html += "\" ";
|
||||
html += (field.placeholder) ? this.attr(field, 'placeholder') : "";
|
||||
html += (options.mode === 'edit' && field.editRequired) ? "required " : "";
|
||||
@ -915,7 +911,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
|
||||
html += (field.controlNGClass) ? "ng-class='" + field.controlNGClass + "' " : "";
|
||||
html += "class='form-control Form-textInput";
|
||||
html += (field['class']) ? " " + this.attr(field, 'class') : "";
|
||||
html += "' ";
|
||||
html += (field.chkPass) ? "chk-pass " : "";
|
||||
|
||||
@ -1044,7 +1039,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += "ng-model=\"" + fld + '" ';
|
||||
html += 'name="' + fld + '" ';
|
||||
html += "class=\"form-control Form-textArea";
|
||||
html += (field['class']) ? " " + field['class'] : "";
|
||||
html += (field['elementClass']) ? " " + field['elementClass'] : "";
|
||||
html += "\" ";
|
||||
html += (field.ngChange) ? this.attr(field, 'ngChange') : "";
|
||||
@ -1083,7 +1077,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += "ng-model=\"" + fld + '" ';
|
||||
html += 'name="' + fld + '" ';
|
||||
html += "class=\"form-control Form-dropDown";
|
||||
html += (field['class']) ? " " + field['class'] : "";
|
||||
html += "\" ";
|
||||
html += (field.ngOptions) ? this.attr(field, 'ngOptions') : "" ;
|
||||
html += (field.ngChange) ? this.attr(field, 'ngChange') : "";
|
||||
@ -1138,7 +1131,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
if (!field.slider && !field.spinner) {
|
||||
html += "form-control";
|
||||
}
|
||||
html += (field['class']) ? " " + field['class'] : "";
|
||||
html += "\" ";
|
||||
html += (field.slider) ? "aw-slider=\"" + fld + "\" " : "";
|
||||
html += (field.spinner) ? "aw-spinner=\"" + fld + "\" " : "";
|
||||
@ -1387,14 +1379,16 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
|
||||
// title and exit button
|
||||
html += "<div class=\"Form-header\">";
|
||||
html += "<div class=\"Form-title\">";
|
||||
html += "<div class=\"Form-title ";
|
||||
html += (this.form.titleClass) ? this.form.titleClass : "";
|
||||
html += "\">";
|
||||
html += (options.mode === 'edit') ? this.form.editTitle : this.form.addTitle;
|
||||
if(this.form.name === "user"){
|
||||
html+= "<span class=\"Form-title--is_superuser\" "+
|
||||
"ng-if=is_superuser>Admin</span>";
|
||||
}
|
||||
html += "</div>\n";
|
||||
if(options.cancelButton !== undefined && options.cancelButton === false) {
|
||||
if(this.form.cancelButton !== undefined && this.form.cancelButton === false) {
|
||||
html += "<div class=\"Form-exitHolder\">";
|
||||
html += "</div>";
|
||||
} else {
|
||||
@ -1403,9 +1397,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += "<i class=\"fa fa-times-circle\"></i>";
|
||||
html += "</button></div>\n";
|
||||
}
|
||||
html += "</div>\n"; //end of Form-header
|
||||
|
||||
|
||||
html += "</div>\n"; //end of Form-header
|
||||
|
||||
if (this.form.tabs) {
|
||||
var collection;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user