mirror of
https://github.com/ansible/awx.git
synced 2026-03-07 19:51:08 -03:30
AC-352 First pass at SCM integration
This commit is contained in:
@@ -65,7 +65,8 @@ angular.module('ansible', [
|
|||||||
'SelectionHelper',
|
'SelectionHelper',
|
||||||
'LicenseFormDefinition',
|
'LicenseFormDefinition',
|
||||||
'License',
|
'License',
|
||||||
'HostGroupsFormDefinition'
|
'HostGroupsFormDefinition',
|
||||||
|
'SCMUpdateHelper'
|
||||||
])
|
])
|
||||||
.config(['$routeProvider', function($routeProvider) {
|
.config(['$routeProvider', function($routeProvider) {
|
||||||
$routeProvider.
|
$routeProvider.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, ProjectList,
|
function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, ProjectList,
|
||||||
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
|
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
|
||||||
ClearScope, ProcessErrors, GetBasePath, SelectionInit)
|
ClearScope, ProcessErrors, GetBasePath, SelectionInit, SCMUpdate)
|
||||||
{
|
{
|
||||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
//scope.
|
//scope.
|
||||||
@@ -63,11 +63,25 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
|
|||||||
action: action
|
action: action
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope.scmUpdate = function(project_id) {
|
||||||
|
for (var i=0; i < scope.projects.length; i++) {
|
||||||
|
if (scope.projects[i].id == project_id) {
|
||||||
|
if (scope.projects[i].scm_type == "") {
|
||||||
|
Alert('Missing SCM Setup', 'Before running an SCM update, edit the project and provide the SCM access information.', 'alert-info');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SCMUpdate({ scope: scope, project: scope.projects[i]});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'ProjectList', 'GenerateList',
|
ProjectsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'ProjectList', 'GenerateList',
|
||||||
'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors',
|
'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors',
|
||||||
'GetBasePath', 'SelectionInit'];
|
'GetBasePath', 'SelectionInit', 'SCMUpdate'];
|
||||||
|
|
||||||
|
|
||||||
function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm,
|
function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm,
|
||||||
@@ -90,6 +104,10 @@ function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParam
|
|||||||
LoadBreadCrumbs();
|
LoadBreadCrumbs();
|
||||||
GetProjectPath({ scope: scope, master: master });
|
GetProjectPath({ scope: scope, master: master });
|
||||||
|
|
||||||
|
scope.scm_type_options = [
|
||||||
|
{ label: 'GitHub', value: 'git' },
|
||||||
|
{ label: 'SVN', value: 'svn' }];
|
||||||
|
|
||||||
LookUpInit({
|
LookUpInit({
|
||||||
scope: scope,
|
scope: scope,
|
||||||
form: form,
|
form: form,
|
||||||
@@ -164,9 +182,28 @@ function ProjectsEdit ($scope, $rootScope, $compile, $location, $log, $routePara
|
|||||||
var id = $routeParams.id;
|
var id = $routeParams.id;
|
||||||
var relatedSets = {};
|
var relatedSets = {};
|
||||||
|
|
||||||
|
scope.scm_type_options = [
|
||||||
|
{ label: 'GitHub', value: 'git' },
|
||||||
|
{ label: 'SVN', value: 'svn' }];
|
||||||
|
|
||||||
scope.project_local_paths = [];
|
scope.project_local_paths = [];
|
||||||
scope.base_dir = '';
|
scope.base_dir = '';
|
||||||
|
|
||||||
|
function setAskCheckboxes() {
|
||||||
|
for (var fld in form.fields) {
|
||||||
|
if (form.fields[fld].type == 'password' && form.fields[fld].ask && scope[fld] == 'ASK') {
|
||||||
|
// turn on 'ask' checkbox for password fields with value of 'ASK'
|
||||||
|
$("#" + fld + "-clear-btn").attr("disabled","disabled");
|
||||||
|
scope[fld + '_ask'] = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scope[fld + '_ask'] = false;
|
||||||
|
$("#" + fld + "-clear-btn").removeAttr("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// After the project is loaded, retrieve each related set
|
// After the project is loaded, retrieve each related set
|
||||||
if (scope.projectLoadedRemove) {
|
if (scope.projectLoadedRemove) {
|
||||||
scope.projectLoadedRemove();
|
scope.projectLoadedRemove();
|
||||||
@@ -203,6 +240,9 @@ function ProjectsEdit ($scope, $rootScope, $compile, $location, $log, $routePara
|
|||||||
relatedSets[set] = { url: related[set], iterator: form.related[set].iterator };
|
relatedSets[set] = { url: related[set], iterator: form.related[set].iterator };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setAskCheckboxes();
|
||||||
|
|
||||||
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
||||||
RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets });
|
RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets });
|
||||||
RelatedPaginateInit({ scope: scope, relatedSets: relatedSets });
|
RelatedPaginateInit({ scope: scope, relatedSets: relatedSets });
|
||||||
@@ -221,6 +261,9 @@ function ProjectsEdit ($scope, $rootScope, $compile, $location, $log, $routePara
|
|||||||
for (var fld in form.fields) {
|
for (var fld in form.fields) {
|
||||||
params[fld] = scope[fld];
|
params[fld] = scope[fld];
|
||||||
}
|
}
|
||||||
|
if (scope.scm_type) {
|
||||||
|
params.scm_type = scope.scm_type.value;
|
||||||
|
}
|
||||||
Rest.setUrl(defaultUrl);
|
Rest.setUrl(defaultUrl);
|
||||||
Rest.put(params)
|
Rest.put(params)
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data, status, headers, config) {
|
||||||
@@ -276,6 +319,35 @@ function ProjectsEdit ($scope, $rootScope, $compile, $location, $log, $routePara
|
|||||||
action: action
|
action: action
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Password change
|
||||||
|
scope.clearPWConfirm = function(fld) {
|
||||||
|
// If password value changes, make sure password_confirm must be re-entered
|
||||||
|
scope[fld] = '';
|
||||||
|
scope[form.name + '_form'][fld].$setValidity('awpassmatch', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Respond to 'Ask at runtime?' checkbox
|
||||||
|
scope.ask = function(fld, associated) {
|
||||||
|
if (scope[fld + '_ask']) {
|
||||||
|
$("#" + fld + "-clear-btn").attr("disabled","disabled");
|
||||||
|
scope[fld] = 'ASK';
|
||||||
|
scope[associated] = '';
|
||||||
|
scope[form.name + '_form'][associated].$setValidity('awpassmatch', true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#" + fld + "-clear-btn").removeAttr("disabled");
|
||||||
|
scope[fld] = '';
|
||||||
|
scope[associated] = '';
|
||||||
|
scope[form.name + '_form'][associated].$setValidity('awpassmatch', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.clear = function(fld, associated) {
|
||||||
|
scope[fld] = '';
|
||||||
|
scope[associated] = '';
|
||||||
|
scope[form.name + '_form'][associated].$setValidity('awpassmatch', true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'ProjectsForm',
|
ProjectsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'ProjectsForm',
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ angular.module('ProjectFormDefinition', [])
|
|||||||
.value(
|
.value(
|
||||||
'ProjectsForm', {
|
'ProjectsForm', {
|
||||||
|
|
||||||
addTitle: 'Create Project', //Title in add mode
|
addTitle: 'Create Project', // Title in add mode
|
||||||
editTitle: '{{ name }}', //Title in edit mode
|
editTitle: '{{ name }}', // Title in edit mode
|
||||||
name: 'project', //entity or model name in singular form
|
name: 'project', // entity or model name in singular form
|
||||||
well: true, //Wrap the form with TB well/
|
well: true, // Wrap the form with TB well
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
name: {
|
name: {
|
||||||
@@ -30,7 +30,7 @@ angular.module('ProjectFormDefinition', [])
|
|||||||
addRequired: false,
|
addRequired: false,
|
||||||
editRequired: false
|
editRequired: false
|
||||||
},
|
},
|
||||||
organization: {
|
organization: {
|
||||||
label: 'Organization',
|
label: 'Organization',
|
||||||
type: 'lookup',
|
type: 'lookup',
|
||||||
sourceModel: 'organization',
|
sourceModel: 'organization',
|
||||||
@@ -43,6 +43,7 @@ angular.module('ProjectFormDefinition', [])
|
|||||||
awPopOver: '<p>A project must have at least one organization. Pick one organization now to create the project, and then after ' +
|
awPopOver: '<p>A project must have at least one organization. Pick one organization now to create the project, and then after ' +
|
||||||
'the project is created you can add additional organizations.' ,
|
'the project is created you can add additional organizations.' ,
|
||||||
dataTitle: 'Organization',
|
dataTitle: 'Organization',
|
||||||
|
dataContainer: 'body',
|
||||||
dataPlacement: 'right'
|
dataPlacement: 'right'
|
||||||
},
|
},
|
||||||
base_dir: {
|
base_dir: {
|
||||||
@@ -54,6 +55,7 @@ angular.module('ProjectFormDefinition', [])
|
|||||||
'Together the base path and selected playbook directory provide the full path used to locate playbooks.</p>' +
|
'Together the base path and selected playbook directory provide the full path used to locate playbooks.</p>' +
|
||||||
'<p>Use PROJECTS_ROOT in your environment settings file to determine the base path value.</p>',
|
'<p>Use PROJECTS_ROOT in your environment settings file to determine the base path value.</p>',
|
||||||
dataTitle: 'Project Base Path',
|
dataTitle: 'Project Base Path',
|
||||||
|
dataContainer: 'body',
|
||||||
dataPlacement: 'right'
|
dataPlacement: 'right'
|
||||||
},
|
},
|
||||||
local_path: {
|
local_path: {
|
||||||
@@ -67,7 +69,136 @@ angular.module('ProjectFormDefinition', [])
|
|||||||
'Together the base path and the playbook directory provide the full path used to locate playbooks.</p>' +
|
'Together the base path and the playbook directory provide the full path used to locate playbooks.</p>' +
|
||||||
'<p>Use PROJECTS_ROOT in your environment settings file to determine the base path value.</p>',
|
'<p>Use PROJECTS_ROOT in your environment settings file to determine the base path value.</p>',
|
||||||
dataTitle: 'Project Path',
|
dataTitle: 'Project Path',
|
||||||
|
dataContainer: 'body',
|
||||||
dataPlacement: 'right'
|
dataPlacement: 'right'
|
||||||
|
},
|
||||||
|
scm_type: {
|
||||||
|
label: 'SCM Type',
|
||||||
|
type: 'select',
|
||||||
|
ngOptions: 'type.label for type in scm_type_options',
|
||||||
|
"default": '',
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false
|
||||||
|
},
|
||||||
|
scm_url: {
|
||||||
|
label: 'SCM URL',
|
||||||
|
type: 'text',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awRequiredWhen: {variable: "scm_type", init: "true" }
|
||||||
|
},
|
||||||
|
scm_branch: {
|
||||||
|
label: 'SCM Branch',
|
||||||
|
type: 'text',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false
|
||||||
|
},
|
||||||
|
scm_username: {
|
||||||
|
label: 'SCM Username',
|
||||||
|
type: 'text',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false
|
||||||
|
},
|
||||||
|
"scm_password": {
|
||||||
|
label: 'SCM Password',
|
||||||
|
type: 'password',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
ngChange: "clearPWConfirm('scm_password_confirm')",
|
||||||
|
ask: true,
|
||||||
|
clear: true,
|
||||||
|
associated: 'scm_password_confirm',
|
||||||
|
autocomplete: false
|
||||||
|
},
|
||||||
|
"scm_password_confirm": {
|
||||||
|
label: 'Confirm Password',
|
||||||
|
type: 'password',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awPassMatch: true,
|
||||||
|
associated: 'scm_password',
|
||||||
|
autocomplete: false
|
||||||
|
},
|
||||||
|
"scm_key_data": {
|
||||||
|
label: 'SCM Private Key',
|
||||||
|
type: 'textarea',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
rows: 10
|
||||||
|
},
|
||||||
|
"scm_key_unlock": {
|
||||||
|
label: 'SCM Key Password',
|
||||||
|
type: 'password',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null && scm_key_data",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
ngChange: "clearPWConfirm('scm_key_unlock_confirm')",
|
||||||
|
associated: 'scm_key_unlock_confirm',
|
||||||
|
ask: true,
|
||||||
|
clear: true
|
||||||
|
},
|
||||||
|
"scm_key_unlock_confirm": {
|
||||||
|
label: 'Confirm Key Password',
|
||||||
|
type: 'password',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null && scm_key_data",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awPassMatch: true,
|
||||||
|
associated: 'scm_key_unlock'
|
||||||
|
},
|
||||||
|
checkbox_group: {
|
||||||
|
label: 'SCM Options',
|
||||||
|
type: 'checkbox_group',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'scm_clean',
|
||||||
|
label: 'Clean',
|
||||||
|
type: 'checkbox',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awPopOver: '<p>Remove any local modifications prior to performing an update.</p>',
|
||||||
|
dataTitle: 'SCM Clean',
|
||||||
|
dataContainer: 'body',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
labelClass: 'checkbox-options'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scm_delete_on_update',
|
||||||
|
label: 'Delete on Update',
|
||||||
|
type: 'checkbox',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awPopOver: '<p>Delete the local repository in its entirety prior to performing an update.</p><p>Depending on the size of the ' +
|
||||||
|
'repository this may significantly increase the amount of time required to complete an update.</p>',
|
||||||
|
dataTitle: 'SCM Delete',
|
||||||
|
dataContainer: 'body',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
labelClass: 'checkbox-options'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scm_update_on_launch',
|
||||||
|
label: 'Update on Launch',
|
||||||
|
type: 'checkbox',
|
||||||
|
ngShow: "scm_type !== '' && scm_type !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awPopOver: '<p>Each time a job runs using this project, perform an update to the local repository prior to starting the job.</p>',
|
||||||
|
dataTitle: 'SCM Update',
|
||||||
|
dataContainer: 'body',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
labelClass: 'checkbox-options'
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
28
awx/ui/static/js/helpers/SCMUpdate.js
Normal file
28
awx/ui/static/js/helpers/SCMUpdate.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* SCMUpdate.js
|
||||||
|
*
|
||||||
|
* Use to kick off an update the project
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
angular.module('SCMUpdateHelper', ['RestServices', 'Utilities'])
|
||||||
|
.factory('SCMUpdate', ['Alert', 'Rest', 'GetBasePath','ProcessErrors',
|
||||||
|
function(Alert, Rest, GetBasePath, ProcessErrors) {
|
||||||
|
return function(params) {
|
||||||
|
|
||||||
|
var scope = params.scope;
|
||||||
|
var project = params.project;
|
||||||
|
|
||||||
|
Rest.setUrl(project.related.update);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
console.log(data);
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to access ' + project.related.update + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}]);
|
||||||
@@ -52,7 +52,7 @@ angular.module('InventoriesListDefinition', [])
|
|||||||
|
|
||||||
dropdown: {
|
dropdown: {
|
||||||
type: 'DropDown',
|
type: 'DropDown',
|
||||||
label: 'View Jobs',
|
label: 'View',
|
||||||
'class': 'btn-xs',
|
'class': 'btn-xs',
|
||||||
options: [
|
options: [
|
||||||
{ ngClick: 'viewJobs(\{\{ inventory.id \}\})', label: 'Jobs' },
|
{ ngClick: 'viewJobs(\{\{ inventory.id \}\})', label: 'Jobs' },
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ angular.module('ProjectsListDefinition', [])
|
|||||||
},
|
},
|
||||||
|
|
||||||
fieldActions: {
|
fieldActions: {
|
||||||
|
|
||||||
edit: {
|
edit: {
|
||||||
label: 'Edit',
|
label: 'Edit',
|
||||||
ngClick: "editProject(\{\{ project.id \}\})",
|
ngClick: "editProject(\{\{ project.id \}\})",
|
||||||
@@ -49,6 +50,14 @@ angular.module('ProjectsListDefinition', [])
|
|||||||
awToolTip: 'View/edit project'
|
awToolTip: 'View/edit project'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
scm_update: {
|
||||||
|
label: 'Update',
|
||||||
|
icon: 'icon-cloud-download',
|
||||||
|
"class": 'btn-xs btn-success',
|
||||||
|
ngClick: 'scmUpdate(\{\{ project.id \}\})',
|
||||||
|
awToolTip: 'Perform an SCM update on this project'
|
||||||
|
},
|
||||||
|
|
||||||
"delete": {
|
"delete": {
|
||||||
label: 'Delete',
|
label: 'Delete',
|
||||||
ngClick: "deleteProject(\{\{ project.id \}\},'\{\{ project.name \}\}')",
|
ngClick: "deleteProject(\{\{ project.id \}\},'\{\{ project.name \}\}')",
|
||||||
|
|||||||
@@ -231,6 +231,10 @@ a:hover {
|
|||||||
max-width: 100px;
|
max-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-horizontal .buttons {
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Outline required fields in Red when focused */
|
/* Outline required fields in Red when focused */
|
||||||
|
|
||||||
.form-control[required]:focus {
|
.form-control[required]:focus {
|
||||||
@@ -411,6 +415,11 @@ select.field-mini-height {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.checkbox-options {
|
||||||
|
padding-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Display list actions next to search widget */
|
/* Display list actions next to search widget */
|
||||||
|
|
||||||
.list-actions {
|
.list-actions {
|
||||||
|
|||||||
@@ -265,42 +265,64 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
|
|||||||
buildField: function(fld, field, options, form) {
|
buildField: function(fld, field, options, form) {
|
||||||
|
|
||||||
function getFieldWidth() {
|
function getFieldWidth() {
|
||||||
var x;
|
var x;
|
||||||
if (form.formFieldSize) {
|
if (form.formFieldSize) {
|
||||||
x = form.formFieldSize;
|
x = form.formFieldSize;
|
||||||
}
|
}
|
||||||
else if (field.xtraWide) {
|
else if (field.xtraWide) {
|
||||||
x = "col-lg-10";
|
x = "col-lg-10";
|
||||||
}
|
}
|
||||||
else if (field.column) {
|
else if (field.column) {
|
||||||
x = "col-lg-8";
|
x = "col-lg-8";
|
||||||
}
|
}
|
||||||
else if (!form.formFieldSize && options.modal) {
|
else if (!form.formFieldSize && options.modal) {
|
||||||
x = "col-lg-10";
|
x = "col-lg-10";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x = "col-lg-6";
|
x = "col-lg-6";
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLabelWidth() {
|
function getLabelWidth() {
|
||||||
var x;
|
var x;
|
||||||
if (form.formLabelSize) {
|
if (form.formLabelSize) {
|
||||||
x = form.formLabelSize;
|
x = form.formLabelSize;
|
||||||
}
|
}
|
||||||
else if (field.column) {
|
else if (field.column) {
|
||||||
x = "col-lg-4";
|
x = "col-lg-4";
|
||||||
}
|
}
|
||||||
else if (!form.formLabelSize && options.modal) {
|
else if (!form.formLabelSize && options.modal) {
|
||||||
x = "col-lg-2";
|
x = "col-lg-2";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x = "col-lg-2";
|
x = "col-lg-2";
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildCheckbox(field, fld) {
|
||||||
|
var html='';
|
||||||
|
html += "<label class=\"checkbox-inline"
|
||||||
|
html += (field.labelClass) ? " " + field.labelClass : "";
|
||||||
|
html += "\">";
|
||||||
|
html += "<input type=\"checkbox\" ";
|
||||||
|
html += Attr(field,'type');
|
||||||
|
html += "ng-model=\"" + fld + '" ';
|
||||||
|
html += "name=\"" + fld + '" ';
|
||||||
|
html += (field.ngChange) ? Attr(field,'ngChange') : "";
|
||||||
|
html += (field.id) ? Attr(field,'id') : "";
|
||||||
|
html += (field['class']) ? Attr(field,'class') : "";
|
||||||
|
html += Attr(field,'trueValue');
|
||||||
|
html += Attr(field,'falseValue');
|
||||||
|
html += (field.checked) ? "checked " : "";
|
||||||
|
html += (field.readonly) ? "disabled " : "";
|
||||||
|
html += " > " + field.label + "\n";
|
||||||
|
html += (field.awPopOver) ? Attr(field, 'awPopOver', fld) : "";
|
||||||
|
html += "</label>\n";
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
if (field.type == 'hidden') {
|
if (field.type == 'hidden') {
|
||||||
@@ -517,28 +539,38 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
|
|||||||
html += "</div>\n";
|
html += "</div>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//checkbox group
|
||||||
|
if (field.type == 'checkbox_group') {
|
||||||
|
html += "<label class=\"control-label " + getLabelWidth() + "\">" +
|
||||||
|
field.label + "</label>\n";
|
||||||
|
for (var i=0; i < field.fields.length; i++) {
|
||||||
|
html += buildCheckbox(field.fields[i], field.fields[i].name);
|
||||||
|
}
|
||||||
|
// Add error messages
|
||||||
|
if ( (options.mode == 'add' && field.addRequired) || (options.mode == 'edit' && field.editRequired) ) {
|
||||||
|
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$dirty && " +
|
||||||
|
this.form.name + '_form.' + fld + ".$error.required\">A value is required!</div>\n";
|
||||||
|
}
|
||||||
|
if (field.integer) {
|
||||||
|
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$error.integer\">Must be an integer value</div>\n";
|
||||||
|
}
|
||||||
|
if (field.min || field.max) {
|
||||||
|
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$error.min || " +
|
||||||
|
this.form.name + '_form.' + fld + ".$error.max\">Must be in range " + field.min + " to " +
|
||||||
|
field.max + "</div>\n";
|
||||||
|
}
|
||||||
|
html += "<div class=\"error api-error\" ng-bind=\"" + fld + "_api_error\"></div>\n";
|
||||||
|
}
|
||||||
|
|
||||||
//checkbox
|
//checkbox
|
||||||
if (field.type == 'checkbox') {
|
if (field.type == 'checkbox') {
|
||||||
html += "<label class=\"control-label " + getLabelWidth() + "\" > </label>\n";
|
html += "<label class=\"control-label " + getLabelWidth() + "\" > </label>\n";
|
||||||
html += "<div ";
|
html += "<div ";
|
||||||
html += (field.controlNGClass) ? "ng-class=\"" + field.controlNGClass + "\" " : "";
|
html += (field.controlNGClass) ? "ng-class=\"" + field.controlNGClass + "\" " : "";
|
||||||
html += "class=\"" + getFieldWidth() + "\">\n";
|
html += "class=\"" + getFieldWidth() + "\">\n";
|
||||||
html += "<label class=\"checkbox-inline\">";
|
html += buildCheckbox(field, fld);
|
||||||
html += "<input type=\"checkbox\" ";
|
|
||||||
html += this.attr(field,'type');
|
|
||||||
html += "ng-model=\"" + fld + '" ';
|
|
||||||
html += "name=\"" + fld + '" ';
|
|
||||||
html += (field.ngChange) ? this.attr(field,'ngChange') : "";
|
|
||||||
html += (field.id) ? this.attr(field,'id') : "";
|
|
||||||
html += this.attr(field,'trueValue');
|
|
||||||
html += this.attr(field,'falseValue');
|
|
||||||
html += (field.checked) ? "checked " : "";
|
|
||||||
html += (field.readonly) ? "disabled " : "";
|
|
||||||
html += " > " + field.label + "\n";
|
|
||||||
html += (field.awPopOver) ? this.attr(field, 'awPopOver', fld) : "";
|
|
||||||
html += "</label>\n";
|
|
||||||
html += "<div class=\"error api-error\" ng-bind=\"" + fld + "_api_error\"></div>\n";
|
html += "<div class=\"error api-error\" ng-bind=\"" + fld + "_api_error\"></div>\n";
|
||||||
html += "</div>\n";
|
html += "</div>\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
//radio
|
//radio
|
||||||
@@ -782,6 +814,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
|
|||||||
html += "<div" + sectionShow + ">\n";
|
html += "<div" + sectionShow + ">\n";
|
||||||
section = field.section;
|
section = field.section;
|
||||||
}
|
}
|
||||||
|
|
||||||
html += this.buildField(fld, field, options, this.form);
|
html += this.buildField(fld, field, options, this.form);
|
||||||
}
|
}
|
||||||
if (section !== '') {
|
if (section !== '') {
|
||||||
|
|||||||
@@ -100,6 +100,7 @@
|
|||||||
<script src="{{ STATIC_URL }}js/helpers/md5.js"></script>
|
<script src="{{ STATIC_URL }}js/helpers/md5.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/helpers/Access.js"></script>
|
<script src="{{ STATIC_URL }}js/helpers/Access.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/helpers/Selection.js"></script>
|
<script src="{{ STATIC_URL }}js/helpers/Selection.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}js/helpers/SCMUpdate.js"></script>
|
||||||
|
|
||||||
<script src="{{ STATIC_URL }}lib/less/less-1.4.1.min.js"></script>
|
<script src="{{ STATIC_URL }}lib/less/less-1.4.1.min.js"></script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user