mirror of
https://github.com/ansible/awx.git
synced 2026-03-24 12:25:01 -02:30
adding beginning of survey maker and portal mode
This commit is contained in:
@@ -114,7 +114,9 @@ angular.module('Tower', [
|
|||||||
'lrInfiniteScroll',
|
'lrInfiniteScroll',
|
||||||
'LoadConfigHelper',
|
'LoadConfigHelper',
|
||||||
'SocketHelper',
|
'SocketHelper',
|
||||||
'AboutAnsibleHelpModal'
|
'AboutAnsibleHelpModal',
|
||||||
|
'SurveyMakerFormDefinition',
|
||||||
|
'SurveyQuestionFormDefinition'
|
||||||
])
|
])
|
||||||
|
|
||||||
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
||||||
@@ -132,9 +134,10 @@ angular.module('Tower', [
|
|||||||
controller: 'JobsListController'
|
controller: 'JobsListController'
|
||||||
}).
|
}).
|
||||||
// when('/portal', {
|
// when('/portal', {
|
||||||
|
// templateUrl: urlPrefix + 'partials/portal.html'
|
||||||
// controller: 'Portal'
|
// controller: 'Portal'
|
||||||
|
// }).
|
||||||
|
|
||||||
// })
|
|
||||||
when('/jobs/:id', {
|
when('/jobs/:id', {
|
||||||
templateUrl: urlPrefix + 'partials/job_detail.html',
|
templateUrl: urlPrefix + 'partials/job_detail.html',
|
||||||
controller: 'JobDetailController'
|
controller: 'JobDetailController'
|
||||||
@@ -160,6 +163,16 @@ angular.module('Tower', [
|
|||||||
controller: 'JobTemplatesEdit'
|
controller: 'JobTemplatesEdit'
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
when('/job_templates/add/survey', {
|
||||||
|
templateUrl: urlPrefix + 'partials/survey_maker.html',
|
||||||
|
controller: 'SurveyMakerAdd'
|
||||||
|
}).
|
||||||
|
|
||||||
|
when('/job_templates/:template_id/survey', {
|
||||||
|
templateUrl: urlPrefix + 'partials/survey_maker.html',
|
||||||
|
controller: 'SurveyMakerAdd'
|
||||||
|
}).
|
||||||
|
|
||||||
when('/job_templates/:id/schedules', {
|
when('/job_templates/:id/schedules', {
|
||||||
templateUrl: urlPrefix + 'partials/schedule_detail.html',
|
templateUrl: urlPrefix + 'partials/schedule_detail.html',
|
||||||
controller: 'ScheduleEditController'
|
controller: 'ScheduleEditController'
|
||||||
|
|||||||
@@ -335,6 +335,11 @@ function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $routePa
|
|||||||
$scope[fld] = master[fld];
|
$scope[fld] = master[fld];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//navigate to the survey maker
|
||||||
|
$scope.navigateToSurvey = function() {
|
||||||
|
$location.path($location.path() + '/survey');
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
JobTemplatesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm',
|
JobTemplatesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm',
|
||||||
@@ -813,6 +818,11 @@ function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//navigate to the survey maker
|
||||||
|
$scope.navigateToSurvey = function() {
|
||||||
|
$location.path($location.path() + '/survey');
|
||||||
|
};
|
||||||
|
|
||||||
// Related set: Delete button
|
// Related set: Delete button
|
||||||
$scope['delete'] = function (set, itm_id, name, title) {
|
$scope['delete'] = function (set, itm_id, name, title) {
|
||||||
$rootScope.flashMessage = null;
|
$rootScope.flashMessage = null;
|
||||||
|
|||||||
191
awx/ui/static/js/controllers/Portal.js
Normal file
191
awx/ui/static/js/controllers/Portal.js
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
// /************************************
|
||||||
|
// * Copyright (c) 2014 AnsibleWorks, Inc.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// * Portal.js
|
||||||
|
// *
|
||||||
|
// * Controller functions for portal mode
|
||||||
|
// *
|
||||||
|
// */
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @ngdoc function
|
||||||
|
// * @name controllers.function:Portal
|
||||||
|
// * @description This controller's for portal mode
|
||||||
|
// */
|
||||||
|
// 'use strict';
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @ngdoc method
|
||||||
|
// * @name controllers.function:Portal#Portal
|
||||||
|
// * @methodOf controllers.function:Portal
|
||||||
|
// * @description portal mode woohoo
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// */
|
||||||
|
// function Portal($scope, $compile, $routeParams, $rootScope, $location, $log, Wait,
|
||||||
|
// ClearScope, Stream, Rest, GetBasePath, ProcessErrors, Button){
|
||||||
|
|
||||||
|
// ClearScope('portal');
|
||||||
|
|
||||||
|
// // var buttons, html, e, waitCount, loadedCount,borderStyles, jobs_scope, schedule_scope;
|
||||||
|
|
||||||
|
// // // Add buttons to the top of the Home page. We're using lib/ansible/generator_helpers.js-> Buttons()
|
||||||
|
// // // to build buttons dynamically and insure all styling and icons match the rest of the application.
|
||||||
|
// // buttons = {
|
||||||
|
// // refresh: {
|
||||||
|
// // mode: 'all',
|
||||||
|
// // awToolTip: "Refresh the page",
|
||||||
|
// // ngClick: "refresh()",
|
||||||
|
// // ngShow:"socketStatus == 'error'"
|
||||||
|
// // },
|
||||||
|
// // stream: {
|
||||||
|
// // ngClick: "showActivity()",
|
||||||
|
// // awToolTip: "View Activity Stream",
|
||||||
|
// // mode: 'all'
|
||||||
|
// // }
|
||||||
|
// // };
|
||||||
|
|
||||||
|
// // html = Button({
|
||||||
|
// // btn: buttons.refresh,
|
||||||
|
// // action: 'refresh',
|
||||||
|
// // toolbar: true
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // html += Button({
|
||||||
|
// // btn: buttons.stream,
|
||||||
|
// // action: 'stream',
|
||||||
|
// // toolbar: true
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // e = angular.element(document.getElementById('home-list-actions'));
|
||||||
|
// // e.html(html);
|
||||||
|
// // $compile(e)($scope);
|
||||||
|
|
||||||
|
// // waitCount = 4;
|
||||||
|
// // loadedCount = 0;
|
||||||
|
|
||||||
|
// // if (!$routeParams.login) {
|
||||||
|
// // // If we're not logging in, start the Wait widget. Otherwise, it's already running.
|
||||||
|
// // //Wait('start');
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // if ($scope.removeWidgetLoaded) {
|
||||||
|
// // $scope.removeWidgetLoaded();
|
||||||
|
// // }
|
||||||
|
// // $scope.removeWidgetLoaded = $scope.$on('WidgetLoaded', function (e, label, jobscope, schedulescope) {
|
||||||
|
// // // Once all the widgets report back 'loaded', turn off Wait widget
|
||||||
|
// // if(label==="dashboard_jobs"){
|
||||||
|
// // jobs_scope = jobscope;
|
||||||
|
// // schedule_scope = schedulescope;
|
||||||
|
// // }
|
||||||
|
// // loadedCount++;
|
||||||
|
// // if (loadedCount === waitCount) {
|
||||||
|
// // $(window).resize(_.debounce(function() {
|
||||||
|
// // $scope.$emit('ResizeJobGraph');
|
||||||
|
// // $scope.$emit('ResizeHostGraph');
|
||||||
|
// // $scope.$emit('ResizeHostPieGraph');
|
||||||
|
// // Wait('stop');
|
||||||
|
// // }, 500));
|
||||||
|
// // $(window).resize();
|
||||||
|
// // }
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // if ($scope.removeDashboardReady) {
|
||||||
|
// // $scope.removeDashboardReady();
|
||||||
|
// // }
|
||||||
|
// // $scope.removeDashboardReady = $scope.$on('dashboardReady', function (e, data) {
|
||||||
|
// // nv.dev=false;
|
||||||
|
|
||||||
|
|
||||||
|
// // borderStyles = {"border": "1px solid #A9A9A9",
|
||||||
|
// // "border-radius": "4px",
|
||||||
|
// // "padding": "5px",
|
||||||
|
// // "margin-bottom": "15px"};
|
||||||
|
// // $('.graph-container').css(borderStyles);
|
||||||
|
|
||||||
|
// // var winHeight = $(window).height(),
|
||||||
|
// // available_height = winHeight - $('#main-menu-container .navbar').outerHeight() - $('#count-container').outerHeight() - 120;
|
||||||
|
// // $('.graph-container').height(available_height/2);
|
||||||
|
// // // // chart.update();
|
||||||
|
|
||||||
|
// // DashboardCounts({
|
||||||
|
// // scope: $scope,
|
||||||
|
// // target: 'dash-counts',
|
||||||
|
// // dashboard: data
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // JobStatusGraph({
|
||||||
|
// // scope: $scope,
|
||||||
|
// // target: 'dash-job-status-graph',
|
||||||
|
// // dashboard: data
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // if ($rootScope.user_is_superuser === true) {
|
||||||
|
// // waitCount = 5;
|
||||||
|
// // HostGraph({
|
||||||
|
// // scope: $scope,
|
||||||
|
// // target: 'dash-host-count-graph',
|
||||||
|
// // dashboard: data
|
||||||
|
// // });
|
||||||
|
// // }
|
||||||
|
// // else{
|
||||||
|
// // $('#dash-host-count-graph').remove(); //replaceWith("<div id='dash-host-count-graph' class='left-side col-sm-12 col-xs-12'></div>");
|
||||||
|
// // }
|
||||||
|
// // DashboardJobs({
|
||||||
|
// // scope: $scope,
|
||||||
|
// // target: 'dash-jobs-list',
|
||||||
|
// // dashboard: data
|
||||||
|
// // });
|
||||||
|
// // HostPieChart({
|
||||||
|
// // scope: $scope,
|
||||||
|
// // target: 'dash-host-status-graph',
|
||||||
|
// // dashboard: data
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // if ($rootScope.removeJobStatusChange) {
|
||||||
|
// // $rootScope.removeJobStatusChange();
|
||||||
|
// // }
|
||||||
|
// // $rootScope.removeJobStatusChange = $rootScope.$on('JobStatusChange', function() {
|
||||||
|
// // jobs_scope.refreshJobs();
|
||||||
|
// // $scope.$emit('ReloadJobStatusGraph');
|
||||||
|
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // if ($rootScope.removeScheduleChange) {
|
||||||
|
// // $rootScope.removeScheduleChange();
|
||||||
|
// // }
|
||||||
|
// // $rootScope.removeScheduleChange = $rootScope.$on('ScheduleChange', function() {
|
||||||
|
// // schedule_scope.refreshSchedules();
|
||||||
|
// // $scope.$emit('ReloadJobStatusGraph');
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // $scope.showActivity = function () {
|
||||||
|
// // Stream({
|
||||||
|
// // scope: $scope
|
||||||
|
// // });
|
||||||
|
// // };
|
||||||
|
|
||||||
|
// // $scope.refresh = function () {
|
||||||
|
// // Wait('start');
|
||||||
|
// // loadedCount = 0;
|
||||||
|
// // Rest.setUrl(GetBasePath('dashboard'));
|
||||||
|
// // Rest.get()
|
||||||
|
// // .success(function (data) {
|
||||||
|
// // $scope.$emit('dashboardReady', data);
|
||||||
|
// // })
|
||||||
|
// // .error(function (data, status) {
|
||||||
|
// // ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard: ' + status });
|
||||||
|
// // });
|
||||||
|
// // };
|
||||||
|
|
||||||
|
// // $scope.refresh();
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Home.$inject = ['$scope', '$compile', '$routeParams', '$rootScope', '$location', '$log','Wait',
|
||||||
|
// 'ClearScope', 'Stream', 'Rest', 'GetBasePath', 'ProcessErrors', 'Button'
|
||||||
|
// ];
|
||||||
320
awx/ui/static/js/controllers/SurveyMaker.js
Normal file
320
awx/ui/static/js/controllers/SurveyMaker.js
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
/************************************
|
||||||
|
* Copyright (c) 2014 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* SurveyMaker.js
|
||||||
|
*
|
||||||
|
* Controller functions for the survey maker
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name controllers.function:SurveyMaker
|
||||||
|
* @description This controller's for the survey maker page
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function SurveyMakerAdd($scope, $rootScope, $compile, $location, $log, $routeParams, SurveyMakerForm,
|
||||||
|
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath,
|
||||||
|
ReturnToCaller, Wait, SurveyQuestionForm) {
|
||||||
|
|
||||||
|
ClearScope();
|
||||||
|
|
||||||
|
// Inject dynamic view
|
||||||
|
var generator = GenerateForm,
|
||||||
|
form = SurveyMakerForm,
|
||||||
|
base = $location.path().replace(/^\//, '').split('/')[0];
|
||||||
|
|
||||||
|
$scope.survey_questions=[];
|
||||||
|
|
||||||
|
$scope.answer_types=[
|
||||||
|
{name: 'Text' , type: 'text'},
|
||||||
|
{name: 'Textarea', type: 'text'},
|
||||||
|
{name: 'Multiple Choice (single select)', type: 'mc'},
|
||||||
|
{name: 'Multiple Choice (multiple select)', type: 'mc'},
|
||||||
|
{name: 'JSON', type: 'json'},
|
||||||
|
{name: 'Integer', type: 'number'},
|
||||||
|
{name: 'Float', type: 'number'}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
generator.inject(form, { mode: 'add', related: false, scope: $scope});
|
||||||
|
generator.reset();
|
||||||
|
|
||||||
|
// LoadBreadCrumbs();
|
||||||
|
|
||||||
|
$scope.addQuestion = function(){
|
||||||
|
GenerateForm.inject(SurveyQuestionForm, {mode:'add', id:'new_question', scope:$scope, breadCrumbs: false});
|
||||||
|
};
|
||||||
|
$scope.addQuestion();
|
||||||
|
|
||||||
|
// $('#question_shadow').mouseenter(function(){
|
||||||
|
// $('#question_shadow').css({
|
||||||
|
// "opacity": "1",
|
||||||
|
// "border": "1px solid",
|
||||||
|
// "border-color": "rgb(204,204,204)",
|
||||||
|
// "border-radius": "4px"
|
||||||
|
// });
|
||||||
|
// $('#question_add_btn').show();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// $('#question_shadow').mouseleave(function(){
|
||||||
|
// $('#question_shadow').css({
|
||||||
|
// "opacity": ".4",
|
||||||
|
// "border": "1px dashed",
|
||||||
|
// "border-color": "rgb(204,204,204)",
|
||||||
|
// "border-radius": "4px"
|
||||||
|
// });
|
||||||
|
// $('#question_add_btn').hide();
|
||||||
|
// })
|
||||||
|
|
||||||
|
|
||||||
|
// $('#question_shadow').on("click" , function(){
|
||||||
|
// // var survey_width = $('#survey_maker_question_area').width()-10,
|
||||||
|
// // html = "";
|
||||||
|
|
||||||
|
// // $('#add_question_btn').attr('disabled', 'disabled')
|
||||||
|
// // $('#survey_maker_question_area').append(html);
|
||||||
|
// addQuestion();
|
||||||
|
// $('#question_shadow').hide();
|
||||||
|
// $('#question_shadow').css({
|
||||||
|
// "opacity": ".4",
|
||||||
|
// "border": "1px dashed",
|
||||||
|
// "border-color": "rgb(204,204,204)",
|
||||||
|
// "border-radius": "4px"
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
$scope.finalizeQuestion= function(data){
|
||||||
|
var html = '<div class="question_final">';
|
||||||
|
// angular.forEach(data, function(value, key) {
|
||||||
|
// html+='<label for="question_text"><span class="label-text">'+data.label+'</span></label>'+data.question_text;
|
||||||
|
// });
|
||||||
|
html+='<label for="question_text"><span class="label-text">Question Text</span></label>'+data.question_text;
|
||||||
|
html+='<label for="question_text"><span class="label-text">Question Question</span></label>'+data.question_description;
|
||||||
|
html+='<label for="question_text"><span class="label-text">Answer Response Variable</span></label>'+data.response_variable_name;
|
||||||
|
html+='<label for="question_text"><span class="label-text">Answer Type</span></label>'+data.answer_type;
|
||||||
|
html+='<label for="question_text"><span class="label-text">Answer Options</span></label>'+data.answer_option_text;
|
||||||
|
html+='<label for="question_text"><span class="label-text">Answer Options</span></label>'+data.answer_option_number;
|
||||||
|
html+='<label for="question_text"><span class="label-text">Answer Options</span></label>'+data.answer_option_multiple_choice;
|
||||||
|
html+='<label for="question_text"><span class="label-text">Default Answer</span></label>'+data.default_answer;
|
||||||
|
html+='<label for="question_text"><span class="label-text">Answer Required</span></label>'+data.is_required;
|
||||||
|
html+='</div>';
|
||||||
|
|
||||||
|
$('#finalized_questions').before(html);
|
||||||
|
$('#add_question_btn').show();
|
||||||
|
$('#add_question_btn').removeAttr('disabled');
|
||||||
|
$('#add_question_btn').on("click" , function(){
|
||||||
|
$scope.addQuestion();
|
||||||
|
$('#add_question_btn').attr('disabled', 'disabled');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$scope.submitQuestion = function(){
|
||||||
|
var form = SurveyQuestionForm,
|
||||||
|
data = {}, labels={}, fld;
|
||||||
|
//generator.clearApiErrors();
|
||||||
|
Wait('start');
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (fld in form.fields) {
|
||||||
|
if($scope[fld]){
|
||||||
|
data[fld] = $scope[fld];
|
||||||
|
// labels[fld] = form.fields[fld].label;
|
||||||
|
}
|
||||||
|
// if (form.fields[fld].type === 'select' && fld !== 'playbook') {
|
||||||
|
// data[fld] = $scope[fld].value;
|
||||||
|
// } else {
|
||||||
|
// if (fld !== 'variables') {
|
||||||
|
// data[fld] = $scope[fld];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
Wait('stop');
|
||||||
|
$scope.survey_questions.push(data);
|
||||||
|
$('#new_question .aw-form-well').remove();
|
||||||
|
// for(fld in form.fields){
|
||||||
|
// $scope[fld] = '';
|
||||||
|
// }
|
||||||
|
$scope.finalizeQuestion(data , labels);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
Wait('stop');
|
||||||
|
Alert("Error", "Error parsing extra variables. Parser returned: " + err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Save
|
||||||
|
$scope.formSave = function () {
|
||||||
|
generator.clearApiErrors();
|
||||||
|
Wait('start');
|
||||||
|
var url = GetBasePath(base);
|
||||||
|
url += (base !== 'organizations') ? $routeParams.project_id + '/organizations/' : '';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.post({ name: $scope.name, description: $scope.description })
|
||||||
|
.success(function (data) {
|
||||||
|
Wait('stop');
|
||||||
|
if (base === 'organizations') {
|
||||||
|
$rootScope.flashMessage = "New organization successfully created!";
|
||||||
|
$location.path('/organizations/' + data.id);
|
||||||
|
} else {
|
||||||
|
ReturnToCaller(1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
||||||
|
msg: 'Failed to add new organization. Post returned status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cancel
|
||||||
|
$scope.formReset = function () {
|
||||||
|
$rootScope.flashMessage = null;
|
||||||
|
generator.reset();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SurveyMakerAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'SurveyMakerForm',
|
||||||
|
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', 'ReturnToCaller', 'Wait', 'SurveyQuestionForm'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
// function OrganizationsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm, GenerateForm, Rest,
|
||||||
|
// Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, Prompt, ClearScope, GetBasePath, Wait, Stream) {
|
||||||
|
|
||||||
|
// ClearScope();
|
||||||
|
|
||||||
|
// // Inject dynamic view
|
||||||
|
// var form = OrganizationForm,
|
||||||
|
// generator = GenerateForm,
|
||||||
|
// defaultUrl = GetBasePath('organizations'),
|
||||||
|
// base = $location.path().replace(/^\//, '').split('/')[0],
|
||||||
|
// master = {},
|
||||||
|
// id = $routeParams.organization_id,
|
||||||
|
// relatedSets = {};
|
||||||
|
|
||||||
|
// generator.inject(form, { mode: 'edit', related: true, scope: $scope});
|
||||||
|
// generator.reset();
|
||||||
|
|
||||||
|
// // After the Organization is loaded, retrieve each related set
|
||||||
|
// if ($scope.organizationLoadedRemove) {
|
||||||
|
// $scope.organizationLoadedRemove();
|
||||||
|
// }
|
||||||
|
// $scope.organizationLoadedRemove = $scope.$on('organizationLoaded', function () {
|
||||||
|
// for (var set in relatedSets) {
|
||||||
|
// $scope.search(relatedSets[set].iterator);
|
||||||
|
// }
|
||||||
|
// Wait('stop');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // Retrieve detail record and prepopulate the form
|
||||||
|
// Wait('start');
|
||||||
|
// Rest.setUrl(defaultUrl + id + '/');
|
||||||
|
// Rest.get()
|
||||||
|
// .success(function (data) {
|
||||||
|
// var fld, related, set;
|
||||||
|
// LoadBreadCrumbs({ path: '/organizations/' + id, title: data.name });
|
||||||
|
// for (fld in form.fields) {
|
||||||
|
// if (data[fld]) {
|
||||||
|
// $scope[fld] = data[fld];
|
||||||
|
// master[fld] = data[fld];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// related = data.related;
|
||||||
|
// for (set in form.related) {
|
||||||
|
// if (related[set]) {
|
||||||
|
// relatedSets[set] = {
|
||||||
|
// url: related[set],
|
||||||
|
// iterator: form.related[set].iterator
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
||||||
|
// RelatedSearchInit({ scope: $scope, form: form, relatedSets: relatedSets });
|
||||||
|
// RelatedPaginateInit({ scope: $scope, relatedSets: relatedSets });
|
||||||
|
// $scope.$emit('organizationLoaded');
|
||||||
|
// })
|
||||||
|
// .error(function (data, status) {
|
||||||
|
// ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
||||||
|
// msg: 'Failed to retrieve organization: ' + $routeParams.id + '. GET status: ' + status });
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
// // Save changes to the parent
|
||||||
|
// $scope.formSave = function () {
|
||||||
|
// var fld, params = {};
|
||||||
|
// generator.clearApiErrors();
|
||||||
|
// Wait('start');
|
||||||
|
// for (fld in form.fields) {
|
||||||
|
// params[fld] = $scope[fld];
|
||||||
|
// }
|
||||||
|
// Rest.setUrl(defaultUrl + id + '/');
|
||||||
|
// Rest.put(params)
|
||||||
|
// .success(function () {
|
||||||
|
// Wait('stop');
|
||||||
|
// master = params;
|
||||||
|
// $rootScope.flashMessage = "Your changes were successfully saved!";
|
||||||
|
// })
|
||||||
|
// .error(function (data, status) {
|
||||||
|
// ProcessErrors($scope, data, status, OrganizationForm, { hdr: 'Error!',
|
||||||
|
// msg: 'Failed to update organization: ' + id + '. PUT status: ' + status });
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
// $scope.showActivity = function () {
|
||||||
|
// Stream({
|
||||||
|
// scope: $scope
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Reset the form
|
||||||
|
// $scope.formReset = function () {
|
||||||
|
// $rootScope.flashMessage = null;
|
||||||
|
// generator.reset();
|
||||||
|
// for (var fld in master) {
|
||||||
|
// $scope[fld] = master[fld];
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Related set: Add button
|
||||||
|
// $scope.add = function (set) {
|
||||||
|
// $rootScope.flashMessage = null;
|
||||||
|
// $location.path('/' + base + '/' + $routeParams.organization_id + '/' + set);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Related set: Edit button
|
||||||
|
// $scope.edit = function (set, id) {
|
||||||
|
// $rootScope.flashMessage = null;
|
||||||
|
// $location.path('/' + set + '/' + id);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Related set: Delete button
|
||||||
|
// $scope['delete'] = function (set, itm_id, name, title) {
|
||||||
|
// $rootScope.flashMessage = null;
|
||||||
|
|
||||||
|
// var action = function () {
|
||||||
|
// Wait('start');
|
||||||
|
// var url = defaultUrl + $routeParams.organization_id + '/' + set + '/';
|
||||||
|
// Rest.setUrl(url);
|
||||||
|
// Rest.post({ id: itm_id, disassociate: 1 })
|
||||||
|
// .success(function () {
|
||||||
|
// $('#prompt-modal').modal('hide');
|
||||||
|
// $scope.search(form.related[set].iterator);
|
||||||
|
// })
|
||||||
|
// .error(function (data, status) {
|
||||||
|
// $('#prompt-modal').modal('hide');
|
||||||
|
// ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
|
// msg: 'Call to ' + url + ' failed. POST returned status: ' + status });
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Prompt({
|
||||||
|
// hdr: 'Delete',
|
||||||
|
// body: 'Are you sure you want to remove ' + name + ' from ' + $scope.name + ' ' + title + '?',
|
||||||
|
// action: action
|
||||||
|
// });
|
||||||
|
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// OrganizationsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'OrganizationForm', 'GenerateForm',
|
||||||
|
// 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath',
|
||||||
|
// 'Wait', 'Stream'
|
||||||
|
// ];
|
||||||
@@ -240,6 +240,20 @@ angular.module('JobTemplateFormDefinition', ['SchedulesListDefinition', 'Complet
|
|||||||
dataTitle: 'Prompt for Extra Variables',
|
dataTitle: 'Prompt for Extra Variables',
|
||||||
dataContainer: "body"
|
dataContainer: "body"
|
||||||
},
|
},
|
||||||
|
enable_survey: {
|
||||||
|
type: 'custom',
|
||||||
|
column: 2,
|
||||||
|
control: '<div class="form-group">'+
|
||||||
|
'<div class="checkbox">'+
|
||||||
|
'<label><input type="checkbox" ng-model="enable_survey" name="enable_survey" id="job_templates_enable_survey_chbox" class="ng-valid ng-valid-api-error ng-dirty" ng-true-value="true" ng-false-value="false">'+
|
||||||
|
'<span class="label-text">Enable Survey</span><a id="awp-enable_survey" href="" aw-pop-over="<p>If checked, user will be prompted at job launch with a survey of questions related to the job.</p>'+
|
||||||
|
'<div class="popover-footer"><span class="key">esc</span> or click to close</div>" data-placement="right" data-container="body" data-title="Enable Survey" class="help-link" data-original-title="" title="" tabindex="-1">'+
|
||||||
|
'<i class="fa fa-question-circle"></i></a> </label>'+
|
||||||
|
'<div class="error api-error ng-binding" id="job_templates-enable_survey-api-error" ng-bind="enable_survey_api_error"></div>'+
|
||||||
|
'<button type="button" class="btn btn-sm btn-default" id="job_templates_edit_survey_btn" ng-click="navigateToSurvey()"><i class="fa fa-pencil"></i> Edit Survey</button>'+
|
||||||
|
'</div>'+
|
||||||
|
'</div>'
|
||||||
|
},
|
||||||
allow_callbacks: {
|
allow_callbacks: {
|
||||||
label: 'Allow Provisioning Callbacks',
|
label: 'Allow Provisioning Callbacks',
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
|
|||||||
73
awx/ui/static/js/forms/SurveyMaker.js
Normal file
73
awx/ui/static/js/forms/SurveyMaker.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2014 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* SurveyMaker.js
|
||||||
|
* Form definition for survey maker model
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name forms.function:SurveyMaker
|
||||||
|
* @description This form is for adding/editing a survey
|
||||||
|
*/
|
||||||
|
angular.module('SurveyMakerFormDefinition', [])
|
||||||
|
.value('SurveyMakerForm', {
|
||||||
|
|
||||||
|
addTitle: 'Add Survey', //Title in add mode
|
||||||
|
editTitle: 'Edit Survey', //Title in edit mode
|
||||||
|
name: 'survey_maker', //entity or model name in singular form
|
||||||
|
well: true,
|
||||||
|
collapse: true,
|
||||||
|
collapseTitle: "Properties",
|
||||||
|
collapseMode: 'edit',
|
||||||
|
collapseOpen: true,
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
stream: {
|
||||||
|
'class': "btn-primary btn-xs activity-btn",
|
||||||
|
ngClick: "showActivity()",
|
||||||
|
awToolTip: "View Activity Stream",
|
||||||
|
dataPlacement: "top",
|
||||||
|
icon: "icon-comments-alt",
|
||||||
|
mode: 'edit',
|
||||||
|
iconSize: 'large'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fields: {
|
||||||
|
name: {
|
||||||
|
label: 'Survey Name',
|
||||||
|
type: 'text',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
capitalize: false
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
label: 'Survey Description',
|
||||||
|
type: 'text',
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false
|
||||||
|
},
|
||||||
|
questions: {
|
||||||
|
type: 'custom',
|
||||||
|
control: '<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" aw-tool-tip="Create a new question" data-placement="top" data-original-title="" title="" disabled><i class="fa fa-plus fa-lg"></i> Add Question</button>'+
|
||||||
|
'<div id="new_question"></div>'
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
buttons: { //for now always generates <button> tags
|
||||||
|
save: {
|
||||||
|
ngClick: 'formSave()', //$scope.function to call on click, optional
|
||||||
|
ngDisabled: true //Disable when $pristine or $invalid, optional
|
||||||
|
},
|
||||||
|
reset: {
|
||||||
|
ngClick: 'formReset()',
|
||||||
|
ngDisabled: true //Disabled when $pristine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
183
awx/ui/static/js/forms/SurveyQuestion.js
Normal file
183
awx/ui/static/js/forms/SurveyQuestion.js
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2014 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* Inventories.js
|
||||||
|
* Form definition for question model
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name forms.function:Questions
|
||||||
|
* @description This form is for adding a question
|
||||||
|
*/
|
||||||
|
angular.module('SurveyQuestionFormDefinition', [])
|
||||||
|
.value('SurveyQuestionForm', {
|
||||||
|
|
||||||
|
addTitle: 'Add Question',
|
||||||
|
editTitle: '{{ inventory_name }}',
|
||||||
|
name: 'question_unique',
|
||||||
|
well: true,
|
||||||
|
twoColumns: true,
|
||||||
|
|
||||||
|
// actions: {
|
||||||
|
// stream: {
|
||||||
|
// 'class': "btn-primary btn-xs activity-btn",
|
||||||
|
// ngClick: "showActivity()",
|
||||||
|
// awToolTip: "View Activity Stream",
|
||||||
|
// dataPlacement: "top",
|
||||||
|
// icon: "icon-comments-alt",
|
||||||
|
// mode: 'edit',
|
||||||
|
// iconSize: 'large'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
|
||||||
|
fields: {
|
||||||
|
question_text: {
|
||||||
|
realName: 'question_text',
|
||||||
|
label: 'Question Text',
|
||||||
|
type: 'text',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
capitalize: true,
|
||||||
|
column: 1
|
||||||
|
},
|
||||||
|
question_description: {
|
||||||
|
realName: 'question_description',
|
||||||
|
label: 'Question Description',
|
||||||
|
type: 'textarea',
|
||||||
|
rows: 2,
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
column: 2
|
||||||
|
},
|
||||||
|
response_variable_name: {
|
||||||
|
label: 'Answer Variable Name',
|
||||||
|
type: 'text',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
column: 2
|
||||||
|
// sourceModel: 'organization',
|
||||||
|
// sourceField: 'name',
|
||||||
|
// ngClick: 'lookUpOrganization()',
|
||||||
|
// awRequiredWhen: {
|
||||||
|
// variable: "organizationrequired",
|
||||||
|
// init: "true"
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
answer_type: {
|
||||||
|
realName: 'answer_type',
|
||||||
|
label: 'Answer Type',
|
||||||
|
type: 'select',
|
||||||
|
ngOptions: 'answer_types.name for answer_types in answer_types',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
column: 1
|
||||||
|
|
||||||
|
},
|
||||||
|
answer_options_text: {
|
||||||
|
realName: 'answer_options',
|
||||||
|
label: 'Answer Options',
|
||||||
|
type: 'text',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
ngHide: 'answer_type.type!=="text" ',
|
||||||
|
column: 1
|
||||||
|
},
|
||||||
|
answer_options_multiple_choice: {
|
||||||
|
realName: 'answer_options',
|
||||||
|
label: 'Multiple Choice Options',
|
||||||
|
type: 'textarea',
|
||||||
|
rows: 3,
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
ngShow: 'answer_type.type==="mc" ',
|
||||||
|
awPopOver: '<p>Type an option on each line.</p>'+
|
||||||
|
'<p>For example the following input:<br><br>Apple<br>\n Banana<br>\n Cherry<br><br>would be displayed as:</p>\n'+
|
||||||
|
'<ol><li>Apple</li><li>Banana</li><li>Cherry</li><ol>',
|
||||||
|
dataTitle: 'Multiple Choice Options',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
dataContainer: "body",
|
||||||
|
column: 1
|
||||||
|
},
|
||||||
|
answer_options_number: {
|
||||||
|
realName: 'answer_options',
|
||||||
|
// label: '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="answer_min" type="number" class="form-control"></div>'+
|
||||||
|
'<div class="col-xs-6"><label for="minimum"><span class="label-text">Maximum</span></label><input id="answer_max" type="number" class="form-control"></div></div>',
|
||||||
|
ngShow: 'answer_type.type==="number" ',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
column: 1
|
||||||
|
},
|
||||||
|
answer_options_json: {
|
||||||
|
realName: 'answer_options',
|
||||||
|
label: 'Answer Options',
|
||||||
|
type: 'textarea',
|
||||||
|
rows: 3,
|
||||||
|
ngShow: 'answer_type.type==="json" ',
|
||||||
|
addRequired: true,
|
||||||
|
editRequired: true,
|
||||||
|
awPopOver: '<p>Insert some good JSON!</p>',
|
||||||
|
dataTitle: 'Answer Options',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
dataContainer: "body",
|
||||||
|
column: 1
|
||||||
|
},
|
||||||
|
default_answer: {
|
||||||
|
realName: 'default_answer',
|
||||||
|
label: 'Default Answer',
|
||||||
|
type: 'text',
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
column: 1
|
||||||
|
},
|
||||||
|
is_required: {
|
||||||
|
label: 'Answer required or optional',
|
||||||
|
type: 'custom',
|
||||||
|
column: 2,
|
||||||
|
control: '<div><label for="required"><span class="label-text">Required</span></label><input id="answer_required" type="radio" checked=true></div>'+
|
||||||
|
'<div><label for="optional"><span class="label-text">Optional</span></label><input id="answer_optional" type="radio"></div>',
|
||||||
|
|
||||||
|
}
|
||||||
|
// answer_options: {
|
||||||
|
// label: 'Variables',
|
||||||
|
// type: 'textarea',
|
||||||
|
// 'class': 'span12',
|
||||||
|
// addRequired: false,
|
||||||
|
// editRequird: false,
|
||||||
|
// rows: 6,
|
||||||
|
// "default": "---",
|
||||||
|
// awPopOver: "<p>Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
|
||||||
|
// "JSON:<br />\n" +
|
||||||
|
// "<blockquote>{<br />\"somevar\": \"somevalue\",<br />\"password\": \"magic\"<br /> }</blockquote>\n" +
|
||||||
|
// "YAML:<br />\n" +
|
||||||
|
// "<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
|
||||||
|
// '<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
|
||||||
|
// '<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
|
||||||
|
// dataTitle: 'Inventory Variables',
|
||||||
|
// dataPlacement: 'right',
|
||||||
|
// dataContainer: 'body'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
buttons: {
|
||||||
|
submit_quesiton: {
|
||||||
|
ngClick: 'submitQuestion()',
|
||||||
|
ngDisabled: true,
|
||||||
|
'class': 'btn btn-sm btn-primary',
|
||||||
|
label: 'Submit Question'
|
||||||
|
},
|
||||||
|
reset: {
|
||||||
|
ngClick: 'questionReset()',
|
||||||
|
ngDisabled: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
related: {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -11,6 +11,12 @@
|
|||||||
* @ngdoc function
|
* @ngdoc function
|
||||||
* @name helpers.function:License
|
* @name helpers.function:License
|
||||||
* @description Routines for checking and reporting license status
|
* @description Routines for checking and reporting license status
|
||||||
|
* CheckLicense.test() is called in app.js, in line 532, which is when the license is checked. The license information is
|
||||||
|
* stored in local storage using 'Store()'.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
@import "lists.less";
|
@import "lists.less";
|
||||||
@import "new-dashboard.less";
|
@import "new-dashboard.less";
|
||||||
@import "jPushMenu.less";
|
@import "jPushMenu.less";
|
||||||
|
@import "survey-maker.less";
|
||||||
|
|
||||||
/* Bootstrap fix that's causing a right margin to appear
|
/* Bootstrap fix that's causing a right margin to appear
|
||||||
whenver a modal is opened */
|
whenver a modal is opened */
|
||||||
|
|||||||
49
awx/ui/static/less/survey-maker.less
Normal file
49
awx/ui/static/less/survey-maker.less
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2014 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* survey-maker.css
|
||||||
|
*
|
||||||
|
* custom styles for the survey maker
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #survey_maker_question_area{
|
||||||
|
* border: 1px solid;
|
||||||
|
* border-color: rgb(204,204,204);
|
||||||
|
* border-radius: 4px;
|
||||||
|
* padding: 15px;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
.question_form{
|
||||||
|
border: 1px solid;
|
||||||
|
border-color: rgb(204,204,204);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 5px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.survey_maker_question{
|
||||||
|
border: 1px solid;
|
||||||
|
border-color: rgb(204,204,204);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question_final{
|
||||||
|
border: 1px dashed;
|
||||||
|
border-color: rgb(204,204,204);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 5px;
|
||||||
|
margin-top: 15px;
|
||||||
|
height: 130px;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#add_question_btn{
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
3
awx/ui/static/partials/portal.html
Normal file
3
awx/ui/static/partials/portal.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="tab-pane" id="portal">
|
||||||
|
<div ng-cloak id="htmlTemplate"></div>
|
||||||
|
</div>
|
||||||
3
awx/ui/static/partials/survey_maker.html
Normal file
3
awx/ui/static/partials/survey_maker.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="tab-pane" id="survey_maker">
|
||||||
|
<div id="htmlTemplate" class="ng-scope"></div>
|
||||||
|
</div>
|
||||||
@@ -80,6 +80,7 @@
|
|||||||
<script src="{{ STATIC_URL }}js/controllers/Permissions.js"></script>
|
<script src="{{ STATIC_URL }}js/controllers/Permissions.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/controllers/Schedules.js"></script>
|
<script src="{{ STATIC_URL }}js/controllers/Schedules.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/controllers/Sockets.js"></script>
|
<script src="{{ STATIC_URL }}js/controllers/Sockets.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}js/controllers/SurveyMaker.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/Users.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/Users.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/Organizations.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/Organizations.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/Inventories.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/Inventories.js"></script>
|
||||||
@@ -101,6 +102,8 @@
|
|||||||
<script src="{{ STATIC_URL }}js/forms/LicenseForm.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/LicenseForm.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/LicenseUpdate.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/LicenseUpdate.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/Source.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/Source.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}js/forms/SurveyMaker.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}js/forms/SurveyQuestion.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/LogViewerStatus.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/LogViewerStatus.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/LogViewerOptions.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/LogViewerOptions.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Users.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Users.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user