Use broccoli to build app

This commit is contained in:
Joe Fiorini
2015-02-04 09:38:54 -05:00
parent 2eb16eb04e
commit a9e0de98d7
150 changed files with 17234 additions and 16381 deletions
+5
View File
@@ -32,6 +32,10 @@ tar-build
/bower.json
/package.json
node_modules/**
/tmp
# UI build debugging
/DEBUG-*
# Testing
.coverage
@@ -63,3 +67,4 @@ setup/inventory
env/*
nohup.out
reports
+1
View File
@@ -8,6 +8,7 @@
"latedef": "nofunc",
"noarg": true,
"nonew": true,
"maxerr": 10000,
"notypeof": true,
"globals": {
"angular":false,
+53 -11
View File
@@ -10,6 +10,8 @@ var concatFiles = require('broccoli-sourcemap-concat');
var compileLess = require('broccoli-less-single');
var gzip = require('broccoli-gzip');
var debug = require('broccoli-stew').debug;
var ES6 = require('broccoli-es6modules');
var Funnel = require('broccoli-funnel');
// Get extra args after '--'
var allArgs = parseArgs(process.argv.slice(2), { '--': true });
@@ -19,8 +21,15 @@ var shouldCompress = isUndefined(args.compress) ? false : args.compress;
var debugMode = isUndefined(args.debug) ? false : args.debug;
var silentMode = isUndefined(args.silent) ? false : args.silent;
var appName = 'tower';
if (debugMode) {
log('*** DEBUG MODE ***');
}
var vendorFiles =
[ 'jquery/dist/jquery.js',
[ 'loader.js/loader.js',
'jquery/dist/jquery.js',
'angular/angular.js',
'angular-route/angular-route.js',
'angular-resource/angular-resource.js',
@@ -34,7 +43,7 @@ var vendorFiles =
'angular-animate/angular-animate.js',
'angular-tz-extensions/packages/jstimezonedetect/jstz.js',
'socket.io-client/dist/socket.io.js',
'd3js/build/d3.v3.js',
'd3/d3.js',
'novus-nvd3/nv.d3.js',
'angular-codemirror/lib/AngularCodeMirror.js',
'timezone-js/src/date.js',
@@ -59,11 +68,21 @@ var vendorFiles =
];
function log() {
var msgs = Array.prototype.splice.apply(arguments);
var msgs = Array.prototype.slice.apply(arguments);
if (!silentMode) {
console.log.apply(null, msgs);
}
return msgs.slice(-1);
}
function doDebug(name, tree) {
if (debugMode) {
tree = debug(tree, { name: name });
}
return tree;
}
function prependLibDir(file) {
@@ -73,21 +92,44 @@ function prependLibDir(file) {
vendorFiles = vendorFiles.map(prependLibDir);
var root = 'awx/ui/static';
var app = root;
var app = new Funnel(root,
{ include: flatten([vendorFiles, 'js/**/*.js'])
});
function log(msg, obj) {
console.log(msg + ":", obj);
return obj;
}
app = doDebug('initial-select', app);
var appStyles = new Funnel(root,
{ include: ['**/*.less']
});
var applicationJS = new Funnel(app,
{ include: ['**/*.js'],
srcDir: 'js',
destDir: appName
});
applicationJS = doDebug('app-funnel', applicationJS);
var vendorJS = new Funnel(app,
{ include: ['lib/**/*.js']
});
vendorJS = doDebug('vendor-funnel', vendorJS);
applicationJS = new ES6(applicationJS);
app = mergeTrees([vendorJS, applicationJS]);
app = doDebug('merged-app-vendor', app);
app = concatFiles(app,
{ outputFile: 'tower.concat.js',
inputFiles: flatten([vendorFiles, ['js/**/*.js', 'js/app.js', 'js/config.js', 'js/local_config.js']])
inputFiles: flatten([vendorFiles, ['tower/**/*.js', 'tower/app.js', 'tower/config.js', 'tower/local_config.js']])
});
app = debug(app, {name: 'concat'});
app = doDebug('concat', app);
var styles = compileLess(path.join(root, 'less'), 'ansible-ui.less', 'tower.min.css');
var styles = compileLess(appStyles, 'less/ansible-ui.less', 'tower.min.css');
app = mergeTrees([app, styles]);
+93 -62
View File
@@ -7,8 +7,7 @@
*
*/
var urlPrefix,
$AnsibleConfig;
var urlPrefix;
if ($basePath) {
urlPrefix = $basePath;
@@ -18,17 +17,46 @@ if ($basePath) {
urlPrefix = $basePath;
}
import * as Helpers from 'tower/helpers';
import * as Forms from 'tower/forms';
import * as Lists from 'tower/lists';
import * as Widgets from 'tower/widgets';
import * as Help from 'tower/help';
import {Home, HomeGroups, HomeHosts} from 'tower/controllers/Home';
import {SocketsController} from 'tower/controllers/Sockets';
import {Authenticate} from 'tower/controllers/Authentication';
import {CredentialsAdd, CredentialsEdit, CredentialsList} from 'tower/controllers/Credentials';
import {JobsListController} from 'tower/controllers/Jobs';
import {PortalController} from 'tower/controllers/Portal';
angular.module('Tower', [
import dataServices from 'tower/services/_data-services';
import dashboardGraphs from 'tower/directives/_dashboard-graphs';
import {JobDetailController} from 'tower/controllers/JobDetail';
import {JobStdoutController} from 'tower/controllers/JobStdout';
import {JobTemplatesList, JobTemplatesAdd, JobTemplatesEdit} from 'tower/controllers/JobTemplates';
import {ScheduleEditController} from 'tower/controllers/Schedules';
import {ProjectsList, ProjectsAdd, ProjectsEdit} from 'tower/controllers/Projects';
import {OrganizationsList, OrganizationsAdd, OrganizationsEdit} from 'tower/controllers/Organizations';
import {InventoriesList, InventoriesAdd, InventoriesEdit} from 'tower/controllers/Inventories';
import {AdminsList} from 'tower/controllers/Admins';
import {UsersList, UsersAdd, UsersEdit} from 'tower/controllers/Users';
import {TeamsList, TeamsAdd, TeamsEdit} from 'tower/controllers/Teams';
import {PermissionsAdd, PermissionsList, PermissionsEdit} from 'tower/controllers/Permissions';
var tower = angular.module('Tower', [
'ngRoute',
'ngSanitize',
'ngCookies',
'RestServices',
'DataServices',
'DashboardGraphs',
dataServices.name,
dashboardGraphs.name,
'AuthService',
'Utilities',
'LicenseHelper',
Helpers.License.name,
'OrganizationFormDefinition',
'UserFormDefinition',
'FormGenerator',
@@ -138,267 +166,267 @@ angular.module('Tower', [
when('/jobs', {
templateUrl: urlPrefix + 'partials/jobs.html',
controller: 'JobsListController'
controller: JobsListController
}).
when('/portal', {
templateUrl: urlPrefix + 'partials/portal.html',
controller: 'PortalController'
controller: PortalController
}).
when('/jobs/:id', {
templateUrl: urlPrefix + 'partials/job_detail.html',
controller: 'JobDetailController'
controller: JobDetailController
}).
when('/jobs/:id/stdout', {
templateUrl: urlPrefix + 'partials/job_stdout.html',
controller: 'JobStdoutController'
controller: JobStdoutController
}).
when('/job_templates', {
templateUrl: urlPrefix + 'partials/job_templates.html',
controller: 'JobTemplatesList'
controller: JobTemplatesList
}).
when('/job_templates/add', {
templateUrl: urlPrefix + 'partials/job_templates.html',
controller: 'JobTemplatesAdd'
controller: JobTemplatesAdd
}).
when('/job_templates/:template_id', {
templateUrl: urlPrefix + 'partials/job_templates.html',
controller: 'JobTemplatesEdit'
controller: JobTemplatesEdit
}).
when('/job_templates/:id/schedules', {
templateUrl: urlPrefix + 'partials/schedule_detail.html',
controller: 'ScheduleEditController'
controller: ScheduleEditController
}).
when('/projects', {
templateUrl: urlPrefix + 'partials/projects.html',
controller: 'ProjectsList'
controller: ProjectsList
}).
when('/projects/add', {
templateUrl: urlPrefix + 'partials/projects.html',
controller: 'ProjectsAdd'
controller: ProjectsAdd
}).
when('/projects/:id', {
templateUrl: urlPrefix + 'partials/projects.html',
controller: 'ProjectsEdit'
controller: ProjectsEdit
}).
when('/projects/:id/schedules', {
templateUrl: urlPrefix + 'partials/schedule_detail.html',
controller: 'ScheduleEditController'
controller: ScheduleEditController
}).
when('/projects/:project_id/organizations', {
templateUrl: urlPrefix + 'partials/projects.html',
controller: 'OrganizationsList'
controller: OrganizationsList
}).
when('/projects/:project_id/organizations/add', {
templateUrl: urlPrefix + 'partials/projects.html',
controller: 'OrganizationsAdd'
controller: OrganizationsAdd
}).
when('/inventories', {
templateUrl: urlPrefix + 'partials/inventories.html',
controller: 'InventoriesList'
controller: InventoriesList
}).
when('/inventories/add', {
templateUrl: urlPrefix + 'partials/inventories.html',
controller: 'InventoriesAdd'
controller: InventoriesAdd
}).
when('/inventories/:inventory_id', {
templateUrl: urlPrefix + 'partials/inventory-edit.html',
controller: 'InventoriesEdit'
controller: InventoriesEdit
}).
when('/organizations', {
templateUrl: urlPrefix + 'partials/organizations.html',
controller: 'OrganizationsList'
controller: OrganizationsList
}).
when('/organizations/add', {
templateUrl: urlPrefix + 'partials/organizations.html',
controller: 'OrganizationsAdd'
controller: OrganizationsAdd
}).
when('/organizations/:organization_id', {
templateUrl: urlPrefix + 'partials/organizations.html',
controller: 'OrganizationsEdit'
controller: OrganizationsEdit
}).
when('/organizations/:organization_id/admins', {
templateUrl: urlPrefix + 'partials/organizations.html',
controller: 'AdminsList'
controller: AdminsList
}).
when('/organizations/:organization_id/users', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'UsersList'
controller: UsersList
}).
when('/organizations/:organization_id/users/add', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'UsersAdd'
controller: UsersAdd
}).
when('/organizations/:organization_id/users/:user_id', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'UsersEdit'
controller: UsersEdit
}).
when('/teams', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'TeamsList'
controller: TeamsList
}).
when('/teams/add', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'TeamsAdd'
controller: TeamsAdd
}).
when('/teams/:team_id', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'TeamsEdit'
controller: TeamsEdit
}).
when('/teams/:team_id/permissions/add', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'PermissionsAdd'
controller: PermissionsAdd
}).
when('/teams/:team_id/permissions', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'PermissionsList'
controller: PermissionsList
}).
when('/teams/:team_id/permissions/:permission_id', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'PermissionsEdit'
controller: PermissionsEdit
}).
when('/teams/:team_id/users', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'UsersList'
controller: UsersList
}).
when('/teams/:team_id/users/:user_id', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'UsersEdit'
controller: UsersEdit
}).
when('/teams/:team_id/projects', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'ProjectsList'
controller: ProjectsList
}).
when('/teams/:team_id/projects/add', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'ProjectsAdd'
controller: ProjectsAdd
}).
when('/teams/:team_id/projects/:project_id', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'ProjectsEdit'
controller: ProjectsEdit
}).
when('/teams/:team_id/credentials', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'CredentialsList'
controller: CredentialsList
}).
when('/teams/:team_id/credentials/add', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'CredentialsAdd'
controller: CredentialsAdd
}).
when('/teams/:team_id/credentials/:credential_id', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'CredentialsEdit'
controller: CredentialsEdit
}).
when('/credentials', {
templateUrl: urlPrefix + 'partials/credentials.html',
controller: 'CredentialsList'
controller: CredentialsList
}).
when('/credentials/add', {
templateUrl: urlPrefix + 'partials/credentials.html',
controller: 'CredentialsAdd'
controller: CredentialsAdd
}).
when('/credentials/:credential_id', {
templateUrl: urlPrefix + 'partials/credentials.html',
controller: 'CredentialsEdit'
controller: CredentialsEdit
}).
when('/users', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'UsersList'
controller: UsersList
}).
when('/users/add', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'UsersAdd'
controller: UsersAdd
}).
when('/users/:user_id', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'UsersEdit'
controller: UsersEdit
}).
when('/users/:user_id/credentials', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'CredentialsList'
controller: CredentialsList
}).
when('/users/:user_id/permissions/add', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'PermissionsAdd'
controller: PermissionsAdd
}).
when('/users/:user_id/permissions', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'PermissionsList'
controller: PermissionsList
}).
when('/users/:user_id/permissions/:permission_id', {
templateUrl: urlPrefix + 'partials/users.html',
controller: 'PermissionsEdit'
controller: PermissionsEdit
}).
when('/users/:user_id/credentials/add', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'CredentialsAdd'
controller: CredentialsAdd
}).
when('/teams/:user_id/credentials/:credential_id', {
templateUrl: urlPrefix + 'partials/teams.html',
controller: 'CredentialsEdit'
controller: CredentialsEdit
}).
when('/login', {
templateUrl: urlPrefix + 'partials/blank.html',
controller: 'Authenticate'
controller: Authenticate
}).
when('/logout', {
templateUrl: urlPrefix + 'partials/blank.html',
controller: 'Authenticate'
controller: Authenticate
}).
when('/home', {
templateUrl: urlPrefix + 'partials/home.html',
controller: 'Home',
controller: Home,
resolve: {
graphData: ['$q', 'jobStatusGraphData', 'hostCountGraphData', function($q, jobStatusGraphData, hostCountGraphData) {
return $q.all({
@@ -411,17 +439,17 @@ angular.module('Tower', [
when('/home/groups', {
templateUrl: urlPrefix + 'partials/subhome.html',
controller: 'HomeGroups'
controller: HomeGroups
}).
when('/home/hosts', {
templateUrl: urlPrefix + 'partials/subhome.html',
controller: 'HomeHosts'
controller: HomeHosts
}).
when('/sockets', {
templateUrl: urlPrefix + 'partials/sockets.html',
controller: 'SocketsController'
controller: SocketsController
}).
otherwise({
@@ -756,3 +784,6 @@ angular.module('Tower', [
LoadConfig();
}
]);
export default tower;
+1 -1
View File
@@ -19,7 +19,7 @@
*/
function AdminsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, AdminList, GenerateList, LoadBreadCrumbs,
export function AdminsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, AdminList, GenerateList, LoadBreadCrumbs,
Prompt, SearchInit, PaginateInit, ReturnToCaller, GetBasePath, SelectionInit) {
var list = AdminList,
@@ -59,7 +59,7 @@
*/
function Authenticate($log, $cookieStore, $compile, $window, $rootScope, $location, Authorization, ToggleClass, Alert, Wait,
export function Authenticate($log, $cookieStore, $compile, $window, $rootScope, $location, Authorization, ToggleClass, Alert, Wait,
Timer, Empty, ClearScope) {
var setLoginFocus, lastPath, sessionExpired, loginAgain,
+3 -3
View File
@@ -13,7 +13,7 @@
*/
function CredentialsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, CredentialList,
export function CredentialsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, CredentialList,
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
ClearScope, ProcessErrors, GetBasePath, SelectionInit, GetChoices, Wait, Stream) {
@@ -134,7 +134,7 @@ CredentialsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeP
];
function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, GenerateForm, Rest, Alert,
export function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, GenerateForm, Rest, Alert,
ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GenerateList, SearchInit, PaginateInit, LookUpInit, UserList, TeamList,
GetBasePath, GetChoices, Empty, KindChange, OwnerChange, LoginMethodChange, FormSave) {
@@ -286,7 +286,7 @@ CredentialsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log
];
function CredentialsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, GenerateForm, Rest, Alert,
export function CredentialsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, GenerateForm, Rest, Alert,
ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, Prompt, GetBasePath, GetChoices,
KindChange, UserList, TeamList, LookUpInit, Empty, OwnerChange, LoginMethodChange, FormSave, Stream, Wait) {
+5 -3
View File
@@ -25,7 +25,8 @@
* Host count graph should only be loaded if the user is a super user
*
*/
function Home($scope, $compile, $routeParams, $rootScope, $location, $log, Wait, DashboardCounts, DashboardJobs,
export function Home($scope, $compile, $routeParams, $rootScope, $location, $log, Wait, DashboardCounts, DashboardJobs,
ClearScope, Stream, Rest, GetBasePath, ProcessErrors, Button, $window, graphData){
ClearScope('home');
@@ -136,7 +137,7 @@ Home.$inject = ['$scope', '$compile', '$routeParams', '$rootScope', '$location',
* @description This controls the 'home/groups' page that is loaded from the dashboard
*
*/
function HomeGroups($log, $scope, $filter, $compile, $location, $routeParams, LogViewer, HomeGroupList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
export function HomeGroups($log, $scope, $filter, $compile, $location, $routeParams, LogViewer, HomeGroupList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
GetBasePath, SearchInit, PaginateInit, FormatDate, GetHostsStatusMsg, GetSyncStatusMsg, ViewUpdateStatus, Stream, GroupsEdit, Wait,
Alert, Rest, Empty, InventoryUpdate, Find, GroupsCancelUpdate, Store, Socket) {
@@ -572,7 +573,8 @@ HomeGroups.$inject = ['$log', '$scope', '$filter', '$compile', '$location', '$ro
* @description This loads the page for 'home/hosts'
*
*/
function HomeHosts($scope, $location, $routeParams, HomeHostList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
export function HomeHosts($scope, $location, $routeParams, HomeHostList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
GetBasePath, SearchInit, PaginateInit, FormatDate, SetStatus, ToggleHostEnabled, HostsEdit, Stream, Find, ShowJobSummary, ViewJob) {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
+3 -3
View File
@@ -14,7 +14,7 @@
*/
function InventoriesList($scope, $rootScope, $location, $log, $routeParams, $compile, $filter, Rest, Alert, InventoryList, GenerateList,
export function InventoriesList($scope, $rootScope, $location, $log, $routeParams, $compile, $filter, Rest, Alert, InventoryList, GenerateList,
LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, Wait, Stream,
EditInventoryProperties, Find, Empty, LogViewer) {
@@ -368,7 +368,7 @@ InventoriesList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeP
];
function InventoriesAdd($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm, GenerateForm, Rest,
export function InventoriesAdd($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm, GenerateForm, Rest,
Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GenerateList, OrganizationList, SearchInit, PaginateInit,
LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON) {
@@ -478,7 +478,7 @@ InventoriesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log
function InventoriesEdit ($log, $scope, $location, $routeParams, $compile, GenerateList, ClearScope, Empty, Wait, Rest, Alert, LoadBreadCrumbs, GetBasePath, ProcessErrors,
export function InventoriesEdit ($log, $scope, $location, $routeParams, $compile, GenerateList, ClearScope, Empty, Wait, Rest, Alert, LoadBreadCrumbs, GetBasePath, ProcessErrors,
Breadcrumbs, InventoryGroups, InjectHosts, Find, HostsReload, SearchInit, PaginateInit, GetSyncStatusMsg, GetHostsStatusMsg, GroupsEdit, InventoryUpdate,
GroupsCancelUpdate, ViewUpdateStatus, GroupsDelete, Store, HostsEdit, HostsDelete, EditInventoryProperties, ToggleHostEnabled, Stream, ShowJobSummary,
InventoryGroupsHelp, HelpDialog, ViewJob, WatchInventoryWindowResize, GetHostContainerRows, GetGroupContainerRows, GetGroupContainerHeight,
+1 -1
View File
@@ -11,7 +11,7 @@
*/
function JobDetailController ($location, $rootScope, $scope, $compile, $routeParams, $log, ClearScope, Breadcrumbs, LoadBreadCrumbs, GetBasePath, Wait, Rest,
export function JobDetailController ($location, $rootScope, $scope, $compile, $routeParams, $log, ClearScope, Breadcrumbs, LoadBreadCrumbs, GetBasePath, Wait, Rest,
ProcessErrors, SelectPlay, SelectTask, Socket, GetElapsed, DrawGraph, LoadHostSummary, ReloadHostSummaryList, JobIsFinished, SetTaskStyles, DigestEvent,
UpdateDOM, EventViewer, DeleteJob, PlaybookRun, HostEventsViewer, LoadPlays, LoadTasks, LoadHosts, HostsEdit, ParseVariableString) {
+2 -2
View File
@@ -14,7 +14,7 @@
*/
function JobEventsList($sce, $filter, $scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobEventList, GenerateList,
export function JobEventsList($sce, $filter, $scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobEventList, GenerateList,
LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, LookUpInit, ToggleChildren,
FormatDate, EventView, Refresh, Wait) {
@@ -260,7 +260,7 @@ JobEventsList.$inject = ['$sce', '$filter', '$scope', '$rootScope', '$location',
'GetBasePath', 'LookUpInit', 'ToggleChildren', 'FormatDate', 'EventView', 'Refresh', 'Wait'
];
function JobEventsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobEventsForm, GenerateForm,
export function JobEventsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobEventsForm, GenerateForm,
Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, FormatDate, EventView, Wait) {
ClearScope();
+1 -1
View File
@@ -14,7 +14,7 @@
*/
function JobHostSummaryList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobHostList, GenerateList,
export function JobHostSummaryList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobHostList, GenerateList,
LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, Refresh,
JobStatusToolTip) {
+1 -1
View File
@@ -11,7 +11,7 @@
*/
function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams, ClearScope, GetBasePath, Wait, Rest, ProcessErrors, Socket) {
export function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams, ClearScope, GetBasePath, Wait, Rest, ProcessErrors, Socket) {
ClearScope();
+3 -3
View File
@@ -14,7 +14,7 @@
*/
function JobTemplatesList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobTemplateList,
export function JobTemplatesList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobTemplateList,
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors,
GetBasePath, JobTemplateForm, CredentialList, LookUpInit, PlaybookRun, Wait, Stream, CreateDialog, $compile) {
@@ -246,7 +246,7 @@ JobTemplatesList.$inject = ['$scope', '$rootScope', '$location', '$log', '$route
'PlaybookRun', 'Wait', 'Stream', 'CreateDialog' , '$compile'
];
function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm,
export function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GetBasePath,
InventoryList, CredentialList, ProjectList, LookUpInit, md5Setup, ParseTypeChange, Wait, Empty, ToJSON,
CallbackHelpInit, SurveyControllerInit, Prompt) {
@@ -551,7 +551,7 @@ JobTemplatesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$lo
];
function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, GenerateForm, Rest,
export function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, GenerateForm, Rest,
Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList,
CredentialList, ProjectList, LookUpInit, GetBasePath, md5Setup, ParseTypeChange, JobStatusToolTip, FormatDate,
Wait, Stream, Empty, Prompt, ParseVariableString, ToJSON, SchedulesControllerInit, JobsControllerInit, JobsListUpdate,
+1 -1
View File
@@ -14,7 +14,7 @@
*/
function JobsListController ($rootScope, $log, $scope, $compile, $routeParams, ClearScope, Breadcrumbs, LoadBreadCrumbs, LoadSchedulesScope,
export function JobsListController ($rootScope, $log, $scope, $compile, $routeParams, ClearScope, Breadcrumbs, LoadBreadCrumbs, LoadSchedulesScope,
LoadJobsScope, RunningJobsList, CompletedJobsList, QueuedJobsList, ScheduledJobsList, GetChoices, GetBasePath, Wait, Socket) {
ClearScope();
@@ -14,7 +14,7 @@
*/
function OrganizationsList($routeParams, $scope, $rootScope, $location, $log, Rest, Alert, LoadBreadCrumbs, Prompt,
export function OrganizationsList($routeParams, $scope, $rootScope, $location, $log, Rest, Alert, LoadBreadCrumbs, Prompt,
GenerateList, OrganizationList, SearchInit, PaginateInit, ClearScope, ProcessErrors, GetBasePath, SelectionInit, Wait, Stream) {
ClearScope();
@@ -101,7 +101,7 @@ OrganizationsList.$inject = ['$routeParams', '$scope', '$rootScope', '$location'
];
function OrganizationsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm,
export function OrganizationsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath,
ReturnToCaller, Wait) {
@@ -152,7 +152,7 @@ OrganizationsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$l
];
function OrganizationsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm, GenerateForm, Rest,
export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm, GenerateForm, Rest,
Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, Prompt, ClearScope, GetBasePath, Wait, Stream) {
ClearScope();
+3 -3
View File
@@ -14,7 +14,7 @@
*/
function PermissionsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, PermissionList,
export function PermissionsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, PermissionList,
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors,
GetBasePath, CheckAccess, Wait) {
@@ -102,7 +102,7 @@ PermissionsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeP
];
function PermissionsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm,
export function PermissionsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope,
GetBasePath, ReturnToCaller, InventoryList, ProjectList, LookUpInit, CheckAccess,
Wait, PermissionCategoryChange) {
@@ -199,7 +199,7 @@ PermissionsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log
];
function PermissionsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm,
export function PermissionsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt, GetBasePath,
InventoryList, ProjectList, LookUpInit, CheckAccess, Wait, PermissionCategoryChange) {
+1 -1
View File
@@ -24,7 +24,7 @@
*
*
*/
function PortalController($scope, $compile, $routeParams, $rootScope, $location, $log, Wait, ClearScope, Stream, Rest, GetBasePath, ProcessErrors,
export function PortalController($scope, $compile, $routeParams, $rootScope, $location, $log, Wait, ClearScope, Stream, Rest, GetBasePath, ProcessErrors,
Button, PortalJobsWidget, GenerateList, PortalJobTemplateList, SearchInit, PaginateInit, PlaybookRun){
ClearScope('portal');
+3 -3
View File
@@ -14,7 +14,7 @@
*/
function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, ProjectList, GenerateList, LoadBreadCrumbs,
export function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, ProjectList, GenerateList, LoadBreadCrumbs,
Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, SelectionInit, ProjectUpdate,
Refresh, Wait, Stream, GetChoices, Empty, Find, LogViewer, GetProjectIcon, GetProjectToolTip) {
@@ -391,7 +391,7 @@ ProjectsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routePara
];
function ProjectsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, GenerateForm, Rest, Alert, ProcessErrors,
export function ProjectsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, GenerateForm, Rest, Alert, ProcessErrors,
LoadBreadCrumbs, ClearScope, GetBasePath, ReturnToCaller, GetProjectPath, LookUpInit, OrganizationList,
CredentialList, GetChoices, DebugForm, Wait) {
@@ -537,7 +537,7 @@ ProjectsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log',
];
function ProjectsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm,
export function ProjectsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, Prompt,
ClearScope, GetBasePath, ReturnToCaller, GetProjectPath, Authorization, CredentialList, LookUpInit, GetChoices,
Empty, DebugForm, Wait, Stream, SchedulesControllerInit, SchedulesListInit, SchedulesList, ProjectUpdate) {
+1 -1
View File
@@ -14,7 +14,7 @@
*/
function ScheduleEditController($scope, $compile, $location, $routeParams, SchedulesList, Rest, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
export function ScheduleEditController($scope, $compile, $location, $routeParams, SchedulesList, Rest, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
GetBasePath, Wait, Breadcrumbs, Find, LoadDialogPartial, LoadSchedulesScope, GetChoices, Stream) {
ClearScope();
+1 -1
View File
@@ -13,7 +13,7 @@
*/
function SocketsController ($scope, $compile, ClearScope, Socket) {
export function SocketsController ($scope, $compile, ClearScope, Socket) {
ClearScope();
+3 -3
View File
@@ -14,7 +14,7 @@
*/
function TeamsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, TeamList, GenerateList, LoadBreadCrumbs,
export function TeamsList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, TeamList, GenerateList, LoadBreadCrumbs,
Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, SetTeamListeners, GetBasePath, SelectionInit, Wait,
Stream) {
@@ -116,7 +116,7 @@ TeamsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams'
];
function TeamsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm,
export function TeamsAdd($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm,
Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GenerateList,
OrganizationList, SearchInit, PaginateInit, GetBasePath, LookUpInit, Wait) {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
@@ -177,7 +177,7 @@ TeamsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$r
];
function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm, Rest, Alert, ProcessErrors,
export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm, Rest, Alert, ProcessErrors,
LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, LookUpInit, Prompt, GetBasePath, CheckAccess,
OrganizationList, Wait, Stream) {
+3 -3
View File
@@ -13,7 +13,7 @@
*/
function UsersList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, UserList, GenerateList, LoadBreadCrumbs,
export function UsersList($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, UserList, GenerateList, LoadBreadCrumbs,
Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, SelectionInit, Wait, Stream) {
ClearScope();
@@ -105,7 +105,7 @@ UsersList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams'
];
function UsersAdd($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, GenerateForm, Rest, Alert, ProcessErrors,
export function UsersAdd($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, GenerateForm, Rest, Alert, ProcessErrors,
LoadBreadCrumbs, ReturnToCaller, ClearScope, GetBasePath, LookUpInit, OrganizationList, ResetForm, Wait) {
ClearScope();
@@ -208,7 +208,7 @@ UsersAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$r
];
function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, GenerateForm, Rest, Alert,
export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, GenerateForm, Rest, Alert,
ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, GetBasePath,
Prompt, CheckAccess, ResetForm, Wait, Stream) {
@@ -1 +1,12 @@
angular.module('DashboardGraphs', []);
import JobStatusGraph from 'tower/directives/job-status-graph';
import HostCountGraph from 'tower/directives/host-count-graph';
import HostStatusGraph from 'tower/directives/host-status-graph';
import AutoSizeModule from 'tower/directives/auto-size-module';
import AdjustGraphSize from 'tower/services/adjust-graph-size';
export default angular.module('DashboardGraphs', [])
.directive('jobStatusGraph', JobStatusGraph)
.directive('hostCountGraph', HostCountGraph)
.directive('hostStatusGraph', HostStatusGraph)
.directive('autoSizeModule', AutoSizeModule)
.service('adjustGraphSize', AdjustGraphSize);
@@ -1,5 +1,9 @@
angular.module('DashboardGraphs')
.directive('autoSizeModule', ['$window', function($window) {
export default
[ '$window',
AutoSizeModule
];
function AutoSizeModule($window) {
// Adjusts the size of the module so that all modules
// fit into a single a page; assumes there are 2 rows
@@ -32,4 +36,4 @@ angular.module('DashboardGraphs')
};
}]);
}
@@ -1,5 +1,10 @@
angular.module('DashboardGraphs').
directive('hostCountGraph', ['GetBasePath', 'Rest', 'adjustGraphSize', '$window', function(getBasePath, Rest, adjustGraphSize, $window) {
export default
[ 'adjustGraphSize',
'$window',
HostCountGraph
];
function HostCountGraph(adjustGraphSize, $window) {
return {
restrict: 'E',
@@ -42,11 +47,11 @@ angular.module('DashboardGraphs').
{ "key" : "Hosts" ,
"color" : "#1778c3",
"values": data.hosts
},
{ "key" : "License" ,
"color" : "#171717",
"values": data.hosts
}
},
{ "key" : "License" ,
"color" : "#171717",
"values": data.hosts
}
];
graphData.map(function(series) {
@@ -116,4 +121,4 @@ angular.module('DashboardGraphs').
}
}
}]);
}
@@ -1,6 +1,10 @@
angular.module('DashboardGraphs')
.directive('hostStatusGraph', ['$compile', '$window',
function ($compile, $window) {
export default
[ '$compile',
'$window',
HostStatusGraph
];
function HostStatusGraph($compile, $window) {
return {
restrict: 'E',
link: link,
@@ -99,4 +103,4 @@ angular.module('DashboardGraphs')
}
}
}]);
}
@@ -1,6 +1,15 @@
angular.module('DashboardGraphs')
.directive('jobStatusGraph', ['$rootScope', '$compile', '$location' , '$window', 'Wait', 'adjustGraphSize', 'jobStatusGraphData',
function ($rootScope, $compile , $location, $window, Wait, adjustGraphSize) {
export default
[ '$rootScope',
'$compile',
'$location' ,
'$window',
'Wait',
'adjustGraphSize',
'jobStatusGraphData',
JobStatusGraph
];
function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustGraphSize) {
return {
restrict: 'E',
templateUrl: '/static/partials/job_status_graph.html',
@@ -117,4 +126,4 @@ angular.module('DashboardGraphs')
}
}
}]);
}
+58
View File
@@ -0,0 +1,58 @@
import ActivityDetail from "tower/forms/ActivityDetail";
import Credentials from "tower/forms/Credentials";
import CustomInventory from "tower/forms/CustomInventory";
import EventsViewer from "tower/forms/EventsViewer";
import Groups from "tower/forms/Groups";
import HostGroups from "tower/forms/HostGroups";
import Hosts from "tower/forms/Hosts";
import Inventories from "tower/forms/Inventories";
import InventoryStatus from "tower/forms/InventoryStatus";
import JobEventData from "tower/forms/JobEventData";
import JobSummary from "tower/forms/JobSummary";
import JobTemplates from "tower/forms/JobTemplates";
import JobVarsPrompt from "tower/forms/JobVarsPrompt";
import Jobs from "tower/forms/Jobs";
import LicenseForm from "tower/forms/LicenseForm";
import LicenseUpdate from "tower/forms/LicenseUpdate";
import LogViewerOptions from "tower/forms/LogViewerOptions";
import LogViewerStatus from "tower/forms/LogViewerStatus";
import Organizations from "tower/forms/Organizations";
import Permissions from "tower/forms/Permissions";
import ProjectStatus from "tower/forms/ProjectStatus";
import Projects from "tower/forms/Projects";
import Source from "tower/forms/Source";
import SurveyMaker from "tower/forms/SurveyMaker";
import SurveyQuestion from "tower/forms/SurveyQuestion";
import Teams from "tower/forms/Teams";
import Users from "tower/forms/Users";
export
{ ActivityDetail,
Credentials,
CustomInventory,
EventsViewer,
Groups,
HostGroups,
Hosts,
Inventories,
InventoryStatus,
JobEventData,
JobSummary,
JobTemplates,
JobVarsPrompt,
Jobs,
LicenseForm,
LicenseUpdate,
LogViewerOptions,
LogViewerStatus,
Organizations,
Permissions,
ProjectStatus,
Projects,
Source,
SurveyMaker,
SurveyQuestion,
Teams,
Users
}
+28 -26
View File
@@ -16,33 +16,35 @@
* @name forms.function:ActivityDetail
* @description This form is for activity detail modal that can be shown on most pages.
*/
angular.module('ActivityDetailDefinition', [])
.value('ActivityDetailForm', {
name: 'activity',
editTitle: 'Activity Detail',
well: false,
'class': 'horizontal-narrow',
formFieldSize: 'col-lg-10',
formLabelSize: 'col-lg-2',
export default
angular.module('ActivityDetailDefinition', [])
.value('ActivityDetailForm', {
fields: {
user: {
label: "Initiated by",
type: 'text',
readonly: true
},
operation: {
label: 'Action',
type: 'text',
readonly: true
},
changes: {
label: 'Changes',
type: 'textarea',
ngHide: "!changes || changes =='' || changes == 'null'",
readonly: true
name: 'activity',
editTitle: 'Activity Detail',
well: false,
'class': 'horizontal-narrow',
formFieldSize: 'col-lg-10',
formLabelSize: 'col-lg-2',
fields: {
user: {
label: "Initiated by",
type: 'text',
readonly: true
},
operation: {
label: 'Action',
type: 'text',
readonly: true
},
changes: {
label: 'Changes',
type: 'textarea',
ngHide: "!changes || changes =='' || changes == 'null'",
readonly: true
}
}
}
}); //Form
}); //Form
+425 -423
View File
@@ -10,438 +10,440 @@
* @name forms.function:Credentials
* @description This form is for adding/editing a Credential
*/
angular.module('CredentialFormDefinition', [])
.value('CredentialForm', {
addTitle: 'Create Credential', //Legend in add mode
editTitle: '{{ name }}', //Legend in edit mode
name: 'credential',
well: true,
forceListeners: true,
export default
angular.module('CredentialFormDefinition', [])
.value('CredentialForm', {
actions: {
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
}
},
addTitle: 'Create Credential', //Legend in add mode
editTitle: '{{ name }}', //Legend in edit mode
name: 'credential',
well: true,
forceListeners: true,
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
autocomplete: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
owner: {
label: "Does this credential belong to a team or user?",
type: 'radio_group',
ngChange: "ownerChange()",
options: [{
label: 'User',
value: 'user',
selected: true
}, {
label: 'Team',
value: 'team'
}],
awPopOver: "<p>A credential must be associated with either a user or a team. Choosing a user allows only the selected user access " +
"to the credential. Choosing a team shares the credential with all team members.</p>",
dataTitle: 'Owner',
dataPlacement: 'right',
dataContainer: "body"
},
user: {
label: 'User that owns this credential',
type: 'lookup',
sourceModel: 'user',
sourceField: 'username',
ngClick: 'lookUpUser()',
ngShow: "owner == 'user'",
awRequiredWhen: {
variable: "user_required",
init: "false"
actions: {
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
}
},
team: {
label: 'Team that owns this credential',
type: 'lookup',
sourceModel: 'team',
sourceField: 'name',
ngClick: 'lookUpTeam()',
ngShow: "owner == 'team'",
awRequiredWhen: {
variable: "team_required",
init: "false"
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
autocomplete: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
owner: {
label: "Does this credential belong to a team or user?",
type: 'radio_group',
ngChange: "ownerChange()",
options: [{
label: 'User',
value: 'user',
selected: true
}, {
label: 'Team',
value: 'team'
}],
awPopOver: "<p>A credential must be associated with either a user or a team. Choosing a user allows only the selected user access " +
"to the credential. Choosing a team shares the credential with all team members.</p>",
dataTitle: 'Owner',
dataPlacement: 'right',
dataContainer: "body"
},
user: {
label: 'User that owns this credential',
type: 'lookup',
sourceModel: 'user',
sourceField: 'username',
ngClick: 'lookUpUser()',
ngShow: "owner == 'user'",
awRequiredWhen: {
variable: "user_required",
init: "false"
}
},
team: {
label: 'Team that owns this credential',
type: 'lookup',
sourceModel: 'team',
sourceField: 'name',
ngClick: 'lookUpTeam()',
ngShow: "owner == 'team'",
awRequiredWhen: {
variable: "team_required",
init: "false"
}
},
kind: {
label: 'Type',
excludeModal: true,
type: 'select',
ngOptions: 'kind.label for kind in credential_kind_options track by kind.value', // select as label for value in array 'kind.label for kind in credential_kind_options',
ngChange: 'kindChange()',
addRequired: true,
editRequired: true,
awPopOver:'<dl>\n' +
'<dt>Machine</dt>\n' +
'<dd>Authentication for remote machine access. This can include SSH keys, usernames, passwords, ' +
'and sudo information. Machine credentials are used when submitting jobs to run playbooks against ' +
'remote hosts.</dd>' +
'<dt>Source Control</dt>\n' +
'<dd>Used to check out and synchronize playbook repositories with a remote source control ' +
'management system such as Git, Subversion (svn), or Mercurial (hg). These credentials are ' +
'used on the Projects tab.</dd>\n' +
'<dt>Others (Cloud Providers)</dt>\n' +
'<dd>Access keys for authenticating to the specific ' +
'cloud provider, usually used for inventory sync ' +
'and deployment.</dd>\n' +
'</dl>\n',
dataTitle: 'Type',
dataPlacement: 'right',
dataContainer: "body"
// helpCollapse: [{
// hdr: 'Select a Credential Type',
// content: '<dl>\n' +
// '<dt>Machine</dt>\n' +
// '<dd>Authentication for remote machine access. This can include SSH keys, usernames, passwords, ' +
// 'and sudo information. Machine credentials are used when submitting jobs to run playbooks against ' +
// 'remote hosts.</dd>' +
// '<dt>Source Control</dt>\n' +
// '<dd>Used to check out and synchronize playbook repositories with a remote source control ' +
// 'management system such as Git, Subversion (svn), or Mercurial (hg). These credentials are ' +
// 'used on the Projects tab.</dd>\n' +
// '<dt>Others (Cloud Providers)</dt>\n' +
// '<dd>Access keys for authenticating to the specific ' +
// 'cloud provider, usually used for inventory sync ' +
// 'and deployment.</dd>\n' +
// '</dl>\n'
// }]
},
access_key: {
label: 'Access Key',
type: 'text',
ngShow: "kind.value == 'aws'",
awRequiredWhen: {
variable: "aws_required",
init: false
},
autocomplete: false,
apiField: 'username'
},
secret_key: {
label: 'Secret Key',
type: 'password',
ngShow: "kind.value == 'aws'",
awRequiredWhen: {
variable: "aws_required",
init: false
},
autocomplete: false,
ask: false,
clear: false,
apiField: 'passwowrd'
},
"host": {
labelBind: 'hostLabel',
type: 'text',
ngShow: "kind.value == 'vmware'",
autocomplete: false,
awRequiredWhen: {
variable: 'host_required',
init: false
}
},
"username": {
labelBind: 'usernameLabel',
type: 'text',
ngShow: "kind.value && kind.value !== 'aws' && " +
"kind.value !== 'gce' && kind.value!=='azure'",
awRequiredWhen: {
variable: 'username_required',
init: false
},
autocomplete: false
},
"email_address": {
labelBind: 'usernameLabel',
type: 'email',
ngShow: "kind.value === 'gce'",
awRequiredWhen: {
variable: 'email_required',
init: false
},
autocomplete: false,
awPopOver: '<p>The email address assigned to the Google Compute Engine <b><i>service account.</b></i></p>',
dataTitle: 'Email',
dataPlacement: 'right',
dataContainer: "body"
},
"subscription_id": {
labelBind: "usernameLabel",
type: 'text',
ngShow: "kind.value == 'azure'",
awRequiredWhen: {
variable: 'subscription_required',
init: false
},
addRequired: false,
editRequired: false,
autocomplete: false,
awPopOver: '<p>Subscription ID is an Azure construct, which is mapped to a username.</p>',
dataTitle: 'Subscription ID',
dataPlacement: 'right',
dataContainer: "body"
},
"api_key": {
label: 'API Key',
type: 'password',
ngShow: "kind.value == 'rax'",
awRequiredWhen: {
variable: "rackspace_required",
init: false
},
autocomplete: false,
ask: false,
clear: false,
// apiField: 'passwowrd'
},
"password": {
label: 'Password',
type: 'password',
ngShow: "kind.value == 'scm' || kind.value == 'vmware'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('password_confirm')",
ask: false,
clear: false,
associated: 'password_confirm',
autocomplete: false,
awRequiredWhen: {
variable: "password_required",
init: false
}
},
"password_confirm": {
label: 'Confirm Password',
type: 'password',
ngShow: "kind.value == 'scm' || kind.value == 'vmware'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'password',
autocomplete: false,
awRequiredWhen: {
variable: "password_required",
init: false
}
},
"ssh_password": {
label: 'Password', // formally 'SSH Password'
type: 'password',
ngShow: "kind.value == 'ssh'",
ngChange: "clearPWConfirm('ssh_password_confirm')",
addRequired: false,
editRequired: false,
ask: true,
clear: true,
associated: 'ssh_password_confirm',
autocomplete: false
},
"ssh_password_confirm": {
label: 'Confirm Password', // formally 'Confirm SSH password'
type: 'password',
ngShow: "kind.value == 'ssh'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'ssh_password',
autocomplete: false
},
"ssh_key_data": {
labelBind: 'sshKeyDataLabel',
type: 'textarea',
ngShow: "kind.value == 'ssh' || kind.value == 'scm' || " +
"kind.value == 'gce' || kind.value == 'azure'",
awRequiredWhen: {
variable: 'key_required',
init: true
},
hintText: "{{ key_hint }}",
addRequired: false,
editRequired: false,
awDropFile: true,
'class': 'ssh-key-field',
rows: 10,
awPopOver: "SSH key description",
awPopOverWatch: "key_description",
dataTitle: 'Help',
dataPlacement: 'right',
dataContainer: "body"
},
"ssh_key_unlock": {
label: 'Key Password',
type: 'password',
ngShow: "kind.value == 'ssh' || kind.value == 'scm'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('ssh_key_unlock_confirm')",
associated: 'ssh_key_unlock_confirm',
ask: true,
askShow: "kind.value == 'ssh'", // Only allow ask for machine credentials
clear: true
},
"ssh_key_unlock_confirm": {
label: 'Confirm Key Password',
type: 'password',
ngShow: "kind.value == 'ssh' || kind.value == 'scm'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'ssh_key_unlock'
},
"login_method": {
label: "Login Method", // FIXME: Confirm this label is ok?
type: 'radio_group',
ngShow: "kind.value == 'ssh'",
ngChange: "loginMethodChange()",
options: [{
label: 'None', // FIXME: Maybe 'Default' or 'SSH only' instead?
value: '',
selected: true
}, {
label: 'Sudo',
value: 'sudo'
}, {
label: 'Su',
value: 'su'
}],
awPopOver: "<p>A credential may optionally provide a sudo username and password or su username and password to use when running a playbook.</p>",
dataPlacement: 'right',
dataContainer: "body"
},
"sudo_username": {
label: 'Sudo Username',
type: 'text',
ngShow: "kind.value == 'ssh' && login_method == 'sudo'",
addRequired: false,
editRequired: false,
autocomplete: false
},
"sudo_password": {
label: 'Sudo Password',
type: 'password',
ngShow: "kind.value == 'ssh' && login_method == 'sudo'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('sudo_password_confirm')",
ask: true,
clear: true,
associated: 'sudo_password_confirm',
autocomplete: false
},
"sudo_password_confirm": {
label: 'Confirm Sudo Password',
type: 'password',
ngShow: "kind.value == 'ssh' && login_method == 'sudo'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'sudo_password',
autocomplete: false
},
"su_username": {
label: 'Su Username',
type: 'text',
ngShow: "kind.value == 'ssh' && login_method == 'su'",
addRequired: false,
editRequired: false,
autocomplete: false
},
"su_password": {
label: 'Su Password',
type: 'password',
ngShow: "kind.value == 'ssh' && login_method == 'su'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('su_password_confirm')",
ask: true,
clear: true,
associated: 'su_password_confirm',
autocomplete: false
},
"su_password_confirm": {
label: 'Confirm Su Password',
type: 'password',
ngShow: "kind.value == 'ssh' && login_method == 'su'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'su_password',
autocomplete: false
},
"project": {
label: "Project",
type: 'text',
ngShow: "kind.value == 'gce'",
awRequiredWhen: {
variable: 'project_required',
init: false
},
awPopOver: "<p>The Project ID is the GCE assigned identification. It is constructed as two words followed by a three digit number. Such as: </p><p>adjective-noun-000</p>",
dataTitle: 'Project ID',
dataPlacement: 'right',
dataContainer: "body",
addRequired: false,
editRequired: false,
autocomplete: false
},
"vault_password": {
label: "Vault Password",
type: 'password',
ngShow: "kind.value == 'ssh'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('vault_password_confirm')",
ask: true,
clear: true,
associated: 'vault_password_confirm',
autocomplete: false
},
"vault_password_confirm": {
label: "Confirm Vault Password",
type: 'password',
ngShow: "kind.value == 'ssh'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'vault_password',
autocomplete: false
}
},
kind: {
label: 'Type',
excludeModal: true,
type: 'select',
ngOptions: 'kind.label for kind in credential_kind_options track by kind.value', // select as label for value in array 'kind.label for kind in credential_kind_options',
ngChange: 'kindChange()',
addRequired: true,
editRequired: true,
awPopOver:'<dl>\n' +
'<dt>Machine</dt>\n' +
'<dd>Authentication for remote machine access. This can include SSH keys, usernames, passwords, ' +
'and sudo information. Machine credentials are used when submitting jobs to run playbooks against ' +
'remote hosts.</dd>' +
'<dt>Source Control</dt>\n' +
'<dd>Used to check out and synchronize playbook repositories with a remote source control ' +
'management system such as Git, Subversion (svn), or Mercurial (hg). These credentials are ' +
'used on the Projects tab.</dd>\n' +
'<dt>Others (Cloud Providers)</dt>\n' +
'<dd>Access keys for authenticating to the specific ' +
'cloud provider, usually used for inventory sync ' +
'and deployment.</dd>\n' +
'</dl>\n',
dataTitle: 'Type',
dataPlacement: 'right',
dataContainer: "body"
// helpCollapse: [{
// hdr: 'Select a Credential Type',
// content: '<dl>\n' +
// '<dt>Machine</dt>\n' +
// '<dd>Authentication for remote machine access. This can include SSH keys, usernames, passwords, ' +
// 'and sudo information. Machine credentials are used when submitting jobs to run playbooks against ' +
// 'remote hosts.</dd>' +
// '<dt>Source Control</dt>\n' +
// '<dd>Used to check out and synchronize playbook repositories with a remote source control ' +
// 'management system such as Git, Subversion (svn), or Mercurial (hg). These credentials are ' +
// 'used on the Projects tab.</dd>\n' +
// '<dt>Others (Cloud Providers)</dt>\n' +
// '<dd>Access keys for authenticating to the specific ' +
// 'cloud provider, usually used for inventory sync ' +
// 'and deployment.</dd>\n' +
// '</dl>\n'
// }]
},
access_key: {
label: 'Access Key',
type: 'text',
ngShow: "kind.value == 'aws'",
awRequiredWhen: {
variable: "aws_required",
init: false
buttons: {
save: {
label: 'Save',
ngClick: 'formSave()', //$scope.function to call on click, optional
ngDisabled: true //Disable when $pristine or $invalid, optional
},
autocomplete: false,
apiField: 'username'
},
secret_key: {
label: 'Secret Key',
type: 'password',
ngShow: "kind.value == 'aws'",
awRequiredWhen: {
variable: "aws_required",
init: false
},
autocomplete: false,
ask: false,
clear: false,
apiField: 'passwowrd'
},
"host": {
labelBind: 'hostLabel',
type: 'text',
ngShow: "kind.value == 'vmware'",
autocomplete: false,
awRequiredWhen: {
variable: 'host_required',
init: false
reset: {
ngClick: 'formReset()',
ngDisabled: true //Disabled when $pristine
}
},
"username": {
labelBind: 'usernameLabel',
type: 'text',
ngShow: "kind.value && kind.value !== 'aws' && " +
"kind.value !== 'gce' && kind.value!=='azure'",
awRequiredWhen: {
variable: 'username_required',
init: false
},
autocomplete: false
},
"email_address": {
labelBind: 'usernameLabel',
type: 'email',
ngShow: "kind.value === 'gce'",
awRequiredWhen: {
variable: 'email_required',
init: false
},
autocomplete: false,
awPopOver: '<p>The email address assigned to the Google Compute Engine <b><i>service account.</b></i></p>',
dataTitle: 'Email',
dataPlacement: 'right',
dataContainer: "body"
},
"subscription_id": {
labelBind: "usernameLabel",
type: 'text',
ngShow: "kind.value == 'azure'",
awRequiredWhen: {
variable: 'subscription_required',
init: false
},
addRequired: false,
editRequired: false,
autocomplete: false,
awPopOver: '<p>Subscription ID is an Azure construct, which is mapped to a username.</p>',
dataTitle: 'Subscription ID',
dataPlacement: 'right',
dataContainer: "body"
},
"api_key": {
label: 'API Key',
type: 'password',
ngShow: "kind.value == 'rax'",
awRequiredWhen: {
variable: "rackspace_required",
init: false
},
autocomplete: false,
ask: false,
clear: false,
// apiField: 'passwowrd'
},
"password": {
label: 'Password',
type: 'password',
ngShow: "kind.value == 'scm' || kind.value == 'vmware'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('password_confirm')",
ask: false,
clear: false,
associated: 'password_confirm',
autocomplete: false,
awRequiredWhen: {
variable: "password_required",
init: false
}
},
"password_confirm": {
label: 'Confirm Password',
type: 'password',
ngShow: "kind.value == 'scm' || kind.value == 'vmware'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'password',
autocomplete: false,
awRequiredWhen: {
variable: "password_required",
init: false
}
},
"ssh_password": {
label: 'Password', // formally 'SSH Password'
type: 'password',
ngShow: "kind.value == 'ssh'",
ngChange: "clearPWConfirm('ssh_password_confirm')",
addRequired: false,
editRequired: false,
ask: true,
clear: true,
associated: 'ssh_password_confirm',
autocomplete: false
},
"ssh_password_confirm": {
label: 'Confirm Password', // formally 'Confirm SSH password'
type: 'password',
ngShow: "kind.value == 'ssh'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'ssh_password',
autocomplete: false
},
"ssh_key_data": {
labelBind: 'sshKeyDataLabel',
type: 'textarea',
ngShow: "kind.value == 'ssh' || kind.value == 'scm' || " +
"kind.value == 'gce' || kind.value == 'azure'",
awRequiredWhen: {
variable: 'key_required',
init: true
},
hintText: "{{ key_hint }}",
addRequired: false,
editRequired: false,
awDropFile: true,
'class': 'ssh-key-field',
rows: 10,
awPopOver: "SSH key description",
awPopOverWatch: "key_description",
dataTitle: 'Help',
dataPlacement: 'right',
dataContainer: "body"
},
"ssh_key_unlock": {
label: 'Key Password',
type: 'password',
ngShow: "kind.value == 'ssh' || kind.value == 'scm'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('ssh_key_unlock_confirm')",
associated: 'ssh_key_unlock_confirm',
ask: true,
askShow: "kind.value == 'ssh'", // Only allow ask for machine credentials
clear: true
},
"ssh_key_unlock_confirm": {
label: 'Confirm Key Password',
type: 'password',
ngShow: "kind.value == 'ssh' || kind.value == 'scm'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'ssh_key_unlock'
},
"login_method": {
label: "Login Method", // FIXME: Confirm this label is ok?
type: 'radio_group',
ngShow: "kind.value == 'ssh'",
ngChange: "loginMethodChange()",
options: [{
label: 'None', // FIXME: Maybe 'Default' or 'SSH only' instead?
value: '',
selected: true
}, {
label: 'Sudo',
value: 'sudo'
}, {
label: 'Su',
value: 'su'
}],
awPopOver: "<p>A credential may optionally provide a sudo username and password or su username and password to use when running a playbook.</p>",
dataPlacement: 'right',
dataContainer: "body"
},
"sudo_username": {
label: 'Sudo Username',
type: 'text',
ngShow: "kind.value == 'ssh' && login_method == 'sudo'",
addRequired: false,
editRequired: false,
autocomplete: false
},
"sudo_password": {
label: 'Sudo Password',
type: 'password',
ngShow: "kind.value == 'ssh' && login_method == 'sudo'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('sudo_password_confirm')",
ask: true,
clear: true,
associated: 'sudo_password_confirm',
autocomplete: false
},
"sudo_password_confirm": {
label: 'Confirm Sudo Password',
type: 'password',
ngShow: "kind.value == 'ssh' && login_method == 'sudo'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'sudo_password',
autocomplete: false
},
"su_username": {
label: 'Su Username',
type: 'text',
ngShow: "kind.value == 'ssh' && login_method == 'su'",
addRequired: false,
editRequired: false,
autocomplete: false
},
"su_password": {
label: 'Su Password',
type: 'password',
ngShow: "kind.value == 'ssh' && login_method == 'su'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('su_password_confirm')",
ask: true,
clear: true,
associated: 'su_password_confirm',
autocomplete: false
},
"su_password_confirm": {
label: 'Confirm Su Password',
type: 'password',
ngShow: "kind.value == 'ssh' && login_method == 'su'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'su_password',
autocomplete: false
},
"project": {
label: "Project",
type: 'text',
ngShow: "kind.value == 'gce'",
awRequiredWhen: {
variable: 'project_required',
init: false
},
awPopOver: "<p>The Project ID is the GCE assigned identification. It is constructed as two words followed by a three digit number. Such as: </p><p>adjective-noun-000</p>",
dataTitle: 'Project ID',
dataPlacement: 'right',
dataContainer: "body",
addRequired: false,
editRequired: false,
autocomplete: false
},
related: {}
"vault_password": {
label: "Vault Password",
type: 'password',
ngShow: "kind.value == 'ssh'",
addRequired: false,
editRequired: false,
ngChange: "clearPWConfirm('vault_password_confirm')",
ask: true,
clear: true,
associated: 'vault_password_confirm',
autocomplete: false
},
"vault_password_confirm": {
label: "Confirm Vault Password",
type: 'password',
ngShow: "kind.value == 'ssh'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'vault_password',
autocomplete: false
}
},
buttons: {
save: {
label: '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
}
},
related: {}
});
});
+59 -57
View File
@@ -11,68 +11,70 @@
* @name forms.function:Organizations
* @description This form is for adding/editing an organization
*/
angular.module('CustomInventoryFormDefinition', [])
.value('CustomInventoryForm', {
addTitle: 'Create Custom Inventory', //Title in add mode
editTitle: '{{ name }}', //Title in edit mode
name: 'custom_inventory', //entity or model name in singular form
well: false,
showActions: false,
export default
angular.module('CustomInventoryFormDefinition', [])
.value('CustomInventoryForm', {
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
organization: {
label: 'Organization',
type: 'lookup',
awRequiredWhen: {
variable: "orgrequired",
init: true
addTitle: 'Create Custom Inventory', //Title in add mode
editTitle: '{{ name }}', //Title in edit mode
name: 'custom_inventory', //entity or model name in singular form
well: false,
showActions: false,
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
organization: {
label: 'Organization',
type: 'lookup',
awRequiredWhen: {
variable: "orgrequired",
init: true
},
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()'
},
script: {
label: 'Custom Script',
type: 'textarea',
hintText: "Drag and drop an inventory script on the field below",
addRequired: true,
editRequired: true,
awDropFile: true,
'class': 'ssh-key-field',
rows: 10,
awPopOver: "<p>Drag and drop your custom inventory script file here or create one in the field to import your custom inventory. " +
"<br><br> Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python</p>",
dataTitle: 'Custom Script',
dataPlacement: 'right',
dataContainer: "body"
},
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()'
},
script: {
label: 'Custom Script',
type: 'textarea',
hintText: "Drag and drop an inventory script on the field below",
addRequired: true,
editRequired: true,
awDropFile: true,
'class': 'ssh-key-field',
rows: 10,
awPopOver: "<p>Drag and drop your custom inventory script file here or create one in the field to import your custom inventory. " +
"<br><br> Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python</p>",
dataTitle: 'Custom Script',
dataPlacement: 'right',
dataContainer: "body"
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
}
},
},
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
}
},
}); //OrganizationForm
}); //OrganizationForm
+71 -69
View File
@@ -9,74 +9,76 @@
* @name forms.function:EventsViewer
* @description This form is for events on the job detail page
*/
angular.module('EventsViewerFormDefinition', [])
.value('EventsViewerForm', {
fields: {
host_name: {
label: 'Host',
section: 'Event'
},
status: {
label: 'Status',
section: 'Event'
},
id: {
label: 'ID',
section: 'Event'
},
created: {
label: 'Created On',
section: 'Event'
},
role: {
label: 'Role',
section: 'Event'
},
play: {
label: 'Play',
type: 'text',
section: 'Event'
},
task: {
label: 'Task',
section: 'Event'
},
item: {
label: 'Item',
section: 'Event'
},
module_name: {
label: 'Module',
section: 'Event'
},
module_args: {
label: 'Arguments',
section: 'Event'
},
rc: {
label: 'Return Code',
section: 'Results'
},
msg: {
label: 'Message',
section: 'Results'
},
results: {
label: 'Results',
section: 'Results'
},
start: {
label: 'Start',
section: 'Timing'
},
end: {
label: 'End',
section: 'Timing'
},
delta: {
label: 'Elapsed',
section: 'Timing'
export default
angular.module('EventsViewerFormDefinition', [])
.value('EventsViewerForm', {
fields: {
host_name: {
label: 'Host',
section: 'Event'
},
status: {
label: 'Status',
section: 'Event'
},
id: {
label: 'ID',
section: 'Event'
},
created: {
label: 'Created On',
section: 'Event'
},
role: {
label: 'Role',
section: 'Event'
},
play: {
label: 'Play',
type: 'text',
section: 'Event'
},
task: {
label: 'Task',
section: 'Event'
},
item: {
label: 'Item',
section: 'Event'
},
module_name: {
label: 'Module',
section: 'Event'
},
module_args: {
label: 'Arguments',
section: 'Event'
},
rc: {
label: 'Return Code',
section: 'Results'
},
msg: {
label: 'Message',
section: 'Results'
},
results: {
label: 'Results',
section: 'Results'
},
start: {
label: 'Start',
section: 'Timing'
},
end: {
label: 'End',
section: 'Timing'
},
delta: {
label: 'Elapsed',
section: 'Timing'
}
}
}
});
});
+49 -47
View File
@@ -11,56 +11,58 @@
* @name forms.function:Groups
* @description This form is for adding/editing a Group on the inventory page
*/
angular.module('GroupFormDefinition', [])
.value('GroupForm', {
addTitle: 'Create Group',
editTitle: 'Edit Group',
showTitle: true,
cancelButton: false,
name: 'group',
well: false,
export default
angular.module('GroupFormDefinition', [])
.value('GroupForm', {
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
tab: 'properties'
addTitle: 'Create Group',
editTitle: 'Edit Group',
showTitle: true,
cancelButton: false,
name: 'group',
well: false,
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
tab: 'properties'
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false,
tab: 'properties'
},
variables: {
label: 'Variables',
type: 'textarea',
addRequired: false,
editRequird: false,
rows: 12,
'default': '---',
dataTitle: 'Group Variables',
dataPlacement: 'right',
awPopOver: "<p>Variables defined here apply to all child groups and hosts.</p>" +
"<p>Enter 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>',
dataContainer: 'body',
tab: 'properties'
}
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false,
tab: 'properties'
},
variables: {
label: 'Variables',
type: 'textarea',
addRequired: false,
editRequird: false,
rows: 12,
'default': '---',
dataTitle: 'Group Variables',
dataPlacement: 'right',
awPopOver: "<p>Variables defined here apply to all child groups and hosts.</p>" +
"<p>Enter 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>',
dataContainer: 'body',
tab: 'properties'
}
},
buttons: { },
buttons: { },
related: { }
related: { }
});
});
+39 -37
View File
@@ -11,47 +11,49 @@
* @name forms.function:HostGroups
* @description This form is for groups of hosts on the inventory page
*/
angular.module('HostGroupsFormDefinition', [])
.value('HostGroupsForm', {
editTitle: 'Host Groups',
name: 'host',
well: false,
formLabelSize: 'col-lg-3',
formFieldSize: 'col-lg-9',
export default
angular.module('HostGroupsFormDefinition', [])
.value('HostGroupsForm', {
fields: {
groups: {
label: 'Groups',
type: 'select',
multiple: true,
ngOptions: 'group.name for group in inventory_groups track by group.value',
addRequired: true,
editRequired: true,
awPopOver: "<p>Provide a host name, ip address, or ip address:port. Examples include:</p>" +
"<blockquote>myserver.domain.com<br/>" +
"127.0.0.1<br />" +
"10.1.0.140:25<br />" +
"server.example.com:25" +
"</blockquote>",
dataTitle: 'Host Name',
dataPlacement: 'right',
dataContainer: '#form-modal .modal-content'
}
},
editTitle: 'Host Groups',
name: 'host',
well: false,
formLabelSize: 'col-lg-3',
formFieldSize: 'col-lg-9',
buttons: { //for now always generates <button> tags
save: {
ngClick: 'formSave()',
ngDisabled: true
fields: {
groups: {
label: 'Groups',
type: 'select',
multiple: true,
ngOptions: 'group.name for group in inventory_groups track by group.value',
addRequired: true,
editRequired: true,
awPopOver: "<p>Provide a host name, ip address, or ip address:port. Examples include:</p>" +
"<blockquote>myserver.domain.com<br/>" +
"127.0.0.1<br />" +
"10.1.0.140:25<br />" +
"server.example.com:25" +
"</blockquote>",
dataTitle: 'Host Name',
dataPlacement: 'right',
dataContainer: '#form-modal .modal-content'
}
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
related: { }
buttons: { //for now always generates <button> tags
save: {
ngClick: 'formSave()',
ngDisabled: true
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
}); //UserForm
related: { }
}); //UserForm
+83 -81
View File
@@ -11,90 +11,92 @@
* @name forms.function:Hosts
* @description This form is for adding/editing a host on the inventory page
*/
angular.module('HostFormDefinition', [])
.value('HostForm', {
addTitle: 'Create Host',
editTitle: '{{ name }}',
name: 'host',
well: false,
formLabelSize: 'col-lg-3',
formFieldSize: 'col-lg-9',
export default
angular.module('HostFormDefinition', [])
.value('HostForm', {
fields: {
name: {
label: 'Host Name',
type: 'text',
addRequired: true,
editRequired: true,
awPopOver: "<p>Provide a host name, ip address, or ip address:port. Examples include:</p>" +
"<blockquote>myserver.domain.com<br/>" +
"127.0.0.1<br />" +
"10.1.0.140:25<br />" +
"server.example.com:25" +
"</blockquote>",
dataTitle: 'Host Name',
dataPlacement: 'right',
dataContainer: 'body'
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
enabled: {
label: 'Enabled?',
type: 'checkbox',
addRequired: false,
editRequired: false,
"default": true,
awPopOver: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that " +
"are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>",
dataTitle: 'Host Enabled',
dataPlacement: 'right',
dataContainer: 'body',
ngDisabled: 'has_inventory_sources == true'
},
variables: {
label: 'Variables',
type: 'textarea',
addRequired: false,
editRequird: false,
rows: 6,
"class": "modal-input-xlarge",
"default": "---",
awPopOver: "<p>Enter 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: 'Host Variables',
dataPlacement: 'right',
dataContainer: 'body'
},
inventory: {
type: 'hidden',
includeOnEdit: true,
includeOnAdd: true
}
},
addTitle: 'Create Host',
editTitle: '{{ name }}',
name: 'host',
well: false,
formLabelSize: 'col-lg-3',
formFieldSize: 'col-lg-9',
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
fields: {
name: {
label: 'Host Name',
type: 'text',
addRequired: true,
editRequired: true,
awPopOver: "<p>Provide a host name, ip address, or ip address:port. Examples include:</p>" +
"<blockquote>myserver.domain.com<br/>" +
"127.0.0.1<br />" +
"10.1.0.140:25<br />" +
"server.example.com:25" +
"</blockquote>",
dataTitle: 'Host Name',
dataPlacement: 'right',
dataContainer: 'body'
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
enabled: {
label: 'Enabled?',
type: 'checkbox',
addRequired: false,
editRequired: false,
"default": true,
awPopOver: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that " +
"are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>",
dataTitle: 'Host Enabled',
dataPlacement: 'right',
dataContainer: 'body',
ngDisabled: 'has_inventory_sources == true'
},
variables: {
label: 'Variables',
type: 'textarea',
addRequired: false,
editRequird: false,
rows: 6,
"class": "modal-input-xlarge",
"default": "---",
awPopOver: "<p>Enter 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: 'Host Variables',
dataPlacement: 'right',
dataContainer: 'body'
},
inventory: {
type: 'hidden',
includeOnEdit: true,
includeOnAdd: true
}
},
reset: {
ngClick: 'formReset()',
ngDisabled: true //Disabled when $pristine
}
*/
},
related: {}
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
}
*/
},
});
related: {}
});
+77 -75
View File
@@ -11,87 +11,89 @@
* @name forms.function:Inventories
* @description This form is for adding/editing an inventory
*/
angular.module('InventoryFormDefinition', [])
.value('InventoryForm', {
addTitle: 'Create Inventory',
editTitle: '{{ inventory_name }}',
name: 'inventory',
well: true,
export default
angular.module('InventoryFormDefinition', [])
.value('InventoryForm', {
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'
}
},
addTitle: 'Create Inventory',
editTitle: '{{ inventory_name }}',
name: 'inventory',
well: true,
fields: {
inventory_name: {
realName: 'name',
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
inventory_description: {
realName: 'description',
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
organization: {
label: 'Organization',
type: 'lookup',
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()',
awRequiredWhen: {
variable: "organizationrequired",
init: "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'
}
},
variables: {
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: {
save: {
ngClick: 'formSave()',
ngDisabled: true
fields: {
inventory_name: {
realName: 'name',
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
inventory_description: {
realName: 'description',
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
organization: {
label: 'Organization',
type: 'lookup',
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()',
awRequiredWhen: {
variable: "organizationrequired",
init: "true"
}
},
variables: {
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'
}
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
buttons: {
save: {
ngClick: 'formSave()',
ngDisabled: true
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
related: {
}
},
related: {
}
});
});
+46 -45
View File
@@ -11,51 +11,52 @@
* @name forms.function:InventoryStatus
* @description This form is for adding/editing an InventoryStatus
*/
angular.module('InventoryStatusDefinition', [])
.value('InventoryStatusForm', {
export default
angular.module('InventoryStatusDefinition', [])
.value('InventoryStatusForm', {
name: 'inventory_update',
editTitle: 'Inventory Status',
well: false,
'class': 'horizontal-narrow',
name: 'inventory_update',
editTitle: 'Inventory Status',
well: false,
'class': 'horizontal-narrow',
fields: {
license_error: {
type: 'alertblock',
'class': 'alert-info',
alertTxt: 'The invenvtory update process exceeded the available number of licensed hosts. ' +
'<strong><a ng-click=\"viewLicense()\" href=\"\">View your license</a></strong> ' +
'for more information.',
ngShow: 'license_error',
closeable: true
},
created: {
label: 'Created',
type: 'text',
readonly: true
},
status: {
label: 'Status',
type: 'text',
readonly: true,
'class': 'nowrap mono-space resizable',
rows: '{{ status_rows }}'
},
result_stdout: {
label: 'Std Out',
type: 'textarea',
ngShow: 'result_stdout',
'class': 'nowrap mono-space resizable',
readonly: true,
rows: '{{ stdout_rows }}'
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
ngShow: 'result_traceback',
'class': 'nowrap mono-space resizable',
readonly: true,
rows: '{{ traceback_rows }}'
fields: {
license_error: {
type: 'alertblock',
'class': 'alert-info',
alertTxt: 'The invenvtory update process exceeded the available number of licensed hosts. ' +
'<strong><a ng-click=\"viewLicense()\" href=\"\">View your license</a></strong> ' +
'for more information.',
ngShow: 'license_error',
closeable: true
},
created: {
label: 'Created',
type: 'text',
readonly: true
},
status: {
label: 'Status',
type: 'text',
readonly: true,
'class': 'nowrap mono-space resizable',
rows: '{{ status_rows }}'
},
result_stdout: {
label: 'Std Out',
type: 'textarea',
ngShow: 'result_stdout',
'class': 'nowrap mono-space resizable',
readonly: true,
rows: '{{ stdout_rows }}'
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
ngShow: 'result_traceback',
'class': 'nowrap mono-space resizable',
readonly: true,
rows: '{{ traceback_rows }}'
}
}
}
}); //Form
}); //Form
+17 -15
View File
@@ -11,22 +11,24 @@
* @name forms.function:JobEventData
* @description Not sure if this is used...
*/
angular.module('JobEventDataDefinition', [])
.value('JobEventDataForm', {
editTitle: '{{ id }} - {{ event_display }}',
name: 'job_events',
well: false,
'class': 'horizontal-narrow',
export default
angular.module('JobEventDataDefinition', [])
.value('JobEventDataForm', {
fields: {
event_data: {
label: false,
type: 'textarea',
readonly: true,
rows: 18,
'class': 'modal-input-xxlarge'
editTitle: '{{ id }} - {{ event_display }}',
name: 'job_events',
well: false,
'class': 'horizontal-narrow',
fields: {
event_data: {
label: false,
type: 'textarea',
readonly: true,
rows: 18,
'class': 'modal-input-xxlarge'
}
}
}
}); //Form
}); //Form
+38 -37
View File
@@ -12,43 +12,44 @@
* @description Display job status info in a dialog
*/
angular.module('JobSummaryDefinition', [])
.value('JobSummary', {
export default
angular.module('JobSummaryDefinition', [])
.value('JobSummary', {
editTitle: '{{ id }} - {{ name }}',
name: 'jobs',
well: false,
editTitle: '{{ id }} - {{ name }}',
name: 'jobs',
well: false,
fields: {
status: {
//label: 'Job Status',
type: 'custom',
control: '<div class=\"job-detail-status\"><span style="padding-right: 15px; font-weight: bold;">Status</span> ' +
'<i class=\"fa icon-job-{{ status }}\"></i> {{ status }}</div>',
readonly: true
},
created: {
label: 'Created On',
type: 'text',
readonly: true
},
result_stdout: {
label: 'Standard Out',
type: 'textarea',
readonly: true,
xtraWide: true,
rows: '{{ stdout_rows }}',
'class': 'nowrap mono-space resizable',
ngShow: 'result_stdout != ""'
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
xtraWide: true,
readonly: true,
rows: '{{ traceback_rows }}',
'class': 'nowrap mono-space resizable',
ngShow: 'result_traceback != ""'
fields: {
status: {
//label: 'Job Status',
type: 'custom',
control: '<div class=\"job-detail-status\"><span style="padding-right: 15px; font-weight: bold;">Status</span> ' +
'<i class=\"fa icon-job-{{ status }}\"></i> {{ status }}</div>',
readonly: true
},
created: {
label: 'Created On',
type: 'text',
readonly: true
},
result_stdout: {
label: 'Standard Out',
type: 'textarea',
readonly: true,
xtraWide: true,
rows: '{{ stdout_rows }}',
'class': 'nowrap mono-space resizable',
ngShow: 'result_stdout != ""'
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
xtraWide: true,
readonly: true,
rows: '{{ traceback_rows }}',
'class': 'nowrap mono-space resizable',
ngShow: 'result_traceback != ""'
}
}
}
});
});
+362 -362
View File
@@ -13,375 +13,375 @@
* @description This form is for adding/editing a Job Template
*/
export default
angular.module('JobTemplateFormDefinition', ['SchedulesListDefinition', 'CompletedJobsDefinition'])
angular.module('JobTemplateFormDefinition', ['SchedulesListDefinition', 'CompletedJobsDefinition'])
.value ('JobTemplateFormObject', {
.value ('JobTemplateFormObject', {
addTitle: 'Create Job Templates',
editTitle: '{{ name }}',
name: 'job_templates',
twoColumns: true,
well: true,
base: 'job_templates',
collapse: true,
collapseTitle: "Properties",
collapseMode: 'edit',
collapseOpenFirst: true, //Always open first panel
addTitle: 'Create Job Templates',
editTitle: '{{ name }}',
name: 'job_templates',
twoColumns: true,
well: true,
base: 'job_templates',
collapse: true,
collapseTitle: "Properties",
collapseMode: 'edit',
collapseOpenFirst: true, //Always open first panel
actions: {
// submit: {
// ngClick: 'launch()',
// awToolTip: 'Start a job using this template',
// dataPlacement: 'top',
// mode: 'edit'
// },
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
dataPlacement: "top",
icon: "icon-comments-alt",
mode: 'edit',
iconSize: 'large'
}
},
actions: {
// submit: {
// ngClick: 'launch()',
// awToolTip: 'Start a job using this template',
// dataPlacement: 'top',
// mode: 'edit'
// },
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: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
column: 1
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false,
column: 1
},
job_type: {
label: 'Job Type',
type: 'select',
ngOptions: 'type.label for type in job_type_options track by type.value',
"default": 0,
addRequired: true,
editRequired: true,
column: 1,
awPopOver: "<p>When this template is submitted as a job, setting the type to <em>run</em> will execute the playbook, running tasks " +
" on the selected hosts.</p> <p>Setting the type to <em>check</em> will not execute the playbook. Instead, ansible will check playbook " +
" syntax, test environment setup and report problems.</p>",
dataTitle: 'Job Type',
dataPlacement: 'right',
dataContainer: "body"
},
inventory: {
label: 'Inventory',
type: 'lookup',
sourceModel: 'inventory',
sourceField: 'name',
ngClick: 'lookUpInventory()',
awRequiredWhen: {variable: "inventoryrequired", init: "true" },
column: 1,
awPopOver: "<p>Select the inventory containing the hosts you want this job to manage.</p>",
dataTitle: 'Inventory',
dataPlacement: 'right',
dataContainer: "body"
},
project: {
label: 'Project',
type: 'lookup',
sourceModel: 'project',
sourceField: 'name',
ngClick: 'lookUpProject()',
awRequiredWhen: {variable: "projectrequired", init: "true" },
column: 1,
awPopOver: "<p>Select the project containing the playbook you want this job to execute.</p>",
dataTitle: 'Project',
dataPlacement: 'right',
dataContainer: "body"
},
playbook: {
label: 'Playbook',
type:'select',
ngOptions: 'book for book in playbook_options track by book',
id: 'playbook-select',
awRequiredWhen: {variable: "playbookrequired", init: "true" },
column: 1,
awPopOver: "<p>Select the playbook to be executed by this job.</p>",
dataTitle: 'Playbook',
dataPlacement: 'right',
dataContainer: "body"
},
credential: {
label: 'Machine Credential',
type: 'lookup',
sourceModel: 'credential',
sourceField: 'name',
ngClick: 'lookUpCredential()',
addRequired: false,
editRequired: false,
column: 1,
awPopOver: "<p>Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing " +
" the username and SSH key or password that Ansbile will need to log into the remote hosts.</p>",
dataTitle: 'Credential',
dataPlacement: 'right',
dataContainer: "body"
},
cloud_credential: {
label: 'Cloud Credential',
type: 'lookup',
sourceModel: 'cloud_credential',
sourceField: 'name',
ngClick: 'lookUpCloudcredential()',
addRequired: false,
editRequired: false,
column: 1,
awPopOver: "<p>Selecting an optional cloud credential in the job template will pass along the access credentials to the " +
"running playbook, allowing provisioning into the cloud without manually passing parameters to the included modules.</p>",
dataTitle: 'Cloud Credential',
dataPlacement: 'right',
dataContainer: "body"
},
forks: {
label: 'Forks',
id: 'forks-number',
type: 'number',
integer: true,
min: 0,
spinner: true,
"default": '0',
addRequired: false,
editRequired: false,
'class': "input-small",
column: 1,
awPopOver: '<p>The number of parallel or simultaneous processes to use while executing the playbook. 0 signifies ' +
'the default value from the <a href=\"http://docs.ansible.com/intro_configuration.html#the-ansible-configuration-file\" ' +
' target=\"_blank\">ansible configuration file</a>.</p>',
dataTitle: 'Forks',
dataPlacement: 'right',
dataContainer: "body"
},
limit: {
label: 'Limit',
type: 'text',
addRequired: false,
editRequired: false,
column: 1,
awPopOver: "<p>Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. " +
"Multiple patterns can be separated by &#59; &#58; or &#44;</p><p>For more information and examples see " +
"<a href=\"http://docs.ansible.com/intro_patterns.html\" target=\"_blank\">the Patterns topic at docs.ansible.com</a>.</p>",
dataTitle: 'Limit',
dataPlacement: 'right',
dataContainer: "body"
},
verbosity: {
label: 'Verbosity',
type: 'select',
ngOptions: 'v.label for v in verbosity_options track by v.value',
"default": 0,
addRequired: true,
editRequired: true,
column: 1,
awPopOver: "<p>Control the level of output ansible will produce as the playbook executes.</p>",
dataTitle: 'Verbosity',
dataPlacement: 'right',
dataContainer: "body"
},
job_tags: {
label: 'Job Tags',
type: 'textarea',
rows: 1,
addRequired: false,
editRequired: false,
'class': 'span12',
column: 2,
awPopOver: "<p>Provide a comma separated list of tags.</p>\n" +
"<p>Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.</p>" +
"<p>For example, you might have a task consisiting of a long list of actions. Tag values can be assigned to each action. " +
"Suppose the actions have been assigned tag values of &quot;configuration&quot;, &quot;packages&quot; and &quot;install&quot;.</p>" +
"<p>If you just want to run the &quot;configuration&quot; and &quot;packages&quot; actions, you would enter the following here " +
"in the Job Tags field:</p>\n<blockquote>configuration,packages</blockquote>\n",
dataTitle: "Job Tags",
dataPlacement: "right",
dataContainer: "body"
},
variables: {
label: 'Extra Variables',
type: 'textarea',
rows: 6,
"class": 'span12',
addRequired: false,
editRequired: false,
"default": "---",
column: 2,
awPopOver: "<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter " +
"for ansible-playbook. Provide key/value pairs using either YAML or JSON.</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",
dataTitle: 'Extra Variables',
dataPlacement: 'right',
dataContainer: "body"
},
ask_variables_on_launch: {
label: 'Prompt for Extra Variables',
type: 'checkbox',
addRequired: false,
editRequird: false,
trueValue: 'true',
falseValue: 'false',
column: 2,
awPopOver: "<p>If checked, user will be prompted at job launch with a dialog allowing override of the extra variables setting.</p>",
dataPlacement: 'right',
dataTitle: 'Prompt for Extra Variables',
dataContainer: "body"
},
// survey_enabled: {
// type: 'custom',
// column: 2,
// control: '<div class="form-group">'+
// '<div class="checkbox">'+
// '<label><input type="checkbox" ng-model="survey_enabled" name="survey_enabled" id="job_templates_survey_enabled_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-survey_enabled" 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=&quot;popover-footer&quot;><span class=&quot;key&quot;>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-survey_enabled-api-error" ng-bind="survey_enabled_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> Create Survey</button>'+
// '</div>'+
// '</div>'
// },
survey_enabled: {
label: 'Enable Survey',
type: 'checkbox',
addRequired: false,
editRequird: false,
// trueValue: true,
// falseValue: false,
ngChange: "surveyEnabled()",
column: 2,
awPopOver: "<p>If checked, user will be prompted at job launch with a series of questions related to the job.</p>",
dataPlacement: 'right',
dataTitle: 'Enable Survey',
dataContainer: "body"
},
create_survey: {
type: 'custom',
column: 2,
control: '<button type="button" class="btn btn-sm btn-primary" id="job_templates_create_survey_btn" ng-show="survey_enabled" ng-click="addSurvey()"><i class="fa fa-pencil"></i> Create Survey</button>'+
'<button style="display:none;" type="button" class="btn btn-sm btn-primary" id="job_templates_edit_survey_btn" ng-show="survey_enabled" ng-click="editSurvey()"><i class="fa fa-pencil"></i> Edit Survey</button>'+
'<button style="display:none;margin-left:5px" type="button" class="btn btn-sm btn-primary" id="job_templates_delete_survey_btn" ng-show="survey_enabled" ng-click="deleteSurvey()"><i class="fa fa-trash-o"></i> Delete Survey</button>'
// label: 'Create Survey',
// type: 'text',
// addRequired: false,
// editRequired: false,
// // readonly: true,
// // ngShow: "survey_enabled",
// column: 2,
// awPopOver: "survey_help",
// awPopOverWatch: "survey_help",
// dataPlacement: 'right',
// dataTitle: 'Provisioning Callback URL',
// dataContainer: "body"
},
allow_callbacks: {
label: 'Allow Provisioning Callbacks',
type: 'checkbox',
addRequired: false,
editRequird: false,
trueValue: 'true',
falseValue: 'false',
ngChange: "toggleCallback('host_config_key')",
column: 2,
awPopOver: "<p>Enables creation of a provisioning callback URL. Using the URL a host can contact Tower and request a configuration update " +
"using this job template.</p>",
dataPlacement: 'right',
dataTitle: 'Allow Provisioning Callbacks',
dataContainer: "body"
},
callback_url: {
label: 'Provisioning Callback URL',
type: 'text',
addRequired: false,
editRequired: false,
readonly: true,
ngShow: "allow_callbacks",
column: 2,
awPopOver: "callback_help",
awPopOverWatch: "callback_help",
dataPlacement: 'right',
dataTitle: 'Provisioning Callback URL',
dataContainer: "body"
},
host_config_key: {
label: 'Host Config Key',
type: 'text',
ngShow: "allow_callbacks",
ngChange: "configKeyChange()",
genMD5: true,
column: 2,
awPopOver: "callback_help",
awPopOverWatch: "callback_help",
dataPlacement: 'right',
dataTitle: "Host Config Key",
dataContainer: "body"
}
},
buttons: { //for now always generates <button> tags
save: {
ngClick: 'formSave()', //$scope.function to call on click, optional
ngDisabled: "job_templates_form.$invalid || can_edit!==true"//true //Disable when $pristine or $invalid, optional and when can_edit = false, for permission reasons
},
reset: {
ngClick: 'formReset()',
ngDisabled: true //Disabled when $pristine
}
},
related: {
schedules: {
include: "SchedulesList"
},
"completed_jobs": {
include: "CompletedJobsList"
}
},
relatedSets: function(urls) {
return {
completed_jobs: {
iterator: 'completed_job',
url: urls.jobs + '?or__status=successful&or__status=failed&or__status=error&or__status=canceled'
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
column: 1
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false,
column: 1
},
job_type: {
label: 'Job Type',
type: 'select',
ngOptions: 'type.label for type in job_type_options track by type.value',
"default": 0,
addRequired: true,
editRequired: true,
column: 1,
awPopOver: "<p>When this template is submitted as a job, setting the type to <em>run</em> will execute the playbook, running tasks " +
" on the selected hosts.</p> <p>Setting the type to <em>check</em> will not execute the playbook. Instead, ansible will check playbook " +
" syntax, test environment setup and report problems.</p>",
dataTitle: 'Job Type',
dataPlacement: 'right',
dataContainer: "body"
},
inventory: {
label: 'Inventory',
type: 'lookup',
sourceModel: 'inventory',
sourceField: 'name',
ngClick: 'lookUpInventory()',
awRequiredWhen: {variable: "inventoryrequired", init: "true" },
column: 1,
awPopOver: "<p>Select the inventory containing the hosts you want this job to manage.</p>",
dataTitle: 'Inventory',
dataPlacement: 'right',
dataContainer: "body"
},
project: {
label: 'Project',
type: 'lookup',
sourceModel: 'project',
sourceField: 'name',
ngClick: 'lookUpProject()',
awRequiredWhen: {variable: "projectrequired", init: "true" },
column: 1,
awPopOver: "<p>Select the project containing the playbook you want this job to execute.</p>",
dataTitle: 'Project',
dataPlacement: 'right',
dataContainer: "body"
},
playbook: {
label: 'Playbook',
type:'select',
ngOptions: 'book for book in playbook_options track by book',
id: 'playbook-select',
awRequiredWhen: {variable: "playbookrequired", init: "true" },
column: 1,
awPopOver: "<p>Select the playbook to be executed by this job.</p>",
dataTitle: 'Playbook',
dataPlacement: 'right',
dataContainer: "body"
},
credential: {
label: 'Machine Credential',
type: 'lookup',
sourceModel: 'credential',
sourceField: 'name',
ngClick: 'lookUpCredential()',
addRequired: false,
editRequired: false,
column: 1,
awPopOver: "<p>Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing " +
" the username and SSH key or password that Ansbile will need to log into the remote hosts.</p>",
dataTitle: 'Credential',
dataPlacement: 'right',
dataContainer: "body"
},
cloud_credential: {
label: 'Cloud Credential',
type: 'lookup',
sourceModel: 'cloud_credential',
sourceField: 'name',
ngClick: 'lookUpCloudcredential()',
addRequired: false,
editRequired: false,
column: 1,
awPopOver: "<p>Selecting an optional cloud credential in the job template will pass along the access credentials to the " +
"running playbook, allowing provisioning into the cloud without manually passing parameters to the included modules.</p>",
dataTitle: 'Cloud Credential',
dataPlacement: 'right',
dataContainer: "body"
},
forks: {
label: 'Forks',
id: 'forks-number',
type: 'number',
integer: true,
min: 0,
spinner: true,
"default": '0',
addRequired: false,
editRequired: false,
'class': "input-small",
column: 1,
awPopOver: '<p>The number of parallel or simultaneous processes to use while executing the playbook. 0 signifies ' +
'the default value from the <a href=\"http://docs.ansible.com/intro_configuration.html#the-ansible-configuration-file\" ' +
' target=\"_blank\">ansible configuration file</a>.</p>',
dataTitle: 'Forks',
dataPlacement: 'right',
dataContainer: "body"
},
limit: {
label: 'Limit',
type: 'text',
addRequired: false,
editRequired: false,
column: 1,
awPopOver: "<p>Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. " +
"Multiple patterns can be separated by &#59; &#58; or &#44;</p><p>For more information and examples see " +
"<a href=\"http://docs.ansible.com/intro_patterns.html\" target=\"_blank\">the Patterns topic at docs.ansible.com</a>.</p>",
dataTitle: 'Limit',
dataPlacement: 'right',
dataContainer: "body"
},
verbosity: {
label: 'Verbosity',
type: 'select',
ngOptions: 'v.label for v in verbosity_options track by v.value',
"default": 0,
addRequired: true,
editRequired: true,
column: 1,
awPopOver: "<p>Control the level of output ansible will produce as the playbook executes.</p>",
dataTitle: 'Verbosity',
dataPlacement: 'right',
dataContainer: "body"
},
job_tags: {
label: 'Job Tags',
type: 'textarea',
rows: 1,
addRequired: false,
editRequired: false,
'class': 'span12',
column: 2,
awPopOver: "<p>Provide a comma separated list of tags.</p>\n" +
"<p>Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.</p>" +
"<p>For example, you might have a task consisiting of a long list of actions. Tag values can be assigned to each action. " +
"Suppose the actions have been assigned tag values of &quot;configuration&quot;, &quot;packages&quot; and &quot;install&quot;.</p>" +
"<p>If you just want to run the &quot;configuration&quot; and &quot;packages&quot; actions, you would enter the following here " +
"in the Job Tags field:</p>\n<blockquote>configuration,packages</blockquote>\n",
dataTitle: "Job Tags",
dataPlacement: "right",
dataContainer: "body"
},
variables: {
label: 'Extra Variables',
type: 'textarea',
rows: 6,
"class": 'span12',
addRequired: false,
editRequired: false,
"default": "---",
column: 2,
awPopOver: "<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter " +
"for ansible-playbook. Provide key/value pairs using either YAML or JSON.</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",
dataTitle: 'Extra Variables',
dataPlacement: 'right',
dataContainer: "body"
},
ask_variables_on_launch: {
label: 'Prompt for Extra Variables',
type: 'checkbox',
addRequired: false,
editRequird: false,
trueValue: 'true',
falseValue: 'false',
column: 2,
awPopOver: "<p>If checked, user will be prompted at job launch with a dialog allowing override of the extra variables setting.</p>",
dataPlacement: 'right',
dataTitle: 'Prompt for Extra Variables',
dataContainer: "body"
},
// survey_enabled: {
// type: 'custom',
// column: 2,
// control: '<div class="form-group">'+
// '<div class="checkbox">'+
// '<label><input type="checkbox" ng-model="survey_enabled" name="survey_enabled" id="job_templates_survey_enabled_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-survey_enabled" 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=&quot;popover-footer&quot;><span class=&quot;key&quot;>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-survey_enabled-api-error" ng-bind="survey_enabled_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> Create Survey</button>'+
// '</div>'+
// '</div>'
// },
survey_enabled: {
label: 'Enable Survey',
type: 'checkbox',
addRequired: false,
editRequird: false,
// trueValue: true,
// falseValue: false,
ngChange: "surveyEnabled()",
column: 2,
awPopOver: "<p>If checked, user will be prompted at job launch with a series of questions related to the job.</p>",
dataPlacement: 'right',
dataTitle: 'Enable Survey',
dataContainer: "body"
},
create_survey: {
type: 'custom',
column: 2,
control: '<button type="button" class="btn btn-sm btn-primary" id="job_templates_create_survey_btn" ng-show="survey_enabled" ng-click="addSurvey()"><i class="fa fa-pencil"></i> Create Survey</button>'+
'<button style="display:none;" type="button" class="btn btn-sm btn-primary" id="job_templates_edit_survey_btn" ng-show="survey_enabled" ng-click="editSurvey()"><i class="fa fa-pencil"></i> Edit Survey</button>'+
'<button style="display:none;margin-left:5px" type="button" class="btn btn-sm btn-primary" id="job_templates_delete_survey_btn" ng-show="survey_enabled" ng-click="deleteSurvey()"><i class="fa fa-trash-o"></i> Delete Survey</button>'
// label: 'Create Survey',
// type: 'text',
// addRequired: false,
// editRequired: false,
// // readonly: true,
// // ngShow: "survey_enabled",
// column: 2,
// awPopOver: "survey_help",
// awPopOverWatch: "survey_help",
// dataPlacement: 'right',
// dataTitle: 'Provisioning Callback URL',
// dataContainer: "body"
},
allow_callbacks: {
label: 'Allow Provisioning Callbacks',
type: 'checkbox',
addRequired: false,
editRequird: false,
trueValue: 'true',
falseValue: 'false',
ngChange: "toggleCallback('host_config_key')",
column: 2,
awPopOver: "<p>Enables creation of a provisioning callback URL. Using the URL a host can contact Tower and request a configuration update " +
"using this job template.</p>",
dataPlacement: 'right',
dataTitle: 'Allow Provisioning Callbacks',
dataContainer: "body"
},
callback_url: {
label: 'Provisioning Callback URL',
type: 'text',
addRequired: false,
editRequired: false,
readonly: true,
ngShow: "allow_callbacks",
column: 2,
awPopOver: "callback_help",
awPopOverWatch: "callback_help",
dataPlacement: 'right',
dataTitle: 'Provisioning Callback URL',
dataContainer: "body"
},
host_config_key: {
label: 'Host Config Key',
type: 'text',
ngShow: "allow_callbacks",
ngChange: "configKeyChange()",
genMD5: true,
column: 2,
awPopOver: "callback_help",
awPopOverWatch: "callback_help",
dataPlacement: 'right',
dataTitle: "Host Config Key",
dataContainer: "body"
}
},
buttons: { //for now always generates <button> tags
save: {
ngClick: 'formSave()', //$scope.function to call on click, optional
ngDisabled: "job_templates_form.$invalid || can_edit!==true"//true //Disable when $pristine or $invalid, optional and when can_edit = false, for permission reasons
},
reset: {
ngClick: 'formReset()',
ngDisabled: true //Disabled when $pristine
}
},
related: {
schedules: {
iterator: 'schedule',
url: urls.schedules
include: "SchedulesList"
},
"completed_jobs": {
include: "CompletedJobsList"
}
};
}
})
},
.factory('JobTemplateForm', ['JobTemplateFormObject', 'SchedulesList', 'CompletedJobsList',
function(JobTemplateFormObject, SchedulesList, CompletedJobsList) {
return function() {
var itm;
for (itm in JobTemplateFormObject.related) {
if (JobTemplateFormObject.related[itm].include === "SchedulesList") {
JobTemplateFormObject.related[itm] = SchedulesList;
JobTemplateFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
if (JobTemplateFormObject.related[itm].include === "CompletedJobsList") {
JobTemplateFormObject.related[itm] = CompletedJobsList;
JobTemplateFormObject.related[itm].generateList = true;
}
relatedSets: function(urls) {
return {
completed_jobs: {
iterator: 'completed_job',
url: urls.jobs + '?or__status=successful&or__status=failed&or__status=error&or__status=canceled'
},
schedules: {
iterator: 'schedule',
url: urls.schedules
}
};
}
})
return JobTemplateFormObject;
};
}]);
.factory('JobTemplateForm', ['JobTemplateFormObject', 'SchedulesList', 'CompletedJobsList',
function(JobTemplateFormObject, SchedulesList, CompletedJobsList) {
return function() {
var itm;
for (itm in JobTemplateFormObject.related) {
if (JobTemplateFormObject.related[itm].include === "SchedulesList") {
JobTemplateFormObject.related[itm] = SchedulesList;
JobTemplateFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
}
if (JobTemplateFormObject.related[itm].include === "CompletedJobsList") {
JobTemplateFormObject.related[itm] = CompletedJobsList;
JobTemplateFormObject.related[itm].generateList = true;
}
}
return JobTemplateFormObject;
};
}]);
+21 -21
View File
@@ -12,31 +12,31 @@
* @description This form is for job variables prompt modal
*/
export default
angular.module('JobVarsPromptFormDefinition', [])
angular.module('JobVarsPromptFormDefinition', [])
.value ('JobVarsPromptForm', {
.value ('JobVarsPromptForm', {
addTitle: '',
editTitle: '',
name: 'job',
well: false,
addTitle: '',
editTitle: '',
name: 'job',
well: false,
actions: { },
actions: { },
fields: {
extra_vars: {
label: null,
type: 'textarea',
rows: 6,
addRequired: false,
editRequired: false,
"default": "---"
}
},
fields: {
extra_vars: {
label: null,
type: 'textarea',
rows: 6,
addRequired: false,
editRequired: false,
"default": "---"
}
},
buttons: { },
buttons: { },
related: { }
related: { }
});
});
+101 -99
View File
@@ -11,108 +11,110 @@
* @name forms.function:Jobs
* @description This form is for adding/editing a Job
*/
angular.module('JobFormDefinition', [])
.value('JobForm', {
addTitle: 'Create Job',
editTitle: '{{ id }} - {{ name }}',
name: 'jobs',
well: true,
base: 'jobs',
collapse: true,
collapseMode: 'edit',
collapseTitle: 'Job Status',
collapseOpenFirst: true, //Always open first panel
export default
angular.module('JobFormDefinition', [])
.value('JobForm', {
navigationLinks: {
details: {
href: "/#/jobs/{{ job_id }}",
label: 'Status',
icon: 'icon-zoom-in',
active: true,
ngShow: "job_id !== null"
addTitle: 'Create Job',
editTitle: '{{ id }} - {{ name }}',
name: 'jobs',
well: true,
base: 'jobs',
collapse: true,
collapseMode: 'edit',
collapseTitle: 'Job Status',
collapseOpenFirst: true, //Always open first panel
navigationLinks: {
details: {
href: "/#/jobs/{{ job_id }}",
label: 'Status',
icon: 'icon-zoom-in',
active: true,
ngShow: "job_id !== null"
},
events: {
href: "/#/jobs/{{ job_id }}/job_events",
label: 'Events',
icon: 'icon-list-ul'
},
hosts: {
href: "/#/jobs/{{ job_id }}/job_host_summaries",
label: 'Host Summary',
icon: 'icon-laptop'
}
},
events: {
href: "/#/jobs/{{ job_id }}/job_events",
label: 'Events',
icon: 'icon-list-ul'
fields: {
status: {
type: 'custom',
control: "<i class=\"fa icon-job-{{ status }}\"></i> &nbsp;{{ job_explanation }}",
readonly: true
},
result_stdout: {
label: 'Standard Out',
type: 'textarea',
readonly: true,
xtraWide: true,
rows: "{{ stdout_rows }}",
"class": 'nowrap mono-space allowresize',
ngShow: "result_stdout != ''"
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
xtraWide: true,
readonly: true,
rows: "{{ traceback_rows }}",
"class": 'nowrap mono-space allowresize',
ngShow: "result_traceback != ''"
},
type: {
label: 'Job Type',
type: 'text',
readonly: true
},
launch_type: {
label: 'Launch Type',
type: 'text',
readonly: true
},
created: {
label: 'Created On',
type: 'text',
readonly: true
},
modified: {
label: 'Last Updated',
type: 'text',
readonly: true
}
},
hosts: {
href: "/#/jobs/{{ job_id }}/job_host_summaries",
label: 'Host Summary',
icon: 'icon-laptop'
actions: {
refresh: {
dataPlacement: 'top',
icon: "icon-refresh",
iconSize: 'large',
mode: 'all',
//ngShow: "job_status == 'pending' || job_status == 'waiting' || job_status == 'running'",
'class': 'btn-xs btn-primary',
awToolTip: "Refresh the page",
ngClick: "refresh()"
}
},
related: {
job_template: {
type: 'collection',
title: 'Job Tempate',
iterator: 'job',
index: false,
open: false,
fields: { }
}
}
},
fields: {
status: {
type: 'custom',
control: "<i class=\"fa icon-job-{{ status }}\"></i> &nbsp;{{ job_explanation }}",
readonly: true
},
result_stdout: {
label: 'Standard Out',
type: 'textarea',
readonly: true,
xtraWide: true,
rows: "{{ stdout_rows }}",
"class": 'nowrap mono-space allowresize',
ngShow: "result_stdout != ''"
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
xtraWide: true,
readonly: true,
rows: "{{ traceback_rows }}",
"class": 'nowrap mono-space allowresize',
ngShow: "result_traceback != ''"
},
type: {
label: 'Job Type',
type: 'text',
readonly: true
},
launch_type: {
label: 'Launch Type',
type: 'text',
readonly: true
},
created: {
label: 'Created On',
type: 'text',
readonly: true
},
modified: {
label: 'Last Updated',
type: 'text',
readonly: true
}
},
actions: {
refresh: {
dataPlacement: 'top',
icon: "icon-refresh",
iconSize: 'large',
mode: 'all',
//ngShow: "job_status == 'pending' || job_status == 'waiting' || job_status == 'running'",
'class': 'btn-xs btn-primary',
awToolTip: "Refresh the page",
ngClick: "refresh()"
}
},
related: {
job_template: {
type: 'collection',
title: 'Job Tempate',
iterator: 'job',
index: false,
open: false,
fields: { }
}
}
});
});
+65 -64
View File
@@ -12,71 +12,72 @@
*/
angular.module('LicenseFormDefinition', [])
.value('LicenseForm', {
export default
angular.module('LicenseFormDefinition', [])
.value('LicenseForm', {
name: 'license',
well: false,
tabs: [{
name: 'license',
label: 'License'
}, {
name: 'managed',
label: 'Managed Hosts'
}],
well: false,
fields: {
license_status: {
type: 'custom',
control: "<div class=\"license-status\" ng-class=\"status_color\"><i class=\"fa fa-circle\"></i> {{ license_status }}</div>",
readonly: true,
tab: 'license'
},
tower_version: {
label: 'Tower Version',
type: 'text',
readonly: true,
tab: 'license'
},
license_key: {
label: 'License Key',
type: 'textarea',
'class': 'modal-input-xlarge',
readonly: true,
tab: 'license'
},
license_date: {
label: 'Expires On',
type: 'text',
readonly: true,
tab: 'license'
},
time_remaining: {
label: 'Time Remaining',
type: 'text',
readonly: true,
tab: 'license'
},
available_instances: {
label: 'Available',
type: 'text',
readonly: true,
tab: 'managed'
},
current_instances: {
label: 'Used',
type: 'text',
readonly: true,
tab: 'managed'
},
free_instances: {
label: 'Remaining',
type: 'text',
readonly: true,
controlNGClass: 'free_instances_class',
labelNGClass: 'free_instances_class',
tab: 'managed'
tabs: [{
name: 'license',
label: 'License'
}, {
name: 'managed',
label: 'Managed Hosts'
}],
fields: {
license_status: {
type: 'custom',
control: "<div class=\"license-status\" ng-class=\"status_color\"><i class=\"fa fa-circle\"></i> {{ license_status }}</div>",
readonly: true,
tab: 'license'
},
tower_version: {
label: 'Tower Version',
type: 'text',
readonly: true,
tab: 'license'
},
license_key: {
label: 'License Key',
type: 'textarea',
'class': 'modal-input-xlarge',
readonly: true,
tab: 'license'
},
license_date: {
label: 'Expires On',
type: 'text',
readonly: true,
tab: 'license'
},
time_remaining: {
label: 'Time Remaining',
type: 'text',
readonly: true,
tab: 'license'
},
available_instances: {
label: 'Available',
type: 'text',
readonly: true,
tab: 'managed'
},
current_instances: {
label: 'Used',
type: 'text',
readonly: true,
tab: 'managed'
},
free_instances: {
label: 'Remaining',
type: 'text',
readonly: true,
controlNGClass: 'free_instances_class',
labelNGClass: 'free_instances_class',
tab: 'managed'
}
}
}
});
});
+38 -36
View File
@@ -11,45 +11,47 @@
* @name forms.function:LicenseUpdate
* @description This form is for updating a license
*/
angular.module('LicenseUpdateFormDefinition', [])
.value('LicenseUpdateForm', {
name: 'license',
well: false,
export default
angular.module('LicenseUpdateFormDefinition', [])
.value('LicenseUpdateForm', {
fields: {
license_json: {
label: 'License File',
type: 'textarea',
addRequired: true,
editRequird: true,
rows: 10,
'default': '---'
name: 'license',
well: false,
fields: {
license_json: {
label: 'License File',
type: 'textarea',
addRequired: true,
editRequird: true,
rows: 10,
'default': '---'
},
eula: {
label: 'End User License Agreement',
type: 'textarea',
addRequired: true,
editRequird: true,
rows: 5,
readonly: true
},
eula_agreement: {
label: 'I agree to the End User License Agreement',
type: 'checkbox',
addRequired: true,
editRequird: true
}
},
eula: {
label: 'End User License Agreement',
type: 'textarea',
addRequired: true,
editRequird: true,
rows: 5,
readonly: true
buttons: {
form_submit: {
label: "Submit",
"class": "pull-right btn-primary",
ngClick: "submitLicenseKey()",
// ngDisabled: "true"
}
},
eula_agreement: {
label: 'I agree to the End User License Agreement',
type: 'checkbox',
addRequired: true,
editRequird: true
}
},
buttons: {
form_submit: {
label: "Submit",
"class": "pull-right btn-primary",
ngClick: "submitLicenseKey()",
// ngDisabled: "true"
}
},
related: { }
related: { }
}); //LicenseUpdateForm
}); //LicenseUpdateForm
+88 -86
View File
@@ -11,92 +11,94 @@
* @name forms.function:LogViewerOptions
* @description This form is for the page to view logs
*/
angular.module('LogViewerOptionsDefinition', [])
.value('LogViewerOptionsForm', {
name: 'status',
well: false,
export default
angular.module('LogViewerOptionsDefinition', [])
.value('LogViewerOptionsForm', {
fields: {
"job_template": {
label: "Job Template",
type: "text",
readonly: true
},
"inventory": {
label: "Inventory",
type: "text",
readonly: true
},
"project": {
label: "Project",
type: "text",
readonly: true
},
"playbook": {
label: "Playbook",
type: "text",
readonly: true
},
"credential": {
label: "Credential",
type: "text",
readonly: true
},
"cloud credential": {
label: "Cloud Cred.",
type: "text",
readonly: true
},
"forks": {
label: "Forks",
type: "text",
readonly: true
},
"limit": {
label: "Limit",
type: "text",
readonly: true
},
"verbosity": {
label: "Verbosity",
type: "text",
readonly: true
},
"job_tags": {
label: "Job Tags",
type: "text",
readonly: true
},
"inventory_source": {
label: "Group",
type: "text",
readonly: true
},
"source": {
label: "Source",
type: "text",
readonly: true
},
"source_path": {
label: "Source Path",
type: "text",
readonly: true
},
"source_regions":{
label: "Regions",
type: "text",
readonly: true
},
"overwrite": {
label: "Overwrite",
type: "text",
readonly: true
},
"overwrite_vars": {
label: "Overwrite Vars",
type: "text",
readonly: true
name: 'status',
well: false,
fields: {
"job_template": {
label: "Job Template",
type: "text",
readonly: true
},
"inventory": {
label: "Inventory",
type: "text",
readonly: true
},
"project": {
label: "Project",
type: "text",
readonly: true
},
"playbook": {
label: "Playbook",
type: "text",
readonly: true
},
"credential": {
label: "Credential",
type: "text",
readonly: true
},
"cloud credential": {
label: "Cloud Cred.",
type: "text",
readonly: true
},
"forks": {
label: "Forks",
type: "text",
readonly: true
},
"limit": {
label: "Limit",
type: "text",
readonly: true
},
"verbosity": {
label: "Verbosity",
type: "text",
readonly: true
},
"job_tags": {
label: "Job Tags",
type: "text",
readonly: true
},
"inventory_source": {
label: "Group",
type: "text",
readonly: true
},
"source": {
label: "Source",
type: "text",
readonly: true
},
"source_path": {
label: "Source Path",
type: "text",
readonly: true
},
"source_regions":{
label: "Regions",
type: "text",
readonly: true
},
"overwrite": {
label: "Overwrite",
type: "text",
readonly: true
},
"overwrite_vars": {
label: "Overwrite Vars",
type: "text",
readonly: true
}
}
}
});
});
+45 -43
View File
@@ -11,50 +11,52 @@
* @name forms.function:LogViewerStatus
* @description Form definition for LogViewer.js helper
*/
angular.module('LogViewerStatusDefinition', [])
.value('LogViewerStatusForm', {
name: 'status',
well: false,
export default
angular.module('LogViewerStatusDefinition', [])
.value('LogViewerStatusForm', {
fields: {
"name": {
label: "Name",
type: "text",
readonly: true,
},
"status": {
label: "Status",
type: "text",
readonly: true
},
"license_error": {
label: "License Error",
type: "text",
readonly: true
},
"started": {
label: "Started",
type: "date",
"filter": "date:'MM/dd/yy HH:mm:ss'",
readonly: true
},
"finished": {
label: "Finished",
type: "date",
"filter": "date:'MM/dd/yy HH:mm:ss'",
readonly: true
},
"elapsed": {
label: "Elapsed",
type: "text",
readonly: true
},
"launch_type": {
label: "Launch Type",
type: "text",
readonly: true
name: 'status',
well: false,
fields: {
"name": {
label: "Name",
type: "text",
readonly: true,
},
"status": {
label: "Status",
type: "text",
readonly: true
},
"license_error": {
label: "License Error",
type: "text",
readonly: true
},
"started": {
label: "Started",
type: "date",
"filter": "date:'MM/dd/yy HH:mm:ss'",
readonly: true
},
"finished": {
label: "Finished",
type: "date",
"filter": "date:'MM/dd/yy HH:mm:ss'",
readonly: true
},
"elapsed": {
label: "Elapsed",
type: "text",
readonly: true
},
"launch_type": {
label: "Launch Type",
type: "text",
readonly: true
}
}
}
});
});
+136 -134
View File
@@ -11,151 +11,153 @@
* @name forms.function:Organizations
* @description This form is for adding/editing an organization
*/
angular.module('OrganizationFormDefinition', [])
.value('OrganizationForm', {
addTitle: 'Create Organization', //Title in add mode
editTitle: '{{ name }}', //Title in edit mode
name: 'organization', //entity or model name in singular form
well: true,
collapse: true,
collapseTitle: "Properties",
collapseMode: 'edit',
collapseOpen: true,
export default
angular.module('OrganizationFormDefinition', [])
.value('OrganizationForm', {
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'
}
},
addTitle: 'Create Organization', //Title in add mode
editTitle: '{{ name }}', //Title in edit mode
name: 'organization', //entity or model name in singular form
well: true,
collapse: true,
collapseTitle: "Properties",
collapseMode: 'edit',
collapseOpen: true,
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
}
},
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
}
},
related: {
users: {
type: 'collection',
title: 'Users',
iterator: 'user',
index: false,
open: false,
actions: {
add: {
ngClick: "add('users')",
label: 'Add',
icon: 'icon-plus',
awToolTip: 'Add a new user'
}
},
fields: {
username: {
key: true,
label: 'Username'
},
first_name: {
label: 'First Name'
},
last_name: {
label: 'Last Name'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('users', user.id, user.username)",
icon: 'icon-edit',
'class': 'btn-default',
awToolTip: 'Edit user'
},
"delete": {
label: 'Delete',
ngClick: "delete('users', user.id, user.username, 'users')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Remove user'
}
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'
}
},
admins: { // Assumes a plural name (e.g. things)
type: 'collection',
title: 'Administrators',
iterator: 'admin', // Singular form of name (e.g. thing)
index: false,
open: false, // Open accordion on load?
base: '/users',
actions: { // Actions displayed top right of list
add: {
ngClick: "add('admins')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add new administrator'
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
}
},
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
}
},
related: {
users: {
type: 'collection',
title: 'Users',
iterator: 'user',
index: false,
open: false,
actions: {
add: {
ngClick: "add('users')",
label: 'Add',
icon: 'icon-plus',
awToolTip: 'Add a new user'
}
},
fields: {
username: {
key: true,
label: 'Username'
},
first_name: {
label: 'First Name'
},
last_name: {
label: 'Last Name'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('users', user.id, user.username)",
icon: 'icon-edit',
'class': 'btn-default',
awToolTip: 'Edit user'
},
"delete": {
label: 'Delete',
ngClick: "delete('users', user.id, user.username, 'users')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Remove user'
}
}
},
fields: {
username: {
key: true,
label: 'Username'
admins: { // Assumes a plural name (e.g. things)
type: 'collection',
title: 'Administrators',
iterator: 'admin', // Singular form of name (e.g. thing)
index: false,
open: false, // Open accordion on load?
base: '/users',
actions: { // Actions displayed top right of list
add: {
ngClick: "add('admins')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add new administrator'
}
},
first_name: {
label: 'First Name'
fields: {
username: {
key: true,
label: 'Username'
},
first_name: {
label: 'First Name'
},
last_name: {
label: 'Last Name'
}
},
last_name: {
label: 'Last Name'
}
},
fieldActions: { // Actions available on each row
edit: {
label: 'Edit',
ngClick: "edit('users', admin.id, admin.username)",
icon: 'icon-edit',
awToolTip: 'Edit administrator',
'class': 'btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('admins', admin.id, admin.username, 'administrators')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Remove administrator'
fieldActions: { // Actions available on each row
edit: {
label: 'Edit',
ngClick: "edit('users', admin.id, admin.username)",
icon: 'icon-edit',
awToolTip: 'Edit administrator',
'class': 'btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('admins', admin.id, admin.username, 'administrators')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Remove administrator'
}
}
}
}
}
}); //OrganizationForm
}); //OrganizationForm
+120 -118
View File
@@ -12,131 +12,133 @@
* @name forms.function:Permissions
* @description This form is for adding/editing persmissions
*/
angular.module('PermissionFormDefinition', [])
.value('PermissionsForm', {
addTitle: 'Add Permission', //Title in add mode
editTitle: '{{ name }}', //Title in edit mode
name: 'permission', //entity or model name in singular form
well: true, //Wrap the form with TB well
forceListeners: true,
export default
angular.module('PermissionFormDefinition', [])
.value('PermissionsForm', {
stream: {
'class': "btn-primary btn-xs activity-btn",
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
dataPlacement: "top",
icon: "icon-comments-alt",
mode: 'edit',
iconSize: 'large'
},
addTitle: 'Add Permission', //Title in add mode
editTitle: '{{ name }}', //Title in edit mode
name: 'permission', //entity or model name in singular form
well: true, //Wrap the form with TB well
forceListeners: true,
fields: {
category: {
label: 'Permission Type',
labelClass: 'prepend-asterisk',
type: 'radio_group',
options: [{
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: {
category: {
label: 'Permission Type',
labelClass: 'prepend-asterisk',
type: 'radio_group',
options: [{
label: 'Inventory',
value: 'Inventory',
selected: true
}, {
label: 'Job Template',
value: 'Deploy'
}],
ngChange: 'selectCategory()'
},
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
user: {
label: 'User',
type: 'hidden'
},
team: {
label: 'Team',
type: 'hidden'
},
project: {
label: 'Project',
type: 'lookup',
sourceModel: 'project',
sourceField: 'name',
ngShow: "category == 'Deploy'",
ngClick: 'lookUpProject()',
awRequiredWhen: {
variable: "projectrequired",
init: "false"
}
},
inventory: {
label: 'Inventory',
value: 'Inventory',
selected: true
}, {
label: 'Job Template',
value: 'Deploy'
}],
ngChange: 'selectCategory()'
},
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
user: {
label: 'User',
type: 'hidden'
},
team: {
label: 'Team',
type: 'hidden'
},
project: {
label: 'Project',
type: 'lookup',
sourceModel: 'project',
sourceField: 'name',
ngShow: "category == 'Deploy'",
ngClick: 'lookUpProject()',
awRequiredWhen: {
variable: "projectrequired",
init: "false"
type: 'lookup',
sourceModel: 'inventory',
sourceField: 'name',
ngClick: 'lookUpInventory()',
awRequiredWhen: {
variable: "inventoryrequired",
init: "true"
}
},
permission_type: {
label: 'Permission',
labelClass: 'prepend-asterisk',
type: 'radio_group',
options: [{
label: 'Read',
value: 'read',
ngShow: "category == 'Inventory'"
}, {
label: 'Write',
value: 'write',
ngShow: "category == 'Inventory'"
}, {
label: 'Admin',
value: 'admin',
ngShow: "category == 'Inventory'"
}, {
label: 'Create',
value: 'create',
ngShow: "category == 'Deploy'"
}, {
label: 'Run',
value: 'run',
ngShow: "category == 'Deploy'"
}, {
label: 'Check',
value: 'check',
ngShow: "category == 'Deploy'"
}],
helpCollapse: [{
hdr: 'Permission',
ngBind: 'permissionTypeHelp'
}]
}
},
inventory: {
label: 'Inventory',
type: 'lookup',
sourceModel: 'inventory',
sourceField: 'name',
ngClick: 'lookUpInventory()',
awRequiredWhen: {
variable: "inventoryrequired",
init: "true"
buttons: {
save: {
ngClick: 'formSave()',
ngDisabled: true
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
permission_type: {
label: 'Permission',
labelClass: 'prepend-asterisk',
type: 'radio_group',
options: [{
label: 'Read',
value: 'read',
ngShow: "category == 'Inventory'"
}, {
label: 'Write',
value: 'write',
ngShow: "category == 'Inventory'"
}, {
label: 'Admin',
value: 'admin',
ngShow: "category == 'Inventory'"
}, {
label: 'Create',
value: 'create',
ngShow: "category == 'Deploy'"
}, {
label: 'Run',
value: 'run',
ngShow: "category == 'Deploy'"
}, {
label: 'Check',
value: 'check',
ngShow: "category == 'Deploy'"
}],
helpCollapse: [{
hdr: 'Permission',
ngBind: 'permissionTypeHelp'
}]
}
},
buttons: {
save: {
ngClick: 'formSave()',
ngDisabled: true
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
related: { }
related: { }
}); // Form
}); // Form
+36 -34
View File
@@ -11,40 +11,42 @@
* @name forms.function:ProjectStatus
* @description This form is for adding/editing project status
*/
angular.module('ProjectStatusDefinition', [])
.value('ProjectStatusForm', {
name: 'project_update',
editTitle: 'SCM Status',
well: false,
'class': 'horizontal-narrow',
export default
angular.module('ProjectStatusDefinition', [])
.value('ProjectStatusForm', {
fields: {
created: {
label: 'Created',
type: 'text',
readonly: true
},
status: {
label: 'Status',
type: 'text',
readonly: true
},
result_stdout: {
label: 'Std Out',
type: 'textarea',
ngShow: "result_stdout",
'class': 'mono-space',
readonly: true,
rows: 15
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
ngShow: "result_traceback",
'class': 'mono-space',
readonly: true,
rows: 15
name: 'project_update',
editTitle: 'SCM Status',
well: false,
'class': 'horizontal-narrow',
fields: {
created: {
label: 'Created',
type: 'text',
readonly: true
},
status: {
label: 'Status',
type: 'text',
readonly: true
},
result_stdout: {
label: 'Std Out',
type: 'textarea',
ngShow: "result_stdout",
'class': 'mono-space',
readonly: true,
rows: 15
},
result_traceback: {
label: 'Traceback',
type: 'textarea',
ngShow: "result_traceback",
'class': 'mono-space',
readonly: true,
rows: 15
}
}
}
}); //Form
}); //Form
+3 -1
View File
@@ -12,6 +12,8 @@
* @name forms.function:Projects
* @description This form is for adding/editing projects
*/
export default
angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
.value('ProjectsFormObject', {
@@ -330,4 +332,4 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
}
return ProjectsFormObject;
};
}]);
}]);
+239 -237
View File
@@ -11,248 +11,250 @@
* @name forms.function:Source
* @description This form is for group model
*/
angular.module('SourceFormDefinition', [])
.value('SourceForm', {
addTitle: 'Create Source',
editTitle: 'Edit Source',
showTitle: false,
cancelButton: false,
name: 'source',
well: false,
export default
angular.module('SourceFormDefinition', [])
.value('SourceForm', {
fields: {
source: {
label: 'Source',
type: 'select',
ngOptions: 'source.label for source in source_type_options track by source.value',
ngChange: 'sourceChange()',
addRequired: false,
editRequired: false
},
source_path: {
label: 'Script Path',
ngShow: "source && source.value == 'file'",
type: 'text',
awRequiredWhen: {
variable: "sourcePathRequired",
init: "false"
addTitle: 'Create Source',
editTitle: 'Edit Source',
showTitle: false,
cancelButton: false,
name: 'source',
well: false,
fields: {
source: {
label: 'Source',
type: 'select',
ngOptions: 'source.label for source in source_type_options track by source.value',
ngChange: 'sourceChange()',
addRequired: false,
editRequired: false
},
source_path: {
label: 'Script Path',
ngShow: "source && source.value == 'file'",
type: 'text',
awRequiredWhen: {
variable: "sourcePathRequired",
init: "false"
}
},
credential: {
label: 'Cloud Credential',
type: 'lookup',
ngShow: "source && source.value !== 'manual' && source.value !== 'custom'",
sourceModel: 'credential',
sourceField: 'name',
ngClick: 'lookUpCredential()',
addRequired: false,
editRequired: false
},
source_regions: {
label: 'Regions',
type: 'text',
ngShow: "source && (source.value == 'rax' || source.value == 'ec2' || source.value == 'gce' || source.value == 'azure')",
addRequired: false,
editRequired: false,
awMultiselect: 'source_region_choices',
dataTitle: 'Source Regions',
dataPlacement: 'right',
awPopOver: "<p>Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
"or choose <em>All</em> to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
"</p>",
dataContainer: 'body'
},
instance_filters: {
label: 'Instance Filters',
type: 'text',
ngShow: "source && source.value == 'ec2'",
addRequired: false,
editRequired: false,
dataTitle: 'Instance Filters',
dataPlacement: 'right',
awPopOver: "<p>Provide a comma-separated list of filter expressions. " +
"Hosts are imported to Tower when <em>ANY</em> of the filters match.</p>" +
"Limit to hosts having a tag:<br />\n" +
"<blockquote>tag-key=TowerManaged</blockquote>\n" +
"Limit to hosts using either key pair:<br />\n" +
"<blockquote>key-name=staging, key-name=production</blockquote>\n" +
"Limit to hosts where the Name tag begins with <em>test</em>:<br />\n" +
"<blockquote>tag:Name=test*</blockquote>\n" +
"<p>View the <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html\" target=\"_blank\">Describe Instances documentation</a> " +
"for a complete list of supported filters.</p>",
dataContainer: 'body'
},
group_by: {
label: 'Only Group By',
type: 'text',
ngShow: "source && source.value == 'ec2'",
addRequired: false,
editRequired: false,
awMultiselect: 'group_by_choices',
dataTitle: 'Only Group By',
dataPlacement: 'right',
awPopOver: "<p>Select which groups to create automatically. " +
"Tower will create group names similar to the following examples based on the options selected:</p><ul>" +
"<li>Availability Zone: <strong>zones &raquo; us-east-1b</strong></li>" +
"<li>Image ID: <strong>images &raquo; ami-b007ab1e</strong></li>" +
"<li>Instance ID: <strong>instances &raquo; i-ca11ab1e</strong></li>" +
"<li>Instance Type: <strong>types &raquo; type_m1_medium</strong></li>" +
"<li>Key Name: <strong>keys &raquo; key_testing</strong></li>" +
"<li>Region: <strong>regions &raquo; us-east-1</strong></li>" +
"<li>Security Group: <strong>security_groups &raquo; security_group_default</strong></li>" +
"<li>Tags: <strong>tags &raquo; tag_Name &raquo; tag_Name_host1</strong></li>" +
"<li>VPC ID: <strong>vpcs &raquo; vpc-5ca1ab1e</strong></li>" +
"</ul><p>If blank, all groups above are created except <em>Instance ID</em>.</p>",
dataContainer: 'body'
},
source_script: {
label : "Custom Inventory Script",
labelClass: 'prepend-asterisk',
type: 'lookup',
ngShow: "source && source.value === 'custom'",
sourceModel: 'source_script',
sourceField: 'name',
ngClick: 'lookUpSource_script()' , //'lookUpCustom_inventory()',
addRequired: true,
editRequired: true
},
extra_vars: {
label: 'Environment Variables', //"{{vars_label}}" ,
ngShow: "source && source.value=='custom' ",
type: 'textarea',
addRequired: false,
editRequired: false,
rows: 6,
'default': '---',
parseTypeName: 'envParseType',
dataTitle: "Environment Variables",
dataPlacement: 'right',
awPopOver: "<p>Provide key/value pairs using either YAML or JSON.</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",
dataContainer: 'body'
},
source_vars: {
label: 'Source Variables', //"{{vars_label}}" ,
ngShow: "source && (source.value == 'file' || source.value == 'ec2')",
type: 'textarea',
addRequired: false,
editRequird: false,
rows: 6,
'default': '---',
parseTypeName: 'envParseType',
dataTitle: "Source Variables",
dataPlacement: 'right',
awPopOver: "<p>Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/plugins/inventory/ec2.ini\" target=\"_blank\">" +
"view ec2.ini in the Ansible github repo.</a></p>" +
"<p>Enter 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>',
dataContainer: 'body'
},
inventory_variables: {
label: 'Source Variables', //"{{vars_label}}" ,
ngShow: "source && (source.value == 'vmware')",
type: 'textarea',
addRequired: false,
editRequird: false,
rows: 6,
'default': '---',
parseTypeName: 'envParseType',
dataTitle: "Source Variables",
dataPlacement: 'right',
awPopOver: "<p>Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/plugins/inventory/vmware.ini\" target=\"_blank\">" +
"view vmware.ini in the Ansible github repo.</a></p>" +
"<p>Enter 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>',
dataContainer: 'body'
},
checkbox_group: {
label: 'Update Options',
type: 'checkbox_group',
ngShow: "source && (source.value !== 'manual' && source.value !== null)",
fields: [{
name: 'overwrite',
label: 'Overwrite',
type: 'checkbox',
ngShow: "source.value !== 'manual' && source.value !== null",
addRequired: false,
editRequired: false,
awPopOver: '<p>If checked, all child groups and hosts not found on the external source will be deleted from ' +
'the local inventory.</p><p>When not checked, local child hosts and groups not found on the external source will ' +
'remain untouched by the inventory update process.</p>',
dataTitle: 'Overwrite',
dataContainer: 'body',
dataPlacement: 'right',
labelClass: 'checkbox-options'
}, {
name: 'overwrite_vars',
label: 'Overwrite Variables',
type: 'checkbox',
ngShow: "source.value !== 'manual' && source.value !== null",
addRequired: false,
editRequired: false,
awPopOver: '<p>If checked, all variables for child groups and hosts will be removed and replaced by those ' +
'found on the external source.</p><p>When not checked, a merge will be performed, combining local variables with ' +
'those found on the external source.</p>',
dataTitle: 'Overwrite Variables',
dataContainer: 'body',
dataPlacement: 'right',
labelClass: 'checkbox-options'
}, {
name: 'update_on_launch',
label: 'Update on Launch',
type: 'checkbox',
ngShow: "source.value !== 'manual' && source.value !== null",
addRequired: false,
editRequired: false,
awPopOver: '<p>Each time a job runs using this inventory, refresh the inventory from the selected source before ' +
'executing job tasks.</p>',
dataTitle: 'Update on Launch',
dataContainer: 'body',
dataPlacement: 'right',
labelClass: 'checkbox-options'
}]
},
update_cache_timeout: {
label: "Cache Timeout <span class=\"small-text\"> (seconds)</span>",
id: 'source-cache-timeout',
type: 'number',
integer: true,
min: 0,
ngShow: "source && source.value !== 'manual' && update_on_launch",
spinner: true,
"default": 0,
addRequired: false,
editRequired: false,
awPopOver: '<p>Time in seconds to consider an inventory sync to be current. During job runs and callbacks the task system will ' +
'evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, ' +
'and a new inventory sync will be performed.</p>',
dataTitle: 'Cache Timeout',
dataPlacement: 'right',
dataContainer: "body"
}
},
credential: {
label: 'Cloud Credential',
type: 'lookup',
ngShow: "source && source.value !== 'manual' && source.value !== 'custom'",
sourceModel: 'credential',
sourceField: 'name',
ngClick: 'lookUpCredential()',
addRequired: false,
editRequired: false
},
source_regions: {
label: 'Regions',
type: 'text',
ngShow: "source && (source.value == 'rax' || source.value == 'ec2' || source.value == 'gce' || source.value == 'azure')",
addRequired: false,
editRequired: false,
awMultiselect: 'source_region_choices',
dataTitle: 'Source Regions',
dataPlacement: 'right',
awPopOver: "<p>Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
"or choose <em>All</em> to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
"</p>",
dataContainer: 'body'
},
instance_filters: {
label: 'Instance Filters',
type: 'text',
ngShow: "source && source.value == 'ec2'",
addRequired: false,
editRequired: false,
dataTitle: 'Instance Filters',
dataPlacement: 'right',
awPopOver: "<p>Provide a comma-separated list of filter expressions. " +
"Hosts are imported to Tower when <em>ANY</em> of the filters match.</p>" +
"Limit to hosts having a tag:<br />\n" +
"<blockquote>tag-key=TowerManaged</blockquote>\n" +
"Limit to hosts using either key pair:<br />\n" +
"<blockquote>key-name=staging, key-name=production</blockquote>\n" +
"Limit to hosts where the Name tag begins with <em>test</em>:<br />\n" +
"<blockquote>tag:Name=test*</blockquote>\n" +
"<p>View the <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html\" target=\"_blank\">Describe Instances documentation</a> " +
"for a complete list of supported filters.</p>",
dataContainer: 'body'
},
group_by: {
label: 'Only Group By',
type: 'text',
ngShow: "source && source.value == 'ec2'",
addRequired: false,
editRequired: false,
awMultiselect: 'group_by_choices',
dataTitle: 'Only Group By',
dataPlacement: 'right',
awPopOver: "<p>Select which groups to create automatically. " +
"Tower will create group names similar to the following examples based on the options selected:</p><ul>" +
"<li>Availability Zone: <strong>zones &raquo; us-east-1b</strong></li>" +
"<li>Image ID: <strong>images &raquo; ami-b007ab1e</strong></li>" +
"<li>Instance ID: <strong>instances &raquo; i-ca11ab1e</strong></li>" +
"<li>Instance Type: <strong>types &raquo; type_m1_medium</strong></li>" +
"<li>Key Name: <strong>keys &raquo; key_testing</strong></li>" +
"<li>Region: <strong>regions &raquo; us-east-1</strong></li>" +
"<li>Security Group: <strong>security_groups &raquo; security_group_default</strong></li>" +
"<li>Tags: <strong>tags &raquo; tag_Name &raquo; tag_Name_host1</strong></li>" +
"<li>VPC ID: <strong>vpcs &raquo; vpc-5ca1ab1e</strong></li>" +
"</ul><p>If blank, all groups above are created except <em>Instance ID</em>.</p>",
dataContainer: 'body'
},
source_script: {
label : "Custom Inventory Script",
labelClass: 'prepend-asterisk',
type: 'lookup',
ngShow: "source && source.value === 'custom'",
sourceModel: 'source_script',
sourceField: 'name',
ngClick: 'lookUpSource_script()' , //'lookUpCustom_inventory()',
addRequired: true,
editRequired: true
},
extra_vars: {
label: 'Environment Variables', //"{{vars_label}}" ,
ngShow: "source && source.value=='custom' ",
type: 'textarea',
addRequired: false,
editRequired: false,
rows: 6,
'default': '---',
parseTypeName: 'envParseType',
dataTitle: "Environment Variables",
dataPlacement: 'right',
awPopOver: "<p>Provide key/value pairs using either YAML or JSON.</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",
dataContainer: 'body'
},
source_vars: {
label: 'Source Variables', //"{{vars_label}}" ,
ngShow: "source && (source.value == 'file' || source.value == 'ec2')",
type: 'textarea',
addRequired: false,
editRequird: false,
rows: 6,
'default': '---',
parseTypeName: 'envParseType',
dataTitle: "Source Variables",
dataPlacement: 'right',
awPopOver: "<p>Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/plugins/inventory/ec2.ini\" target=\"_blank\">" +
"view ec2.ini in the Ansible github repo.</a></p>" +
"<p>Enter 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>',
dataContainer: 'body'
},
inventory_variables: {
label: 'Source Variables', //"{{vars_label}}" ,
ngShow: "source && (source.value == 'vmware')",
type: 'textarea',
addRequired: false,
editRequird: false,
rows: 6,
'default': '---',
parseTypeName: 'envParseType',
dataTitle: "Source Variables",
dataPlacement: 'right',
awPopOver: "<p>Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables " +
"<a href=\"https://github.com/ansible/ansible/blob/devel/plugins/inventory/vmware.ini\" target=\"_blank\">" +
"view vmware.ini in the Ansible github repo.</a></p>" +
"<p>Enter 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>',
dataContainer: 'body'
},
checkbox_group: {
label: 'Update Options',
type: 'checkbox_group',
ngShow: "source && (source.value !== 'manual' && source.value !== null)",
fields: [{
name: 'overwrite',
label: 'Overwrite',
type: 'checkbox',
ngShow: "source.value !== 'manual' && source.value !== null",
addRequired: false,
editRequired: false,
awPopOver: '<p>If checked, all child groups and hosts not found on the external source will be deleted from ' +
'the local inventory.</p><p>When not checked, local child hosts and groups not found on the external source will ' +
'remain untouched by the inventory update process.</p>',
dataTitle: 'Overwrite',
dataContainer: 'body',
dataPlacement: 'right',
labelClass: 'checkbox-options'
}, {
name: 'overwrite_vars',
label: 'Overwrite Variables',
type: 'checkbox',
ngShow: "source.value !== 'manual' && source.value !== null",
addRequired: false,
editRequired: false,
awPopOver: '<p>If checked, all variables for child groups and hosts will be removed and replaced by those ' +
'found on the external source.</p><p>When not checked, a merge will be performed, combining local variables with ' +
'those found on the external source.</p>',
dataTitle: 'Overwrite Variables',
dataContainer: 'body',
dataPlacement: 'right',
labelClass: 'checkbox-options'
}, {
name: 'update_on_launch',
label: 'Update on Launch',
type: 'checkbox',
ngShow: "source.value !== 'manual' && source.value !== null",
addRequired: false,
editRequired: false,
awPopOver: '<p>Each time a job runs using this inventory, refresh the inventory from the selected source before ' +
'executing job tasks.</p>',
dataTitle: 'Update on Launch',
dataContainer: 'body',
dataPlacement: 'right',
labelClass: 'checkbox-options'
}]
buttons: {
},
update_cache_timeout: {
label: "Cache Timeout <span class=\"small-text\"> (seconds)</span>",
id: 'source-cache-timeout',
type: 'number',
integer: true,
min: 0,
ngShow: "source && source.value !== 'manual' && update_on_launch",
spinner: true,
"default": 0,
addRequired: false,
editRequired: false,
awPopOver: '<p>Time in seconds to consider an inventory sync to be current. During job runs and callbacks the task system will ' +
'evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, ' +
'and a new inventory sync will be performed.</p>',
dataTitle: 'Cache Timeout',
dataPlacement: 'right',
dataContainer: "body"
}
},
buttons: {
related: { }
},
related: { }
});
});
+52 -50
View File
@@ -11,60 +11,62 @@
* @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,
breadCrumbs: false,
export default
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,
breadCrumbs: false,
fields: {
survey_name: {
type: 'custom',
control: '<div class="row">'+
// '<div class="col-sm-6">
// <div class="form-group">'+
// '<label for="survey_name"><span class="label-text prepend-asterisk">Survey Name</span></label>
// <div>'+
// '<input type="text" ng-model="survey_name" name="survey_name" id="survey_maker_survey_name" class="form-control ng-pristine ng-invalid ng-invalid-required" required="" capitalize>'+
// '<div class="error ng-hide" id="survey_maker-survey_name-required-error" ng-show="survey_maker_form.survey_name.$dirty &amp;&amp; survey_maker_form.survey_name.$error.required">Please enter a survey name.</div>'+
// '<div class="error api-error ng-binding" id="survey_maker-survey_name-api-error" ng-bind="survey_name_api_error"></div>'+
// '</div></div></div>'+
// '<div class="col-sm-6"><div class="form-group">'+
// '<label for="survey_description"><span class="label-text">Survey Description</span></label><div>'+
// '<input type="text" ng-model="survey_description" name="survey_description" id="survey_maker_survey_description" class="form-control ng-pristine ng-valid">'+
// '<div class="error api-error ng-binding" id="survey_maker-survey_description-api-error" ng-bind="survey_description_api_error"></div>'+
// '</div></div></div>'+
'<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> Add Question</button>'+
'<div id="new_question"></div>'+
'</div>'+
'</div>'//</div>'
// label: 'Survey Name',
// type: 'text',
// addRequired: true,
// editRequired: true,
// capitalize: false,
// // column: 1
fields: {
survey_name: {
type: 'custom',
control: '<div class="row">'+
// '<div class="col-sm-6">
// <div class="form-group">'+
// '<label for="survey_name"><span class="label-text prepend-asterisk">Survey Name</span></label>
// <div>'+
// '<input type="text" ng-model="survey_name" name="survey_name" id="survey_maker_survey_name" class="form-control ng-pristine ng-invalid ng-invalid-required" required="" capitalize>'+
// '<div class="error ng-hide" id="survey_maker-survey_name-required-error" ng-show="survey_maker_form.survey_name.$dirty &amp;&amp; survey_maker_form.survey_name.$error.required">Please enter a survey name.</div>'+
// '<div class="error api-error ng-binding" id="survey_maker-survey_name-api-error" ng-bind="survey_name_api_error"></div>'+
// '</div></div></div>'+
// '<div class="col-sm-6"><div class="form-group">'+
// '<label for="survey_description"><span class="label-text">Survey Description</span></label><div>'+
// '<input type="text" ng-model="survey_description" name="survey_description" id="survey_maker_survey_description" class="form-control ng-pristine ng-valid">'+
// '<div class="error api-error ng-binding" id="survey_maker-survey_description-api-error" ng-bind="survey_description_api_error"></div>'+
// '</div></div></div>'+
'<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> Add Question</button>'+
'<div id="new_question"></div>'+
'</div>'+
'</div>'//</div>'
// label: 'Survey Name',
// type: 'text',
// addRequired: true,
// editRequired: true,
// capitalize: false,
// // column: 1
},
},
},
// 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
// 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
// }
// }
// reset: {
// ngClick: 'formReset()',
// ngDisabled: true //Disabled when $pristine
// }
// }
});
});
+254 -252
View File
@@ -11,261 +11,263 @@
* @name forms.function:Questions
* @description This form is for adding a question
*/
angular.module('SurveyQuestionFormDefinition', [])
.value('SurveyQuestionForm', {
addTitle: 'Add Question',
editTitle: 'Edit Question',
base: 'survey_question',
name: 'survey_question',
well: true,
twoColumns: true,
breadcrumbs: false,
export default
angular.module('SurveyQuestionFormDefinition', [])
.value('SurveyQuestionForm', {
fields: {
question_name: {
realName: 'question_text',
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
column: 1,
awSurveyQuestion: true
},
question_description: {
realName: 'question_description',
label: 'Description',
type: 'text',
// rows: 2,
addRequired: false,
editRequired: false,
column: 1
},
// variable: {
// label: 'Answer Variable Name',
// type: 'text',
// addRequired: true,
// editRequired: true,
// column: 1,
// awPopOver: '<p>The suggested format for variable names are lowercase, underscore-separated descriptive nouns.</p>'+
// '<p>For example: <br>foo_bar<br>\n user_id<br>\n host_name<br>' ,
// dataTitle: 'Answer Variable Name',
// dataPlacement: 'right',
// dataContainer: "body"
// },
variable: {
ealName: 'variable',
type: 'custom',
control:'<label for="variable"><span class="label-text 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=&quot;popover-footer&quot;><span class=&quot;key&quot;>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 class="error ng-hide" id="survey_question-variable-required-error" ng-show="survey_question_form.variable.$dirty &amp;&amp; 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 &amp;&amp; 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>' +
'<div class="error api-error ng-binding" id="survey_question-variable-api-error" ng-bind="variable_api_error"></div>'+
'</div>',
addRequired: true,
editRequired: true,
column: 1
},
type: {
realName: 'answer_type',
label: 'Answer Type',
type: 'select',
defaultText: 'Choose an answer type',
ngOptions: 'answer_types.name for answer_types in answer_types track by answer_types.type',
addRequired: true,
editRequired: true,
column: 2,
ngChange: 'typeChange()'
},
choices: {
realName: 'answer_options',
label: 'Multiple Choice Options',
type: 'textarea',
rows: 3,
addRequired: true,
editRequired: true,
ngRequired: "type.type=== 'multiselect' || type.type=== 'multiplechoice' " ,
ngShow: 'type.type=== "multiselect" || type.type=== "multiplechoice" ',
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: 2
},
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 />'+
'<div class="error" ng-show="survey_question_form.text_min.$error.number || survey_question_form.text_min.$error.integer">The minimum length you entered is not a number. Please enter a 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" class="form-control" integer >'+
'<div class="error" ng-show="survey_question_form.text_max.$error.number || survey_question_form.text_max.$error.integer">The maximum length you entered is not a number. Please enter a number.</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>'+
'</div>',
ngShow: 'type.type==="text" ',
addRequired: true,
editRequired: true,
column: 2
},
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 />'+
'<div class="error" ng-show="survey_question_form.textarea_min.$error.number || survey_question_form.textarea_min.$error.integer">The minimum length you entered is not a number. Please enter a 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" class="form-control" integer >'+
'<div class="error" ng-show="survey_question_form.textarea_max.$error.number || survey_question_form.textarea_max.$error.integer">The maximum length you entered is not a number. Please enter a 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>'+
'</div>',
ngShow: 'type.type==="textarea" ',
addRequired: true,
editRequired: true,
column: 2
},
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 >'+
'<div class="error" ng-show="survey_question_form.int_min.$error.number || survey_question_form.int_min.$error.integer">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 >'+
'<div class="error" ng-show="survey_question_form.int_max.$error.number || survey_question_form.int_max.$error.integer">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>'+
'</div>',
ngShow: 'type.type==="integer" ',
addRequired: true,
editRequired: true,
column: 2
},
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">'+
'<div class="error" ng-show="survey_question_form.float_min.$error.float">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">'+
'<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>'+
addTitle: 'Add Question',
editTitle: 'Edit Question',
base: 'survey_question',
name: 'survey_question',
well: true,
twoColumns: true,
breadcrumbs: false,
'</div>'+
'</div>',
ngShow: 'type.type==="float" ',
addRequired: true,
editRequired: true,
column: 2
fields: {
question_name: {
realName: 'question_text',
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
column: 1,
awSurveyQuestion: true
},
question_description: {
realName: 'question_description',
label: 'Description',
type: 'text',
// rows: 2,
addRequired: false,
editRequired: false,
column: 1
},
// variable: {
// label: 'Answer Variable Name',
// type: 'text',
// addRequired: true,
// editRequired: true,
// column: 1,
// awPopOver: '<p>The suggested format for variable names are lowercase, underscore-separated descriptive nouns.</p>'+
// '<p>For example: <br>foo_bar<br>\n user_id<br>\n host_name<br>' ,
// dataTitle: 'Answer Variable Name',
// dataPlacement: 'right',
// dataContainer: "body"
// },
variable: {
ealName: 'variable',
type: 'custom',
control:'<label for="variable"><span class="label-text 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=&quot;popover-footer&quot;><span class=&quot;key&quot;>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 class="error ng-hide" id="survey_question-variable-required-error" ng-show="survey_question_form.variable.$dirty &amp;&amp; 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 &amp;&amp; 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>' +
'<div class="error api-error ng-binding" id="survey_question-variable-api-error" ng-bind="variable_api_error"></div>'+
'</div>',
addRequired: true,
editRequired: true,
column: 1
},
type: {
realName: 'answer_type',
label: 'Answer Type',
type: 'select',
defaultText: 'Choose an answer type',
ngOptions: 'answer_types.name for answer_types in answer_types track by answer_types.type',
addRequired: true,
editRequired: true,
column: 2,
ngChange: 'typeChange()'
},
choices: {
realName: 'answer_options',
label: 'Multiple Choice Options',
type: 'textarea',
rows: 3,
addRequired: true,
editRequired: true,
ngRequired: "type.type=== 'multiselect' || type.type=== 'multiplechoice' " ,
ngShow: 'type.type=== "multiselect" || type.type=== "multiplechoice" ',
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: 2
},
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 />'+
'<div class="error" ng-show="survey_question_form.text_min.$error.number || survey_question_form.text_min.$error.integer">The minimum length you entered is not a number. Please enter a 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" class="form-control" integer >'+
'<div class="error" ng-show="survey_question_form.text_max.$error.number || survey_question_form.text_max.$error.integer">The maximum length you entered is not a number. Please enter a number.</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>'+
'</div>',
ngShow: 'type.type==="text" ',
addRequired: true,
editRequired: true,
column: 2
},
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 />'+
'<div class="error" ng-show="survey_question_form.textarea_min.$error.number || survey_question_form.textarea_min.$error.integer">The minimum length you entered is not a number. Please enter a 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" class="form-control" integer >'+
'<div class="error" ng-show="survey_question_form.textarea_max.$error.number || survey_question_form.textarea_max.$error.integer">The maximum length you entered is not a number. Please enter a 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>'+
'</div>',
ngShow: 'type.type==="textarea" ',
addRequired: true,
editRequired: true,
column: 2
},
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 >'+
'<div class="error" ng-show="survey_question_form.int_min.$error.number || survey_question_form.int_min.$error.integer">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 >'+
'<div class="error" ng-show="survey_question_form.int_max.$error.number || survey_question_form.int_max.$error.integer">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>'+
'</div>',
ngShow: 'type.type==="integer" ',
addRequired: true,
editRequired: true,
column: 2
},
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">'+
'<div class="error" ng-show="survey_question_form.float_min.$error.float">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">'+
'<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>'+
'</div>'+
'</div>',
ngShow: 'type.type==="float" ',
addRequired: true,
editRequired: true,
column: 2
},
default: {
realName: 'default_answer',
label: 'Default Answer',
type: 'text',
addRequired: false,
editRequired: false,
column: 2,
ngHide: 'type.type === "textarea" || type.type === "multiselect" || type.type === "integer" || type.type === "float" '
},
// default_text: {
// realName: 'default_answer',
// type: 'custom',
// control: '<div>'+
// '<label for="default_text"><span class="label-text">Default Answer</span></label>'+
// '<input type="text" ng-model="default_text" name="default_text" class="form-control" />'+
// '<div class="error" ng-show="survey_question_form.default_text.$error.minlength || survey_question_form.default_text.$error.maxlength"> The answer must be between {{text_min}} to {{text_max}} characters long!</div>'+
// '</div>',
// column: 2,
// ngShow: 'type.type === "text" '
// },
default_multiselect: {
realName: 'default_answer',
label: 'Default Answer',
type: 'textarea',
rows: 3,
addRequired: false,
editRequired: false,
column: 2,
ngShow: 'type.type === "multiselect" '
},
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 />'+
'<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" '
},
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" />'+
'<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" '
},
default_textarea: {
realName: 'default_answer',
label: 'Default Answer',
type: 'textarea',
rows: 3,
addRequired: false,
editRequired: false,
column: 2,
ngShow: 'type.type === "textarea" '
},
required: {
realName: 'required_answer',
label: 'Required',
type: 'checkbox',
addRequired: false,
editRequired: false,
column: 2
}
},
default: {
realName: 'default_answer',
label: 'Default Answer',
type: 'text',
addRequired: false,
editRequired: false,
column: 2,
ngHide: 'type.type === "textarea" || type.type === "multiselect" || type.type === "integer" || type.type === "float" '
},
// default_text: {
// realName: 'default_answer',
// type: 'custom',
// control: '<div>'+
// '<label for="default_text"><span class="label-text">Default Answer</span></label>'+
// '<input type="text" ng-model="default_text" name="default_text" class="form-control" />'+
// '<div class="error" ng-show="survey_question_form.default_text.$error.minlength || survey_question_form.default_text.$error.maxlength"> The answer must be between {{text_min}} to {{text_max}} characters long!</div>'+
// '</div>',
// column: 2,
// ngShow: 'type.type === "text" '
// },
default_multiselect: {
realName: 'default_answer',
label: 'Default Answer',
type: 'textarea',
rows: 3,
addRequired: false,
editRequired: false,
column: 2,
ngShow: 'type.type === "multiselect" '
},
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 />'+
'<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" '
},
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" />'+
'<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" '
},
default_textarea: {
realName: 'default_answer',
label: 'Default Answer',
type: 'textarea',
rows: 3,
addRequired: false,
editRequired: false,
column: 2,
ngShow: 'type.type === "textarea" '
},
required: {
realName: 'required_answer',
label: 'Required',
type: 'checkbox',
addRequired: false,
editRequired: false,
column: 2
buttons: {
question_cancel : {
label: 'Cancel',
'class' : 'btn btn-default',
ngClick: 'cancelQuestion($event)'
},
submit_question: {
ngClick: 'submitQuestion($event)',
ngDisabled: true, //'survey_question.$valid', //"!question_name || !variable || !type || ((type.type==='multiplechoice' || type.type === 'multiselect' ) && !choices)", //|| type.type===multiselect ',//'!question_name || !variable || !type' ,
'class': 'btn btn-sm btn-primary',
label: 'Add Question'
}
}
},
buttons: {
question_cancel : {
label: 'Cancel',
'class' : 'btn btn-default',
ngClick: 'cancelQuestion($event)'
},
submit_question: {
ngClick: 'submitQuestion($event)',
ngDisabled: true, //'survey_question.$valid', //"!question_name || !variable || !type || ((type.type==='multiplechoice' || type.type === 'multiselect' ) && !choices)", //|| type.type===multiselect ',//'!question_name || !variable || !type' ,
'class': 'btn btn-sm btn-primary',
label: 'Add Question'
}
}
});
});
+234 -232
View File
@@ -11,265 +11,267 @@
* @name forms.function:Teams
* @description This form is for adding/editing teams
*/
angular.module('TeamFormDefinition', [])
.value('TeamForm', {
addTitle: 'Create Team', //Legend in add mode
editTitle: '{{ name }}', //Legend in edit mode
name: 'team',
well: true,
collapse: true,
collapseTitle: "Properties",
collapseMode: 'edit',
collapseOpen: true,
export default
angular.module('TeamFormDefinition', [])
.value('TeamForm', {
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'
}
},
addTitle: 'Create Team', //Legend in add mode
editTitle: '{{ name }}', //Legend in edit mode
name: 'team',
well: true,
collapse: true,
collapseTitle: "Properties",
collapseMode: 'edit',
collapseOpen: true,
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
organization: {
label: 'Organization',
type: 'lookup',
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()',
awRequiredWhen: {
variable: "teamrequired",
init: "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'
}
}
},
buttons: {
save: {
ngClick: 'formSave()',
ngDisabled: true
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
related: {
credentials: {
type: 'collection',
title: 'Credentials',
iterator: 'credential',
open: false,
index: false,
actions: {
add: {
ngClick: "add('credentials')",
icon: 'icon-plus',
label: 'Add',
add: 'Add a new credential'
}
fields: {
name: {
label: 'Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: false
},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
description: {
label: 'Description',
type: 'text',
addRequired: false,
editRequired: false
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('credentials', credential.id, credential.name)",
icon: 'icon-edit',
awToolTip: 'Modify the credential',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('credentials', credential.id, credential.name, 'credentials')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Remove the credential'
organization: {
label: 'Organization',
type: 'lookup',
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()',
awRequiredWhen: {
variable: "teamrequired",
init: "true"
}
}
},
permissions: {
type: 'collection',
title: 'Permissions',
iterator: 'permission',
open: false,
index: false,
actions: {
add: {
ngClick: "add('permissions')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a permission for this user',
ngShow: 'PermissionAddAllowed'
}
buttons: {
save: {
ngClick: 'formSave()',
ngDisabled: true
},
fields: {
name: {
key: true,
label: 'Name',
ngClick: "edit('permissions', permission.id, permission.name)"
},
inventory: {
label: 'Inventory',
sourceModel: 'inventory',
sourceField: 'name',
ngBind: 'permission.summary_fields.inventory.name'
},
project: {
label: 'Project',
sourceModel: 'project',
sourceField: 'name',
ngBind: 'permission.summary_fields.project.name'
},
permission_type: {
label: 'Permission'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('permissions', permission.id, permission.name)",
icon: 'icon-edit',
awToolTip: 'Edit the permission',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('permissions', permission.id, permission.name, 'permissions')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Delete the permission',
ngShow: 'PermissionAddAllowed'
}
}
},
projects: {
type: 'collection',
title: 'Projects',
iterator: 'project',
open: false,
index: false,
actions: {
add: {
ngClick: "add('projects')",
icon: 'icon-plus',
label: 'Add'
}
},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('projects', project.id, project.name)",
icon: 'icon-edit',
awToolTip: 'Modify the project',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('projects', project.id, project.name, 'projects')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Remove the project'
}
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
users: {
type: 'collection',
title: 'Users',
iterator: 'user',
open: false,
index: false,
related: {
actions: {
add: {
ngClick: "add('users')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a user'
credentials: {
type: 'collection',
title: 'Credentials',
iterator: 'credential',
open: false,
index: false,
actions: {
add: {
ngClick: "add('credentials')",
icon: 'icon-plus',
label: 'Add',
add: 'Add a new credential'
}
},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('credentials', credential.id, credential.name)",
icon: 'icon-edit',
awToolTip: 'Modify the credential',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('credentials', credential.id, credential.name, 'credentials')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Remove the credential'
}
}
},
fields: {
username: {
key: true,
label: 'Username'
permissions: {
type: 'collection',
title: 'Permissions',
iterator: 'permission',
open: false,
index: false,
actions: {
add: {
ngClick: "add('permissions')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a permission for this user',
ngShow: 'PermissionAddAllowed'
}
},
first_name: {
label: 'First Name'
fields: {
name: {
key: true,
label: 'Name',
ngClick: "edit('permissions', permission.id, permission.name)"
},
inventory: {
label: 'Inventory',
sourceModel: 'inventory',
sourceField: 'name',
ngBind: 'permission.summary_fields.inventory.name'
},
project: {
label: 'Project',
sourceModel: 'project',
sourceField: 'name',
ngBind: 'permission.summary_fields.project.name'
},
permission_type: {
label: 'Permission'
}
},
last_name: {
label: 'Last Name'
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('permissions', permission.id, permission.name)",
icon: 'icon-edit',
awToolTip: 'Edit the permission',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('permissions', permission.id, permission.name, 'permissions')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Delete the permission',
ngShow: 'PermissionAddAllowed'
}
}
},
projects: {
type: 'collection',
title: 'Projects',
iterator: 'project',
open: false,
index: false,
actions: {
add: {
ngClick: "add('projects')",
icon: 'icon-plus',
label: 'Add'
}
},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('projects', project.id, project.name)",
icon: 'icon-edit',
awToolTip: 'Modify the project',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('projects', project.id, project.name, 'projects')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Remove the project'
}
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('users', user.id, user.username)",
icon: 'icon-edit',
awToolTip: 'Edit user',
'class': 'btn btn-default'
users: {
type: 'collection',
title: 'Users',
iterator: 'user',
open: false,
index: false,
actions: {
add: {
ngClick: "add('users')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a user'
}
},
"delete": {
label: 'Delete',
ngClick: "delete('users', user.id, user.username, 'users')",
icon: 'icon-terash',
"class": 'btn-danger',
awToolTip: 'Remove user'
fields: {
username: {
key: true,
label: 'Username'
},
first_name: {
label: 'First Name'
},
last_name: {
label: 'Last Name'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('users', user.id, user.username)",
icon: 'icon-edit',
awToolTip: 'Edit user',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('users', user.id, user.username, 'users')",
icon: 'icon-terash',
"class": 'btn-danger',
awToolTip: 'Remove user'
}
}
}
}
}
}); //InventoryForm
}); //InventoryForm
+258 -256
View File
@@ -11,288 +11,290 @@
* @name forms.function:Users
* @description This form is for adding/editing users
*/
angular.module('UserFormDefinition', [])
.value('UserForm', {
addTitle: 'Create User',
editTitle: '{{ username }}',
name: 'user',
well: true,
forceListeners: true,
collapse: true,
collapseTitle: "Properties",
collapseMode: 'edit',
collapseOpen: true,
export default
angular.module('UserFormDefinition', [])
.value('UserForm', {
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'
}
},
addTitle: 'Create User',
editTitle: '{{ username }}',
name: 'user',
well: true,
forceListeners: true,
collapse: true,
collapseTitle: "Properties",
collapseMode: 'edit',
collapseOpen: true,
fields: {
first_name: {
label: 'First Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: true
},
last_name: {
label: 'Last Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: true
},
email: {
label: 'Email',
type: 'email',
addRequired: true,
editRequired: true,
autocomplete: false
},
organization: {
label: 'Organization',
type: 'lookup',
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()',
excludeMode: 'edit',
awRequiredWhen: {
variable: "orgrequired",
init: true
}
},
username: {
label: 'Username',
type: 'text',
awRequiredWhen: {
variable: "not_ldap_user",
init: true
},
autocomplete: false
},
password: {
label: 'Password',
type: 'password',
ngShow: 'ldap_user == false',
addRequired: true,
editRequired: false,
ngChange: "clearPWConfirm('password_confirm')",
autocomplete: false,
chkPass: true
},
password_confirm: {
label: 'Confirm Password',
type: 'password',
ngShow: 'ldap_user == false',
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'password',
autocomplete: false
},
is_superuser: {
label: 'Superuser (User has full system administration privileges.)',
type: 'checkbox',
trueValue: 'true',
falseValue: 'false',
"default": 'false',
ngShow: "current_user['is_superuser'] == true"
},
ldap_user: {
label: 'Created by LDAP',
type: 'checkbox',
readonly: true
}
},
buttons: {
save: {
ngClick: 'formSave()',
ngDisabled: true
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
related: {
credentials: {
type: 'collection',
title: 'Credentials',
iterator: 'credential',
open: false,
index: false,
actions: {
add: {
ngClick: "add('credentials')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a credential for this user'
}
},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('credentials', credential.id, credential.name)",
icon: 'icon-edit',
awToolTip: 'Edit the credential',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('credentials', credential.id, credential.name, 'credentials')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Delete the credential'
}
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'
}
},
permissions: {
type: 'collection',
title: 'Permissions',
iterator: 'permission',
open: false,
index: false,
fields: {
first_name: {
label: 'First Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: true
},
last_name: {
label: 'Last Name',
type: 'text',
addRequired: true,
editRequired: true,
capitalize: true
},
email: {
label: 'Email',
type: 'email',
addRequired: true,
editRequired: true,
autocomplete: false
},
organization: {
label: 'Organization',
type: 'lookup',
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()',
excludeMode: 'edit',
awRequiredWhen: {
variable: "orgrequired",
init: true
}
},
username: {
label: 'Username',
type: 'text',
awRequiredWhen: {
variable: "not_ldap_user",
init: true
},
autocomplete: false
},
password: {
label: 'Password',
type: 'password',
ngShow: 'ldap_user == false',
addRequired: true,
editRequired: false,
ngChange: "clearPWConfirm('password_confirm')",
autocomplete: false,
chkPass: true
},
password_confirm: {
label: 'Confirm Password',
type: 'password',
ngShow: 'ldap_user == false',
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'password',
autocomplete: false
},
is_superuser: {
label: 'Superuser (User has full system administration privileges.)',
type: 'checkbox',
trueValue: 'true',
falseValue: 'false',
"default": 'false',
ngShow: "current_user['is_superuser'] == true"
},
ldap_user: {
label: 'Created by LDAP',
type: 'checkbox',
readonly: true
}
},
actions: {
add: {
ngClick: "add('permissions')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a permission for this user',
ngShow: 'PermissionAddAllowed'
buttons: {
save: {
ngClick: 'formSave()',
ngDisabled: true
},
reset: {
ngClick: 'formReset()',
ngDisabled: true
}
},
related: {
credentials: {
type: 'collection',
title: 'Credentials',
iterator: 'credential',
open: false,
index: false,
actions: {
add: {
ngClick: "add('credentials')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a credential for this user'
}
},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('credentials', credential.id, credential.name)",
icon: 'icon-edit',
awToolTip: 'Edit the credential',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('credentials', credential.id, credential.name, 'credentials')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Delete the credential'
}
}
},
fields: {
name: {
key: true,
label: 'Name',
ngClick: "edit('permissions', permission.id, permission.name)"
permissions: {
type: 'collection',
title: 'Permissions',
iterator: 'permission',
open: false,
index: false,
actions: {
add: {
ngClick: "add('permissions')",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a permission for this user',
ngShow: 'PermissionAddAllowed'
}
},
inventory: {
label: 'Inventory',
sourceModel: 'inventory',
sourceField: 'name',
ngBind: 'permission.summary_fields.inventory.name'
fields: {
name: {
key: true,
label: 'Name',
ngClick: "edit('permissions', permission.id, permission.name)"
},
inventory: {
label: 'Inventory',
sourceModel: 'inventory',
sourceField: 'name',
ngBind: 'permission.summary_fields.inventory.name'
},
project: {
label: 'Project',
sourceModel: 'project',
sourceField: 'name',
ngBind: 'permission.summary_fields.project.name'
},
permission_type: {
label: 'Permission'
}
},
project: {
label: 'Project',
sourceModel: 'project',
sourceField: 'name',
ngBind: 'permission.summary_fields.project.name'
},
permission_type: {
label: 'Permission'
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('permissions', permission.id, permission.name)",
icon: 'icon-edit',
awToolTip: 'Edit the permission',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('permissions', permission.id, permission.name, 'permissions')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Delete the permission',
ngShow: 'PermissionAddAllowed'
}
}
},
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('permissions', permission.id, permission.name)",
icon: 'icon-edit',
awToolTip: 'Edit the permission',
'class': 'btn btn-default'
},
admin_of_organizations: { // Assumes a plural name (e.g. things)
type: 'collection',
title: 'Admin of Organizations',
iterator: 'adminof', // Singular form of name (e.g. thing)
open: false, // Open accordion on load?
index: false,
base: '/organizations',
"delete": {
label: 'Delete',
ngClick: "delete('permissions', permission.id, permission.name, 'permissions')",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Delete the permission',
ngShow: 'PermissionAddAllowed'
actions: {},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
}
}
},
},
organizations: {
type: 'collection',
title: 'Organizations',
iterator: 'organization',
index: false,
open: false,
admin_of_organizations: { // Assumes a plural name (e.g. things)
type: 'collection',
title: 'Admin of Organizations',
iterator: 'adminof', // Singular form of name (e.g. thing)
open: false, // Open accordion on load?
index: false,
base: '/organizations',
actions: {},
actions: {},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
}
}
},
},
organizations: {
type: 'collection',
title: 'Organizations',
iterator: 'organization',
index: false,
open: false,
teams: {
type: 'collection',
title: 'Teams',
iterator: 'team',
open: false,
index: false,
actions: {},
actions: {},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
}
},
teams: {
type: 'collection',
title: 'Teams',
iterator: 'team',
open: false,
index: false,
actions: {},
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description'
}
}
}
}
}
}); //UserForm
}); //UserForm
+11
View File
@@ -0,0 +1,11 @@
import ChromeSocketHelp from "tower/help/ChromeSocketHelp";
import FirefoxSocketHelp from "tower/help/FirefoxSocketHelp";
import InventoryGroups from "tower/help/InventoryGroups";
import SafariSocketHelp from "tower/help/SafariSocketHelp";
export
{ ChromeSocketHelp,
FirefoxSocketHelp,
InventoryGroups,
SafariSocketHelp
}
+82
View File
@@ -0,0 +1,82 @@
import 'tower/forms';
import 'tower/lists';
import AboutAnsible from "tower/helpers/AboutAnsible";
import Access from "tower/helpers/Access";
import Children from "tower/helpers/Children";
import ConfigureTower from "tower/helpers/ConfigureTower";
import Credentials from "tower/helpers/Credentials";
import CustomInventory from "tower/helpers/CustomInventory";
import EventViewer from "tower/helpers/EventViewer";
import Events from "tower/helpers/Events";
import Groups from "tower/helpers/Groups";
import HostEventsViewer from "tower/helpers/HostEventsViewer";
import Hosts from "tower/helpers/Hosts";
import JobDetail from "tower/helpers/JobDetail";
import JobSubmission from "tower/helpers/JobSubmission";
import JobTemplates from "tower/helpers/JobTemplates";
import Jobs from "tower/helpers/Jobs";
import License from "tower/helpers/License";
import LoadConfig from "tower/helpers/LoadConfig";
import LogViewer from "tower/helpers/LogViewer";
import Lookup from "tower/helpers/Lookup";
import PaginationHelpers from "tower/helpers/PaginationHelpers";
import Parse from "tower/helpers/Parse";
import Permissions from "tower/helpers/Permissions";
import ProjectPath from "tower/helpers/ProjectPath";
import Projects from "tower/helpers/Projects";
import Schedules from "tower/helpers/Schedules";
import Selection from "tower/helpers/Selection";
import SocketHelper from "tower/helpers/SocketHelper";
import Survey from "tower/helpers/Survey";
import Users from "tower/helpers/Users";
import Variables from "tower/helpers/Variables";
import ApiDefaults from "tower/helpers/api-defaults";
import inventory from "tower/helpers/inventory";
import MD5 from "tower/helpers/md5";
import RefreshRelated from "tower/helpers/refresh-related";
import Refresh from "tower/helpers/refresh";
import RelatedSearch from "tower/helpers/related-search";
import Search from "tower/helpers/search";
import Teams from "tower/helpers/teams";
export
{ AboutAnsible,
Access,
Children,
ConfigureTower,
Credentials,
CustomInventory,
EventViewer,
Events,
Groups,
HostEventsViewer,
Hosts,
JobDetail,
JobSubmission,
JobTemplates,
Jobs,
License,
LoadConfig,
LogViewer,
Lookup,
PaginationHelpers,
Parse,
Permissions,
ProjectPath,
Projects,
Schedules,
Selection,
SocketHelper,
Survey,
Users,
Variables,
ApiDefaults,
inventory,
MD5,
RefreshRelated,
Refresh,
RelatedSearch,
Search,
Teams
}
+64 -63
View File
@@ -18,74 +18,75 @@
*/
angular.module('AboutAnsibleHelpModal', ['RestServices', 'Utilities','ModalDialog'])
.factory('AboutAnsibleHelp', ['$rootScope', '$compile', '$location' , 'Rest', 'GetBasePath', 'ProcessErrors', 'Wait', 'CreateDialog',
function ($rootScope, $compile , $location, Rest, GetBasePath, ProcessErrors, Wait, CreateDialog) {
return function () {
export default
angular.module('AboutAnsibleHelpModal', ['RestServices', 'Utilities','ModalDialog'])
.factory('AboutAnsibleHelp', ['$rootScope', '$compile', '$location' , 'Rest', 'GetBasePath', 'ProcessErrors', 'Wait', 'CreateDialog',
function ($rootScope, $compile , $location, Rest, GetBasePath, ProcessErrors, Wait, CreateDialog) {
return function () {
var scope= $rootScope.$new(),
url;
var scope= $rootScope.$new(),
url;
url = GetBasePath('config');
Rest.setUrl(url);
Rest.get()
.success(function (data){
scope.$emit('BuildAboutDialog', data);
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get: ' + url + ' GET returned: ' + status });
url = GetBasePath('config');
Rest.setUrl(url);
Rest.get()
.success(function (data){
scope.$emit('BuildAboutDialog', data);
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get: ' + url + ' GET returned: ' + status });
});
if (scope.removeDialogReady) {
scope.removeDialogReady();
}
scope.removeDialogReady = scope.$on('DialogReady', function() {
// element = angular.element(document.getElementById('about-modal-dialog'));
// $compile(element)(scope);
$('#about-modal-dialog').dialog('open');
});
if (scope.removeDialogReady) {
scope.removeDialogReady();
}
scope.removeDialogReady = scope.$on('DialogReady', function() {
// element = angular.element(document.getElementById('about-modal-dialog'));
// $compile(element)(scope);
$('#about-modal-dialog').dialog('open');
});
if (scope.removeBuildAboutDialog) {
scope.removeBuildAboutDialog();
}
scope.removeBuildAboutDialog = scope.$on('BuildAboutDialog', function(e, data) {
var spaces, i, j,
paddedStr = "",
version = data.version.replace(/-.*$/,'');
spaces = Math.floor((16-version.length)/2);
for( i=0; i<=spaces; i++){
paddedStr = paddedStr +" ";
if (scope.removeBuildAboutDialog) {
scope.removeBuildAboutDialog();
}
paddedStr = paddedStr+version;
for( j = paddedStr.length; j<16; j++){
paddedStr = paddedStr + " ";
}
$('#about-modal-version').html(paddedStr);
scope.modalOK = function(){
$('#about-modal-dialog').dialog('close');
};
CreateDialog({
id: 'about-modal-dialog',
scope: scope,
// buttons: [],
width: 710,
height: 380,
minWidth: 300,
resizable: false,
// title: , //'<img src="static/img/tower_login_logo.png">' ,//'About Ansible',
callback: 'DialogReady',
onOpen: function(){
$('#dialog-ok-button').focus();
$('#about-modal-dialog').scrollTop(0);
$('#about-modal-dialog').css('overflow-x', 'hidden');
$('.ui-widget-overlay').css('width', '100%');
scope.removeBuildAboutDialog = scope.$on('BuildAboutDialog', function(e, data) {
var spaces, i, j,
paddedStr = "",
version = data.version.replace(/-.*$/,'');
spaces = Math.floor((16-version.length)/2);
for( i=0; i<=spaces; i++){
paddedStr = paddedStr +" ";
}
paddedStr = paddedStr+version;
for( j = paddedStr.length; j<16; j++){
paddedStr = paddedStr + " ";
}
$('#about-modal-version').html(paddedStr);
scope.modalOK = function(){
$('#about-modal-dialog').dialog('close');
};
CreateDialog({
id: 'about-modal-dialog',
scope: scope,
// buttons: [],
width: 710,
height: 380,
minWidth: 300,
resizable: false,
// title: , //'<img src="static/img/tower_login_logo.png">' ,//'About Ansible',
callback: 'DialogReady',
onOpen: function(){
$('#dialog-ok-button').focus();
$('#about-modal-dialog').scrollTop(0);
$('#about-modal-dialog').css('overflow-x', 'hidden');
$('.ui-widget-overlay').css('width', '100%');
}
});
});
});
};
}
]);
};
}
]);
+46 -46
View File
@@ -13,56 +13,56 @@
*/
export default
angular.module('AccessHelper', ['RestServices', 'Utilities'])
angular.module('AccessHelper', ['RestServices', 'Utilities'])
.factory('CheckAccess', ['$rootScope', 'Alert', 'Rest', 'GetBasePath', 'ProcessErrors', '$cookieStore', function ($rootScope, Alert, Rest, GetBasePath, ProcessErrors, $cookieStore) {
return function (params) {
// set PermissionAddAllowed to true or false based on user access. admins and org admins are granted
// accesss.
var scope = params.scope,
callback = params.callback || undefined,
me;
.factory('CheckAccess', ['$rootScope', 'Alert', 'Rest', 'GetBasePath', 'ProcessErrors', '$cookieStore', function ($rootScope, Alert, Rest, GetBasePath, ProcessErrors, $cookieStore) {
return function (params) {
// set PermissionAddAllowed to true or false based on user access. admins and org admins are granted
// accesss.
var scope = params.scope,
callback = params.callback || undefined,
me;
// uer may have refreshed the browser, in which case retrieve current user info from session cookie
me = ($rootScope.current_user) ? $rootScope.current_user : $cookieStore.get('current_user');
// uer may have refreshed the browser, in which case retrieve current user info from session cookie
me = ($rootScope.current_user) ? $rootScope.current_user : $cookieStore.get('current_user');
if (me.is_superuser) {
scope.PermissionAddAllowed = true;
if(callback){
scope.$emit(callback);
}
} else {
if (me.related.admin_of_organizations) {
Rest.setUrl(me.related.admin_of_organizations);
Rest.get()
.success(function (data) {
if (data.results.length > 0) {
scope.PermissionAddAllowed = true;
} else {
scope.PermissionAddAllowed = false;
}
if(callback){
scope.$emit(callback);
}
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, {
hdr: 'Error!',
msg: 'Call to ' + me.related.admin_of_organizations +
' failed. DELETE returned status: ' + status
if (me.is_superuser) {
scope.PermissionAddAllowed = true;
if(callback){
scope.$emit(callback);
}
} else {
if (me.related.admin_of_organizations) {
Rest.setUrl(me.related.admin_of_organizations);
Rest.get()
.success(function (data) {
if (data.results.length > 0) {
scope.PermissionAddAllowed = true;
} else {
scope.PermissionAddAllowed = false;
}
if(callback){
scope.$emit(callback);
}
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, {
hdr: 'Error!',
msg: 'Call to ' + me.related.admin_of_organizations +
' failed. DELETE returned status: ' + status
});
});
});
}
}
}
//if (!access) {
// Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.');
//}
//return access;
};
}])
//if (!access) {
// Alert('Access Denied', 'You do not have access to this function. Please contact your system administrator.');
//}
//return access;
};
}])
.factory('IsAdmin', ['$rootScope', function($rootScope) {
return function() { return ($rootScope.current_user && $rootScope.current_user.is_superuser); };
}]);
.factory('IsAdmin', ['$rootScope', function($rootScope) {
return function() { return ($rootScope.current_user && $rootScope.current_user.is_superuser); };
}]);
+86 -86
View File
@@ -12,100 +12,100 @@
* See the filter in job_events.js list.
*/
export default
angular.module('ChildrenHelper', ['RestServices', 'Utilities'])
.factory('ToggleChildren', ['$location', 'Store', function ($location, Store) {
return function (params) {
angular.module('ChildrenHelper', ['RestServices', 'Utilities'])
.factory('ToggleChildren', ['$location', 'Store', function ($location, Store) {
return function (params) {
var scope = params.scope,
list = params.list,
id = params.id,
set = scope[list.name],
clicked,
//base = $location.path().replace(/^\//, '').split('/')[0],
path = $location.path(),
local_child_store;
var scope = params.scope,
list = params.list,
id = params.id,
set = scope[list.name],
clicked,
//base = $location.path().replace(/^\//, '').split('/')[0],
path = $location.path(),
local_child_store;
function updateExpand(key, expand) {
var found = false;
local_child_store.every(function(child, i) {
if (child.key === key) {
local_child_store[i].expand = expand;
found = true;
return false;
}
return true;
});
if (!found) {
local_child_store.push({ key: key, expand: expand });
}
}
function updateShow(key, show) {
var found = false;
local_child_store.every(function(child, i) {
if (child.key === key) {
local_child_store[i].show = show;
found = true;
return false;
}
return true;
});
if (!found) {
local_child_store.push({ key: key, show: show });
}
}
function expand(node) {
var i, has_children = false;
for (i = node + 1; i < set.length; i++) {
if (set[i].parent === set[node].id) {
updateShow(set[i].key, true);
set[i].show = true;
function updateExpand(key, expand) {
var found = false;
local_child_store.every(function(child, i) {
if (child.key === key) {
local_child_store[i].expand = expand;
found = true;
return false;
}
return true;
});
if (!found) {
local_child_store.push({ key: key, expand: expand });
}
}
set[node].ngicon = (has_children) ? 'fa fa-minus-square-o node-toggle' : 'fa fa-minus-square-o node-toggle';
}
function collapse(node) {
var i, has_children = false;
for (i = node + 1; i < set.length; i++) {
if (set[i].parent === set[node].id) {
set[i].show = false;
has_children = true;
updateShow(set[i].key, false);
if (set[i].related.children) {
collapse(i);
function updateShow(key, show) {
var found = false;
local_child_store.every(function(child, i) {
if (child.key === key) {
local_child_store[i].show = show;
found = true;
return false;
}
return true;
});
if (!found) {
local_child_store.push({ key: key, show: show });
}
}
function expand(node) {
var i, has_children = false;
for (i = node + 1; i < set.length; i++) {
if (set[i].parent === set[node].id) {
updateShow(set[i].key, true);
set[i].show = true;
}
}
set[node].ngicon = (has_children) ? 'fa fa-minus-square-o node-toggle' : 'fa fa-minus-square-o node-toggle';
}
set[node].ngicon = (has_children) ? 'fa fa-plus-square-o node-toggle' : 'fa fa-square-o node-toggle';
}
local_child_store = Store(path + '_children');
if (!local_child_store) {
local_child_store = [];
}
// Scan the array list and find the clicked element
set.every(function(row, i) {
if (row.id === id) {
clicked = i;
return false;
function collapse(node) {
var i, has_children = false;
for (i = node + 1; i < set.length; i++) {
if (set[i].parent === set[node].id) {
set[i].show = false;
has_children = true;
updateShow(set[i].key, false);
if (set[i].related.children) {
collapse(i);
}
}
}
set[node].ngicon = (has_children) ? 'fa fa-plus-square-o node-toggle' : 'fa fa-square-o node-toggle';
}
return true;
});
// Expand or collapse children based on clicked element's icon
if (/plus-square-o/.test(set[clicked].ngicon)) {
// Expand: lookup and display children
expand(clicked);
updateExpand(set[clicked].key, true);
} else if (/minus-square-o/.test(set[clicked].ngicon)) {
collapse(clicked);
updateExpand(set[clicked].key, false);
}
Store(path + '_children', local_child_store);
};
}
]);
local_child_store = Store(path + '_children');
if (!local_child_store) {
local_child_store = [];
}
// Scan the array list and find the clicked element
set.every(function(row, i) {
if (row.id === id) {
clicked = i;
return false;
}
return true;
});
// Expand or collapse children based on clicked element's icon
if (/plus-square-o/.test(set[clicked].ngicon)) {
// Expand: lookup and display children
expand(clicked);
updateExpand(set[clicked].key, true);
} else if (/minus-square-o/.test(set[clicked].ngicon)) {
collapse(clicked);
updateExpand(set[clicked].key, false);
}
Store(path + '_children', local_child_store);
};
}
]);
+433 -433
View File
@@ -12,458 +12,458 @@
*/
export default
angular.module('ConfigureTowerHelper', [ 'Utilities', 'RestServices', 'SchedulesHelper', 'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'ModalDialog',
'GeneratorHelpers'])
angular.module('ConfigureTowerHelper', [ 'Utilities', 'RestServices', 'SchedulesHelper', 'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'ModalDialog',
'GeneratorHelpers'])
.factory('ConfigureTower', ['Wait', '$location' , '$compile', 'CreateDialog', 'ConfigureTowerJobsList', 'GenerateList', 'GetBasePath' , 'SearchInit' , 'PaginateInit', 'PlaybookRun', 'LoadSchedulesScope',
'SchedulesList', 'SchedulesControllerInit' , 'ConfigureTowerSchedule', 'Rest' , 'ProcessErrors',
function(Wait, $location, $compile, CreateDialog, ConfigureTowerJobsList, GenerateList, GetBasePath, SearchInit, PaginateInit, PlaybookRun, LoadSchedulesScope,
SchedulesList, SchedulesControllerInit, ConfigureTowerSchedule, Rest, ProcessErrors) {
return function(params) {
// Set modal dimensions based on viewport width
.factory('ConfigureTower', ['Wait', '$location' , '$compile', 'CreateDialog', 'ConfigureTowerJobsList', 'GenerateList', 'GetBasePath' , 'SearchInit' , 'PaginateInit', 'PlaybookRun', 'LoadSchedulesScope',
'SchedulesList', 'SchedulesControllerInit' , 'ConfigureTowerSchedule', 'Rest' , 'ProcessErrors',
function(Wait, $location, $compile, CreateDialog, ConfigureTowerJobsList, GenerateList, GetBasePath, SearchInit, PaginateInit, PlaybookRun, LoadSchedulesScope,
SchedulesList, SchedulesControllerInit, ConfigureTowerSchedule, Rest, ProcessErrors) {
return function(params) {
// Set modal dimensions based on viewport width
var scope = params.scope.$new(),
parent_scope = params.scope,
callback = 'OpenConfig',
defaultUrl = GetBasePath('system_job_templates'),
list = ConfigureTowerJobsList,
view = GenerateList, e,
scheduleUrl = GetBasePath('system_job_templates'),
buttons = [
{
"label": "Close",
"onClick": function() {
// $(this).dialog('close');
scope.cancelConfigure();
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "configure-close-button"
}
];
scope.cleanupJob = true;
if(scope.removeOpenConfig) {
scope.removeOpenConfig();
}
scope.removeOpenConfig = scope.$on('OpenConfig', function() {
$('#configure-tower-dialog').dialog('open');
$('#configure-close-button').focus();
$('#configure-close-button').blur();
});
view.inject( list, {
id : 'configure-jobs',
mode: 'edit',
scope: scope,
breadCrumbs: false,
showSearch: false
});
SearchInit({
scope: scope,
set: 'configure_jobs',
list: list,
url: defaultUrl
});
PaginateInit({
scope: scope,
list: list,
url: defaultUrl
});
scope.search(list.iterator);
SchedulesControllerInit({
scope: scope,
parent_scope: parent_scope,
// list: list
});
CreateDialog({
id: 'configure-tower-dialog',
title: 'Management Jobs',
target: 'configure-tower-dialog',
scope: scope,
buttons: buttons,
width: 670,
height: 800,
minWidth: 400,
callback: callback,
onClose: function () {
// Destroy on close
$('.tooltip').each(function () {
// Remove any lingering tooltip <div> elements
$(this).remove();
});
$('.popover').each(function () {
// remove lingering popover <div> elements
$(this).remove();
});
$("#configure-jobs").show();
$("#configure-schedules-form-container").hide();
$('#configure-schedules-list').empty();
$('#configure-schedules-form').empty();
$('#configure-schedules-detail').empty();
$('#configure-tower-dialog').hide();
$(this).dialog('destroy');
scope.cancelConfigure();
},
});
// Cancel
scope.cancelConfigure = function () {
try {
$('#configure-tower-dialog').dialog('close');
$("#configure-save-button").remove();
}
catch(e) {
//ignore
}
if (scope.searchCleanup) {
scope.searchCleanup();
}
// if (!Empty(parent_scope) && parent_scope.restoreSearch) {
// parent_scope.restoreSearch();
// }
else {
Wait('stop');
}
};
scope.submitJob = function (id, name) {
Wait('start');
defaultUrl = GetBasePath('system_job_templates')+id+'/launch/';
CreateDialog({
id: 'prompt-for-days' ,
title: name,
scope: scope,
width: 500,
height: 300,
minWidth: 200,
callback: 'PromptForDays',
onOpen: function(){
e = angular.element(document.getElementById('prompt_for_days_form'));
scope.prompt_for_days_form.days_to_keep.$setViewValue(30);
$compile(e)(scope);
$('#prompt-for-days-launch').attr("ng-disabled", 'prompt_for_days_form.$invalid');
e = angular.element(document.getElementById('prompt-for-days-launch'));
$compile(e)(scope);
},
buttons: [{
"label": "Cancel",
var scope = params.scope.$new(),
parent_scope = params.scope,
callback = 'OpenConfig',
defaultUrl = GetBasePath('system_job_templates'),
list = ConfigureTowerJobsList,
view = GenerateList, e,
scheduleUrl = GetBasePath('system_job_templates'),
buttons = [
{
"label": "Close",
"onClick": function() {
$(this).dialog('close');
// $(this).dialog('close');
scope.cancelConfigure();
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "prompt-for-days-cancel"
},{
"label": "Launch",
"onClick": function() {
var extra_vars = {"days": scope.days_to_keep },
data = {};
data.extra_vars = JSON.stringify(extra_vars);
"id": "configure-close-button"
}
];
Rest.setUrl(defaultUrl);
Rest.post(data)
.success(function() {
Wait('stop');
$("#prompt-for-days").dialog("close");
$("#configure-tower-dialog").dialog('close');
$location.path('/jobs/');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed updating job ' + scope.job_template_id + ' with variables. POST returned: ' + status });
});
},
"icon": "fa-rocket",
"class": "btn btn-primary",
"id": "prompt-for-days-launch"
}]
});
scope.cleanupJob = true;
if (scope.removePromptForDays) {
scope.removePromptForDays();
if(scope.removeOpenConfig) {
scope.removeOpenConfig();
}
scope.removePromptForDays = scope.$on('PromptForDays', function() {
// $('#configure-tower-dialog').dialog('close');
$('#prompt-for-days').show();
$('#prompt-for-days').dialog('open');
Wait('stop');
scope.removeOpenConfig = scope.$on('OpenConfig', function() {
$('#configure-tower-dialog').dialog('open');
$('#configure-close-button').focus();
$('#configure-close-button').blur();
});
view.inject( list, {
id : 'configure-jobs',
mode: 'edit',
scope: scope,
breadCrumbs: false,
showSearch: false
});
SearchInit({
scope: scope,
set: 'configure_jobs',
list: list,
url: defaultUrl
});
PaginateInit({
scope: scope,
list: list,
url: defaultUrl
});
scope.search(list.iterator);
SchedulesControllerInit({
scope: scope,
parent_scope: parent_scope,
// list: list
});
CreateDialog({
id: 'configure-tower-dialog',
title: 'Management Jobs',
target: 'configure-tower-dialog',
scope: scope,
buttons: buttons,
width: 670,
height: 800,
minWidth: 400,
callback: callback,
onClose: function () {
// Destroy on close
$('.tooltip').each(function () {
// Remove any lingering tooltip <div> elements
$(this).remove();
});
$('.popover').each(function () {
// remove lingering popover <div> elements
$(this).remove();
});
$("#configure-jobs").show();
$("#configure-schedules-form-container").hide();
$('#configure-schedules-list').empty();
$('#configure-schedules-form').empty();
$('#configure-schedules-detail').empty();
$('#configure-tower-dialog').hide();
$(this).dialog('destroy');
scope.cancelConfigure();
},
});
// Cancel
scope.cancelConfigure = function () {
try {
$('#configure-tower-dialog').dialog('close');
$("#configure-save-button").remove();
}
catch(e) {
//ignore
}
if (scope.searchCleanup) {
scope.searchCleanup();
}
// if (!Empty(parent_scope) && parent_scope.restoreSearch) {
// parent_scope.restoreSearch();
// }
else {
Wait('stop');
}
};
scope.submitJob = function (id, name) {
Wait('start');
defaultUrl = GetBasePath('system_job_templates')+id+'/launch/';
CreateDialog({
id: 'prompt-for-days' ,
title: name,
scope: scope,
width: 500,
height: 300,
minWidth: 200,
callback: 'PromptForDays',
onOpen: function(){
e = angular.element(document.getElementById('prompt_for_days_form'));
scope.prompt_for_days_form.days_to_keep.$setViewValue(30);
$compile(e)(scope);
$('#prompt-for-days-launch').attr("ng-disabled", 'prompt_for_days_form.$invalid');
e = angular.element(document.getElementById('prompt-for-days-launch'));
$compile(e)(scope);
},
buttons: [{
"label": "Cancel",
"onClick": function() {
$(this).dialog('close');
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "prompt-for-days-cancel"
},{
"label": "Launch",
"onClick": function() {
var extra_vars = {"days": scope.days_to_keep },
data = {};
data.extra_vars = JSON.stringify(extra_vars);
Rest.setUrl(defaultUrl);
Rest.post(data)
.success(function() {
Wait('stop');
$("#prompt-for-days").dialog("close");
$("#configure-tower-dialog").dialog('close');
$location.path('/jobs/');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed updating job ' + scope.job_template_id + ' with variables. POST returned: ' + status });
});
},
"icon": "fa-rocket",
"class": "btn btn-primary",
"id": "prompt-for-days-launch"
}]
});
if (scope.removePromptForDays) {
scope.removePromptForDays();
}
scope.removePromptForDays = scope.$on('PromptForDays', function() {
// $('#configure-tower-dialog').dialog('close');
$('#prompt-for-days').show();
$('#prompt-for-days').dialog('open');
Wait('stop');
});
};
scope.configureSchedule = function(id, name) {
Rest.setUrl(scheduleUrl+id+'/schedules/');
Rest.get()
.success(function(data) {
if(data.count>0){
scope.days=data.results[0].extra_data.days;
ConfigureTowerSchedule({
scope: scope,
mode: 'edit',
url: scheduleUrl+id+'/schedules/'
});
} else {
ConfigureTowerSchedule({
scope: scope,
mode: 'add',
url: scheduleUrl+id+'/schedules/',
name: name
});
}
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed getting schedule information' });
});
};
parent_scope.refreshJobs = function(){
scope.search(SchedulesList.iterator);
};
};
}])
.factory('ConfigureTowerSchedule', ['$compile','SchedulerInit', 'Rest', 'Wait', 'SetSchedulesInnerDialogSize', 'SchedulePost', 'ProcessErrors', 'GetBasePath', 'Empty', 'Prompt',
function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, SchedulePost, ProcessErrors, GetBasePath, Empty, Prompt) {
return function(params) {
var parent_scope = params.scope,
mode = params.mode, // 'add' or 'edit'
url = params.url,
scope = parent_scope.$new(),
id = params.id || undefined,
name = params.name || undefined,
schedule = {},
scheduler,
target,
showForm,
list,
detail,
restoreList,
container,
elem;
Wait('start');
// $('#configure-jobs').hide();
detail = $('#configure-schedules-detail').hide();
list = $('#configure-schedules-list');
target = $('#configure-schedules-form');
container = $('#configure-schedules-form-container');
$("#configure-jobs").show();
$("#configure-schedules-form-container").hide();
scope.mode = mode;
// Clean up any lingering stuff
container.hide();
target.empty();
$('.tooltip').each(function () {
$(this).remove();
});
$('.popover').each(function () {
$(this).remove();
});
$("#configure-cancel-button").after('<button type="button" class="btn btn-primary btn-sm" id="configure-save-button" ng-click="saveScheduleForm()" style="margin-left:5px"><i class="fa fa-check"></i> Save</button>');
elem = angular.element(document.getElementById('configure-schedules-form-container'));
$compile(elem)(scope);
if (scope.removeScheduleReady) {
scope.removeScheduleReady();
}
scope.removeScheduleReady = scope.$on('ScheduleReady', function() {
// Insert the scheduler widget into the hidden div
scheduler = SchedulerInit({ scope: scope, requireFutureStartTime: false });
scheduler.inject('configure-schedules-form', false);
scheduler.injectDetail('configure-schedules-detail', false);
scheduler.clear();
scope.formShowing = true;
scope.showRRuleDetail = false;
scope.schedulesTitle = (mode === 'edit') ? 'Edit Schedule' : 'Create Schedule';
// display the scheduler widget
showForm = function() {
$('#configure-jobs').show('slide', { direction: 'left' }, 500);
$('#configure-jobs').hide();
Wait('stop');
$('#configure-schedules-overlay').width($('#configure-schedules-tab')
.width()).height($('#configure-schedules-tab').height()).show();
container.width($('#configure-schedules-tab').width() - 18);
SetSchedulesInnerDialogSize();
container.show('slide', { direction: 'right' }, 300);
// scope.schedulerPurgeDays = (!Empty(scope.days)) ? Number(scope.days) : 30;
target.show();
if(mode==="add"){
scope.$apply(function(){
scope.schedulerPurgeDays = 30;
scope.schedulerName = name+' Schedule';
});
}
if (mode === 'edit') {
scope.$apply(function() {
scheduler.setRRule(schedule.rrule);
scheduler.setName(schedule.name);
scope.schedulerPurgeDays = (!Empty(scope.days)) ? Number(scope.days) : 30;
});
}
};
setTimeout(function() { showForm(); }, 1000);
});
restoreList = function() {
// $('#group-save-button').prop('disabled', false);
$('#configure-jobs').show('slide', { direction: 'right' }, 500);
// $('#configure-jobs').width($('#configure-jobs').width()).height($('#configure-jobs').height()).hide();
// parent_scope.refreshSchedules();
list.show('slide', { direction: 'right' }, 500);
$('#configure-schedules-overlay').width($('#configure-schedules-tab').width()).height($('#configure-schedules-tab').height()).hide();
parent_scope.refreshSchedules();
};
scope.configureSchedule = function(id, name) {
Rest.setUrl(scheduleUrl+id+'/schedules/');
scope.showScheduleDetail = function() {
if (scope.formShowing) {
if (scheduler.isValid()) {
detail.width($('#configure-schedules-form').width()).height($('#configure-schedules-form').height());
target.hide();
detail.show();
scope.formShowing = false;
}
}
else {
detail.hide();
target.show();
scope.formShowing = true;
}
};
if (scope.removeScheduleSaved) {
scope.removeScheduleSaved();
}
scope.removeScheduleSaved = scope.$on('ScheduleSaved', function() {
Wait('stop');
$("#configure-save-button").remove();
container.hide('slide', { direction: 'left' }, 500, restoreList);
scope.$destroy();
});
scope.saveScheduleForm = function() {
var extra_vars;
if (scheduler.isValid()) {
scope.schedulerIsValid = true;
url = (mode==="edit") ? GetBasePath('schedules')+id+'/' : url;
extra_vars = {
"days" : scope.scheduler_form.schedulerPurgeDays.$viewValue
};
schedule.extra_data = JSON.stringify(extra_vars);
SchedulePost({
scope: scope,
url: url,
scheduler: scheduler,
callback: 'ScheduleSaved',
mode: mode,
schedule: schedule
});
}
else {
scope.schedulerIsValid = false;
}
};
scope.deleteSystemSchedule = function(){
var hdr = 'Delete Schedule',
action = function () {
Wait('start');
Rest.setUrl(schedule.url);
Rest.destroy()
.success(function () {
$('#prompt-modal').modal('hide');
Wait('stop');
// scope.$emit(callback, id);
scope.cancelScheduleForm();
})
.error(function (data, status) {
try {
$('#prompt-modal').modal('hide');
}
catch(e) {
// ignore
}
ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url +
' failed. DELETE returned: ' + status });
});
};
Prompt({
hdr: hdr,
body: "<div class=\"alert alert-info\">Are you sure you want to delete the <em>" + scope.schedulerName + "</em> schedule?</div>",
action: action,
backdrop: false
});
// }
// } else {
// //a schedule doesn't exist
// $("#prompt_action_btn").text('OK');
// $('#prompt_cancel_btn').hide();
// var action2 = function(){
// $('#prompt-modal').modal('hide');
// $("#prompt_action_btn").text('Yes');
// $('#prompt_cancel_btn').show();
// };
// Prompt({
// hdr: "Delete",
// body: "<div class=\"alert alert-info\">No schedule exists for that job. </div>",
// action: action2,
// backdrop: false
// });
// }
// })
// .error(function(data, status) {
// ProcessErrors(scope, data, status, null, { hdr: 'Error!',
// msg: 'Failed updating job ' + scope.job_template_id + ' with variables. PUT returned: ' + status });
// });
};
scope.cancelScheduleForm = function() {
container.hide('slide', { direction: 'right' }, 500, restoreList);
$("#configure-save-button").remove();
scope.$destroy();
};
if (mode === 'edit') {
// Get the existing record
Rest.setUrl(url); //GetBasePath('schedules')+id+'/');
Rest.get()
.success(function(data) {
if(data.count>0){
scope.days=data.results[0].extra_data.days;
ConfigureTowerSchedule({
scope: scope,
mode: 'edit',
url: scheduleUrl+id+'/schedules/'
});
} else {
ConfigureTowerSchedule({
scope: scope,
mode: 'add',
url: scheduleUrl+id+'/schedules/',
name: name
});
schedule = data.results[0];
id = schedule.id;
if (!/DTSTART/.test(schedule.rrule)) {
schedule.rrule += ";DTSTART=" + schedule.dtstart.replace(/\.\d+Z$/,'Z');
}
schedule.rrule = schedule.rrule.replace(/ RRULE:/,';');
schedule.rrule = schedule.rrule.replace(/DTSTART:/,'DTSTART=');
scope.$emit('ScheduleReady');
})
.error(function(data, status) {
.error(function(data,status){
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed getting schedule information' });
msg: 'Failed to get: ' + url + ' GET returned: ' + status });
});
};
parent_scope.refreshJobs = function(){
scope.search(SchedulesList.iterator);
};
};
}])
.factory('ConfigureTowerSchedule', ['$compile','SchedulerInit', 'Rest', 'Wait', 'SetSchedulesInnerDialogSize', 'SchedulePost', 'ProcessErrors', 'GetBasePath', 'Empty', 'Prompt',
function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, SchedulePost, ProcessErrors, GetBasePath, Empty, Prompt) {
return function(params) {
var parent_scope = params.scope,
mode = params.mode, // 'add' or 'edit'
url = params.url,
scope = parent_scope.$new(),
id = params.id || undefined,
name = params.name || undefined,
schedule = {},
scheduler,
target,
showForm,
list,
detail,
restoreList,
container,
elem;
Wait('start');
// $('#configure-jobs').hide();
detail = $('#configure-schedules-detail').hide();
list = $('#configure-schedules-list');
target = $('#configure-schedules-form');
container = $('#configure-schedules-form-container');
$("#configure-jobs").show();
$("#configure-schedules-form-container").hide();
scope.mode = mode;
// Clean up any lingering stuff
container.hide();
target.empty();
$('.tooltip').each(function () {
$(this).remove();
});
$('.popover').each(function () {
$(this).remove();
});
$("#configure-cancel-button").after('<button type="button" class="btn btn-primary btn-sm" id="configure-save-button" ng-click="saveScheduleForm()" style="margin-left:5px"><i class="fa fa-check"></i> Save</button>');
elem = angular.element(document.getElementById('configure-schedules-form-container'));
$compile(elem)(scope);
if (scope.removeScheduleReady) {
scope.removeScheduleReady();
}
scope.removeScheduleReady = scope.$on('ScheduleReady', function() {
// Insert the scheduler widget into the hidden div
scheduler = SchedulerInit({ scope: scope, requireFutureStartTime: false });
scheduler.inject('configure-schedules-form', false);
scheduler.injectDetail('configure-schedules-detail', false);
scheduler.clear();
scope.formShowing = true;
scope.showRRuleDetail = false;
scope.schedulesTitle = (mode === 'edit') ? 'Edit Schedule' : 'Create Schedule';
// display the scheduler widget
showForm = function() {
$('#configure-jobs').show('slide', { direction: 'left' }, 500);
$('#configure-jobs').hide();
Wait('stop');
$('#configure-schedules-overlay').width($('#configure-schedules-tab')
.width()).height($('#configure-schedules-tab').height()).show();
container.width($('#configure-schedules-tab').width() - 18);
SetSchedulesInnerDialogSize();
container.show('slide', { direction: 'right' }, 300);
// scope.schedulerPurgeDays = (!Empty(scope.days)) ? Number(scope.days) : 30;
target.show();
if(mode==="add"){
scope.$apply(function(){
scope.schedulerPurgeDays = 30;
scope.schedulerName = name+' Schedule';
});
}
if (mode === 'edit') {
scope.$apply(function() {
scheduler.setRRule(schedule.rrule);
scheduler.setName(schedule.name);
scope.schedulerPurgeDays = (!Empty(scope.days)) ? Number(scope.days) : 30;
});
}
};
setTimeout(function() { showForm(); }, 1000);
});
restoreList = function() {
// $('#group-save-button').prop('disabled', false);
$('#configure-jobs').show('slide', { direction: 'right' }, 500);
// $('#configure-jobs').width($('#configure-jobs').width()).height($('#configure-jobs').height()).hide();
// parent_scope.refreshSchedules();
list.show('slide', { direction: 'right' }, 500);
$('#configure-schedules-overlay').width($('#configure-schedules-tab').width()).height($('#configure-schedules-tab').height()).hide();
parent_scope.refreshSchedules();
};
scope.showScheduleDetail = function() {
if (scope.formShowing) {
if (scheduler.isValid()) {
detail.width($('#configure-schedules-form').width()).height($('#configure-schedules-form').height());
target.hide();
detail.show();
scope.formShowing = false;
}
}
else {
detail.hide();
target.show();
scope.formShowing = true;
scope.$emit('ScheduleReady');
}
};
if (scope.removeScheduleSaved) {
scope.removeScheduleSaved();
}
scope.removeScheduleSaved = scope.$on('ScheduleSaved', function() {
Wait('stop');
$("#configure-save-button").remove();
container.hide('slide', { direction: 'left' }, 500, restoreList);
scope.$destroy();
});
scope.saveScheduleForm = function() {
var extra_vars;
if (scheduler.isValid()) {
scope.schedulerIsValid = true;
url = (mode==="edit") ? GetBasePath('schedules')+id+'/' : url;
extra_vars = {
"days" : scope.scheduler_form.schedulerPurgeDays.$viewValue
};
schedule.extra_data = JSON.stringify(extra_vars);
SchedulePost({
scope: scope,
url: url,
scheduler: scheduler,
callback: 'ScheduleSaved',
mode: mode,
schedule: schedule
});
}
else {
scope.schedulerIsValid = false;
}
};
scope.deleteSystemSchedule = function(){
var hdr = 'Delete Schedule',
action = function () {
Wait('start');
Rest.setUrl(schedule.url);
Rest.destroy()
.success(function () {
$('#prompt-modal').modal('hide');
Wait('stop');
// scope.$emit(callback, id);
scope.cancelScheduleForm();
})
.error(function (data, status) {
try {
$('#prompt-modal').modal('hide');
}
catch(e) {
// ignore
}
ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url +
' failed. DELETE returned: ' + status });
});
};
Prompt({
hdr: hdr,
body: "<div class=\"alert alert-info\">Are you sure you want to delete the <em>" + scope.schedulerName + "</em> schedule?</div>",
action: action,
backdrop: false
});
// }
// } else {
// //a schedule doesn't exist
// $("#prompt_action_btn").text('OK');
// $('#prompt_cancel_btn').hide();
// var action2 = function(){
// $('#prompt-modal').modal('hide');
// $("#prompt_action_btn").text('Yes');
// $('#prompt_cancel_btn').show();
// };
// Prompt({
// hdr: "Delete",
// body: "<div class=\"alert alert-info\">No schedule exists for that job. </div>",
// action: action2,
// backdrop: false
// });
// }
// })
// .error(function(data, status) {
// ProcessErrors(scope, data, status, null, { hdr: 'Error!',
// msg: 'Failed updating job ' + scope.job_template_id + ' with variables. PUT returned: ' + status });
// });
};
scope.cancelScheduleForm = function() {
container.hide('slide', { direction: 'right' }, 500, restoreList);
$("#configure-save-button").remove();
scope.$destroy();
};
if (mode === 'edit') {
// Get the existing record
Rest.setUrl(url); //GetBasePath('schedules')+id+'/');
Rest.get()
.success(function(data) {
schedule = data.results[0];
id = schedule.id;
if (!/DTSTART/.test(schedule.rrule)) {
schedule.rrule += ";DTSTART=" + schedule.dtstart.replace(/\.\d+Z$/,'Z');
}
schedule.rrule = schedule.rrule.replace(/ RRULE:/,';');
schedule.rrule = schedule.rrule.replace(/DTSTART:/,'DTSTART=');
scope.$emit('ScheduleReady');
})
.error(function(data,status){
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get: ' + url + ' GET returned: ' + status });
});
}
else {
scope.$emit('ScheduleReady');
}
};
}]);
}]);
+251 -227
View File
@@ -5,263 +5,287 @@
*
*
*/
/**
/**
* @ngdoc function
* @name helpers.function:Credentials
* @description Functions shared amongst Credential related controllers
*/
*/
export default
angular.module('CredentialsHelper', ['Utilities'])
.factory('KindChange', ['Empty',
function (Empty) {
return function (params) {
function (Empty) {
return function (params) {
var scope = params.scope,
reset = params.reset,
collapse, id;
var scope = params.scope,
reset = params.reset,
collapse, id;
$('.popover').each(function() {
// remove lingering popover <div>. Seems to be a bug in TB3 RC1
$(this).remove();
});
$('.tooltip').each( function() {
// close any lingering tool tipss
$(this).hide();
});
// Put things in a default state
scope.usernameLabel = 'Username';
scope.aws_required = false;
scope.email_required = false;
scope.rackspace_required = false;
scope.sshKeyDataLabel = 'SSH Private Key';
scope.username_required = false; // JT-- added username_required b/c mutliple 'kinds' need username to be required (GCE)
scope.key_required = false; // JT -- doing the same for key and project
scope.project_required = false;
scope.subscription_required = false;
scope.key_description = "Paste the contents of the SSH private key file.";
scope.key_hint= "drag and drop an SSH private key file on the field below";
scope.host_required = false;
scope.password_required = false;
scope.hostLabel = '';
$('.popover').each(function() {
// remove lingering popover <div>. Seems to be a bug in TB3 RC1
$(this).remove();
});
$('.tooltip').each( function() {
// close any lingering tool tipss
$(this).hide();
});
// Put things in a default state
scope.usernameLabel = 'Username';
scope.aws_required = false;
scope.email_required = false;
scope.rackspace_required = false;
scope.sshKeyDataLabel = 'SSH Private Key';
scope.username_required = false; // JT-- added username_required b/c mutliple 'kinds' need username to be required (GCE)
scope.key_required = false; // JT -- doing the same for key and project
scope.project_required = false;
scope.subscription_required = false;
scope.key_description = "Paste the contents of the SSH private key file.<div class=\"popover-footer\"><span class=\"key\">esc</span> or click to close</div>";
scope.key_hint= "drag and drop an SSH private key file on the field below";
scope.host_required = false;
scope.password_required = false;
scope.hostLabel = '';
if (!Empty(scope.kind)) {
// Apply kind specific settings
switch (scope.kind.value) {
case 'aws':
scope.aws_required = true;
break;
case 'rax':
scope.rackspace_required = true;
scope.username_required = true;
break;
case 'ssh':
scope.usernameLabel = 'Username'; //formally 'SSH Username'
break;
case 'scm':
scope.sshKeyDataLabel = 'SCM Private Key';
break;
case 'gce':
scope.usernameLabel = 'Service Account Email Address';
scope.sshKeyDataLabel = 'RSA Private Key';
scope.email_required = true;
scope.key_required = true;
scope.project_required = true;
scope.key_description = 'Paste the contents of the PEM file associated with the service account email.';
scope.key_hint= "drag and drop a private key file on the field below";
break;
case 'azure':
scope.usernameLabel = "Subscription ID";
scope.sshKeyDataLabel = 'Management Certificate';
scope.subscription_required = true;
scope.key_required = true;
scope.key_description = "Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console.";
scope.key_hint= "drag and drop a management certificate file on the field below";
break;
case 'vmware':
scope.username_required = true;
scope.host_required = true;
scope.password_required = true;
scope.hostLabel = "vCenter Host";
break;
}
}
$('.popover').each(function() {
// remove lingering popover <div>. Seems to be a bug in TB3 RC1
$(this).remove();
});
$('.tooltip').each( function() {
// close any lingering tool tipss
$(this).hide();
});
// Put things in a default state
scope.usernameLabel = 'Username';
scope.aws_required = false;
scope.email_required = false;
scope.rackspace_required = false;
scope.sshKeyDataLabel = 'SSH Private Key';
scope.username_required = false; // JT-- added username_required b/c mutliple 'kinds' need username to be required (GCE)
scope.key_required = false; // JT -- doing the same for key and project
scope.project_required = false;
scope.subscription_required = false;
scope.key_description = "Paste the contents of the SSH private key file.";
scope.key_hint= "drag and drop an SSH private key file on the field below";
scope.host_required = false;
scope.password_required = false;
scope.hostLabel = '';
// Reset all the field values related to Kind.
if (reset) {
scope.access_key = null;
scope.secret_key = null;
scope.api_key = null;
scope.username = null;
scope.password = null;
scope.password_confirm = null;
scope.ssh_key_data = null;
scope.ssh_key_unlock = null;
scope.ssh_key_unlock_confirm = null;
scope.sudo_username = null;
scope.sudo_password = null;
scope.sudo_password_confirm = null;
scope.su_username = null;
scope.su_password = null;
scope.su_password_confirm = null;
}
if (!Empty(scope.kind)) {
// Apply kind specific settings
switch (scope.kind.value) {
case 'aws':
scope.aws_required = true;
break;
case 'rax':
scope.rackspace_required = true;
scope.username_required = true;
break;
case 'ssh':
scope.usernameLabel = 'Username'; //formally 'SSH Username'
break;
case 'scm':
scope.sshKeyDataLabel = 'SCM Private Key';
break;
case 'gce':
scope.usernameLabel = 'Service Account Email Address';
scope.sshKeyDataLabel = 'RSA Private Key';
scope.email_required = true;
scope.key_required = true;
scope.project_required = true;
scope.key_description = 'Paste the contents of the PEM file associated with the service account email.';
scope.key_hint= "drag and drop a private key file on the field below";
break;
case 'azure':
scope.usernameLabel = "Subscription ID";
scope.sshKeyDataLabel = 'Management Certificate';
scope.subscription_required = true;
scope.key_required = true;
scope.key_description = "Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console.";
scope.key_hint= "drag and drop a management certificate file on the field below";
break;
case 'vmware':
scope.username_required = true;
scope.host_required = true;
scope.password_required = true;
scope.hostLabel = "vCenter Host";
break;
}
}
// Collapse or open help widget based on whether scm value is selected
collapse = $('#credential_kind').parent().find('.panel-collapse').first();
id = collapse.attr('id');
if (!Empty(scope.kind) && scope.kind.value !== '') {
if ($('#' + id + '-icon').hasClass('icon-minus')) {
scope.accordionToggle('#' + id);
}
} else {
if ($('#' + id + '-icon').hasClass('icon-plus')) {
scope.accordionToggle('#' + id);
}
}
// Reset all the field values related to Kind.
if (reset) {
scope.access_key = null;
scope.secret_key = null;
scope.api_key = null;
scope.username = null;
scope.password = null;
scope.password_confirm = null;
scope.ssh_key_data = null;
scope.ssh_key_unlock = null;
scope.ssh_key_unlock_confirm = null;
scope.sudo_username = null;
scope.sudo_password = null;
scope.sudo_password_confirm = null;
scope.su_username = null;
scope.su_password = null;
scope.su_password_confirm = null;
}
};
}
// Collapse or open help widget based on whether scm value is selected
collapse = $('#credential_kind').parent().find('.panel-collapse').first();
id = collapse.attr('id');
if (!Empty(scope.kind) && scope.kind.value !== '') {
if ($('#' + id + '-icon').hasClass('icon-minus')) {
scope.accordionToggle('#' + id);
}
} else {
if ($('#' + id + '-icon').hasClass('icon-plus')) {
scope.accordionToggle('#' + id);
}
}
};
}
])
.factory('OwnerChange', [
function () {
return function (params) {
var scope = params.scope,
owner = scope.owner;
if (owner === 'team') {
scope.team_required = true;
scope.user_required = false;
scope.user = null;
scope.user_username = null;
} else {
scope.team_required = false;
scope.user_required = true;
scope.team = null;
scope.team_name = null;
}
};
}
return function (params) {
var scope = params.scope,
owner = scope.owner;
if (owner === 'team') {
scope.team_required = true;
scope.user_required = false;
scope.user = null;
scope.user_username = null;
} else {
scope.team_required = false;
scope.user_required = true;
scope.team = null;
scope.team_name = null;
}
};
}
])
.factory('LoginMethodChange', [
function () {
return function (params) {
var scope = params.scope,
login_method = scope.login_method;
if (login_method !== 'sudo') {
scope.sudo_username = null;
scope.sudo_password = null;
}
if (login_method !== 'su') {
scope.su_username = null;
scope.su_password = null;
}
};
}
return function (params) {
var scope = params.scope,
login_method = scope.login_method;
if (login_method !== 'sudo') {
scope.sudo_username = null;
scope.sudo_password = null;
}
if (login_method !== 'su') {
scope.su_username = null;
scope.su_password = null;
}
};
}
])
.factory('FormSave', ['$location', 'Alert', 'Rest', 'ProcessErrors', 'Empty', 'GetBasePath', 'CredentialForm', 'ReturnToCaller', 'Wait',
function ($location, Alert, Rest, ProcessErrors, Empty, GetBasePath, CredentialForm, ReturnToCaller, Wait) {
return function (params) {
var scope = params.scope,
mode = params.mode,
form = CredentialForm,
data = {}, fld, url;
function ($location, Alert, Rest, ProcessErrors, Empty, GetBasePath, CredentialForm, ReturnToCaller, Wait) {
return function (params) {
var scope = params.scope,
mode = params.mode,
form = CredentialForm,
data = {}, fld, url;
for (fld in form.fields) {
if (fld !== 'access_key' && fld !== 'secret_key' && fld !== 'ssh_username' &&
fld !== 'ssh_password') {
if (scope[fld] === null) {
data[fld] = "";
} else {
data[fld] = scope[fld];
}
}
}
for (fld in form.fields) {
if (fld !== 'access_key' && fld !== 'secret_key' && fld !== 'ssh_username' &&
fld !== 'ssh_password') {
if (scope[fld] === null) {
data[fld] = "";
} else {
data[fld] = scope[fld];
}
}
}
if (!Empty(scope.team)) {
data.team = scope.team;
data.user = "";
} else {
data.user = scope.user;
data.team = "";
}
if (!Empty(scope.team)) {
data.team = scope.team;
data.user = "";
} else {
data.user = scope.user;
data.team = "";
}
data.kind = scope.kind.value;
data.kind = scope.kind.value;
switch (data.kind) {
case 'ssh':
data.password = scope.ssh_password;
break;
case 'aws':
data.username = scope.access_key;
data.password = scope.secret_key;
break;
case 'rax':
data.password = scope.api_key;
break;
case 'gce':
data.username = scope.email_address;
data.project = scope.project;
break;
case 'azure':
data.username = scope.subscription_id;
}
switch (data.kind) {
case 'ssh':
data.password = scope.ssh_password;
break;
case 'aws':
data.username = scope.access_key;
data.password = scope.secret_key;
break;
case 'rax':
data.password = scope.api_key;
break;
case 'gce':
data.username = scope.email_address;
data.project = scope.project;
break;
case 'azure':
data.username = scope.subscription_id;
}
if (Empty(data.team) && Empty(data.user)) {
Alert('Missing User or Team', 'You must provide either a User or a Team. If this credential will only be accessed by a specific ' +
'user, select a User. To allow a team of users to access this credential, select a Team.', 'alert-danger');
} else {
Wait('start');
if (mode === 'add') {
url = (!Empty(data.team)) ? GetBasePath('teams') + data.team + '/credentials/' :
GetBasePath('users') + data.user + '/credentials/';
Rest.setUrl(url);
Rest.post(data)
.success(function () {
Wait('stop');
var base = $location.path().replace(/^\//, '').split('/')[0];
if (base === 'credentials') {
ReturnToCaller();
}
else {
ReturnToCaller(1);
}
})
.error(function (data, status) {
Wait('stop');
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to create new Credential. POST status: ' + status
});
});
} else {
url = GetBasePath('credentials') + scope.id + '/';
Rest.setUrl(url);
Rest.put(data)
.success(function () {
Wait('stop');
var base = $location.path().replace(/^\//, '').split('/')[0];
if (base === 'credentials') {
ReturnToCaller();
}
else {
ReturnToCaller(1);
}
})
.error(function (data, status) {
Wait('stop');
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to update Credential. PUT status: ' + status
});
});
}
}
};
}
if (Empty(data.team) && Empty(data.user)) {
Alert('Missing User or Team', 'You must provide either a User or a Team. If this credential will only be accessed by a specific ' +
'user, select a User. To allow a team of users to access this credential, select a Team.', 'alert-danger');
} else {
Wait('start');
if (mode === 'add') {
url = (!Empty(data.team)) ? GetBasePath('teams') + data.team + '/credentials/' :
GetBasePath('users') + data.user + '/credentials/';
Rest.setUrl(url);
Rest.post(data)
.success(function () {
Wait('stop');
var base = $location.path().replace(/^\//, '').split('/')[0];
if (base === 'credentials') {
ReturnToCaller();
}
else {
ReturnToCaller(1);
}
})
.error(function (data, status) {
Wait('stop');
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to create new Credential. POST status: ' + status
});
});
} else {
url = GetBasePath('credentials') + scope.id + '/';
Rest.setUrl(url);
Rest.put(data)
.success(function () {
Wait('stop');
var base = $location.path().replace(/^\//, '').split('/')[0];
if (base === 'credentials') {
ReturnToCaller();
}
else {
ReturnToCaller(1);
}
})
.error(function (data, status) {
Wait('stop');
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to update Credential. PUT status: ' + status
});
});
}
}
};
}
]);
+310 -310
View File
@@ -12,346 +12,346 @@
*/
export default
angular.module('CreateCustomInventoryHelper', [ 'Utilities', 'RestServices', 'SchedulesHelper', 'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'ModalDialog',
'GeneratorHelpers', 'CustomInventoryFormDefinition'])
angular.module('CreateCustomInventoryHelper', [ 'Utilities', 'RestServices', 'SchedulesHelper', 'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'ModalDialog',
'GeneratorHelpers', 'CustomInventoryFormDefinition'])
.factory('CreateCustomInventory', ['Wait', 'CreateDialog', 'CustomInventoryList', 'GenerateList', 'GetBasePath' , 'SearchInit' , 'PaginateInit', 'PlaybookRun', 'CustomInventoryAdd',
'SchedulesList', 'CustomInventoryEdit', 'Rest' , 'ProcessErrors', 'CustomInventoryForm', 'GenerateForm', 'Prompt',
function(Wait, CreateDialog, CustomInventoryList, GenerateList, GetBasePath, SearchInit, PaginateInit, PlaybookRun, CustomInventoryAdd,
SchedulesList, CustomInventoryEdit, Rest, ProcessErrors, CustomInventoryForm, GenerateForm, Prompt) {
return function(params) {
// Set modal dimensions based on viewport width
.factory('CreateCustomInventory', ['Wait', 'CreateDialog', 'CustomInventoryList', 'GenerateList', 'GetBasePath' , 'SearchInit' , 'PaginateInit', 'PlaybookRun', 'CustomInventoryAdd',
'SchedulesList', 'CustomInventoryEdit', 'Rest' , 'ProcessErrors', 'CustomInventoryForm', 'GenerateForm', 'Prompt',
function(Wait, CreateDialog, CustomInventoryList, GenerateList, GetBasePath, SearchInit, PaginateInit, PlaybookRun, CustomInventoryAdd,
SchedulesList, CustomInventoryEdit, Rest, ProcessErrors, CustomInventoryForm, GenerateForm, Prompt) {
return function(params) {
// Set modal dimensions based on viewport width
var scope = params.parent_scope.$new(),
callback = 'OpenConfig',
defaultUrl = GetBasePath('inventory_scripts'),
list = CustomInventoryList,
view = GenerateList,
buttons = [
{
"label": "Close",
"onClick": function() {
// $(this).dialog('close');
scope.cancelConfigure();
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "script-close-button"
}
];
var scope = params.parent_scope.$new(),
callback = 'OpenConfig',
defaultUrl = GetBasePath('inventory_scripts'),
list = CustomInventoryList,
view = GenerateList,
buttons = [
{
"label": "Close",
"onClick": function() {
// $(this).dialog('close');
scope.cleanupJob = true;
if(scope.removeOpenConfig) {
scope.removeOpenConfig();
}
scope.removeOpenConfig = scope.$on('OpenConfig', function() {
$('#custom-script-dialog').dialog('open');
$('#script-close-button').focus();
$('#script-close-button').blur();
});
view.inject( list, {
id : 'custom-script-dialog',
mode: 'edit',
scope: scope,
breadCrumbs: false,
activityStream: false,
showSearch: true
});
SearchInit({
scope: scope,
set: 'source_scripts' , // 'custom_inventories',
list: list,
url: defaultUrl
});
PaginateInit({
scope: scope,
list: list,
url: defaultUrl
});
scope.search(list.iterator);
// SchedulesControllerInit({
// scope: scope,
// parent_scope: parent_scope,
// // list: list
// });
CreateDialog({
id: 'custom-script-dialog',
title: 'Inventory Scripts',
target: 'custom-script-dialog',
scope: scope,
buttons: buttons,
width: 700,
height: 800,
minWidth: 400,
callback: callback,
onClose: function () {
// Destroy on close
$('.tooltip').each(function () {
// Remove any lingering tooltip <div> elements
$(this).remove();
});
$('.popover').each(function () {
// remove lingering popover <div> elements
$(this).remove();
});
// $("#configure-jobs").show();
// $("#configure-schedules-form-container").hide();
// $('#configure-schedules-list').empty();
// $('#configure-schedules-form').empty();
// $('#configure-schedules-detail').empty();
// $('#configure-tower-dialog').hide();
$(this).dialog('destroy');
scope.cancelConfigure();
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "script-close-button"
}
];
scope.cleanupJob = true;
if(scope.removeOpenConfig) {
scope.removeOpenConfig();
}
scope.removeOpenConfig = scope.$on('OpenConfig', function() {
$('#custom-script-dialog').dialog('open');
$('#script-close-button').focus();
$('#script-close-button').blur();
});
view.inject( list, {
id : 'custom-script-dialog',
mode: 'edit',
scope: scope,
breadCrumbs: false,
activityStream: false,
showSearch: true
});
SearchInit({
scope: scope,
set: 'source_scripts' , // 'custom_inventories',
list: list,
url: defaultUrl
});
PaginateInit({
scope: scope,
list: list,
url: defaultUrl
});
scope.search(list.iterator);
// SchedulesControllerInit({
// scope: scope,
// parent_scope: parent_scope,
// // list: list
// });
CreateDialog({
id: 'custom-script-dialog',
title: 'Inventory Scripts',
target: 'custom-script-dialog',
scope: scope,
buttons: buttons,
width: 700,
height: 800,
minWidth: 400,
callback: callback,
onClose: function () {
// Destroy on close
$('.tooltip').each(function () {
// Remove any lingering tooltip <div> elements
$(this).remove();
});
$('.popover').each(function () {
// remove lingering popover <div> elements
$(this).remove();
});
// $("#configure-jobs").show();
// $("#configure-schedules-form-container").hide();
// $('#configure-schedules-list').empty();
// $('#configure-schedules-form').empty();
// $('#configure-schedules-detail').empty();
// $('#configure-tower-dialog').hide();
$(this).dialog('destroy');
scope.cancelConfigure();
},
});
// Cancel
scope.cancelConfigure = function () {
try {
$('#custom-script-dialog').dialog('close');
}
catch(e) {
//ignore
}
if (scope.searchCleanup) {
scope.searchCleanup();
}
// if (!Empty(parent_scope) && parent_scope.restoreSearch) {
// parent_scope.restoreSearch();
// }
else {
Wait('stop');
}
};
scope.editCustomInv = function(id){
CustomInventoryEdit({
scope: scope,
id: id
});
};
scope.deleteCustomInv = function(id, name){
var action = function () {
$('#prompt-modal').modal('hide');
Wait('start');
var url = defaultUrl + id + '/';
Rest.setUrl(url);
Rest.destroy()
.success(function () {
scope.search(list.iterator);
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
});
// Cancel
scope.cancelConfigure = function () {
try {
$('#custom-script-dialog').dialog('close');
}
catch(e) {
//ignore
}
if (scope.searchCleanup) {
scope.searchCleanup();
}
// if (!Empty(parent_scope) && parent_scope.restoreSearch) {
// parent_scope.restoreSearch();
// }
else {
Wait('stop');
}
};
Prompt({
hdr: 'Delete',
body: "<div class\"alert alert-info\">Are you sure you want to delete " + name + "?</div>",
action: action
scope.editCustomInv = function(id){
CustomInventoryEdit({
scope: scope,
id: id
});
};
scope.deleteCustomInv = function(id, name){
var action = function () {
$('#prompt-modal').modal('hide');
Wait('start');
var url = defaultUrl + id + '/';
Rest.setUrl(url);
Rest.destroy()
.success(function () {
scope.search(list.iterator);
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
});
};
Prompt({
hdr: 'Delete',
body: "<div class\"alert alert-info\">Are you sure you want to delete " + name + "?</div>",
action: action
});
};
scope.addCustomInv = function(){
CustomInventoryAdd({
scope: scope
});
};
};
}])
.factory('CustomInventoryAdd', ['$compile','SchedulerInit', 'Rest', 'Wait', 'CustomInventoryList', 'CustomInventoryForm', 'ProcessErrors', 'GetBasePath', 'Empty', 'GenerateForm',
'SearchInit' , 'PaginateInit', 'GenerateList', 'LookUpInit', 'OrganizationList',
function($compile, SchedulerInit, Rest, Wait, CustomInventoryList, CustomInventoryForm, ProcessErrors, GetBasePath, Empty, GenerateForm,
SearchInit, PaginateInit, GenerateList, LookUpInit, OrganizationList) {
return function(params) {
var scope = params.scope,
generator = GenerateForm,
form = CustomInventoryForm,
view = GenerateList,
list = CustomInventoryList,
url = GetBasePath('inventory_scripts');
generator.inject(form, { id:'custom-script-dialog', mode: 'add' , scope:scope, related: false, breadCrumbs: false});
generator.reset();
LookUpInit({
url: GetBasePath('organization'),
scope: scope,
form: form,
// hdr: "Select Custom Inventory",
list: OrganizationList,
field: 'organization',
input_type: 'radio'
});
// Save
scope.formSave = function () {
generator.clearApiErrors();
Wait('start');
Rest.setUrl(url);
Rest.post({ name: scope.name, description: scope.description, organization: scope.organization, script: scope.script })
.success(function () {
view.inject( list, {
id : 'custom-script-dialog',
mode: 'edit',
scope: scope,
breadCrumbs: false,
activityStream: false,
showSearch: true
});
SearchInit({
scope: scope,
set: 'source_scripts', //'custom_inventories',
list: list,
url: url
});
PaginateInit({
scope: scope,
list: list,
url: url
});
scope.search(list.iterator);
Wait('stop');
Wait('stop');
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to add new inventory script. POST returned status: ' + status });
});
};
scope.addCustomInv = function(){
CustomInventoryAdd({
scope: scope
});
// Cancel
scope.formReset = function () {
generator.reset();
};
};
}])
.factory('CustomInventoryEdit', ['$compile','CustomInventoryList', 'Rest', 'Wait', 'GenerateList', 'CustomInventoryForm', 'ProcessErrors', 'GetBasePath', 'Empty', 'GenerateForm',
'SearchInit', 'PaginateInit', '$routeParams', 'OrganizationList', 'LookUpInit',
function($compile, CustomInventoryList, Rest, Wait, GenerateList, CustomInventoryForm, ProcessErrors, GetBasePath, Empty, GenerateForm,
SearchInit, PaginateInit, $routeParams, OrganizationList, LookUpInit) {
return function(params) {
var scope = params.scope,
id = params.id,
generator = GenerateForm,
form = CustomInventoryForm,
view = GenerateList,
list = CustomInventoryList,
master = {},
url = GetBasePath('inventory_scripts');
.factory('CustomInventoryAdd', ['$compile','SchedulerInit', 'Rest', 'Wait', 'CustomInventoryList', 'CustomInventoryForm', 'ProcessErrors', 'GetBasePath', 'Empty', 'GenerateForm',
'SearchInit' , 'PaginateInit', 'GenerateList', 'LookUpInit', 'OrganizationList',
function($compile, SchedulerInit, Rest, Wait, CustomInventoryList, CustomInventoryForm, ProcessErrors, GetBasePath, Empty, GenerateForm,
SearchInit, PaginateInit, GenerateList, LookUpInit, OrganizationList) {
return function(params) {
var scope = params.scope,
generator = GenerateForm,
form = CustomInventoryForm,
view = GenerateList,
list = CustomInventoryList,
url = GetBasePath('inventory_scripts');
generator.inject(form, {
id:'custom-script-dialog',
mode: 'edit' ,
scope:scope,
related: false,
breadCrumbs: false,
activityStream: false
});
generator.reset();
LookUpInit({
url: GetBasePath('organization'),
scope: scope,
form: form,
// hdr: "Select Custom Inventory",
list: OrganizationList,
field: 'organization',
input_type: 'radio'
});
generator.inject(form, { id:'custom-script-dialog', mode: 'add' , scope:scope, related: false, breadCrumbs: false});
generator.reset();
LookUpInit({
url: GetBasePath('organization'),
scope: scope,
form: form,
// hdr: "Select Custom Inventory",
list: OrganizationList,
field: 'organization',
input_type: 'radio'
});
// Save
scope.formSave = function () {
generator.clearApiErrors();
// Retrieve detail record and prepopulate the form
Wait('start');
Rest.setUrl(url);
Rest.post({ name: scope.name, description: scope.description, organization: scope.organization, script: scope.script })
.success(function () {
view.inject( list, {
id : 'custom-script-dialog',
mode: 'edit',
scope: scope,
breadCrumbs: false,
activityStream: false,
showSearch: true
});
Rest.setUrl(url + id+'/');
Rest.get()
.success(function (data) {
var fld;
for (fld in form.fields) {
if (data[fld]) {
scope[fld] = data[fld];
master[fld] = data[fld];
}
SearchInit({
scope: scope,
set: 'source_scripts', //'custom_inventories',
list: list,
url: url
});
PaginateInit({
scope: scope,
list: list,
url: url
});
scope.search(list.iterator);
if (form.fields[fld].sourceModel && data.summary_fields &&
data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
}
}
Wait('stop');
Wait('stop');
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to add new inventory script. POST returned status: ' + status });
msg: 'Failed to retrieve inventory script: ' + $routeParams.id + '. GET status: ' + status });
});
};
// Cancel
scope.formReset = function () {
generator.reset();
};
};
}])
scope.formSave = function () {
generator.clearApiErrors();
Wait('start');
Rest.setUrl(url+ id+'/');
Rest.put({ name: scope.name, description: scope.description, organization: scope.organization, script: scope.script })
.success(function () {
view.inject( list, {
id : 'custom-script-dialog',
mode: 'edit',
scope: scope,
breadCrumbs: false,
activityStream: false,
showSearch: true
});
.factory('CustomInventoryEdit', ['$compile','CustomInventoryList', 'Rest', 'Wait', 'GenerateList', 'CustomInventoryForm', 'ProcessErrors', 'GetBasePath', 'Empty', 'GenerateForm',
'SearchInit', 'PaginateInit', '$routeParams', 'OrganizationList', 'LookUpInit',
function($compile, CustomInventoryList, Rest, Wait, GenerateList, CustomInventoryForm, ProcessErrors, GetBasePath, Empty, GenerateForm,
SearchInit, PaginateInit, $routeParams, OrganizationList, LookUpInit) {
return function(params) {
var scope = params.scope,
id = params.id,
generator = GenerateForm,
form = CustomInventoryForm,
view = GenerateList,
list = CustomInventoryList,
master = {},
url = GetBasePath('inventory_scripts');
SearchInit({
scope: scope,
set: 'source_scripts', //'custom_inventories',
list: list,
url: url
});
PaginateInit({
scope: scope,
list: list,
url: url
});
generator.inject(form, {
id:'custom-script-dialog',
mode: 'edit' ,
scope:scope,
related: false,
breadCrumbs: false,
activityStream: false
});
generator.reset();
LookUpInit({
url: GetBasePath('organization'),
scope: scope,
form: form,
// hdr: "Select Custom Inventory",
list: OrganizationList,
field: 'organization',
input_type: 'radio'
});
scope.search(list.iterator);
// Retrieve detail record and prepopulate the form
Wait('start');
Rest.setUrl(url + id+'/');
Rest.get()
.success(function (data) {
var fld;
for (fld in form.fields) {
if (data[fld]) {
scope[fld] = data[fld];
master[fld] = data[fld];
}
Wait('stop');
if (form.fields[fld].sourceModel && data.summary_fields &&
data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
}
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to add new inventory script. PUT returned status: ' + status });
});
};
scope.formReset = function () {
generator.reset();
for (var fld in master) {
scope[fld] = master[fld];
}
Wait('stop');
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to retrieve inventory script: ' + $routeParams.id + '. GET status: ' + status });
});
scope.organization_name = master.organization_name;
scope.formSave = function () {
generator.clearApiErrors();
Wait('start');
Rest.setUrl(url+ id+'/');
Rest.put({ name: scope.name, description: scope.description, organization: scope.organization, script: scope.script })
.success(function () {
view.inject( list, {
id : 'custom-script-dialog',
mode: 'edit',
scope: scope,
breadCrumbs: false,
activityStream: false,
showSearch: true
});
SearchInit({
scope: scope,
set: 'source_scripts', //'custom_inventories',
list: list,
url: url
});
PaginateInit({
scope: scope,
list: list,
url: url
});
scope.search(list.iterator);
Wait('stop');
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to add new inventory script. PUT returned status: ' + status });
});
};
};
scope.formReset = function () {
generator.reset();
for (var fld in master) {
scope[fld] = master[fld];
}
scope.organization_name = master.organization_name;
};
};
}]);
}]);
File diff suppressed because it is too large Load Diff
+194 -194
View File
@@ -12,29 +12,53 @@
* @description EventView - show the job_events form in a modal dialog
*/
export default
angular.module('EventsHelper', ['RestServices', 'Utilities', 'JobEventDataDefinition', 'JobEventsFormDefinition'])
angular.module('EventsHelper', ['RestServices', 'Utilities', 'JobEventDataDefinition', 'JobEventsFormDefinition'])
.factory('EventView', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'JobEventDataForm', 'Empty', 'JobEventsForm',
function ($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath,
FormatDate, JobEventDataForm, Empty, JobEventsForm) {
return function (params) {
.factory('EventView', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'JobEventDataForm', 'Empty', 'JobEventsForm',
function ($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath,
FormatDate, JobEventDataForm, Empty, JobEventsForm) {
return function (params) {
var event_id = params.event_id,
generator = GenerateForm,
form = angular.copy(JobEventsForm),
scope,
defaultUrl = GetBasePath('base') + 'job_events/' + event_id + '/';
var event_id = params.event_id,
generator = GenerateForm,
form = angular.copy(JobEventsForm),
scope,
defaultUrl = GetBasePath('base') + 'job_events/' + event_id + '/';
// Retrieve detail record and prepopulate the form
Rest.setUrl(defaultUrl);
Rest.get()
.success(function (data) {
var i, n, fld, rows, txt, cDate;
// Retrieve detail record and prepopulate the form
Rest.setUrl(defaultUrl);
Rest.get()
.success(function (data) {
var i, n, fld, rows, txt, cDate;
// If event_data is not available, remove fields that depend on it
if ($.isEmptyObject(data.event_data) || !data.event_data.res || typeof data.event_data.res === 'string') {
for (fld in form.fields) {
switch (fld) {
case 'start':
case 'end':
case 'delta':
case 'msg':
case 'stdout':
case 'stderr':
case 'msg':
case 'results':
case 'module_name':
case 'module_args':
case 'rc':
delete form.fields[fld];
break;
}
}
}
// If event_data is not available, remove fields that depend on it
if ($.isEmptyObject(data.event_data) || !data.event_data.res || typeof data.event_data.res === 'string') {
if ($.isEmptyObject(data.event_data) || !data.event_data.res || typeof data.event_data.res !== 'string') {
delete form.fields.traceback;
}
// Remove remaining form fields that do not have a corresponding data value
for (fld in form.fields) {
switch (fld) {
case 'start':
@@ -44,196 +68,172 @@ angular.module('EventsHelper', ['RestServices', 'Utilities', 'JobEventDataDefini
case 'stdout':
case 'stderr':
case 'msg':
case 'rc':
if (data.event_data && data.event_data.res && Empty(data.event_data.res[fld])) {
delete form.fields[fld];
} else {
if (form.fields[fld].type === 'textarea') {
n = data.event_data.res[fld].match(/\n/g);
rows = (n) ? n.length : 1;
rows = (rows > 10) ? 10 : rows;
rows = (rows < 3) ? 3 : rows;
form.fields[fld].rows = rows;
}
}
break;
case 'results':
if (data.event_data && data.event_data.res && data.event_data.res[fld] === undefined) {
// not defined
delete form.fields[fld];
} else if (!Array.isArray(data.event_data.res[fld]) || data.event_data.res[fld].length === 0) {
// defined, but empty
delete form.fields[fld];
} else {
// defined and not empty, so attempt to size the textarea field
txt = '';
for (i = 0; i < data.event_data.res[fld].length; i++) {
txt += data.event_data.res[fld][i];
}
if (txt === '') {
// there's an array, but the actual text is empty
delete form.fields[fld];
} else {
n = txt.match(/\n/g);
rows = (n) ? n.length : 1;
rows = (rows > 10) ? 10 : rows;
rows = (rows < 3) ? 3 : rows;
form.fields[fld].rows = rows;
}
}
break;
case 'module_name':
case 'module_args':
case 'rc':
delete form.fields[fld];
if (data.event_data && data.event_data.res) {
if (data.event_data.res.invocation === undefined ||
data.event_data.res.invocation[fld] === undefined) {
delete form.fields[fld];
}
}
break;
}
}
}
if ($.isEmptyObject(data.event_data) || !data.event_data.res || typeof data.event_data.res !== 'string') {
delete form.fields.traceback;
}
// Remove remaining form fields that do not have a corresponding data value
for (fld in form.fields) {
switch (fld) {
case 'start':
case 'end':
case 'delta':
case 'msg':
case 'stdout':
case 'stderr':
case 'msg':
case 'rc':
if (data.event_data && data.event_data.res && Empty(data.event_data.res[fld])) {
delete form.fields[fld];
} else {
if (form.fields[fld].type === 'textarea') {
n = data.event_data.res[fld].match(/\n/g);
rows = (n) ? n.length : 1;
rows = (rows > 10) ? 10 : rows;
rows = (rows < 3) ? 3 : rows;
form.fields[fld].rows = rows;
}
}
break;
case 'results':
if (data.event_data && data.event_data.res && data.event_data.res[fld] === undefined) {
// not defined
delete form.fields[fld];
} else if (!Array.isArray(data.event_data.res[fld]) || data.event_data.res[fld].length === 0) {
// defined, but empty
delete form.fields[fld];
} else {
// defined and not empty, so attempt to size the textarea field
txt = '';
for (i = 0; i < data.event_data.res[fld].length; i++) {
txt += data.event_data.res[fld][i];
}
if (txt === '') {
// there's an array, but the actual text is empty
delete form.fields[fld];
} else {
n = txt.match(/\n/g);
rows = (n) ? n.length : 1;
rows = (rows > 10) ? 10 : rows;
rows = (rows < 3) ? 3 : rows;
form.fields[fld].rows = rows;
}
}
break;
case 'module_name':
case 'module_args':
if (data.event_data && data.event_data.res) {
if (data.event_data.res.invocation === undefined ||
data.event_data.res.invocation[fld] === undefined) {
delete form.fields[fld];
}
}
break;
}
}
// load the form
scope = generator.inject(form, {
mode: 'edit',
modal: true,
related: false
});
generator.reset();
scope.formModalAction = function () {
$('#form-modal').modal("hide");
};
scope.formModalActionLabel = 'OK';
scope.formModalCancelShow = false;
scope.formModalInfo = 'View JSON';
$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none');
$('#form-modal').addClass('skinny-modal');
scope.formModalHeader = data.event_display.replace(/^\u00a0*/g, '');
// Respond to View JSON button
scope.formModalInfoAction = function () {
var generator = GenerateForm,
scope = generator.inject(JobEventDataForm, {
// load the form
scope = generator.inject(form, {
mode: 'edit',
modal: true,
related: false,
modal_selector: '#form-modal2',
modal_body_id: 'form-modal2-body',
modal_title_id: 'formModal2Header'
related: false
});
generator.reset();
scope.formModal2Header = data.event_display.replace(/^\u00a0*/g, '');
scope.event_data = JSON.stringify(data.event_data, null, '\t');
scope.formModal2ActionLabel = 'OK';
scope.formModal2CancelShow = false;
scope.formModal2Info = false;
scope.formModalInfo = 'View JSON';
scope.formModal2Action = function () {
$('#form-modal2').modal("hide");
scope.formModalAction = function () {
$('#form-modal').modal("hide");
};
$('#form-modal2 .btn-success').removeClass('btn-success').addClass('btn-none');
};
scope.formModalActionLabel = 'OK';
scope.formModalCancelShow = false;
scope.formModalInfo = 'View JSON';
$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none');
$('#form-modal').addClass('skinny-modal');
scope.formModalHeader = data.event_display.replace(/^\u00a0*/g, '');
if (typeof data.event_data.res === 'string') {
scope.traceback = data.event_data.res;
}
// Respond to View JSON button
scope.formModalInfoAction = function () {
var generator = GenerateForm,
scope = generator.inject(JobEventDataForm, {
mode: 'edit',
modal: true,
related: false,
modal_selector: '#form-modal2',
modal_body_id: 'form-modal2-body',
modal_title_id: 'formModal2Header'
});
generator.reset();
scope.formModal2Header = data.event_display.replace(/^\u00a0*/g, '');
scope.event_data = JSON.stringify(data.event_data, null, '\t');
scope.formModal2ActionLabel = 'OK';
scope.formModal2CancelShow = false;
scope.formModal2Info = false;
scope.formModalInfo = 'View JSON';
scope.formModal2Action = function () {
$('#form-modal2').modal("hide");
};
$('#form-modal2 .btn-success').removeClass('btn-success').addClass('btn-none');
};
for (fld in form.fields) {
switch (fld) {
case 'status':
if (data.failed) {
scope.status = 'error';
} else if (data.changed) {
scope.status = 'changed';
} else {
scope.status = 'success';
}
break;
case 'created':
cDate = new Date(data.created);
scope.created = FormatDate(cDate);
break;
case 'host':
if (data.summary_fields && data.summary_fields.host) {
scope.host = data.summary_fields.host.name;
}
break;
case 'id':
case 'task':
case 'play':
scope[fld] = data[fld];
break;
case 'start':
case 'end':
if (data.event_data && data.event_data.res && !Empty(data.event_data.res[fld])) {
scope[fld] = data.event_data.res[fld];
}
break;
case 'results':
if (Array.isArray(data.event_data.res[fld]) && data.event_data.res[fld].length > 0) {
txt = '';
for (i = 0; i < data.event_data.res[fld].length; i++) {
txt += data.event_data.res[fld][i];
}
if (txt !== '') {
scope[fld] = txt;
}
}
break;
case 'msg':
case 'stdout':
case 'stderr':
case 'delta':
case 'rc':
if (data.event_data && data.event_data.res && data.event_data.res[fld] !== undefined) {
scope[fld] = data.event_data.res[fld];
}
break;
case 'module_name':
case 'module_args':
if (data.event_data.res && data.event_data.res.invocation) {
scope[fld] = data.event_data.res.invocation[fld];
}
break;
if (typeof data.event_data.res === 'string') {
scope.traceback = data.event_data.res;
}
}
if (!scope.$$phase) {
scope.$digest();
}
for (fld in form.fields) {
switch (fld) {
case 'status':
if (data.failed) {
scope.status = 'error';
} else if (data.changed) {
scope.status = 'changed';
} else {
scope.status = 'success';
}
break;
case 'created':
cDate = new Date(data.created);
scope.created = FormatDate(cDate);
break;
case 'host':
if (data.summary_fields && data.summary_fields.host) {
scope.host = data.summary_fields.host.name;
}
break;
case 'id':
case 'task':
case 'play':
scope[fld] = data[fld];
break;
case 'start':
case 'end':
if (data.event_data && data.event_data.res && !Empty(data.event_data.res[fld])) {
scope[fld] = data.event_data.res[fld];
}
})
.error(function (data, status) {
$('#form-modal').modal("hide");
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to retrieve event: ' + event_id + '. GET status: ' + status });
});
};
}
]);
break;
case 'results':
if (Array.isArray(data.event_data.res[fld]) && data.event_data.res[fld].length > 0) {
txt = '';
for (i = 0; i < data.event_data.res[fld].length; i++) {
txt += data.event_data.res[fld][i];
}
if (txt !== '') {
scope[fld] = txt;
}
}
break;
case 'msg':
case 'stdout':
case 'stderr':
case 'delta':
case 'rc':
if (data.event_data && data.event_data.res && data.event_data.res[fld] !== undefined) {
scope[fld] = data.event_data.res[fld];
}
break;
case 'module_name':
case 'module_args':
if (data.event_data.res && data.event_data.res.invocation) {
scope[fld] = data.event_data.res.invocation[fld];
}
break;
}
}
if (!scope.$$phase) {
scope.$digest();
}
})
.error(function (data, status) {
$('#form-modal').modal("hide");
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to retrieve event: ' + event_id + '. GET status: ' + status });
});
};
}
]);
File diff suppressed because it is too large Load Diff
+256 -256
View File
@@ -12,278 +12,278 @@
* @description view a list of events for a given job and host
*/
export default
angular.module('HostEventsViewerHelper', ['ModalDialog', 'Utilities', 'EventViewerHelper'])
angular.module('HostEventsViewerHelper', ['ModalDialog', 'Utilities', 'EventViewerHelper'])
.factory('HostEventsViewer', ['$log', '$compile', 'CreateDialog', 'Wait', 'GetBasePath', 'Empty', 'GetEvents', 'EventViewer',
function($log, $compile, CreateDialog, Wait, GetBasePath, Empty, GetEvents, EventViewer) {
return function(params) {
var parent_scope = params.scope,
scope = parent_scope.$new(true),
job_id = params.job_id,
url = params.url,
title = params.title, //optional
fixHeight, buildTable,
lastID, setStatus, buildRow, status;
.factory('HostEventsViewer', ['$log', '$compile', 'CreateDialog', 'Wait', 'GetBasePath', 'Empty', 'GetEvents', 'EventViewer',
function($log, $compile, CreateDialog, Wait, GetBasePath, Empty, GetEvents, EventViewer) {
return function(params) {
var parent_scope = params.scope,
scope = parent_scope.$new(true),
job_id = params.job_id,
url = params.url,
title = params.title, //optional
fixHeight, buildTable,
lastID, setStatus, buildRow, status;
// initialize the status dropdown
scope.host_events_status_options = [
{ value: "all", name: "All" },
{ value: "changed", name: "Changed" },
{ value: "failed", name: "Failed" },
{ value: "ok", name: "OK" },
{ value: "unreachable", name: "Unreachable" }
];
scope.host_events_search_name = params.name;
status = (params.status) ? params.status : 'all';
scope.host_events_status_options.every(function(opt, idx) {
if (opt.value === status) {
scope.host_events_search_status = scope.host_events_status_options[idx];
return false;
}
return true;
});
if (!scope.host_events_search_status) {
scope.host_events_search_status = scope.host_events_status_options[0];
}
$log.debug('job_id: ' + job_id + ' url: ' + url + ' title: ' + title + ' name: ' + name + ' status: ' + status);
scope.eventsSearchActive = (scope.host_events_search_name) ? true : false;
if (scope.removeModalReady) {
scope.removeModalReady();
}
scope.removeModalReady = scope.$on('ModalReady', function() {
scope.hostViewSearching = false;
$('#host-events-modal-dialog').dialog('open');
});
if (scope.removeJobReady) {
scope.removeJobReady();
}
scope.removeEventReady = scope.$on('EventsReady', function(e, data, maxID) {
var elem, html;
lastID = maxID;
html = buildTable(data);
$('#host-events').html(html);
elem = angular.element(document.getElementById('host-events-modal-dialog'));
$compile(elem)(scope);
CreateDialog({
scope: scope,
width: 675,
height: 600,
minWidth: 450,
callback: 'ModalReady',
id: 'host-events-modal-dialog',
onResizeStop: fixHeight,
title: ( (title) ? title : 'Host Events' ),
onClose: function() {
try {
scope.$destroy();
}
catch(e) {
//ignore
}
},
onOpen: function() {
fixHeight();
// initialize the status dropdown
scope.host_events_status_options = [
{ value: "all", name: "All" },
{ value: "changed", name: "Changed" },
{ value: "failed", name: "Failed" },
{ value: "ok", name: "OK" },
{ value: "unreachable", name: "Unreachable" }
];
scope.host_events_search_name = params.name;
status = (params.status) ? params.status : 'all';
scope.host_events_status_options.every(function(opt, idx) {
if (opt.value === status) {
scope.host_events_search_status = scope.host_events_status_options[idx];
return false;
}
return true;
});
});
if (scope.removeRefreshHTML) {
scope.removeRefreshHTML();
}
scope.removeRefreshHTML = scope.$on('RefreshHTML', function(e, data) {
var elem, html = buildTable(data);
$('#host-events').html(html);
scope.hostViewSearching = false;
elem = angular.element(document.getElementById('host-events'));
$compile(elem)(scope);
});
setStatus = function(result) {
var msg = '', status = 'ok', status_text = 'OK';
if (!result.task && result.event_data && result.event_data.res && result.event_data.res.ansible_facts) {
result.task = "Gathering Facts";
if (!scope.host_events_search_status) {
scope.host_events_search_status = scope.host_events_status_options[0];
}
if (result.event === "runner_on_no_hosts") {
msg = "No hosts remaining";
}
if (result.event === 'runner_on_unreachable') {
status = 'unreachable';
status_text = 'Unreachable';
}
else if (result.failed) {
status = 'failed';
status_text = 'Failed';
}
else if (result.changed) {
status = 'changed';
status_text = 'Changed';
}
if (result.event_data.res && result.event_data.res.msg) {
msg = result.event_data.res.msg;
}
result.msg = msg;
result.status = status;
result.status_text = status_text;
return result;
};
buildRow = function(res) {
var html = '';
html += "<tr>\n";
html += "<td class=\"col-md-3\"><a href=\"\" ng-click=\"showDetails(" + res.id + ")\" aw-tool-tip=\"Click to view details\" data-placement=\"top\"><i class=\"fa icon-job-" + res.status + "\"></i> " + res.status_text + "</a></td>\n";
html += "<td class=\"col-md=3\" ng-non-bindable>" + res.host_name + "</td>\n";
html += "<td class=\"col-md-3\" ng-non-bindable>" + res.play + "</td>\n";
html += "<td class=\"col-md-3\" ng-non-bindable>" + res.task + "</td>\n";
html += "</tr>";
return html;
};
$log.debug('job_id: ' + job_id + ' url: ' + url + ' title: ' + title + ' name: ' + name + ' status: ' + status);
buildTable = function(data) {
var html = "<table class=\"table\">\n";
html += "<tbody>\n";
data.results.forEach(function(result) {
var res = setStatus(result);
html += buildRow(res);
});
html += "</tbody>\n";
html += "</table>\n";
return html;
};
fixHeight = function() {
var available_height = $('#host-events-modal-dialog').height() - $('#host-events-modal-dialog #search-form').height() - $('#host-events-modal-dialog #fixed-table-header').height();
$('#host-events').height(available_height);
$log.debug('set height to: ' + available_height);
// Check width and reset search fields
if ($('#host-events-modal-dialog').width() <= 450) {
$('#host-events-modal-dialog #status-field').css({'margin-left': '7px'});
}
else {
$('#host-events-modal-dialog #status-field').css({'margin-left': '15px'});
}
};
GetEvents({
url: url,
scope: scope,
callback: 'EventsReady'
});
scope.modalOK = function() {
$('#host-events-modal-dialog').dialog('close');
scope.$destroy();
};
scope.searchEvents = function() {
scope.eventsSearchActive = (scope.host_events_search_name) ? true : false;
GetEvents({
scope: scope,
url: url,
callback: 'RefreshHTML'
});
};
scope.searchEventKeyPress = function(e) {
if (e.keyCode === 13) {
scope.searchEvents();
if (scope.removeModalReady) {
scope.removeModalReady();
}
};
scope.showDetails = function(id) {
EventViewer({
scope: parent_scope,
url: GetBasePath('jobs') + job_id + '/job_events/?id=' + id,
scope.removeModalReady = scope.$on('ModalReady', function() {
scope.hostViewSearching = false;
$('#host-events-modal-dialog').dialog('open');
});
};
if (scope.removeEventsScrollDownBuild) {
scope.removeEventsScrollDownBuild();
}
scope.removeEventsScrollDownBuild = scope.$on('EventScrollDownBuild', function(e, data, maxID) {
var elem, html = '';
lastID = maxID;
data.results.forEach(function(result) {
var res = setStatus(result);
html += buildRow(res);
if (scope.removeJobReady) {
scope.removeJobReady();
}
scope.removeEventReady = scope.$on('EventsReady', function(e, data, maxID) {
var elem, html;
lastID = maxID;
html = buildTable(data);
$('#host-events').html(html);
elem = angular.element(document.getElementById('host-events-modal-dialog'));
$compile(elem)(scope);
CreateDialog({
scope: scope,
width: 675,
height: 600,
minWidth: 450,
callback: 'ModalReady',
id: 'host-events-modal-dialog',
onResizeStop: fixHeight,
title: ( (title) ? title : 'Host Events' ),
onClose: function() {
try {
scope.$destroy();
}
catch(e) {
//ignore
}
},
onOpen: function() {
fixHeight();
}
});
});
if (html) {
$('#host-events table tbody').append(html);
if (scope.removeRefreshHTML) {
scope.removeRefreshHTML();
}
scope.removeRefreshHTML = scope.$on('RefreshHTML', function(e, data) {
var elem, html = buildTable(data);
$('#host-events').html(html);
scope.hostViewSearching = false;
elem = angular.element(document.getElementById('host-events'));
$compile(elem)(scope);
}
});
scope.hostEventsScrollDown = function() {
GetEvents({
scope: scope,
url: url,
gt: lastID,
callback: 'EventScrollDownBuild'
});
};
};
}])
.factory('GetEvents', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
return function(params) {
var url = params.url,
scope = params.scope,
gt = params.gt,
callback = params.callback;
if (scope.host_events_search_name) {
url += '?host_name=' + scope.host_events_search_name;
}
else {
url += '?host_name__isnull=false';
}
if (scope.host_events_search_status.value === 'changed') {
url += '&event__icontains=runner&changed=true';
}
else if (scope.host_events_search_status.value === 'failed') {
url += '&event__icontains=runner&failed=true';
}
else if (scope.host_events_search_status.value === 'ok') {
url += '&event=runner_on_ok&changed=false';
}
else if (scope.host_events_search_status.value === 'unreachable') {
url += '&event=runner_on_unreachable';
}
else if (scope.host_events_search_status.value === 'all') {
url += '&event__icontains=runner&not__event=runner_on_skipped';
}
if (gt) {
// used for endless scroll
url += '&id__gt=' + gt;
}
url += '&page_size=50&order=id';
scope.hostViewSearching = true;
Rest.setUrl(url);
Rest.get()
.success(function(data) {
var lastID;
scope.hostViewSearching = false;
if (data.results.length > 0) {
lastID = data.results[data.results.length - 1].id;
setStatus = function(result) {
var msg = '', status = 'ok', status_text = 'OK';
if (!result.task && result.event_data && result.event_data.res && result.event_data.res.ansible_facts) {
result.task = "Gathering Facts";
}
scope.$emit(callback, data, lastID);
})
.error(function(data, status) {
scope.hostViewSearching = false;
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get events ' + url + '. GET returned: ' + status });
if (result.event === "runner_on_no_hosts") {
msg = "No hosts remaining";
}
if (result.event === 'runner_on_unreachable') {
status = 'unreachable';
status_text = 'Unreachable';
}
else if (result.failed) {
status = 'failed';
status_text = 'Failed';
}
else if (result.changed) {
status = 'changed';
status_text = 'Changed';
}
if (result.event_data.res && result.event_data.res.msg) {
msg = result.event_data.res.msg;
}
result.msg = msg;
result.status = status;
result.status_text = status_text;
return result;
};
buildRow = function(res) {
var html = '';
html += "<tr>\n";
html += "<td class=\"col-md-3\"><a href=\"\" ng-click=\"showDetails(" + res.id + ")\" aw-tool-tip=\"Click to view details\" data-placement=\"top\"><i class=\"fa icon-job-" + res.status + "\"></i> " + res.status_text + "</a></td>\n";
html += "<td class=\"col-md=3\" ng-non-bindable>" + res.host_name + "</td>\n";
html += "<td class=\"col-md-3\" ng-non-bindable>" + res.play + "</td>\n";
html += "<td class=\"col-md-3\" ng-non-bindable>" + res.task + "</td>\n";
html += "</tr>";
return html;
};
buildTable = function(data) {
var html = "<table class=\"table\">\n";
html += "<tbody>\n";
data.results.forEach(function(result) {
var res = setStatus(result);
html += buildRow(res);
});
html += "</tbody>\n";
html += "</table>\n";
return html;
};
fixHeight = function() {
var available_height = $('#host-events-modal-dialog').height() - $('#host-events-modal-dialog #search-form').height() - $('#host-events-modal-dialog #fixed-table-header').height();
$('#host-events').height(available_height);
$log.debug('set height to: ' + available_height);
// Check width and reset search fields
if ($('#host-events-modal-dialog').width() <= 450) {
$('#host-events-modal-dialog #status-field').css({'margin-left': '7px'});
}
else {
$('#host-events-modal-dialog #status-field').css({'margin-left': '15px'});
}
};
GetEvents({
url: url,
scope: scope,
callback: 'EventsReady'
});
};
}]);
scope.modalOK = function() {
$('#host-events-modal-dialog').dialog('close');
scope.$destroy();
};
scope.searchEvents = function() {
scope.eventsSearchActive = (scope.host_events_search_name) ? true : false;
GetEvents({
scope: scope,
url: url,
callback: 'RefreshHTML'
});
};
scope.searchEventKeyPress = function(e) {
if (e.keyCode === 13) {
scope.searchEvents();
}
};
scope.showDetails = function(id) {
EventViewer({
scope: parent_scope,
url: GetBasePath('jobs') + job_id + '/job_events/?id=' + id,
});
};
if (scope.removeEventsScrollDownBuild) {
scope.removeEventsScrollDownBuild();
}
scope.removeEventsScrollDownBuild = scope.$on('EventScrollDownBuild', function(e, data, maxID) {
var elem, html = '';
lastID = maxID;
data.results.forEach(function(result) {
var res = setStatus(result);
html += buildRow(res);
});
if (html) {
$('#host-events table tbody').append(html);
elem = angular.element(document.getElementById('host-events'));
$compile(elem)(scope);
}
});
scope.hostEventsScrollDown = function() {
GetEvents({
scope: scope,
url: url,
gt: lastID,
callback: 'EventScrollDownBuild'
});
};
};
}])
.factory('GetEvents', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
return function(params) {
var url = params.url,
scope = params.scope,
gt = params.gt,
callback = params.callback;
if (scope.host_events_search_name) {
url += '?host_name=' + scope.host_events_search_name;
}
else {
url += '?host_name__isnull=false';
}
if (scope.host_events_search_status.value === 'changed') {
url += '&event__icontains=runner&changed=true';
}
else if (scope.host_events_search_status.value === 'failed') {
url += '&event__icontains=runner&failed=true';
}
else if (scope.host_events_search_status.value === 'ok') {
url += '&event=runner_on_ok&changed=false';
}
else if (scope.host_events_search_status.value === 'unreachable') {
url += '&event=runner_on_unreachable';
}
else if (scope.host_events_search_status.value === 'all') {
url += '&event__icontains=runner&not__event=runner_on_skipped';
}
if (gt) {
// used for endless scroll
url += '&id__gt=' + gt;
}
url += '&page_size=50&order=id';
scope.hostViewSearching = true;
Rest.setUrl(url);
Rest.get()
.success(function(data) {
var lastID;
scope.hostViewSearching = false;
if (data.results.length > 0) {
lastID = data.results[data.results.length - 1].id;
}
scope.$emit(callback, data, lastID);
})
.error(function(data, status) {
scope.hostViewSearching = false;
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get events ' + url + '. GET returned: ' + status });
});
};
}]);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+159 -160
View File
@@ -6,13 +6,13 @@
* Routines shared by job related controllers
*
*/
/**
* @ngdoc function
* @name helpers.function:JobTemplatesHelper
* @description Routines shared by job related controllers
/**
* @ngdoc function
* @name helpers.function:JobTemplatesHelper
* @description Routines shared by job related controllers
*/
export default
angular.module('JobTemplatesHelper', ['Utilities'])
/*
@@ -21,181 +21,180 @@ angular.module('JobTemplatesHelper', ['Utilities'])
*/
.factory('CallbackHelpInit', ['$location', 'GetBasePath', 'Rest', 'JobTemplateForm', 'GenerateForm', '$routeParams', 'LoadBreadCrumbs', 'ProcessErrors', 'ParseTypeChange',
'ParseVariableString', 'Empty', 'LookUpInit', 'InventoryList', 'CredentialList','ProjectList', 'RelatedSearchInit', 'RelatedPaginateInit',
function($location, GetBasePath, Rest, JobTemplateForm, GenerateForm, $routeParams, LoadBreadCrumbs, ProcessErrors,ParseTypeChange,
ParseVariableString, Empty, LookUpInit, InventoryList, CredentialList, ProjectList, RelatedSearchInit, RelatedPaginateInit) {
return function(params) {
'ParseVariableString', 'Empty', 'LookUpInit', 'InventoryList', 'CredentialList','ProjectList', 'RelatedSearchInit', 'RelatedPaginateInit',
function($location, GetBasePath, Rest, JobTemplateForm, GenerateForm, $routeParams, LoadBreadCrumbs, ProcessErrors,ParseTypeChange,
ParseVariableString, Empty, LookUpInit, InventoryList, CredentialList, ProjectList, RelatedSearchInit, RelatedPaginateInit) {
return function(params) {
var scope = params.scope,
defaultUrl = GetBasePath('job_templates'),
// generator = GenerateForm,
form = JobTemplateForm(),
// loadingFinishedCount = 0,
// base = $location.path().replace(/^\//, '').split('/')[0],
master = {},
id = $routeParams.template_id,
relatedSets = {};
// checkSCMStatus, getPlaybooks, callback,
// choicesCount = 0;
var scope = params.scope,
defaultUrl = GetBasePath('job_templates'),
// generator = GenerateForm,
form = JobTemplateForm(),
// loadingFinishedCount = 0,
// base = $location.path().replace(/^\//, '').split('/')[0],
master = {},
id = $routeParams.template_id,
relatedSets = {};
// checkSCMStatus, getPlaybooks, callback,
// choicesCount = 0;
// The form uses awPopOverWatch directive to 'watch' scope.callback_help for changes. Each time the
// popover is activated, a function checks the value of scope.callback_help before constructing the content.
scope.setCallbackHelp = function() {
scope.callback_help = "<p>With a provisioning callback URL and a host config key a host can contact Tower and request a configuration update using this job " +
"template. The request from the host must be a POST. Here is an example using curl:</p>\n" +
"<pre>curl --data \"host_config_key=" + scope.example_config_key + "\" " +
scope.callback_server_path + GetBasePath('job_templates') + scope.example_template_id + "/callback/</pre>\n" +
"<p>Note the requesting host must be defined in the inventory associated with the job template. If Tower fails to " +
"locate the host, the request will be denied.</p>" +
"<p>Successful requests create an entry on the Jobs page, where results and history can be viewed.</p>";
};
// The form uses awPopOverWatch directive to 'watch' scope.callback_help for changes. Each time the
// popover is activated, a function checks the value of scope.callback_help before constructing the content.
scope.setCallbackHelp = function() {
scope.callback_help = "<p>With a provisioning callback URL and a host config key a host can contact Tower and request a configuration update using this job " +
"template. The request from the host must be a POST. Here is an example using curl:</p>\n" +
"<pre>curl --data \"host_config_key=" + scope.example_config_key + "\" " +
scope.callback_server_path + GetBasePath('job_templates') + scope.example_template_id + "/callback/</pre>\n" +
"<p>Note the requesting host must be defined in the inventory associated with the job template. If Tower fails to " +
"locate the host, the request will be denied.</p>" +
"<p>Successful requests create an entry on the Jobs page, where results and history can be viewed.</p>";
};
// The md5 helper emits NewMD5Generated whenever a new key is available
if (scope.removeNewMD5Generated) {
scope.removeNewMD5Generated();
}
scope.removeNewMD5Generated = scope.$on('NewMD5Generated', function() {
scope.configKeyChange();
});
// The md5 helper emits NewMD5Generated whenever a new key is available
if (scope.removeNewMD5Generated) {
scope.removeNewMD5Generated();
}
scope.removeNewMD5Generated = scope.$on('NewMD5Generated', function() {
scope.configKeyChange();
});
// Fired when user enters a key value
scope.configKeyChange = function() {
scope.example_config_key = scope.host_config_key;
scope.setCallbackHelp();
};
// Fired when user enters a key value
scope.configKeyChange = function() {
scope.example_config_key = scope.host_config_key;
scope.setCallbackHelp();
};
// Set initial values and construct help text
scope.callback_server_path = $location.protocol() + '://' + $location.host() + (($location.port()) ? ':' + $location.port() : '');
scope.example_config_key = '5a8ec154832b780b9bdef1061764ae5a';
scope.example_template_id = 'N';
scope.setCallbackHelp();
// Set initial values and construct help text
scope.callback_server_path = $location.protocol() + '://' + $location.host() + (($location.port()) ? ':' + $location.port() : '');
scope.example_config_key = '5a8ec154832b780b9bdef1061764ae5a';
scope.example_template_id = 'N';
scope.setCallbackHelp();
scope.fillJobTemplate = function(){
// id = id || $rootScope.copy.id;
// Retrieve detail record and prepopulate the form
Rest.setUrl(defaultUrl + id);
Rest.get()
.success(function (data) {
var fld, i;
LoadBreadCrumbs({ path: '/job_templates/' + id, title: data.name });
for (fld in form.fields) {
if (fld !== 'variables' && 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++) {
if (data[fld] === scope[fld + '_options'][i].value) {
scope[fld] = scope[fld + '_options'][i];
}
}
} else {
scope[fld] = data[fld];
}
} else {
scope[fld] = data[fld];
if(fld ==='survey_enabled'){
// $scope.$emit('EnableSurvey', fld);
$('#job_templates_survey_enabled_chbox').attr('checked', scope[fld]);
if(Empty(data.summary_fields.survey)) {
$('#job_templates_delete_survey_btn').hide();
$('#job_templates_edit_survey_btn').hide();
$('#job_templates_create_survey_btn').show();
}
else{
$('#job_templates_delete_survey_btn').show();
$('#job_templates_edit_survey_btn').show();
$('#job_templates_create_survey_btn').hide();
scope.survey_exists = true;
}
}
}
master[fld] = scope[fld];
}
if (fld === 'variables') {
// Parse extra_vars, converting to YAML.
scope.variables = ParseVariableString(data.extra_vars);
master.variables = scope.variables;
}
if (form.fields[fld].type === 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField];
}
}
scope.fillJobTemplate = function(){
// id = id || $rootScope.copy.id;
// Retrieve detail record and prepopulate the form
Rest.setUrl(defaultUrl + id);
Rest.get()
.success(function (data) {
var fld, i;
LoadBreadCrumbs({ path: '/job_templates/' + id, title: data.name });
for (fld in form.fields) {
if (fld !== 'variables' && 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++) {
if (data[fld] === scope[fld + '_options'][i].value) {
scope[fld] = scope[fld + '_options'][i];
}
}
} else {
scope[fld] = data[fld];
}
} else {
scope[fld] = data[fld];
if(fld ==='survey_enabled'){
// $scope.$emit('EnableSurvey', fld);
$('#job_templates_survey_enabled_chbox').attr('checked', scope[fld]);
if(Empty(data.summary_fields.survey)) {
$('#job_templates_delete_survey_btn').hide();
$('#job_templates_edit_survey_btn').hide();
$('#job_templates_create_survey_btn').show();
}
else{
$('#job_templates_delete_survey_btn').show();
$('#job_templates_edit_survey_btn').show();
$('#job_templates_create_survey_btn').hide();
scope.survey_exists = true;
}
}
}
master[fld] = scope[fld];
}
if (fld === 'variables') {
// Parse extra_vars, converting to YAML.
scope.variables = ParseVariableString(data.extra_vars);
master.variables = scope.variables;
}
if (form.fields[fld].type === 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField];
}
}
scope.url = data.url;
scope.url = data.url;
scope.ask_variables_on_launch = (data.ask_variables_on_launch) ? 'true' : 'false';
master.ask_variables_on_launch = scope.ask_variables_on_launch;
scope.ask_variables_on_launch = (data.ask_variables_on_launch) ? 'true' : 'false';
master.ask_variables_on_launch = scope.ask_variables_on_launch;
relatedSets = form.relatedSets(data.related);
relatedSets = form.relatedSets(data.related);
if (data.host_config_key) {
scope.example_config_key = data.host_config_key;
}
scope.example_template_id = id;
scope.setCallbackHelp();
if (data.host_config_key) {
scope.example_config_key = data.host_config_key;
}
scope.example_template_id = id;
scope.setCallbackHelp();
scope.callback_url = scope.callback_server_path + ((data.related.callback) ? data.related.callback :
GetBasePath('job_templates') + id + '/callback/');
master.callback_url = scope.callback_url;
scope.callback_url = scope.callback_server_path + ((data.related.callback) ? data.related.callback :
GetBasePath('job_templates') + id + '/callback/');
master.callback_url = scope.callback_url;
scope.can_edit = data.summary_fields.can_edit;
scope.can_edit = data.summary_fields.can_edit;
LookUpInit({
scope: scope,
form: form,
current_item: data.inventory,
list: InventoryList,
field: 'inventory',
input_type: "radio"
});
LookUpInit({
scope: scope,
form: form,
current_item: data.inventory,
list: InventoryList,
field: 'inventory',
input_type: "radio"
});
LookUpInit({
url: GetBasePath('credentials') + '?kind=ssh',
scope: scope,
form: form,
current_item: data.credential,
list: CredentialList,
field: 'credential',
hdr: 'Select Machine Credential',
input_type: "radio"
});
LookUpInit({
url: GetBasePath('credentials') + '?kind=ssh',
scope: scope,
form: form,
current_item: data.credential,
list: CredentialList,
field: 'credential',
hdr: 'Select Machine Credential',
input_type: "radio"
});
LookUpInit({
scope: scope,
form: form,
current_item: data.project,
list: ProjectList,
field: 'project',
input_type: "radio"
});
LookUpInit({
scope: scope,
form: form,
current_item: data.project,
list: ProjectList,
field: 'project',
input_type: "radio"
});
RelatedSearchInit({
scope: scope,
form: form,
relatedSets: relatedSets
});
RelatedSearchInit({
scope: scope,
form: form,
relatedSets: relatedSets
});
RelatedPaginateInit({
scope: scope,
relatedSets: relatedSets
});
RelatedPaginateInit({
scope: scope,
relatedSets: relatedSets
});
scope.$emit('jobTemplateLoaded', data.related.cloud_credential, master);
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to retrieve job template: ' + $routeParams.template_id + '. GET status: ' + status
});
});
};
scope.$emit('jobTemplateLoaded', data.related.cloud_credential, master);
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to retrieve job template: ' + $routeParams.template_id + '. GET status: ' + status
});
});
};
};
};
}]);
}]);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1
View File
@@ -16,6 +16,7 @@
export default
angular.module('LoadConfigHelper', ['Utilities'])
.factory('LoadConfig', ['$log', '$rootScope', '$http', 'ProcessErrors', 'Store', function($log, $rootScope, $http, ProcessErrors, Store) {
+340 -340
View File
@@ -10,373 +10,373 @@
* @description logviewer
*/
export default
angular.module('LogViewerHelper', ['ModalDialog', 'Utilities', 'FormGenerator', 'VariablesHelper'])
angular.module('LogViewerHelper', ['ModalDialog', 'Utilities', 'FormGenerator', 'VariablesHelper'])
.factory('LogViewer', ['$location', '$compile', 'CreateDialog', 'GetJob', 'Wait', 'GenerateForm', 'LogViewerStatusForm', 'AddTable', 'AddTextarea',
'LogViewerOptionsForm', 'EnvTable', 'GetBasePath', 'LookUpName', 'Empty', 'AddPreFormattedText', 'ParseVariableString', 'GetChoices',
function($location, $compile, CreateDialog, GetJob, Wait, GenerateForm, LogViewerStatusForm, AddTable, AddTextarea, LogViewerOptionsForm, EnvTable,
GetBasePath, LookUpName, Empty, AddPreFormattedText, ParseVariableString, GetChoices) {
return function(params) {
var parent_scope = params.scope,
url = params.url,
getIcon = params.getIcon,
scope = parent_scope.$new(true),
base = $location.path().replace(/^\//, '').split('/')[0],
pieces;
.factory('LogViewer', ['$location', '$compile', 'CreateDialog', 'GetJob', 'Wait', 'GenerateForm', 'LogViewerStatusForm', 'AddTable', 'AddTextarea',
'LogViewerOptionsForm', 'EnvTable', 'GetBasePath', 'LookUpName', 'Empty', 'AddPreFormattedText', 'ParseVariableString', 'GetChoices',
function($location, $compile, CreateDialog, GetJob, Wait, GenerateForm, LogViewerStatusForm, AddTable, AddTextarea, LogViewerOptionsForm, EnvTable,
GetBasePath, LookUpName, Empty, AddPreFormattedText, ParseVariableString, GetChoices) {
return function(params) {
var parent_scope = params.scope,
url = params.url,
getIcon = params.getIcon,
scope = parent_scope.$new(true),
base = $location.path().replace(/^\//, '').split('/')[0],
pieces;
if (scope.removeModalReady) {
scope.removeModalReady();
}
scope.removeModalReady = scope.$on('ModalReady', function() {
Wait('stop');
$('#logviewer-modal-dialog').dialog('open');
});
if (scope.removeJobReady) {
scope.removeJobReady();
}
scope.removeJobReady = scope.$on('JobReady', function(e, data) {
var key, resizeText, elem;
$('#status-form-container').empty();
$('#options-form-container').empty();
$('#stdout-form-container').empty();
$('#traceback-form-container').empty();
$('#variables-container').empty();
$('#source-container').empty();
$('#logview-tabs li:eq(1)').hide();
$('#logview-tabs li:eq(2)').hide();
$('#logview-tabs li:eq(4)').hide();
$('#logview-tabs li:eq(5)').hide();
// Make sure subsequenct scope references don't bubble up to the parent
for (key in LogViewerStatusForm.fields) {
scope[key] = '';
}
for (key in LogViewerOptionsForm.fields) {
scope[key] = '';
if (scope.removeModalReady) {
scope.removeModalReady();
}
scope.removeModalReady = scope.$on('ModalReady', function() {
Wait('stop');
$('#logviewer-modal-dialog').dialog('open');
});
for (key in data) {
scope[key] = data[key];
if (scope.removeJobReady) {
scope.removeJobReady();
}
scope.created_by = '';
scope.job_template = '';
scope.removeJobReady = scope.$on('JobReady', function(e, data) {
var key, resizeText, elem;
$('#status-form-container').empty();
$('#options-form-container').empty();
$('#stdout-form-container').empty();
$('#traceback-form-container').empty();
$('#variables-container').empty();
$('#source-container').empty();
$('#logview-tabs li:eq(1)').hide();
$('#logview-tabs li:eq(2)').hide();
$('#logview-tabs li:eq(4)').hide();
$('#logview-tabs li:eq(5)').hide();
if (data.related.created_by) {
pieces = data.related.created_by.replace(/^\//,'').replace(/\/$/,'').split('/');
scope.created_by = parseInt(pieces[pieces.length - 1],10);
LookUpName({
scope: scope,
scope_var: 'created_by',
url: GetBasePath('users') + scope.created_by + '/'
});
}
// For jobs link the name to the job parent
if (base === 'jobs') {
if (data.type === 'job') {
scope.name_link = "job_template";
scope.job_template = data.unified_job_template;
scope.job_template_name = (data.summary_fields.job_template) ? data.summary_fields.job_template.name : data.name;
scope.name_id = data.unified_job_template;
// Make sure subsequenct scope references don't bubble up to the parent
for (key in LogViewerStatusForm.fields) {
scope[key] = '';
}
if (data.type === 'project_update') {
scope.name_link = "project";
scope.name_id = data.unified_job_template;
for (key in LogViewerOptionsForm.fields) {
scope[key] = '';
}
if (data.type === 'inventory_update') {
scope.name_link = "inventory_source";
scope.name_id = scope.group;
for (key in data) {
scope[key] = data[key];
}
}
scope.created_by = '';
scope.job_template = '';
AddTable({ scope: scope, form: LogViewerStatusForm, id: 'status-form-container', getIcon: getIcon });
AddTable({ scope: scope, form: LogViewerOptionsForm, id: 'options-form-container', getIcon: getIcon });
if (data.result_stdout) {
$('#logview-tabs li:eq(1)').show();
AddPreFormattedText({
id: 'stdout-form-container',
val: data.result_stdout
});
}
if (data.result_traceback) {
$('#logview-tabs li:eq(2)').show();
AddPreFormattedText({
id: 'traceback-form-container',
val: data.result_traceback
});
}
/*if (data.job_env) {
EnvTable({
id: 'env-form-container',
vars: data.job_env
});
}*/
if (data.extra_vars) {
$('#logview-tabs li:eq(4)').show();
AddTextarea({
container_id: 'variables-container',
fld_id: 'variables',
val: ParseVariableString(data.extra_vars)
});
}
if (data.source_vars) {
$('#logview-tabs li:eq(5)').show();
AddTextarea({
container_id: 'source-container',
fld_id: 'source-variables',
val: ParseVariableString(data.source_vars)
});
}
if (!Empty(scope.source)) {
if (scope.removeChoicesReady) {
scope.removeChoicesReady();
}
scope.removeChoicesReady = scope.$on('ChoicesReady', function() {
scope.source_choices.every(function(e) {
if (e.value === scope.source) {
scope.source = e.label;
return false;
}
return true;
if (data.related.created_by) {
pieces = data.related.created_by.replace(/^\//,'').replace(/\/$/,'').split('/');
scope.created_by = parseInt(pieces[pieces.length - 1],10);
LookUpName({
scope: scope,
scope_var: 'created_by',
url: GetBasePath('users') + scope.created_by + '/'
});
});
GetChoices({
scope: scope,
url: GetBasePath('inventory_sources'),
field: 'source',
variable: 'source_choices',
choice_name: 'choices',
callback: 'ChoicesReady'
});
}
}
if (!Empty(scope.credential)) {
LookUpName({
scope: scope,
scope_var: 'credential',
url: GetBasePath('credentials') + scope.credential + '/'
});
}
// For jobs link the name to the job parent
if (base === 'jobs') {
if (data.type === 'job') {
scope.name_link = "job_template";
scope.job_template = data.unified_job_template;
scope.job_template_name = (data.summary_fields.job_template) ? data.summary_fields.job_template.name : data.name;
scope.name_id = data.unified_job_template;
}
if (data.type === 'project_update') {
scope.name_link = "project";
scope.name_id = data.unified_job_template;
}
if (data.type === 'inventory_update') {
scope.name_link = "inventory_source";
scope.name_id = scope.group;
}
}
if (!Empty(scope.inventory)) {
LookUpName({
scope: scope,
scope_var: 'inventory',
url: GetBasePath('inventory') + scope.inventory + '/'
});
}
AddTable({ scope: scope, form: LogViewerStatusForm, id: 'status-form-container', getIcon: getIcon });
AddTable({ scope: scope, form: LogViewerOptionsForm, id: 'options-form-container', getIcon: getIcon });
if (!Empty(scope.project)) {
LookUpName({
scope: scope,
scope_var: 'project',
url: GetBasePath('projects') + scope.project + '/'
});
}
if (data.result_stdout) {
$('#logview-tabs li:eq(1)').show();
AddPreFormattedText({
id: 'stdout-form-container',
val: data.result_stdout
});
}
if (!Empty(scope.cloud_credential)) {
LookUpName({
scope: scope,
scope_var: 'cloud_credential',
url: GetBasePath('credentials') + scope.cloud_credential + '/'
});
}
if (data.result_traceback) {
$('#logview-tabs li:eq(2)').show();
AddPreFormattedText({
id: 'traceback-form-container',
val: data.result_traceback
});
}
if (!Empty(scope.inventory_source)) {
LookUpName({
scope: scope,
scope_var: 'inventory_source',
url: GetBasePath('inventory_sources') + scope.inventory_source + '/'
});
}
/*if (data.job_env) {
EnvTable({
id: 'env-form-container',
vars: data.job_env
});
}*/
resizeText = function() {
var u = $('#logview-tabs').outerHeight() + 25,
h = $('#logviewer-modal-dialog').innerHeight(),
rows = Math.floor((h - u) / 20);
rows -= 3;
rows = (rows < 6) ? 6 : rows;
$('#logviewer-modal-dialog #variables').attr({ rows: rows });
$('#logviewer-modal-dialog #source-variables').attr({ rows: rows });
if (data.extra_vars) {
$('#logview-tabs li:eq(4)').show();
AddTextarea({
container_id: 'variables-container',
fld_id: 'variables',
val: ParseVariableString(data.extra_vars)
});
}
if (data.source_vars) {
$('#logview-tabs li:eq(5)').show();
AddTextarea({
container_id: 'source-container',
fld_id: 'source-variables',
val: ParseVariableString(data.source_vars)
});
}
if (!Empty(scope.source)) {
if (scope.removeChoicesReady) {
scope.removeChoicesReady();
}
scope.removeChoicesReady = scope.$on('ChoicesReady', function() {
scope.source_choices.every(function(e) {
if (e.value === scope.source) {
scope.source = e.label;
return false;
}
return true;
});
});
GetChoices({
scope: scope,
url: GetBasePath('inventory_sources'),
field: 'source',
variable: 'source_choices',
choice_name: 'choices',
callback: 'ChoicesReady'
});
}
if (!Empty(scope.credential)) {
LookUpName({
scope: scope,
scope_var: 'credential',
url: GetBasePath('credentials') + scope.credential + '/'
});
}
if (!Empty(scope.inventory)) {
LookUpName({
scope: scope,
scope_var: 'inventory',
url: GetBasePath('inventory') + scope.inventory + '/'
});
}
if (!Empty(scope.project)) {
LookUpName({
scope: scope,
scope_var: 'project',
url: GetBasePath('projects') + scope.project + '/'
});
}
if (!Empty(scope.cloud_credential)) {
LookUpName({
scope: scope,
scope_var: 'cloud_credential',
url: GetBasePath('credentials') + scope.cloud_credential + '/'
});
}
if (!Empty(scope.inventory_source)) {
LookUpName({
scope: scope,
scope_var: 'inventory_source',
url: GetBasePath('inventory_sources') + scope.inventory_source + '/'
});
}
resizeText = function() {
var u = $('#logview-tabs').outerHeight() + 25,
h = $('#logviewer-modal-dialog').innerHeight(),
rows = Math.floor((h - u) / 20);
rows -= 3;
rows = (rows < 6) ? 6 : rows;
$('#logviewer-modal-dialog #variables').attr({ rows: rows });
$('#logviewer-modal-dialog #source-variables').attr({ rows: rows });
};
elem = angular.element(document.getElementById('logviewer-modal-dialog'));
$compile(elem)(scope);
CreateDialog({
scope: scope,
width: 600,
height: 550,
minWidth: 450,
callback: 'ModalReady',
id: 'logviewer-modal-dialog',
onResizeStop: resizeText,
title: 'Job Results',
onOpen: function() {
$('#logview-tabs a:first').tab('show');
$('#dialog-ok-button').focus();
resizeText();
}
});
});
GetJob({
url: url,
scope: scope
});
scope.modalOK = function() {
$('#logviewer-modal-dialog').dialog('close');
scope.$destroy();
};
elem = angular.element(document.getElementById('logviewer-modal-dialog'));
$compile(elem)(scope);
CreateDialog({
scope: scope,
width: 600,
height: 550,
minWidth: 450,
callback: 'ModalReady',
id: 'logviewer-modal-dialog',
onResizeStop: resizeText,
title: 'Job Results',
onOpen: function() {
$('#logview-tabs a:first').tab('show');
$('#dialog-ok-button').focus();
resizeText();
}
});
});
GetJob({
url: url,
scope: scope
});
scope.modalOK = function() {
$('#logviewer-modal-dialog').dialog('close');
scope.$destroy();
};
};
}])
}])
.factory('GetJob', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
return function(params) {
var url = params.url,
scope = params.scope;
Rest.setUrl(url);
Rest.get()
.success(function(data){
scope.$emit('JobReady', data);
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to retrieve ' + url + '. GET returned: ' + status });
});
};
}])
.factory('GetJob', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
return function(params) {
var url = params.url,
scope = params.scope;
Rest.setUrl(url);
Rest.get()
.success(function(data){
scope.$emit('JobReady', data);
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to retrieve ' + url + '. GET returned: ' + status });
});
};
}])
.factory('LookUpName', ['Rest', 'ProcessErrors', 'Empty', function(Rest, ProcessErrors, Empty) {
return function(params) {
var url = params.url,
scope_var = params.scope_var,
scope = params.scope;
Rest.setUrl(url);
Rest.get()
.success(function(data) {
if (scope_var === 'inventory_source') {
scope[scope_var + '_name'] = data.summary_fields.group.name;
}
else if (!Empty(data.name)) {
scope[scope_var + '_name'] = data.name;
}
if (!Empty(data.group)) {
// Used for inventory_source
scope.group = data.group;
}
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to retrieve ' + url + '. GET returned: ' + status });
});
};
}])
.factory('LookUpName', ['Rest', 'ProcessErrors', 'Empty', function(Rest, ProcessErrors, Empty) {
return function(params) {
var url = params.url,
scope_var = params.scope_var,
scope = params.scope;
Rest.setUrl(url);
Rest.get()
.success(function(data) {
if (scope_var === 'inventory_source') {
scope[scope_var + '_name'] = data.summary_fields.group.name;
}
else if (!Empty(data.name)) {
scope[scope_var + '_name'] = data.name;
}
if (!Empty(data.group)) {
// Used for inventory_source
scope.group = data.group;
}
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to retrieve ' + url + '. GET returned: ' + status });
});
};
}])
.factory('AddTable', ['$compile', 'Empty', 'Find', function($compile, Empty, Find) {
return function(params) {
var form = params.form,
id = params.id,
scope = params.scope,
getIcon = params.getIcon,
fld, html, url, e,
urls = [
{ "variable": "credential", "url": "/#/credentials/" },
{ "variable": "project", "url": "/#/projects/" },
{ "variable": "inventory", "url": "/#/inventories/" },
{ "variable": "cloud_credential", "url": "/#/credentials/" },
{ "variable": "inventory_source", "url": "/#/home/groups/?id={{ group }}" },
{ "variable": "job_template", "url": "/#/job_templates/" },
{ "variable": "created_by", "url": "/#/users/" }
];
html = "<table class=\"table logviewer-status\">\n";
for (fld in form.fields) {
if (!Empty(scope[fld])) {
html += "<tr><td class=\"fld-label col-md-3 col-sm-3 col-xs-3\">" + form.fields[fld].label + "</td>" +
"<td>";
url = Find({ list: urls, key: "variable", val: fld });
if (url) {
html += "<a href=\"" + url.url;
html += (fld === "inventory_source") ? "" : scope[fld];
html += "\" ng-click=\"modalOK()\">{{ " + fld + '_name' + " }}</a>";
}
else if (fld === 'name' && scope.name_link) {
url = Find({ list: urls, key: "variable", val: scope.name_link });
html += "<a href=\"" + url.url + ( (scope.name_link === 'inventory_source') ? '' : scope.name_id ) + "\" ng-click=\"modalOK()\">{{ " +
( (scope.name_link === 'inventory_source') ? 'inventory_source_name' : fld ) + " }}</a>";
}
else if (fld === 'elapsed') {
html += scope[fld] + " <span class=\"small-text\">seconds</span>";
}
else if (fld === 'status') {
if (getIcon) {
html += "<i class=\"fa icon-job-" + getIcon(scope[fld]) + "\"></i> " + scope[fld];
.factory('AddTable', ['$compile', 'Empty', 'Find', function($compile, Empty, Find) {
return function(params) {
var form = params.form,
id = params.id,
scope = params.scope,
getIcon = params.getIcon,
fld, html, url, e,
urls = [
{ "variable": "credential", "url": "/#/credentials/" },
{ "variable": "project", "url": "/#/projects/" },
{ "variable": "inventory", "url": "/#/inventories/" },
{ "variable": "cloud_credential", "url": "/#/credentials/" },
{ "variable": "inventory_source", "url": "/#/home/groups/?id={{ group }}" },
{ "variable": "job_template", "url": "/#/job_templates/" },
{ "variable": "created_by", "url": "/#/users/" }
];
html = "<table class=\"table logviewer-status\">\n";
for (fld in form.fields) {
if (!Empty(scope[fld])) {
html += "<tr><td class=\"fld-label col-md-3 col-sm-3 col-xs-3\">" + form.fields[fld].label + "</td>" +
"<td>";
url = Find({ list: urls, key: "variable", val: fld });
if (url) {
html += "<a href=\"" + url.url;
html += (fld === "inventory_source") ? "" : scope[fld];
html += "\" ng-click=\"modalOK()\">{{ " + fld + '_name' + " }}</a>";
}
else if (fld === 'name' && scope.name_link) {
url = Find({ list: urls, key: "variable", val: scope.name_link });
html += "<a href=\"" + url.url + ( (scope.name_link === 'inventory_source') ? '' : scope.name_id ) + "\" ng-click=\"modalOK()\">{{ " +
( (scope.name_link === 'inventory_source') ? 'inventory_source_name' : fld ) + " }}</a>";
}
else if (fld === 'elapsed') {
html += scope[fld] + " <span class=\"small-text\">seconds</span>";
}
else if (fld === 'status') {
if (getIcon) {
html += "<i class=\"fa icon-job-" + getIcon(scope[fld]) + "\"></i> " + scope[fld];
}
else {
html += "<i class=\"fa icon-job-" + scope[fld] + "\"></i> " + scope[fld];
}
if (scope.job_explanation) {
html += "<p style=\"padding-top: 12px\">" + scope.job_explanation + "</p>";
}
}
else {
html += "<i class=\"fa icon-job-" + scope[fld] + "\"></i> " + scope[fld];
}
if (scope.job_explanation) {
html += "<p style=\"padding-top: 12px\">" + scope.job_explanation + "</p>";
html += "{{ " + fld ;
html += (form.fields[fld].filter) ? " | " + form.fields[fld].filter : "" ;
html += " }}";
}
html += "</td></tr>\n";
}
else {
html += "{{ " + fld ;
html += (form.fields[fld].filter) ? " | " + form.fields[fld].filter : "" ;
html += " }}";
}
html += "</td></tr>\n";
}
}
html += "</table>\n";
e = angular.element(document.getElementById(id));
e.empty().html(html);
$compile(e)(scope);
};
}])
html += "</table>\n";
e = angular.element(document.getElementById(id));
e.empty().html(html);
$compile(e)(scope);
};
}])
.factory('AddTextarea', [ function() {
return function(params) {
var container_id = params.container_id,
val = params.val,
fld_id = params.fld_id,
html;
html = "<div class=\"form-group\">\n" +
"<textarea id=\"" + fld_id + "\" ng-non-bindable class=\"form-control mono-space\" rows=\"12\" readonly>" + val + "</textarea>" +
"</div>\n";
$('#' + container_id).empty().html(html);
};
}])
.factory('AddTextarea', [ function() {
return function(params) {
var container_id = params.container_id,
val = params.val,
fld_id = params.fld_id,
html;
html = "<div class=\"form-group\">\n" +
"<textarea id=\"" + fld_id + "\" ng-non-bindable class=\"form-control mono-space\" rows=\"12\" readonly>" + val + "</textarea>" +
"</div>\n";
$('#' + container_id).empty().html(html);
};
}])
.factory('AddPreFormattedText', [function() {
return function(params) {
var id = params.id,
val = params.val,
html;
html = "<pre ng-non-bindable>" + val + "</pre>\n";
$('#' + id).empty().html(html);
};
}])
.factory('AddPreFormattedText', [function() {
return function(params) {
var id = params.id,
val = params.val,
html;
html = "<pre ng-non-bindable>" + val + "</pre>\n";
$('#' + id).empty().html(html);
};
}])
.factory('EnvTable', [ function() {
return function(params) {
var id = params.id,
vars = params.vars,
key, html;
html = "<table class=\"table logviewer-status\">\n";
for (key in vars) {
html += "<tr><td class=\"fld-label col-md-4 col-sm-3 col-xs-3 break\">" + key + "</td>" +
"<td ng-non-bindable class=\"break\">" + vars[key] + "</td></tr>\n";
}
html += "</table>\n";
$('#' + id).empty().html(html);
};
}]);
.factory('EnvTable', [ function() {
return function(params) {
var id = params.id,
vars = params.vars,
key, html;
html = "<table class=\"table logviewer-status\">\n";
for (key in vars) {
html += "<tr><td class=\"fld-label col-md-4 col-sm-3 col-xs-3 break\">" + key + "</td>" +
"<td ng-non-bindable class=\"break\">" + vars[key] + "</td></tr>\n";
}
html += "</table>\n";
$('#' + id).empty().html(html);
};
}]);
+194 -194
View File
@@ -23,228 +23,228 @@
*/
export default
angular.module('LookUpHelper', ['RestServices', 'Utilities', 'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'ApiLoader', 'ModalDialog'])
angular.module('LookUpHelper', ['RestServices', 'Utilities', 'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'ApiLoader', 'ModalDialog'])
.factory('LookUpInit', ['Alert', 'Rest', 'GenerateList', 'SearchInit', 'PaginateInit', 'GetBasePath', 'FormatDate', 'Empty', 'CreateDialog',
function (Alert, Rest, GenerateList, SearchInit, PaginateInit, GetBasePath, FormatDate, Empty, CreateDialog) {
return function (params) {
.factory('LookUpInit', ['Alert', 'Rest', 'GenerateList', 'SearchInit', 'PaginateInit', 'GetBasePath', 'FormatDate', 'Empty', 'CreateDialog',
function (Alert, Rest, GenerateList, SearchInit, PaginateInit, GetBasePath, FormatDate, Empty, CreateDialog) {
return function (params) {
var parent_scope = params.scope,
form = params.form,
list = params.list,
field = params.field,
instructions = params.instructions,
postAction = params.postAction,
callback = params.callback,
input_type = (params.input_type) ? params.input_type: "checkbox",
defaultUrl, name, watchUrl;
var parent_scope = params.scope,
form = params.form,
list = params.list,
field = params.field,
instructions = params.instructions,
postAction = params.postAction,
callback = params.callback,
input_type = (params.input_type) ? params.input_type: "checkbox",
defaultUrl, name, watchUrl;
if (params.url) {
// pass in a url value to override the default
defaultUrl = params.url;
} else {
defaultUrl = (list.name === 'inventories') ? GetBasePath('inventory') : GetBasePath(list.name);
}
if (params.url) {
// pass in a url value to override the default
defaultUrl = params.url;
} else {
defaultUrl = (list.name === 'inventories') ? GetBasePath('inventory') : GetBasePath(list.name);
}
if ($('#htmlTemplate #lookup-modal-dialog').length > 0) {
$('#htmlTemplate #lookup-modal-dialog').empty();
}
else {
$('#htmlTemplate').append("<div id=\"lookup-modal-dialog\"></div>");
}
name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1);
watchUrl = (/\/$/.test(defaultUrl)) ? defaultUrl + '?' : defaultUrl + '&';
watchUrl += form.fields[field].sourceField + '__' + 'iexact=:value';
$('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-url', watchUrl);
$('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-source', field);
parent_scope['lookUp' + name] = function () {
var master = {},
scope = parent_scope.$new(),
name, hdr, buttons;
// Generating the search list potentially kills the values held in scope for the field.
// We'll keep a copy in master{} that we can revert back to on cancel;
master[field] = scope[field];
master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] =
scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField];
GenerateList.inject(list, {
mode: 'lookup',
id: 'lookup-modal-dialog',
scope: scope,
instructions: instructions,
input_type: input_type
});
if ($('#htmlTemplate #lookup-modal-dialog').length > 0) {
$('#htmlTemplate #lookup-modal-dialog').empty();
}
else {
$('#htmlTemplate').append("<div id=\"lookup-modal-dialog\"></div>");
}
name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1);
hdr = (params.hdr) ? params.hdr : 'Select ' + name;
// Show pop-up
buttons = [{
label: "Cancel",
icon: "fa-times",
"class": "btn btn-default",
"id": "lookup-cancel-button",
onClick: function() {
$('#lookup-modal-dialog').dialog('close');
watchUrl = (/\/$/.test(defaultUrl)) ? defaultUrl + '?' : defaultUrl + '&';
watchUrl += form.fields[field].sourceField + '__' + 'iexact=:value';
$('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-url', watchUrl);
$('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-source', field);
parent_scope['lookUp' + name] = function () {
var master = {},
scope = parent_scope.$new(),
name, hdr, buttons;
// Generating the search list potentially kills the values held in scope for the field.
// We'll keep a copy in master{} that we can revert back to on cancel;
master[field] = scope[field];
master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] =
scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField];
GenerateList.inject(list, {
mode: 'lookup',
id: 'lookup-modal-dialog',
scope: scope,
instructions: instructions,
input_type: input_type
});
name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1);
hdr = (params.hdr) ? params.hdr : 'Select ' + name;
// Show pop-up
buttons = [{
label: "Cancel",
icon: "fa-times",
"class": "btn btn-default",
"id": "lookup-cancel-button",
onClick: function() {
$('#lookup-modal-dialog').dialog('close');
}
},{
label: "Select",
onClick: function() {
scope.selectAction();
},
icon: "fa-check",
"class": "btn btn-primary",
"id": "lookup-save-button"
}];
if (scope.removeModalReady) {
scope.removeModalReady();
}
},{
label: "Select",
onClick: function() {
scope.selectAction();
},
icon: "fa-check",
"class": "btn btn-primary",
"id": "lookup-save-button"
}];
scope.removeModalReady = scope.$on('ModalReady', function() {
$('#lookup-save-button').attr('disabled','disabled');
$('#lookup-modal-dialog').dialog('open');
});
if (scope.removeModalReady) {
scope.removeModalReady();
}
scope.removeModalReady = scope.$on('ModalReady', function() {
$('#lookup-save-button').attr('disabled','disabled');
$('#lookup-modal-dialog').dialog('open');
});
CreateDialog({
scope: scope,
buttons: buttons,
width: 600,
height: (instructions) ? 625 : 500,
minWidth: 500,
title: hdr,
id: 'lookup-modal-dialog',
onClose: function() {
setTimeout( function() {
scope.$apply( function() {
if (Empty(scope[field])) {
scope[field] = master[field];
scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] =
master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField];
}
});
}, 300);
},
callback: 'ModalReady'
});
CreateDialog({
scope: scope,
buttons: buttons,
width: 600,
height: (instructions) ? 625 : 500,
minWidth: 500,
title: hdr,
id: 'lookup-modal-dialog',
onClose: function() {
setTimeout( function() {
scope.$apply( function() {
if (Empty(scope[field])) {
scope[field] = master[field];
scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] =
master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField];
SearchInit({
scope: scope,
set: list.name,
list: list,
url: defaultUrl
});
PaginateInit({
scope: scope,
list: list,
url: defaultUrl,
mode: 'lookup'
});
if (scope.lookupPostRefreshRemove) {
scope.lookupPostRefreshRemove();
}
scope.lookupPostRefreshRemove = scope.$on('PostRefresh', function () {
var fld, i;
for (fld in list.fields) {
if (list.fields[fld].type && list.fields[fld].type === 'date') {
//convert dates to our standard format
for (i = 0; i < scope[list.name].length; i++) {
scope[list.name][i][fld] = FormatDate(new Date(scope[list.name][i][fld]));
}
}
}
// List generator creates the list, resetting it and losing the previously selected value.
// If the selected value is in the current set, find it and mark selected.
if (!Empty(parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField])) {
scope[list.name].forEach(function(elem) {
if (elem[form.fields[field].sourceField] ===
parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]) {
scope[field] = elem.id;
}
});
}, 300);
},
callback: 'ModalReady'
});
SearchInit({
scope: scope,
set: list.name,
list: list,
url: defaultUrl
});
PaginateInit({
scope: scope,
list: list,
url: defaultUrl,
mode: 'lookup'
});
if (scope.lookupPostRefreshRemove) {
scope.lookupPostRefreshRemove();
}
scope.lookupPostRefreshRemove = scope.$on('PostRefresh', function () {
var fld, i;
for (fld in list.fields) {
if (list.fields[fld].type && list.fields[fld].type === 'date') {
//convert dates to our standard format
for (i = 0; i < scope[list.name].length; i++) {
scope[list.name][i][fld] = FormatDate(new Date(scope[list.name][i][fld]));
}
}
}
// List generator creates the list, resetting it and losing the previously selected value.
// If the selected value is in the current set, find it and mark selected.
if (!Empty(parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField])) {
scope[list.name].forEach(function(elem) {
if (elem[form.fields[field].sourceField] ===
parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField]) {
scope[field] = elem.id;
}
});
if (!Empty(scope[field])) {
scope['toggle_' + list.iterator](scope[field]);
}
}
});
if (!Empty(scope[field])) {
scope['toggle_' + list.iterator](scope[field]);
}
scope.search(list.iterator);
});
scope.search(list.iterator);
scope.selectAction = function () {
var i, found = false;
for (i = 0; i < scope[list.name].length; i++) {
if (scope[list.name][i].checked === '1' || scope[list.name][i].checked===1) {
found = true;
parent_scope[field] = scope[list.name][i].id;
if (parent_scope[form.name + '_form'] && form.fields[field] && form.fields[field].sourceModel) {
parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] =
scope[list.name][i][form.fields[field].sourceField];
if (parent_scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField]) {
parent_scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField]
.$setValidity('awlookup', true);
scope.selectAction = function () {
var i, found = false;
for (i = 0; i < scope[list.name].length; i++) {
if (scope[list.name][i].checked === '1' || scope[list.name][i].checked===1) {
found = true;
parent_scope[field] = scope[list.name][i].id;
if (parent_scope[form.name + '_form'] && form.fields[field] && form.fields[field].sourceModel) {
parent_scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] =
scope[list.name][i][form.fields[field].sourceField];
if (parent_scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField]) {
parent_scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField]
.$setValidity('awlookup', true);
}
}
if (parent_scope[form.name + '_form']) {
parent_scope[form.name + '_form'].$setDirty();
}
}
if (parent_scope[form.name + '_form']) {
parent_scope[form.name + '_form'].$setDirty();
}
if (found) {
// Selection made
$('#lookup-modal-dialog').dialog('close');
if (postAction) {
postAction();
}
if (callback) {
parent_scope.$emit(callback);
}
}
}
if (found) {
// Selection made
$('#lookup-modal-dialog').dialog('close');
if (postAction) {
postAction();
}
if (callback) {
parent_scope.$emit(callback);
}
}
};
};
scope['toggle_' + list.iterator] = function (id) {
var count = 0;
scope[list.name].forEach( function(row, i) {
if (row.id === id) {
if (row.checked === '0') {
scope[list.name][i].checked = '1';
scope[list.name][i].success_class = 'success';
}
else {
scope['toggle_' + list.iterator] = function (id) {
var count = 0;
scope[list.name].forEach( function(row, i) {
if (row.id === id) {
if (row.checked === '0') {
scope[list.name][i].checked = '1';
scope[list.name][i].success_class = 'success';
}
else {
scope[list.name][i].checked = '0';
scope[list.name][i].success_class = '';
}
} else {
scope[list.name][i].checked = '0';
scope[list.name][i].success_class = '';
}
} else {
scope[list.name][i].checked = '0';
scope[list.name][i].success_class = '';
});
// Check if any rows are checked
scope[list.name].forEach(function(row) {
if (row.checked === '1') {
count++;
}
});
if (count === 0) {
$('#lookup-save-button').attr('disabled','disabled');
}
});
// Check if any rows are checked
scope[list.name].forEach(function(row) {
if (row.checked === '1') {
count++;
else {
$('#lookup-save-button').removeAttr('disabled');
}
});
if (count === 0) {
$('#lookup-save-button').attr('disabled','disabled');
}
else {
$('#lookup-save-button').removeAttr('disabled');
}
};
};
};
};
}]);
}]);
+145 -145
View File
@@ -10,155 +10,155 @@
* @description pagination
*/
export default
angular.module('PaginationHelpers', ['Utilities', 'RefreshHelper', 'RefreshRelatedHelper'])
angular.module('PaginationHelpers', ['Utilities', 'RefreshHelper', 'RefreshRelatedHelper'])
.factory('PageRangeSetup', ['Empty',
function (Empty) {
return function (params) {
.factory('PageRangeSetup', ['Empty',
function (Empty) {
return function (params) {
var scope = params.scope,
count = params.count,
next = params.next,
previous = params.previous,
iterator = params.iterator,
i, first, last;
scope[iterator + '_page'] = 1;
scope[iterator + '_num_pages'] = Math.ceil((count / scope[iterator + '_page_size']));
scope[iterator + '_num_pages'] = (scope[iterator + '_num_pages'] <= 0) ? 1 : scope[iterator + '_num_pages'];
scope[iterator + '_total_rows'] = count;
// Which page are we on?
if (Empty(next) && previous) {
// no next page, but there is a previous page
scope[iterator + '_page'] = parseInt(previous.match(/page=\d+/)[0].replace(/page=/, '')) + 1;
} else if (next && Empty(previous)) {
// next page available, but no previous page
scope[iterator + '_page'] = 1;
} else if (next && previous) {
// we're in between next and previous
scope[iterator + '_page'] = parseInt(previous.match(/page=\d+/)[0].replace(/page=/, '')) + 1;
}
// Calc the range of up to 10 pages to show
scope[iterator + '_page_range'] = [];
first = (scope[iterator + '_page'] > 5) ? scope[iterator + '_page'] - 5 : 1;
if (scope[iterator + '_page'] < 6) {
last = (10 <= scope[iterator + '_num_pages']) ? 10 : scope[iterator + '_num_pages'];
} else {
last = (scope[iterator + '_page'] + 4 < scope[iterator + '_num_pages']) ?
scope[iterator + '_page'] + 4 : scope[iterator + '_num_pages'];
}
for (i = first; i <= last; i++) {
scope[iterator + '_page_range'].push(i);
}
};
}
])
.factory('RelatedPaginateInit', ['RefreshRelated', '$cookieStore', 'Wait',
function (RefreshRelated, $cookieStore, Wait) {
return function (params) {
var scope = params.scope,
relatedSets = params.relatedSets,
pageSize = (params.pageSize) ? params.pageSize : 10,
key;
for (key in relatedSets) {
scope[relatedSets[key].iterator + '_url'] = relatedSets[key].url;
scope[relatedSets[key].iterator + '_page'] = 0;
scope[relatedSets[key].iterator + '_page_size'] = pageSize;
}
scope.getPage = function (page, set, iterator) {
var new_url = scope[iterator + '_url'].replace(/.page\=\d+/, ''),
connect = (/\/$/.test(new_url)) ? '?' : '&';
new_url += connect + 'page=' + page;
new_url += (scope[iterator + 'SearchParams']) ? '&' + scope[iterator + 'SearchParams'] +
'&page_size=' + scope[iterator + '_page_size'] : 'page_size=' + scope[iterator + 'PageSize'];
Wait('start');
RefreshRelated({ scope: scope, set: set, iterator: iterator, url: new_url });
};
scope.pageIsActive = function (page, iterator) {
return (page === scope[iterator + '_page']) ? 'active' : '';
};
scope.changePageSize = function (set, iterator) {
// Called when a new page size is selected
var scope = params.scope,
count = params.count,
next = params.next,
previous = params.previous,
iterator = params.iterator,
i, first, last;
scope[iterator + '_page'] = 1;
var url = scope[iterator + '_url'];
scope[iterator + '_num_pages'] = Math.ceil((count / scope[iterator + '_page_size']));
scope[iterator + '_num_pages'] = (scope[iterator + '_num_pages'] <= 0) ? 1 : scope[iterator + '_num_pages'];
scope[iterator + '_total_rows'] = count;
// Using the session cookie, keep track of user rows per page selection
$cookieStore.put(iterator + '_page_size', scope[iterator + '_page_size']);
url = url.replace(/\/\?.*$/, '/');
url += (scope[iterator + 'SearchParams']) ? '?' + scope[iterator + 'SearchParams'] + '&page_size=' + scope[iterator + '_page_size'] :
'?page_size=' + scope[iterator + '_page_size'];
RefreshRelated({
scope: scope,
set: set,
iterator: iterator,
url: url
});
};
};
}
])
.factory('PaginateInit', ['Refresh', '$cookieStore', 'Wait',
function (Refresh, $cookieStore, Wait) {
return function (params) {
var scope = params.scope,
list = params.list,
iterator = (params.iterator) ? params.iterator : list.iterator,
pageSize = params.pageSize,
mode = (params.mode) ? params.mode : null;
scope[iterator + '_page'] = (params.page) ? params.page : 1;
scope[iterator + '_url'] = params.url;
scope[iterator + '_mode'] = mode;
if (pageSize) {
scope[iterator + '_page_size'] = params.pageSize;
} else if (mode === 'lookup') {
scope[iterator + '_page_size'] = 5;
} else {
scope[iterator + '_page_size'] = 20;
}
scope.getPage = function (page, set, iterator) {
var new_url = scope[iterator + '_url'].replace(/.page\=\d+/, ''),
connect = (/\/$/.test(new_url)) ? '?' : '&';
new_url += connect + 'page=' + page;
new_url += (scope[iterator + 'SearchParams']) ? '&' + scope[iterator + 'SearchParams'] +
'&page_size=' + scope[iterator + '_page_size'] : '&page_size=' + scope[iterator + 'PageSize'];
Wait('start');
Refresh({ scope: scope, set: set, iterator: iterator, url: new_url });
};
scope.pageIsActive = function (page, iterator) {
return (page === scope[iterator + '_page']) ? 'active' : '';
};
scope.changePageSize = function (set, iterator, spinner) {
// Called whenever a new page size is selected
scope[iterator + '_page'] = 1;
var new_url = scope[iterator + '_url'].replace(/\?page_size\=\d+/, ''),
connect = (/\/$/.test(new_url)) ? '?' : '&';
new_url += (scope[iterator + 'SearchParams']) ? connect + scope[iterator + 'SearchParams'] + '&page_size=' + scope[iterator + '_page_size'] :
connect + 'page_size=' + scope[iterator + '_page_size'];
if (spinner === undefined || spinner === true) {
Wait('start');
// Which page are we on?
if (Empty(next) && previous) {
// no next page, but there is a previous page
scope[iterator + '_page'] = parseInt(previous.match(/page=\d+/)[0].replace(/page=/, '')) + 1;
} else if (next && Empty(previous)) {
// next page available, but no previous page
scope[iterator + '_page'] = 1;
} else if (next && previous) {
// we're in between next and previous
scope[iterator + '_page'] = parseInt(previous.match(/page=\d+/)[0].replace(/page=/, '')) + 1;
}
// Calc the range of up to 10 pages to show
scope[iterator + '_page_range'] = [];
first = (scope[iterator + '_page'] > 5) ? scope[iterator + '_page'] - 5 : 1;
if (scope[iterator + '_page'] < 6) {
last = (10 <= scope[iterator + '_num_pages']) ? 10 : scope[iterator + '_num_pages'];
} else {
last = (scope[iterator + '_page'] + 4 < scope[iterator + '_num_pages']) ?
scope[iterator + '_page'] + 4 : scope[iterator + '_num_pages'];
}
for (i = first; i <= last; i++) {
scope[iterator + '_page_range'].push(i);
}
Refresh({ scope: scope, set: set, iterator: iterator, url: new_url });
};
};
}
]);
}
])
.factory('RelatedPaginateInit', ['RefreshRelated', '$cookieStore', 'Wait',
function (RefreshRelated, $cookieStore, Wait) {
return function (params) {
var scope = params.scope,
relatedSets = params.relatedSets,
pageSize = (params.pageSize) ? params.pageSize : 10,
key;
for (key in relatedSets) {
scope[relatedSets[key].iterator + '_url'] = relatedSets[key].url;
scope[relatedSets[key].iterator + '_page'] = 0;
scope[relatedSets[key].iterator + '_page_size'] = pageSize;
}
scope.getPage = function (page, set, iterator) {
var new_url = scope[iterator + '_url'].replace(/.page\=\d+/, ''),
connect = (/\/$/.test(new_url)) ? '?' : '&';
new_url += connect + 'page=' + page;
new_url += (scope[iterator + 'SearchParams']) ? '&' + scope[iterator + 'SearchParams'] +
'&page_size=' + scope[iterator + '_page_size'] : 'page_size=' + scope[iterator + 'PageSize'];
Wait('start');
RefreshRelated({ scope: scope, set: set, iterator: iterator, url: new_url });
};
scope.pageIsActive = function (page, iterator) {
return (page === scope[iterator + '_page']) ? 'active' : '';
};
scope.changePageSize = function (set, iterator) {
// Called when a new page size is selected
scope[iterator + '_page'] = 1;
var url = scope[iterator + '_url'];
// Using the session cookie, keep track of user rows per page selection
$cookieStore.put(iterator + '_page_size', scope[iterator + '_page_size']);
url = url.replace(/\/\?.*$/, '/');
url += (scope[iterator + 'SearchParams']) ? '?' + scope[iterator + 'SearchParams'] + '&page_size=' + scope[iterator + '_page_size'] :
'?page_size=' + scope[iterator + '_page_size'];
RefreshRelated({
scope: scope,
set: set,
iterator: iterator,
url: url
});
};
};
}
])
.factory('PaginateInit', ['Refresh', '$cookieStore', 'Wait',
function (Refresh, $cookieStore, Wait) {
return function (params) {
var scope = params.scope,
list = params.list,
iterator = (params.iterator) ? params.iterator : list.iterator,
pageSize = params.pageSize,
mode = (params.mode) ? params.mode : null;
scope[iterator + '_page'] = (params.page) ? params.page : 1;
scope[iterator + '_url'] = params.url;
scope[iterator + '_mode'] = mode;
if (pageSize) {
scope[iterator + '_page_size'] = params.pageSize;
} else if (mode === 'lookup') {
scope[iterator + '_page_size'] = 5;
} else {
scope[iterator + '_page_size'] = 20;
}
scope.getPage = function (page, set, iterator) {
var new_url = scope[iterator + '_url'].replace(/.page\=\d+/, ''),
connect = (/\/$/.test(new_url)) ? '?' : '&';
new_url += connect + 'page=' + page;
new_url += (scope[iterator + 'SearchParams']) ? '&' + scope[iterator + 'SearchParams'] +
'&page_size=' + scope[iterator + '_page_size'] : '&page_size=' + scope[iterator + 'PageSize'];
Wait('start');
Refresh({ scope: scope, set: set, iterator: iterator, url: new_url });
};
scope.pageIsActive = function (page, iterator) {
return (page === scope[iterator + '_page']) ? 'active' : '';
};
scope.changePageSize = function (set, iterator, spinner) {
// Called whenever a new page size is selected
scope[iterator + '_page'] = 1;
var new_url = scope[iterator + '_url'].replace(/\?page_size\=\d+/, ''),
connect = (/\/$/.test(new_url)) ? '?' : '&';
new_url += (scope[iterator + 'SearchParams']) ? connect + scope[iterator + 'SearchParams'] + '&page_size=' + scope[iterator + '_page_size'] :
connect + 'page_size=' + scope[iterator + '_page_size'];
if (spinner === undefined || spinner === true) {
Wait('start');
}
Refresh({ scope: scope, set: set, iterator: iterator, url: new_url });
};
};
}
]);
+77 -77
View File
@@ -13,86 +13,86 @@
*/
export default
angular.module('ParseHelper', ['Utilities', 'AngularCodeMirrorModule'])
.factory('ParseTypeChange', ['Alert', 'AngularCodeMirror', function (Alert, AngularCodeMirror) {
return function (params) {
angular.module('ParseHelper', ['Utilities', 'AngularCodeMirrorModule'])
.factory('ParseTypeChange', ['Alert', 'AngularCodeMirror', function (Alert, AngularCodeMirror) {
return function (params) {
var scope = params.scope,
field_id = params.field_id,
fld = (params.variable) ? params.variable : 'variables',
pfld = (params.parse_variable) ? params.parse_variable : 'parseType',
onReady = params.onReady,
onChange = params.onChange;
var scope = params.scope,
field_id = params.field_id,
fld = (params.variable) ? params.variable : 'variables',
pfld = (params.parse_variable) ? params.parse_variable : 'parseType',
onReady = params.onReady,
onChange = params.onChange;
function removeField() {
//set our model to the last change in CodeMirror and then destroy CodeMirror
scope[fld] = scope.codeMirror.getValue();
function removeField() {
//set our model to the last change in CodeMirror and then destroy CodeMirror
scope[fld] = scope.codeMirror.getValue();
// codeMirror.destroy looks for anything with a CodeMirror class and destroys it, so if there are multiple codeMirror editor instances, it will delete them all,
// // which was the case if launching a job from the job template form. I had to add a check to see if there were multiple instances and only remove the second one found on the modal.
// if( $(".CodeMirror").length >1) {
// var self = scope.codeMirror;
// $('.CodeMirror:eq(1)').empty().remove();
// if (self.element) {
// self.element.show();
// }
// }
// else
scope.codeMirror.destroy();
}
function createField(onChange, onReady) {
//hide the textarea and show a fresh CodeMirror with the current mode (json or yaml)
scope.codeMirror = AngularCodeMirror();
scope.codeMirror.addModes($AnsibleConfig.variable_edit_modes);
scope.codeMirror.showTextArea({ scope: scope, model: fld, element: field_id, mode: scope[pfld], onReady: onReady, onChange: onChange });
}
// Hide the textarea and show a CodeMirror editor
createField(onChange, onReady);
// Toggle displayed variable string between JSON and YAML
scope.parseTypeChange = function() {
var json_obj;
if (scope[pfld] === 'json') {
// converting yaml to json
try {
removeField();
json_obj = jsyaml.load(scope[fld]);
if ($.isEmptyObject(json_obj)) {
scope[fld] = "{}";
}
else {
scope[fld] = JSON.stringify(json_obj, null, " ");
}
createField();
}
catch (e) {
Alert('Parse Error', 'Failed to parse valid YAML. ' + e.message);
setTimeout( function() { scope.$apply( function() { scope[pfld] = 'yaml'; createField(); }); }, 500);
}
// codeMirror.destroy looks for anything with a CodeMirror class and destroys it, so if there are multiple codeMirror editor instances, it will delete them all,
// // which was the case if launching a job from the job template form. I had to add a check to see if there were multiple instances and only remove the second one found on the modal.
// if( $(".CodeMirror").length >1) {
// var self = scope.codeMirror;
// $('.CodeMirror:eq(1)').empty().remove();
// if (self.element) {
// self.element.show();
// }
// }
// else
scope.codeMirror.destroy();
}
else {
// convert json to yaml
try {
removeField();
json_obj = JSON.parse(scope[fld]);
if ($.isEmptyObject(json_obj)) {
scope[fld] = '---';
}
else {
scope[fld] = jsyaml.safeDump(json_obj);
}
createField();
}
catch (e) {
Alert('Parse Error', 'Failed to parse valid JSON. ' + e.message);
setTimeout( function() { scope.$apply( function() { scope[pfld] = 'json'; createField(); }); }, 500 );
}
function createField(onChange, onReady) {
//hide the textarea and show a fresh CodeMirror with the current mode (json or yaml)
scope.codeMirror = AngularCodeMirror();
scope.codeMirror.addModes($AnsibleConfig.variable_edit_modes);
scope.codeMirror.showTextArea({ scope: scope, model: fld, element: field_id, mode: scope[pfld], onReady: onReady, onChange: onChange });
}
// Hide the textarea and show a CodeMirror editor
createField(onChange, onReady);
// Toggle displayed variable string between JSON and YAML
scope.parseTypeChange = function() {
var json_obj;
if (scope[pfld] === 'json') {
// converting yaml to json
try {
removeField();
json_obj = jsyaml.load(scope[fld]);
if ($.isEmptyObject(json_obj)) {
scope[fld] = "{}";
}
else {
scope[fld] = JSON.stringify(json_obj, null, " ");
}
createField();
}
catch (e) {
Alert('Parse Error', 'Failed to parse valid YAML. ' + e.message);
setTimeout( function() { scope.$apply( function() { scope[pfld] = 'yaml'; createField(); }); }, 500);
}
}
else {
// convert json to yaml
try {
removeField();
json_obj = JSON.parse(scope[fld]);
if ($.isEmptyObject(json_obj)) {
scope[fld] = '---';
}
else {
scope[fld] = jsyaml.safeDump(json_obj);
}
createField();
}
catch (e) {
Alert('Parse Error', 'Failed to parse valid JSON. ' + e.message);
setTimeout( function() { scope.$apply( function() { scope[pfld] = 'json'; createField(); }); }, 500 );
}
}
};
};
};
}
]);
}
]);
+41 -39
View File
@@ -10,45 +10,47 @@
* Functions shared amongst Permission related controllers
*
*/
angular.module('PermissionsHelper', [])
// Handle category change event
.factory('PermissionCategoryChange', ['$sce',
function ($sce) {
return function (params) {
var scope = params.scope,
reset = params.reset,
html;
export default
angular.module('PermissionsHelper', [])
if (scope.category === 'Inventory') {
scope.projectrequired = false;
html = "<dl>\n" +
"<dt>Read</dt>\n" +
"<dd>Only allow the user or team to view the inventory.</dd>\n" +
"<dt>Write</dt>\n" +
"<dd>Allow the user or team to modify hosts and groups contained in the inventory, add new hosts and groups, and perform inventory sync operations.\n" +
"<dt>Admin</dt>\n" +
"<dd>Allow the user or team full access to the inventory. This includes reading, writing, deletion of the inventory and inventory sync operations.</dd>\n" +
"</dl>\n";
scope.permissionTypeHelp = $sce.trustAsHtml(html);
} else {
scope.projectrequired = true;
html = "<dl>\n" +
"<dt>Create</dt>\n" +
"<dd>Allow the user or team to create job templates. This implies that they have the Run and Check permissions.</dd>\n" +
"<dt>Run</dt>\n" +
"<dd>Allow the user or team to run a job template from the project against the inventory. In Run mode modules will " +
"be executed, and changes to the inventory will occur.</dd>\n" +
"<dt>Check</dt>\n" +
"<dd>Only allow the user or team to run the project against the inventory as a dry-run operation. In Check mode, module operations " +
"will only be simulated. No changes will occur.</dd>\n" +
"</dl>\n";
scope.permissionTypeHelp = $sce.trustAsHtml(html);
}
// Handle category change event
.factory('PermissionCategoryChange', ['$sce',
function ($sce) {
return function (params) {
var scope = params.scope,
reset = params.reset,
html;
if (reset) {
scope.permission_type = (scope.category === 'Inventory') ? 'read' : 'run'; //default to the first option
}
};
}
]);
if (scope.category === 'Inventory') {
scope.projectrequired = false;
html = "<dl>\n" +
"<dt>Read</dt>\n" +
"<dd>Only allow the user or team to view the inventory.</dd>\n" +
"<dt>Write</dt>\n" +
"<dd>Allow the user or team to modify hosts and groups contained in the inventory, add new hosts and groups, and perform inventory sync operations.\n" +
"<dt>Admin</dt>\n" +
"<dd>Allow the user or team full access to the inventory. This includes reading, writing, deletion of the inventory and inventory sync operations.</dd>\n" +
"</dl>\n";
scope.permissionTypeHelp = $sce.trustAsHtml(html);
} else {
scope.projectrequired = true;
html = "<dl>\n" +
"<dt>Create</dt>\n" +
"<dd>Allow the user or team to create job templates. This implies that they have the Run and Check permissions.</dd>\n" +
"<dt>Run</dt>\n" +
"<dd>Allow the user or team to run a job template from the project against the inventory. In Run mode modules will " +
"be executed, and changes to the inventory will occur.</dd>\n" +
"<dt>Check</dt>\n" +
"<dd>Only allow the user or team to run the project against the inventory as a dry-run operation. In Check mode, module operations " +
"will only be simulated. No changes will occur.</dd>\n" +
"</dl>\n";
scope.permissionTypeHelp = $sce.trustAsHtml(html);
}
if (reset) {
scope.permission_type = (scope.category === 'Inventory') ? 'read' : 'run'; //default to the first option
}
};
}
]);
+66 -64
View File
@@ -12,74 +12,76 @@
* scope.base_dir (readonly field).
*
*/
angular.module('ProjectPathHelper', ['RestServices', 'Utilities'])
.factory('GetProjectPath', ['Alert', 'Rest', 'GetBasePath', 'ProcessErrors',
function (Alert, Rest, GetBasePath, ProcessErrors) {
return function (params) {
var scope = params.scope,
master = params.master;
export default
angular.module('ProjectPathHelper', ['RestServices', 'Utilities'])
.factory('GetProjectPath', ['Alert', 'Rest', 'GetBasePath', 'ProcessErrors',
function (Alert, Rest, GetBasePath, ProcessErrors) {
return function (params) {
function arraySort(data) {
//Sort nodes by name
var i, j, names = [],
newData = [];
for (i = 0; i < data.length; i++) {
names.push(data[i].value);
}
names.sort();
for (j = 0; j < names.length; j++) {
var scope = params.scope,
master = params.master;
function arraySort(data) {
//Sort nodes by name
var i, j, names = [],
newData = [];
for (i = 0; i < data.length; i++) {
if (data[i].value === names[j]) {
newData.push(data[i]);
}
names.push(data[i].value);
}
}
return newData;
}
scope.showMissingPlaybooksAlert = false;
Rest.setUrl(GetBasePath('config'));
Rest.get()
.success(function (data) {
var opts = [], i;
for (i = 0; i < data.project_local_paths.length; i++) {
opts.push({
label: data.project_local_paths[i],
value: data.project_local_paths[i]
});
}
if (scope.local_path) {
// List only includes paths not assigned to projects, so add the
// path assigned to the current project.
opts.push({
label: scope.local_path,
value: scope.local_path
});
}
scope.project_local_paths = arraySort(opts);
if (scope.local_path) {
for (i = 0; scope.project_local_paths.length; i++) {
if (scope.project_local_paths[i].value === scope.local_path) {
scope.local_path = scope.project_local_paths[i];
break;
names.sort();
for (j = 0; j < names.length; j++) {
for (i = 0; i < data.length; i++) {
if (data[i].value === names[j]) {
newData.push(data[i]);
}
}
}
scope.base_dir = data.project_base_dir;
master.local_path = scope.local_path;
master.base_dir = scope.base_dir; // Keep in master object so that it doesn't get
// wiped out on form reset.
if (opts.length === 0) {
// trigger display of alert block when scm_type == manual
scope.showMissingPlaybooksAlert = true;
}
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to access API config. GET status: ' + status });
});
};
}
]);
return newData;
}
scope.showMissingPlaybooksAlert = false;
Rest.setUrl(GetBasePath('config'));
Rest.get()
.success(function (data) {
var opts = [], i;
for (i = 0; i < data.project_local_paths.length; i++) {
opts.push({
label: data.project_local_paths[i],
value: data.project_local_paths[i]
});
}
if (scope.local_path) {
// List only includes paths not assigned to projects, so add the
// path assigned to the current project.
opts.push({
label: scope.local_path,
value: scope.local_path
});
}
scope.project_local_paths = arraySort(opts);
if (scope.local_path) {
for (i = 0; scope.project_local_paths.length; i++) {
if (scope.project_local_paths[i].value === scope.local_path) {
scope.local_path = scope.project_local_paths[i];
break;
}
}
}
scope.base_dir = data.project_base_dir;
master.local_path = scope.local_path;
master.base_dir = scope.base_dir; // Keep in master object so that it doesn't get
// wiped out on form reset.
if (opts.length === 0) {
// trigger display of alert block when scm_type == manual
scope.showMissingPlaybooksAlert = true;
}
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to access API config. GET status: ' + status });
});
};
}
]);
+58 -58
View File
@@ -14,63 +14,63 @@
*/
export default
angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDefinition', 'ProjectFormDefinition'])
angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDefinition', 'ProjectFormDefinition'])
.factory('GetProjectIcon', [ function() {
return function(status) {
var result = '';
switch (status) {
case 'n/a':
case 'ok':
case 'never updated':
result = 'none';
break;
case 'pending':
case 'waiting':
case 'new':
result = 'none';
break;
case 'updating':
case 'running':
result = 'running';
break;
case 'successful':
result = 'success';
break;
case 'failed':
case 'missing':
result = 'error';
}
return result;
};
}])
.factory('GetProjectIcon', [ function() {
return function(status) {
var result = '';
switch (status) {
case 'n/a':
case 'ok':
case 'never updated':
result = 'none';
break;
case 'pending':
case 'waiting':
case 'new':
result = 'none';
break;
case 'updating':
case 'running':
result = 'running';
break;
case 'successful':
result = 'success';
break;
case 'failed':
case 'missing':
result = 'error';
}
return result;
};
}])
.factory('GetProjectToolTip', [ function() {
return function(status) {
var result = '';
switch (status) {
case 'n/a':
case 'ok':
case 'never updated':
result = 'No SCM updates have run for this project';
break;
case 'pending':
case 'waiting':
case 'new':
result = 'Queued. Click for details';
break;
case 'updating':
case 'running':
result = 'Running! Click for details';
break;
case 'successful':
result = 'Success! Click for details';
break;
case 'failed':
case 'missing':
result = 'Failed. Click for details';
}
return result;
};
}]);
.factory('GetProjectToolTip', [ function() {
return function(status) {
var result = '';
switch (status) {
case 'n/a':
case 'ok':
case 'never updated':
result = 'No SCM updates have run for this project';
break;
case 'pending':
case 'waiting':
case 'new':
result = 'Queued. Click for details';
break;
case 'updating':
case 'running':
result = 'Running! Click for details';
break;
case 'successful':
result = 'Success! Click for details';
break;
case 'failed':
case 'missing':
result = 'Failed. Click for details';
}
return result;
};
}]);
File diff suppressed because it is too large Load Diff
+144 -144
View File
@@ -15,163 +15,163 @@
*/
export default
angular.module('SelectionHelper', ['Utilities', 'RestServices'])
angular.module('SelectionHelper', ['Utilities', 'RestServices'])
.factory('SelectionInit', ['Rest', 'Alert', 'ProcessErrors', 'ReturnToCaller', 'Wait',
function (Rest, Alert, ProcessErrors, ReturnToCaller, Wait) {
return function (params) {
.factory('SelectionInit', ['Rest', 'Alert', 'ProcessErrors', 'ReturnToCaller', 'Wait',
function (Rest, Alert, ProcessErrors, ReturnToCaller, Wait) {
return function (params) {
var scope = params.scope,
list = params.list,
target_url = params.url,
returnToCaller = params.returnToCaller,
selected;
var scope = params.scope,
list = params.list,
target_url = params.url,
returnToCaller = params.returnToCaller,
selected;
if (params.selected !== undefined) {
selected = params.selected;
} else {
selected = []; //array of selected row IDs
}
scope.formModalActionDisabled = true;
scope.disableSelectBtn = true;
// toggle row selection
scope['toggle_' + list.iterator] = function (id, ischeckbox) {
var i, j, found;
for (i = 0; i < scope[list.name].length; i++) {
if (scope[list.name][i].id === id) {
if ((scope[list.name][i].checked === "0" && !ischeckbox) || (scope[list.name][i].checked === "0" && ischeckbox)) {
// select the row
scope[list.name][i].checked = '1';
scope[list.name][i].success_class = 'success';
// add selected object to the array
found = false;
for (j = 0; j < selected.length; j++) {
if (selected[j].id === id) {
found = true;
break;
}
}
if (!found) {
selected.push(scope[list.name][i]);
}
} else {
// unselect the row
scope[list.name][i].checked = '0';
scope[list.name][i].success_class = '';
// remove selected object from the array
for (j = 0; j < selected.length; j++) {
if (selected[j].id === id) {
selected.splice(j, 1);
break;
}
}
}
}
}
if (selected.length > 0) {
scope.formModalActionDisabled = false;
scope.disableSelectBtn = false;
if (params.selected !== undefined) {
selected = params.selected;
} else {
scope.formModalActionDisabled = true;
scope.disableSelectBtn = true;
selected = []; //array of selected row IDs
}
};
// Add the selections
scope.finishSelection = function () {
Rest.setUrl(target_url);
var queue = [], j;
scope.formModalActionDisabled = true;
scope.disableSelectBtn = true;
Wait('start');
// toggle row selection
scope['toggle_' + list.iterator] = function (id, ischeckbox) {
var i, j, found;
for (i = 0; i < scope[list.name].length; i++) {
if (scope[list.name][i].id === id) {
if ((scope[list.name][i].checked === "0" && !ischeckbox) || (scope[list.name][i].checked === "0" && ischeckbox)) {
// select the row
scope[list.name][i].checked = '1';
scope[list.name][i].success_class = 'success';
// add selected object to the array
found = false;
for (j = 0; j < selected.length; j++) {
if (selected[j].id === id) {
found = true;
break;
}
}
if (!found) {
selected.push(scope[list.name][i]);
}
} else {
// unselect the row
scope[list.name][i].checked = '0';
scope[list.name][i].success_class = '';
function finished() {
selected = [];
if (returnToCaller !== undefined) {
ReturnToCaller(returnToCaller);
} else {
$('#form-modal').modal('hide');
scope.$emit('modalClosed');
}
}
function postIt(data) {
Rest.post(data)
.success(function (data, status) {
queue.push({ result: 'success', data: data, status: status });
scope.$emit('callFinished');
})
.error(function (data, status, headers) {
queue.push({ result: 'error', data: data, status: status, headers: headers });
scope.$emit('callFinished');
});
}
if (scope.callFinishedRemove) {
scope.callFinishedRemove();
}
scope.callFinishedRemove = scope.$on('callFinished', function () {
// We call the API for each selected item. We need to hang out until all the api
// calls are finished.
var i, errors=0;
if (queue.length === selected.length) {
Wait('stop');
for (i = 0; i < queue.length; i++) {
if (queue[i].result === 'error') {
ProcessErrors(scope, queue[i].data, queue[i].status, null, { hdr: 'POST Failure',
msg: 'Failed to add ' + list.iterator + '. POST returned status: ' + queue[i].status });
errors++;
// remove selected object from the array
for (j = 0; j < selected.length; j++) {
if (selected[j].id === id) {
selected.splice(j, 1);
break;
}
}
}
}
if (errors === 0) {
finished();
}
if (selected.length > 0) {
scope.formModalActionDisabled = false;
scope.disableSelectBtn = false;
} else {
scope.formModalActionDisabled = true;
scope.disableSelectBtn = true;
}
};
// Add the selections
scope.finishSelection = function () {
Rest.setUrl(target_url);
var queue = [], j;
scope.formModalActionDisabled = true;
scope.disableSelectBtn = true;
Wait('start');
function finished() {
selected = [];
if (returnToCaller !== undefined) {
ReturnToCaller(returnToCaller);
} else {
$('#form-modal').modal('hide');
scope.$emit('modalClosed');
}
}
function postIt(data) {
Rest.post(data)
.success(function (data, status) {
queue.push({ result: 'success', data: data, status: status });
scope.$emit('callFinished');
})
.error(function (data, status, headers) {
queue.push({ result: 'error', data: data, status: status, headers: headers });
scope.$emit('callFinished');
});
}
if (scope.callFinishedRemove) {
scope.callFinishedRemove();
}
scope.callFinishedRemove = scope.$on('callFinished', function () {
// We call the API for each selected item. We need to hang out until all the api
// calls are finished.
var i, errors=0;
if (queue.length === selected.length) {
Wait('stop');
for (i = 0; i < queue.length; i++) {
if (queue[i].result === 'error') {
ProcessErrors(scope, queue[i].data, queue[i].status, null, { hdr: 'POST Failure',
msg: 'Failed to add ' + list.iterator + '. POST returned status: ' + queue[i].status });
errors++;
}
}
if (errors === 0) {
finished();
}
}
});
if (selected.length > 0) {
for (j = 0; j < selected.length; j++) {
postIt(selected[j]);
}
} else {
finished();
}
};
scope.formModalAction = scope.finishSelection;
// Initialize our data set after a refresh (page change or search)
if (scope.SelectPostRefreshRemove) {
scope.SelectPostRefreshRemove();
}
scope.SelectPostRefreshRemove = scope.$on('PostRefresh', function () {
var i, j, found;
if (scope[list.name]) {
for (i = 0; i < scope[list.name].length; i++) {
found = false;
for (j = 0; j < selected.length; j++) {
if (selected[j].id === scope[list.name][i].id) {
found = true;
break;
}
}
if (found) {
scope[list.name][i].checked = '1';
scope[list.name][i].success_class = 'success';
} else {
scope[list.name][i].checked = '0';
scope[list.name][i].success_class = '';
}
}
}
});
if (selected.length > 0) {
for (j = 0; j < selected.length; j++) {
postIt(selected[j]);
}
} else {
finished();
}
};
scope.formModalAction = scope.finishSelection;
// Initialize our data set after a refresh (page change or search)
if (scope.SelectPostRefreshRemove) {
scope.SelectPostRefreshRemove();
}
scope.SelectPostRefreshRemove = scope.$on('PostRefresh', function () {
var i, j, found;
if (scope[list.name]) {
for (i = 0; i < scope[list.name].length; i++) {
found = false;
for (j = 0; j < selected.length; j++) {
if (selected[j].id === scope[list.name][i].id) {
found = true;
break;
}
}
if (found) {
scope[list.name][i].checked = '1';
scope[list.name][i].success_class = 'success';
} else {
scope[list.name][i].checked = '0';
scope[list.name][i].success_class = '';
}
}
}
});
};
}
]);
}
]);
+27 -27
View File
@@ -12,34 +12,34 @@
*/
export default
angular.module('SocketHelper', ['Utilities', 'FFSocketHelpDefinition', 'SafariSocketHelpDefinition' , 'ChromeSocketHelpDefinition'])
angular.module('SocketHelper', ['Utilities', 'FFSocketHelpDefinition', 'SafariSocketHelpDefinition' , 'ChromeSocketHelpDefinition'])
.factory('ShowSocketHelp', ['$location', '$rootScope', 'FFSocketHelp', 'SafariSocketHelp', 'ChromeSocketHelp', 'HelpDialog',
function($location, $rootScope, FFSocketHelp, SafariSocketHelp, ChromeSocketHelp, HelpDialog) {
return function() {
var scope = $rootScope.$new();
scope.socketPort = $AnsibleConfig.websocket_port;
scope.socketURL = 'https://' + $location.host() + ':' + scope.socketPort + '/';
if ($rootScope.browser === "FF") {
scope.browserName = "Firefox";
HelpDialog({ defn: FFSocketHelp, scope: scope });
}
else if ($rootScope.browser === "SAFARI") {
scope.browserName = "Safari";
HelpDialog({ defn: SafariSocketHelp, scope: scope });
}
else {
if ($rootScope.browser === "MSIE") {
scope.browserName = "Internet Explorer";
.factory('ShowSocketHelp', ['$location', '$rootScope', 'FFSocketHelp', 'SafariSocketHelp', 'ChromeSocketHelp', 'HelpDialog',
function($location, $rootScope, FFSocketHelp, SafariSocketHelp, ChromeSocketHelp, HelpDialog) {
return function() {
var scope = $rootScope.$new();
scope.socketPort = $AnsibleConfig.websocket_port;
scope.socketURL = 'https://' + $location.host() + ':' + scope.socketPort + '/';
if ($rootScope.browser === "FF") {
scope.browserName = "Firefox";
HelpDialog({ defn: FFSocketHelp, scope: scope });
}
else if ($rootScope.browser === "CHROME") {
scope.browserName = "Chrome";
else if ($rootScope.browser === "SAFARI") {
scope.browserName = "Safari";
HelpDialog({ defn: SafariSocketHelp, scope: scope });
}
else if ($rootScope.browser === "OPERA") {
scope.browserName = "Opera";
else {
if ($rootScope.browser === "MSIE") {
scope.browserName = "Internet Explorer";
}
else if ($rootScope.browser === "CHROME") {
scope.browserName = "Chrome";
}
else if ($rootScope.browser === "OPERA") {
scope.browserName = "Opera";
}
HelpDialog({ defn: ChromeSocketHelp, scope: scope });
}
HelpDialog({ defn: ChromeSocketHelp, scope: scope });
}
};
}]);
};
}]);
+1 -3
View File
@@ -11,8 +11,7 @@
*
*/
export default
angular.module('SurveyHelper', [ 'Utilities', 'RestServices', 'SchedulesHelper', 'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'ModalDialog' ,
'GeneratorHelpers'])
@@ -877,4 +876,3 @@ angular.module('SurveyHelper', [ 'Utilities', 'RestServices', 'SchedulesHelper',
};
}]);
+28 -28
View File
@@ -11,33 +11,33 @@
*/
export default
angular.module('UserHelper', ['UserFormDefinition'])
.factory('ResetForm', ['UserForm',
function (UserForm) {
return function () {
// Restore form to default conditions. Run before applying LDAP configuration.
// LDAP may manage some or all of these fields in which case the user cannot
// make changes to their values in AWX.
angular.module('UserHelper', ['UserFormDefinition'])
.factory('ResetForm', ['UserForm',
function (UserForm) {
return function () {
// Restore form to default conditions. Run before applying LDAP configuration.
// LDAP may manage some or all of these fields in which case the user cannot
// make changes to their values in AWX.
UserForm.fields.first_name.readonly = false;
UserForm.fields.first_name.editRequired = true;
UserForm.fields.last_name.readonly = false;
UserForm.fields.last_name.editRequired = true;
UserForm.fields.email.readonly = false;
UserForm.fields.email.editRequired = true;
UserForm.fields.organization.awRequiredWhen = {
variable: "orgrequired",
init: true
UserForm.fields.first_name.readonly = false;
UserForm.fields.first_name.editRequired = true;
UserForm.fields.last_name.readonly = false;
UserForm.fields.last_name.editRequired = true;
UserForm.fields.email.readonly = false;
UserForm.fields.email.editRequired = true;
UserForm.fields.organization.awRequiredWhen = {
variable: "orgrequired",
init: true
};
UserForm.fields.organization.readonly = false;
UserForm.fields.username.awRequiredWhen = {
variable: "not_ldap_user",
init: true
};
UserForm.fields.username.readonly = false;
UserForm.fields.password.editRequired = false;
UserForm.fields.password.addRrequired = true;
};
UserForm.fields.organization.readonly = false;
UserForm.fields.username.awRequiredWhen = {
variable: "not_ldap_user",
init: true
};
UserForm.fields.username.readonly = false;
UserForm.fields.password.editRequired = false;
UserForm.fields.password.addRrequired = true;
};
}
]);
}
]);
+1 -2
View File
@@ -10,8 +10,7 @@
*
*/
export default
angular.module('VariablesHelper', ['Utilities'])
/**
+73 -73
View File
@@ -11,85 +11,85 @@
* @description this could use more discussion
*/
export default
angular.module('APIDefaults', ['RestServices', 'Utilities'])
.factory('GetAPIDefaults', ['Alert', 'Rest', '$rootScope',
function (Alert, Rest, $rootScope) {
return function (key) {
angular.module('APIDefaults', ['RestServices', 'Utilities'])
.factory('GetAPIDefaults', ['Alert', 'Rest', '$rootScope',
function (Alert, Rest, $rootScope) {
return function (key) {
//Reload a related collection on pagination or search change
//Reload a related collection on pagination or search change
var result = {}, cnt = 0, url;
var result = {}, cnt = 0, url;
function lookup(key) {
var id, result = {};
for (id in $rootScope.apiDefaults) {
if (id === key || id.iterator === key) {
result[id] = $rootScope.apiDefaults[id];
break;
}
}
return result;
}
function lookup(key) {
var id, result = {};
for (id in $rootScope.apiDefaults) {
if (id === key || id.iterator === key) {
result[id] = $rootScope.apiDefaults[id];
break;
function wait() {
if ($.isEmptyObject(result) && cnt < 5) {
cnt++;
setTimeout(1000, wait());
} else if (result.status === 'success') {
return lookup(key);
}
}
return result;
}
function wait() {
if ($.isEmptyObject(result) && cnt < 5) {
cnt++;
setTimeout(1000, wait());
} else if (result.status === 'success') {
if ($rootScope.apiDefaults === null || $rootScope.apiDefaults === undefined) {
url = '/api/v1/';
Rest.setUrl(url);
Rest.get()
.success(function (data) {
var id, defaults = data;
for (id in defaults) {
switch (id) {
case 'organizations':
defaults[id].iterator = 'organization';
break;
case 'jobs':
defaults[id].iterator = 'job';
break;
case 'users':
defaults[id].iterator = 'user';
break;
case 'teams':
defaults[id].iterator = 'team';
break;
case 'hosts':
defaults[id].iterator = 'host';
break;
case 'groups':
defaults[id].iterator = 'group';
break;
case 'projects':
defaults[id].iterator = 'project';
break;
case 'inventories':
defaults[id].iterator = 'inventory';
break;
}
}
$rootScope.apiDefaults = defaults;
result = {
status: 'success'
};
})
.error(function (data, status) {
result = {
status: 'error',
msg: 'Call to ' + url + ' failed. GET returned status: ' + status
};
});
return wait();
} else {
return lookup(key);
}
}
if ($rootScope.apiDefaults === null || $rootScope.apiDefaults === undefined) {
url = '/api/v1/';
Rest.setUrl(url);
Rest.get()
.success(function (data) {
var id, defaults = data;
for (id in defaults) {
switch (id) {
case 'organizations':
defaults[id].iterator = 'organization';
break;
case 'jobs':
defaults[id].iterator = 'job';
break;
case 'users':
defaults[id].iterator = 'user';
break;
case 'teams':
defaults[id].iterator = 'team';
break;
case 'hosts':
defaults[id].iterator = 'host';
break;
case 'groups':
defaults[id].iterator = 'group';
break;
case 'projects':
defaults[id].iterator = 'project';
break;
case 'inventories':
defaults[id].iterator = 'inventory';
break;
}
}
$rootScope.apiDefaults = defaults;
result = {
status: 'success'
};
})
.error(function (data, status) {
result = {
status: 'error',
msg: 'Call to ' + url + ' failed. GET returned status: ' + status
};
});
return wait();
} else {
return lookup(key);
}
};
}
]);
};
}
]);
+349 -349
View File
@@ -11,387 +11,387 @@
* (controllers/Inventories.js)
*/
angular.module('InventoryHelper', ['RestServices', 'Utilities', 'OrganizationListDefinition', 'ListGenerator', 'AuthService',
'InventoryHelper', 'InventoryFormDefinition', 'ParseHelper', 'SearchHelper', 'VariablesHelper',
])
export default
angular.module('InventoryHelper', ['RestServices', 'Utilities', 'OrganizationListDefinition', 'ListGenerator', 'AuthService',
'InventoryHelper', 'InventoryFormDefinition', 'ParseHelper', 'SearchHelper', 'VariablesHelper',
])
.factory('GetGroupContainerHeight', [ function() {
return function() {
.factory('GetGroupContainerHeight', [ function() {
return function() {
/*console.log('window height: ' + $(window).height());
console.log('main-menu: ' + $('.main-menu').outerHeight());
console.log('main_tabs: ' + $('#main_tabs').outerHeight());
console.log('breadcrumbs: ' + $('#breadcrumbs').outerHeight());
console.log('footer: ' + $('.site-footer').outerHeight());
console.log('group-breadcrumbs: ' + $('.group-breadcrumbs').outerHeight());
console.log('searchwidget: ' + $('#groups-container #search-widget-container').outerHeight());
console.log('group table head: ' + $('#groups_table thead').height());
console.log('subtotal: ' + ( $(window).height() - $('.main-menu').outerHeight() - $('#main_tabs').outerHeight() - $('#breadcrumbs').outerHeight() -
$('.site-footer').outerHeight() - $('.group-breadcrumbs').outerHeight() - $('#groups-container #search-widget-container').outerHeight() -
$('#groups_table thead').height() ));
*/
var height = $(window).height() - $('#main-menu-container .navbar').outerHeight() - $('#breadcrumbs').outerHeight() -
$('.site-footer').outerHeight() - $('.group-breadcrumbs').outerHeight() - $('#groups-container #search-widget-container').outerHeight() -
$('#groups_table thead').height() - 90;
height = (height < 600) ? 600 : height;
return height;
};
}])
.factory('GetHostContainerRows', [ function() {
return function() {
var height, rows;
height = $('#hosts-container .list-well').height() - $('#hosts-constainer .list-well .row').height() - $('#hosts_table thead').height();
rows = Math.floor(height / 30) - 2;
rows = (rows < 20) ? 20 : rows;
return rows;
};
}])
.factory('GetGroupContainerRows', [ function() {
return function() {
var height, rows;
height = $('#groups-container .list-table-container').height();
rows = Math.floor(height / 31) - 2;
rows = (rows < 20) ? 20 : rows;
return rows;
};
}])
.factory('SetContainerHeights', [ 'GetGroupContainerHeight', 'GetHostContainerRows', function(GetGroupContainerHeight, GetHostContainerRows) {
return function(params) {
var group_scope = params.group_scope,
host_scope = params.host_scope,
reloadHosts = (params.reloadHosts) ? true : false,
height, rows;
$('#groups-container .list-table-container').height('auto');
$('#hosts-container .list-well').height('auto');
$('#hosts-container .list-table-container').height('auto');
setTimeout(function() {
if ($(window).width() > 1210) {
height = GetGroupContainerHeight();
$('#groups-container .list-table-container').height(height);
$('#hosts-container .list-table-container').height(height);
setTimeout(function() { $('#hosts-container .list-well').height( $('#groups-container .list-well').outerHeight()); }, 500);
}
if (reloadHosts) {
// we need ro recalc the the page size
if ($(window).width() > 1210) {
rows = GetHostContainerRows();
host_scope.host_page_size = rows;
group_scope.group_page_size = rows;
}
else {
// on small screens we go back to the default
host_scope.host_page_size = 20;
group_scope.group_page_size = 20;
}
host_scope.changePageSize('hosts', 'host');
group_scope.changePageSize('groups', 'group');
}
}, 100);
};
}])
.factory('WatchInventoryWindowResize', ['ApplyEllipsis', 'SetContainerHeights',
function (ApplyEllipsis, SetContainerHeights) {
return function (params) {
// Call to set or restore window resize
var group_scope = params.group_scope,
host_scope = params.host_scope;
$(window).off("resize");
$(window).resize(_.debounce(function() {
ApplyEllipsis('#groups_table .group-name a');
ApplyEllipsis('#hosts_table .host-name a');
SetContainerHeights({
group_scope: group_scope,
host_scope: host_scope,
reloadHosts: true
});
}, 500));
/*console.log('window height: ' + $(window).height());
console.log('main-menu: ' + $('.main-menu').outerHeight());
console.log('main_tabs: ' + $('#main_tabs').outerHeight());
console.log('breadcrumbs: ' + $('#breadcrumbs').outerHeight());
console.log('footer: ' + $('.site-footer').outerHeight());
console.log('group-breadcrumbs: ' + $('.group-breadcrumbs').outerHeight());
console.log('searchwidget: ' + $('#groups-container #search-widget-container').outerHeight());
console.log('group table head: ' + $('#groups_table thead').height());
console.log('subtotal: ' + ( $(window).height() - $('.main-menu').outerHeight() - $('#main_tabs').outerHeight() - $('#breadcrumbs').outerHeight() -
$('.site-footer').outerHeight() - $('.group-breadcrumbs').outerHeight() - $('#groups-container #search-widget-container').outerHeight() -
$('#groups_table thead').height() ));
*/
var height = $(window).height() - $('#main-menu-container .navbar').outerHeight() - $('#breadcrumbs').outerHeight() -
$('.site-footer').outerHeight() - $('.group-breadcrumbs').outerHeight() - $('#groups-container #search-widget-container').outerHeight() -
$('#groups_table thead').height() - 90;
height = (height < 600) ? 600 : height;
return height;
};
}
])
}])
.factory('SaveInventory', ['InventoryForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON',
function (InventoryForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, Wait,
ToJSON) {
return function (params) {
.factory('GetHostContainerRows', [ function() {
return function() {
var height, rows;
height = $('#hosts-container .list-well').height() - $('#hosts-constainer .list-well .row').height() - $('#hosts_table thead').height();
rows = Math.floor(height / 30) - 2;
rows = (rows < 20) ? 20 : rows;
return rows;
};
}])
// Save inventory property modifications
.factory('GetGroupContainerRows', [ function() {
return function() {
var height, rows;
height = $('#groups-container .list-table-container').height();
rows = Math.floor(height / 31) - 2;
rows = (rows < 20) ? 20 : rows;
return rows;
};
}])
var scope = params.scope,
form = InventoryForm,
defaultUrl = GetBasePath('inventory'),
fld, json_data, data;
.factory('SetContainerHeights', [ 'GetGroupContainerHeight', 'GetHostContainerRows', function(GetGroupContainerHeight, GetHostContainerRows) {
return function(params) {
var group_scope = params.group_scope,
host_scope = params.host_scope,
reloadHosts = (params.reloadHosts) ? true : false,
height, rows;
Wait('start');
$('#groups-container .list-table-container').height('auto');
$('#hosts-container .list-well').height('auto');
$('#hosts-container .list-table-container').height('auto');
// Make sure we have valid variable data
json_data = ToJSON(scope.parseType, scope.variables);
setTimeout(function() {
if ($(window).width() > 1210) {
height = GetGroupContainerHeight();
$('#groups-container .list-table-container').height(height);
$('#hosts-container .list-table-container').height(height);
setTimeout(function() { $('#hosts-container .list-well').height( $('#groups-container .list-well').outerHeight()); }, 500);
}
data = {};
for (fld in form.fields) {
if (fld !== 'variables') {
if (form.fields[fld].realName) {
data[form.fields[fld].realName] = scope[fld];
} else {
data[fld] = scope[fld];
if (reloadHosts) {
// we need ro recalc the the page size
if ($(window).width() > 1210) {
rows = GetHostContainerRows();
host_scope.host_page_size = rows;
group_scope.group_page_size = rows;
}
else {
// on small screens we go back to the default
host_scope.host_page_size = 20;
group_scope.group_page_size = 20;
}
host_scope.changePageSize('hosts', 'host');
group_scope.changePageSize('groups', 'group');
}
}, 100);
};
}])
.factory('WatchInventoryWindowResize', ['ApplyEllipsis', 'SetContainerHeights',
function (ApplyEllipsis, SetContainerHeights) {
return function (params) {
// Call to set or restore window resize
var group_scope = params.group_scope,
host_scope = params.host_scope;
$(window).off("resize");
$(window).resize(_.debounce(function() {
ApplyEllipsis('#groups_table .group-name a');
ApplyEllipsis('#hosts_table .host-name a');
SetContainerHeights({
group_scope: group_scope,
host_scope: host_scope,
reloadHosts: true
});
}, 500));
};
}
])
.factory('SaveInventory', ['InventoryForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON',
function (InventoryForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, Wait,
ToJSON) {
return function (params) {
// Save inventory property modifications
var scope = params.scope,
form = InventoryForm,
defaultUrl = GetBasePath('inventory'),
fld, json_data, data;
Wait('start');
// Make sure we have valid variable data
json_data = ToJSON(scope.parseType, scope.variables);
data = {};
for (fld in form.fields) {
if (fld !== 'variables') {
if (form.fields[fld].realName) {
data[form.fields[fld].realName] = scope[fld];
} else {
data[fld] = scope[fld];
}
}
}
}
if (scope.removeUpdateInventoryVariables) {
scope.removeUpdateInventoryVariables();
}
scope.removeUpdateInventoryVariables = scope.$on('UpdateInventoryVariables', function(e, data) {
Rest.setUrl(data.related.variable_data);
Rest.put(json_data)
.success(function () {
Wait('stop');
scope.$emit('InventorySaved');
if (scope.removeUpdateInventoryVariables) {
scope.removeUpdateInventoryVariables();
}
scope.removeUpdateInventoryVariables = scope.$on('UpdateInventoryVariables', function(e, data) {
Rest.setUrl(data.related.variable_data);
Rest.put(json_data)
.success(function () {
Wait('stop');
scope.$emit('InventorySaved');
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to update inventory varaibles. PUT returned status: ' + status
});
});
});
Rest.setUrl(defaultUrl + scope.inventory_id + '/');
Rest.put(data)
.success(function (data) {
if (scope.variables) {
scope.$emit('UpdateInventoryVariables', data);
} else {
scope.$emit('InventorySaved');
}
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to update inventory varaibles. PUT returned status: ' + status
});
msg: 'Failed to update inventory. PUT returned status: ' + status });
});
});
};
}
])
Rest.setUrl(defaultUrl + scope.inventory_id + '/');
Rest.put(data)
.success(function (data) {
if (scope.variables) {
scope.$emit('UpdateInventoryVariables', data);
} else {
scope.$emit('InventorySaved');
}
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to update inventory. PUT returned status: ' + status });
.factory('EditInventoryProperties', ['InventoryForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
'GetBasePath', 'ParseTypeChange', 'SaveInventory', 'Wait', 'Store', 'SearchInit', 'ParseVariableString', 'CreateDialog', 'TextareaResize',
function (InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, SaveInventory,
Wait, Store, SearchInit, ParseVariableString, CreateDialog, TextareaResize) {
return function (params) {
var parent_scope = params.scope,
inventory_id = params.inventory_id,
generator = GenerateForm,
form = InventoryForm,
master = {},
//PreviousSearchParams = Store('CurrentSearchParams'),
buttons,
scope = parent_scope.$new();
form.well = false;
generator.inject(form, {
mode: 'edit',
showButtons: false,
showActions: false,
id: 'inventory-edit-modal-dialog',
breadCrumbs: false,
related: false,
scope: scope
});
};
}
])
/* Reset form properties. Otherwise it screws up future requests of the Inventories detail page */
form.well = true;
.factory('EditInventoryProperties', ['InventoryForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
'GetBasePath', 'ParseTypeChange', 'SaveInventory', 'Wait', 'Store', 'SearchInit', 'ParseVariableString', 'CreateDialog', 'TextareaResize',
function (InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, SaveInventory,
Wait, Store, SearchInit, ParseVariableString, CreateDialog, TextareaResize) {
return function (params) {
buttons = [{
label: "Cancel",
onClick: function() {
scope.cancelModal();
},
icon: "fa-times",
"class": "btn btn-default",
"id": "inventory-edit-cancel-button"
},{
label: "Save",
onClick: function() {
scope.saveModal();
},
icon: "fa-check",
"class": "btn btn-primary",
"id": "inventory-edit-save-button"
}];
var parent_scope = params.scope,
inventory_id = params.inventory_id,
generator = GenerateForm,
form = InventoryForm,
master = {},
//PreviousSearchParams = Store('CurrentSearchParams'),
buttons,
scope = parent_scope.$new();
form.well = false;
generator.inject(form, {
mode: 'edit',
showButtons: false,
showActions: false,
id: 'inventory-edit-modal-dialog',
breadCrumbs: false,
related: false,
scope: scope
});
/* Reset form properties. Otherwise it screws up future requests of the Inventories detail page */
form.well = true;
buttons = [{
label: "Cancel",
onClick: function() {
scope.cancelModal();
},
icon: "fa-times",
"class": "btn btn-default",
"id": "inventory-edit-cancel-button"
},{
label: "Save",
onClick: function() {
scope.saveModal();
},
icon: "fa-check",
"class": "btn btn-primary",
"id": "inventory-edit-save-button"
}];
CreateDialog({
scope: scope,
buttons: buttons,
width: 675,
height: 750,
minWidth: 400,
title: 'Inventory Properties',
id: 'inventory-edit-modal-dialog',
clonseOnEscape: false,
onClose: function() {
Wait('stop');
scope.codeMirror.destroy();
$('#inventory-edit-modal-dialog').empty();
},
onResizeStop: function() {
TextareaResize({
scope: scope,
textareaId: 'inventory_variables',
modalId: 'inventory-edit-modal-dialog',
formId: 'inventory_form'
});
},
beforeDestroy: function() {
if (scope.codeMirror) {
CreateDialog({
scope: scope,
buttons: buttons,
width: 675,
height: 750,
minWidth: 400,
title: 'Inventory Properties',
id: 'inventory-edit-modal-dialog',
clonseOnEscape: false,
onClose: function() {
Wait('stop');
scope.codeMirror.destroy();
}
$('#inventory-edit-modal-dialog').empty();
},
onOpen: function() {
$('#inventory_name').focus();
setTimeout(function() {
$('#inventory-edit-modal-dialog').empty();
},
onResizeStop: function() {
TextareaResize({
scope: scope,
textareaId: 'inventory_variables',
modalId: 'inventory-edit-modal-dialog',
formId: 'inventory_form',
parse: true
formId: 'inventory_form'
});
}, 300);
},
callback: 'InventoryEditDialogReady'
});
scope.parseType = 'yaml';
if (scope.removeInventoryPropertiesLoaded) {
scope.removeInventoryPropertiesLoaded();
}
scope.removeInventoryPropertiesLoaded = scope.$on('inventoryPropertiesLoaded', function() {
Wait('stop');
$('#inventory-edit-modal-dialog').dialog('open');
});
scope.formModalActionLabel = 'Save';
scope.formModalCancelShow = true;
scope.formModalInfo = false;
scope.formModalHeader = 'Inventory Properties';
Wait('start');
Rest.setUrl(GetBasePath('inventory') + inventory_id + '/');
Rest.get()
.success(function (data) {
var fld;
for (fld in form.fields) {
if (fld === 'variables') {
scope.variables = ParseVariableString(data.variables);
master.variables = scope.variables;
} else if (fld === 'inventory_name') {
scope[fld] = data.name;
master[fld] = scope[fld];
} else if (fld === 'inventory_description') {
scope[fld] = data.description;
master[fld] = scope[fld];
} else if (data[fld]) {
scope[fld] = data[fld];
master[fld] = scope[fld];
},
beforeDestroy: function() {
if (scope.codeMirror) {
scope.codeMirror.destroy();
}
if (form.fields[fld].sourceModel && data.summary_fields &&
data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
}
}
LookUpInit({
scope: scope,
form: form,
current_item: scope.organization,
list: OrganizationList,
field: 'organization',
input_type: 'radio'
});
scope.$emit('inventoryPropertiesLoaded');
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get inventory: ' + inventory_id + '. GET returned: ' + status });
$('#inventory-edit-modal-dialog').empty();
},
onOpen: function() {
$('#inventory_name').focus();
setTimeout(function() {
TextareaResize({
scope: scope,
textareaId: 'inventory_variables',
modalId: 'inventory-edit-modal-dialog',
formId: 'inventory_form',
parse: true
});
}, 300);
},
callback: 'InventoryEditDialogReady'
});
if (scope.removeInventorySaved) {
scope.removeInventorySaved();
}
scope.removeInventorySaved = scope.$on('InventorySaved', function () {
//$('#form-modal').modal('hide');
// Restore prior search state
//if (scope.searchCleanp) {
// scope.searchCleanup();
//}
//SearchInit({
// scope: parent_scope,
// set: PreviousSearchParams.set,
// list: PreviousSearchParams.list,
// url: PreviousSearchParams.defaultUrl,
// iterator: PreviousSearchParams.iterator,
// sort_order: PreviousSearchParams.sort_order,
// setWidgets: false
//});
//parent_scope.$emit('RefreshInventories');
try {
$('#inventory-edit-modal-dialog').dialog('close');
}
catch(err) {
// ignore
}
parent_scope.$emit('RefreshInventories');
scope.$destroy();
});
scope.parseType = 'yaml';
scope.cancelModal = function () {
// Restore prior search state
/*if (scope.searchCleanp) {
scope.searchCleanup();
if (scope.removeInventoryPropertiesLoaded) {
scope.removeInventoryPropertiesLoaded();
}
SearchInit({
scope: parent_scope,
set: PreviousSearchParams.set,
list: PreviousSearchParams.list,
url: PreviousSearchParams.defaultUrl,
iterator: PreviousSearchParams.iterator,
sort_order: PreviousSearchParams.sort_order,
setWidgets: false
});*/
try {
$('#inventory-edit-modal-dialog').dialog('close');
scope.removeInventoryPropertiesLoaded = scope.$on('inventoryPropertiesLoaded', function() {
Wait('stop');
$('#inventory-edit-modal-dialog').dialog('open');
});
scope.formModalActionLabel = 'Save';
scope.formModalCancelShow = true;
scope.formModalInfo = false;
scope.formModalHeader = 'Inventory Properties';
Wait('start');
Rest.setUrl(GetBasePath('inventory') + inventory_id + '/');
Rest.get()
.success(function (data) {
var fld;
for (fld in form.fields) {
if (fld === 'variables') {
scope.variables = ParseVariableString(data.variables);
master.variables = scope.variables;
} else if (fld === 'inventory_name') {
scope[fld] = data.name;
master[fld] = scope[fld];
} else if (fld === 'inventory_description') {
scope[fld] = data.description;
master[fld] = scope[fld];
} else if (data[fld]) {
scope[fld] = data[fld];
master[fld] = scope[fld];
}
if (form.fields[fld].sourceModel && data.summary_fields &&
data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
}
}
LookUpInit({
scope: scope,
form: form,
current_item: scope.organization,
list: OrganizationList,
field: 'organization',
input_type: 'radio'
});
scope.$emit('inventoryPropertiesLoaded');
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get inventory: ' + inventory_id + '. GET returned: ' + status });
});
if (scope.removeInventorySaved) {
scope.removeInventorySaved();
}
catch(err) {
// ignore
}
scope.$destroy();
scope.removeInventorySaved = scope.$on('InventorySaved', function () {
//$('#form-modal').modal('hide');
// Restore prior search state
//if (scope.searchCleanp) {
// scope.searchCleanup();
//}
//SearchInit({
// scope: parent_scope,
// set: PreviousSearchParams.set,
// list: PreviousSearchParams.list,
// url: PreviousSearchParams.defaultUrl,
// iterator: PreviousSearchParams.iterator,
// sort_order: PreviousSearchParams.sort_order,
// setWidgets: false
//});
//parent_scope.$emit('RefreshInventories');
try {
$('#inventory-edit-modal-dialog').dialog('close');
}
catch(err) {
// ignore
}
parent_scope.$emit('RefreshInventories');
scope.$destroy();
});
scope.cancelModal = function () {
// Restore prior search state
/*if (scope.searchCleanp) {
scope.searchCleanup();
}
SearchInit({
scope: parent_scope,
set: PreviousSearchParams.set,
list: PreviousSearchParams.list,
url: PreviousSearchParams.defaultUrl,
iterator: PreviousSearchParams.iterator,
sort_order: PreviousSearchParams.sort_order,
setWidgets: false
});*/
try {
$('#inventory-edit-modal-dialog').dialog('close');
}
catch(err) {
// ignore
}
scope.$destroy();
};
scope.saveModal = function () {
scope.inventory_id = inventory_id;
SaveInventory({ scope: scope, parent_scope: parent_scope });
};
};
scope.saveModal = function () {
scope.inventory_id = inventory_id;
SaveInventory({ scope: scope, parent_scope: parent_scope });
};
};
}
]);
}
]);
+25 -25
View File
@@ -14,33 +14,33 @@
*/
export default
angular.module('md5Helper', ['RestServices', 'Utilities', 'angular-md5'])
.factory('md5Setup', ['md5', function (md5) {
return function (params) {
angular.module('md5Helper', ['RestServices', 'Utilities', 'angular-md5'])
.factory('md5Setup', ['md5', function (md5) {
return function (params) {
var scope = params.scope,
master = params.master,
check_field = params.check_field,
default_val = params.default_val;
var scope = params.scope,
master = params.master,
check_field = params.check_field,
default_val = params.default_val;
scope[check_field] = default_val;
master[check_field] = default_val;
scope[check_field] = default_val;
master[check_field] = default_val;
scope.genMD5 = function (fld) {
var now = new Date();
scope[fld] = md5.createHash('AnsibleWorks' + now.getTime());
scope.$emit('NewMD5Generated');
};
scope.genMD5 = function (fld) {
var now = new Date();
scope[fld] = md5.createHash('AnsibleWorks' + now.getTime());
scope.$emit('NewMD5Generated');
scope.toggleCallback = function (fld) {
if (scope.allow_callbacks === 'false') {
scope[fld] = '';
}
};
scope.selectAll = function (fld) {
$('input[name="' + fld + '"]').focus().select();
};
};
scope.toggleCallback = function (fld) {
if (scope.allow_callbacks === 'false') {
scope[fld] = '';
}
};
scope.selectAll = function (fld) {
$('input[name="' + fld + '"]').focus().select();
};
};
}]);
}]);
+31 -31
View File
@@ -20,37 +20,37 @@
*/
export default
angular.module('RefreshRelatedHelper', ['RestServices', 'Utilities', 'PaginationHelpers'])
.factory('RefreshRelated', ['ProcessErrors', 'Rest', 'Wait', 'PageRangeSetup',
function (ProcessErrors, Rest, Wait, PageRangeSetup) {
return function (params) {
angular.module('RefreshRelatedHelper', ['RestServices', 'Utilities', 'PaginationHelpers'])
.factory('RefreshRelated', ['ProcessErrors', 'Rest', 'Wait', 'PageRangeSetup',
function (ProcessErrors, Rest, Wait, PageRangeSetup) {
return function (params) {
var scope = params.scope,
set = params.set,
iterator = params.iterator,
url = params.url;
var scope = params.scope,
set = params.set,
iterator = params.iterator,
url = params.url;
Rest.setUrl(url);
Rest.get()
.success(function (data) {
PageRangeSetup({
scope: scope,
count: data.count,
next: data.next,
previous: data.previous,
iterator: iterator
Rest.setUrl(url);
Rest.get()
.success(function (data) {
PageRangeSetup({
scope: scope,
count: data.count,
next: data.next,
previous: data.previous,
iterator: iterator
});
scope[set] = data.results;
scope[iterator + 'Loading'] = false;
scope[iterator + 'HoldInput'] = false;
Wait('stop');
scope.$emit('related' + set);
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status });
});
scope[set] = data.results;
scope[iterator + 'Loading'] = false;
scope[iterator + 'HoldInput'] = false;
Wait('stop');
scope.$emit('related' + set);
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status });
});
};
}
]);
};
}
]);
+43 -43
View File
@@ -19,49 +19,49 @@
*/
export default
angular.module('RefreshHelper', ['RestServices', 'Utilities', 'PaginationHelpers'])
.factory('Refresh', ['ProcessErrors', 'Rest', 'Wait', 'Empty', 'PageRangeSetup',
function (ProcessErrors, Rest, Wait, Empty, PageRangeSetup) {
return function (params) {
angular.module('RefreshHelper', ['RestServices', 'Utilities', 'PaginationHelpers'])
.factory('Refresh', ['ProcessErrors', 'Rest', 'Wait', 'Empty', 'PageRangeSetup',
function (ProcessErrors, Rest, Wait, Empty, PageRangeSetup) {
return function (params) {
var scope = params.scope,
set = params.set,
iterator = params.iterator,
url = params.url,
deferWaitStop = params.deferWaitStop;
var scope = params.scope,
set = params.set,
iterator = params.iterator,
url = params.url,
deferWaitStop = params.deferWaitStop;
scope.current_url = url;
Rest.setUrl(url);
Rest.get()
.success(function (data) {
var i, modifier;
PageRangeSetup({
scope: scope,
count: data.count,
next: data.next,
previous: data.previous,
iterator: iterator
scope.current_url = url;
Rest.setUrl(url);
Rest.get()
.success(function (data) {
var i, modifier;
PageRangeSetup({
scope: scope,
count: data.count,
next: data.next,
previous: data.previous,
iterator: iterator
});
for (i = 1; i <= 3; i++) {
modifier = (i === 1) ? '' : i;
scope[iterator + 'HoldInput' + modifier] = false;
}
scope[set] = data.results;
scope[iterator + 'Loading'] = false;
scope[iterator + 'HidePaginator'] = false;
if (!deferWaitStop) {
Wait('stop');
}
scope.$emit('PostRefresh', set);
})
.error(function (data, status) {
scope[iterator + 'HoldInput'] = false;
ProcessErrors(scope, data, status, null, {
hdr: 'Error!',
msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status
});
});
for (i = 1; i <= 3; i++) {
modifier = (i === 1) ? '' : i;
scope[iterator + 'HoldInput' + modifier] = false;
}
scope[set] = data.results;
scope[iterator + 'Loading'] = false;
scope[iterator + 'HidePaginator'] = false;
if (!deferWaitStop) {
Wait('stop');
}
scope.$emit('PostRefresh', set);
})
.error(function (data, status) {
scope[iterator + 'HoldInput'] = false;
ProcessErrors(scope, data, status, null, {
hdr: 'Error!',
msg: 'Failed to retrieve ' + set + '. GET returned status: ' + status
});
});
};
}
]);
};
}
]);
+224 -224
View File
@@ -20,259 +20,259 @@
*/
export default
angular.module('RelatedSearchHelper', ['RestServices', 'Utilities', 'RefreshRelatedHelper'])
.factory('RelatedSearchInit', ['$timeout', 'Alert', 'Rest', 'RefreshRelated', 'Wait', 'Empty',
function ($timeout, Alert, Rest, RefreshRelated, Wait, Empty) {
return function (params) {
angular.module('RelatedSearchHelper', ['RestServices', 'Utilities', 'RefreshRelatedHelper'])
.factory('RelatedSearchInit', ['$timeout', 'Alert', 'Rest', 'RefreshRelated', 'Wait', 'Empty',
function ($timeout, Alert, Rest, RefreshRelated, Wait, Empty) {
return function (params) {
var scope = params.scope,
relatedSets = params.relatedSets,
form = params.form, f;
var scope = params.scope,
relatedSets = params.relatedSets,
form = params.form, f;
// add 'selected' class to the selected li element
function setSelectedItem(iterator, label) {
$('#' + iterator + 'SearchDropdown' + ' li').each(function() {
$(this).removeClass('selected');
var link = $(this).find('a');
if (label === link.text()) {
$(this).addClass('selected');
}
});
}
// Set default values
function setDefaults(inIterator) {
var iterator, f, fld, set;
for (set in form.related) {
if (form.related[set].type !== 'tree' && (inIterator === undefined || inIterator === form.related[set].iterator)) {
iterator = form.related[set].iterator;
for (fld in form.related[set].fields) {
if (form.related[set].fields[fld].key) {
if (form.related[set].fields[fld].searchable === undefined || form.related[set].fields[fld].searchable === true) {
scope[iterator + 'SearchField'] = fld;
scope[iterator + 'SearchFieldLabel'] = form.related[set].fields[fld].label;
}
break;
}
// add 'selected' class to the selected li element
function setSelectedItem(iterator, label) {
$('#' + iterator + 'SearchDropdown' + ' li').each(function() {
$(this).removeClass('selected');
var link = $(this).find('a');
if (label === link.text()) {
$(this).addClass('selected');
}
});
}
if (Empty(scope[iterator + 'SearchField'])) {
// A field marked as key may not be 'searchable'. Find the first searchable field.
// Set default values
function setDefaults(inIterator) {
var iterator, f, fld, set;
for (set in form.related) {
if (form.related[set].type !== 'tree' && (inIterator === undefined || inIterator === form.related[set].iterator)) {
iterator = form.related[set].iterator;
for (fld in form.related[set].fields) {
if (form.related[set].fields[fld].searchable === undefined || form.related[set].fields[fld].searchable === true) {
scope[iterator + 'SearchField'] = fld;
scope[iterator + 'SearchFieldLabel'] = form.related[set].fields[fld].label;
if (form.related[set].fields[fld].key) {
if (form.related[set].fields[fld].searchable === undefined || form.related[set].fields[fld].searchable === true) {
scope[iterator + 'SearchField'] = fld;
scope[iterator + 'SearchFieldLabel'] = form.related[set].fields[fld].label;
}
break;
}
}
}
scope[iterator + 'SortOrder'] = null;
scope[iterator + 'SearchType'] = 'icontains';
scope[iterator + 'SearchTypeLabel'] = 'Contains';
scope[iterator + 'SearchValue'] = null;
scope[iterator + 'SelectShow'] = false;
//scope[iterator + 'HideSearchType'] = false;
scope[iterator + 'ShowStartBtn'] = true;
scope[iterator + 'HideAllStartBtn'] = false;
f = scope[iterator + 'SearchField'];
if (form.related[set].fields[f].searchType &&
(form.related[set].fields[f].searchType === 'boolean' || form.related[set].fields[f].searchType === 'select')) {
scope[iterator + 'SelectShow'] = true;
scope[iterator + 'SearchSelectOpts'] = form.fields[f].searchOptions;
}
if (form.related[set].fields[f].searchType && form.related[set].fields[f].searchType === 'gtzero') {
scope[iterator + "InputHide"] = true;
}
setSelectedItem(iterator, scope[iterator + 'SearchFieldLabel']);
}
}
}
setDefaults();
scope.resetSearch = function (iterator) {
setDefaults(iterator);
scope.search(iterator);
};
// Functions to handle search widget changes
scope.setSearchField = function (iterator, fld, label) {
var f, related;
for (related in form.related) {
if (form.related[related].iterator === iterator) {
f = form.related[related].fields[fld];
}
}
scope[iterator + 'SearchFieldLabel'] = label;
scope[iterator + 'SearchField'] = fld;
scope[iterator + 'SearchValue'] = '';
scope[iterator + 'SelectShow'] = false;
//scope[iterator + 'HideSearchType'] = false;
scope[iterator + 'InputHide'] = false;
scope[iterator + 'ShowStartBtn'] = true;
if (f.searchType !== undefined && f.searchType === 'gtzero') {
scope[iterator + "InputHide"] = true;
scope[iterator + 'ShowStartBtn'] = false;
}
if (f.searchType !== undefined && (f.searchType === 'boolean' || f.searchType === 'select')) {
scope[iterator + 'SelectShow'] = true;
scope[iterator + 'SearchSelectOpts'] = f.searchOptions;
}
if (f.searchType !== undefined && f.searchType === 'int') {
//scope[iterator + 'HideSearchType'] = true;
scope[iterator + 'SearchType'] = 'int';
}
setSelectedItem(iterator, label);
scope.search(iterator);
};
scope.setSearchType = function (model, type, label) {
scope[model + 'SearchTypeLabel'] = label;
scope[model + 'SearchType'] = type;
scope.search(model);
};
scope.startSearch = function (e, iterator) {
// If use clicks enter while on input field, start the search
if (e.keyCode === 13) {
scope.search(iterator);
}
};
scope.search = function (iterator) {
//scope[iterator + 'SearchSpin'] = true;
Wait('start');
scope[iterator + 'Loading'] = false;
scope[iterator + 'HoldInput'] = true;
if (scope[iterator + 'SearchValue']) {
// User typed a value in input field
scope[iterator + 'ShowStartBtn'] = false;
}
if (iterator === 'host') {
if (scope.hostSearchField === 'has_active_failures') {
if (scope.hostSearchSelectValue && scope.hostSearchSelectValue.value === 1) {
scope.hostFailureFilter = true;
} else {
scope.hostFailureFilter = false;
}
}
}
var fld, key, set, url, sort_order;
for (key in relatedSets) {
if (relatedSets[key].iterator === iterator) {
set = key;
url = relatedSets[key].url;
for (fld in form.related[key].fields) {
if (form.related[key].fields[fld].key) {
if (form.related[key].fields[fld].desc) {
sort_order = '-' + fld;
} else {
sort_order = fld;
if (Empty(scope[iterator + 'SearchField'])) {
// A field marked as key may not be 'searchable'. Find the first searchable field.
for (fld in form.related[set].fields) {
if (form.related[set].fields[fld].searchable === undefined || form.related[set].fields[fld].searchable === true) {
scope[iterator + 'SearchField'] = fld;
scope[iterator + 'SearchFieldLabel'] = form.related[set].fields[fld].label;
break;
}
}
}
scope[iterator + 'SortOrder'] = null;
scope[iterator + 'SearchType'] = 'icontains';
scope[iterator + 'SearchTypeLabel'] = 'Contains';
scope[iterator + 'SearchValue'] = null;
scope[iterator + 'SelectShow'] = false;
//scope[iterator + 'HideSearchType'] = false;
scope[iterator + 'ShowStartBtn'] = true;
scope[iterator + 'HideAllStartBtn'] = false;
f = scope[iterator + 'SearchField'];
if (form.related[set].fields[f].searchType &&
(form.related[set].fields[f].searchType === 'boolean' || form.related[set].fields[f].searchType === 'select')) {
scope[iterator + 'SelectShow'] = true;
scope[iterator + 'SearchSelectOpts'] = form.fields[f].searchOptions;
}
if (form.related[set].fields[f].searchType && form.related[set].fields[f].searchType === 'gtzero') {
scope[iterator + "InputHide"] = true;
}
setSelectedItem(iterator, scope[iterator + 'SearchFieldLabel']);
}
break;
}
}
sort_order = (scope[iterator + 'SortOrder'] === null) ? sort_order : scope[iterator + 'SortOrder'];
f = form.related[set].fields[scope[iterator + 'SearchField']];
if ((scope[iterator + 'SelectShow'] === false && !Empty(scope[iterator + 'SearchValue'])) ||
(scope[iterator + 'SelectShow'] && scope[iterator + 'SearchSelectValue']) ||
(f.searchType && f.searchType === 'gtzero')) {
if (f.sourceModel) {
// handle fields whose source is a related model e.g. inventories.organization
scope[iterator + 'SearchParams'] = f.sourceModel + '__' + f.sourceField + '__';
} else if (f.searchField) {
scope[iterator + 'SearchParams'] = f.searchField + '__';
} else {
scope[iterator + 'SearchParams'] = scope[iterator + 'SearchField'] + '__';
setDefaults();
scope.resetSearch = function (iterator) {
setDefaults(iterator);
scope.search(iterator);
};
// Functions to handle search widget changes
scope.setSearchField = function (iterator, fld, label) {
var f, related;
for (related in form.related) {
if (form.related[related].iterator === iterator) {
f = form.related[related].fields[fld];
}
}
if (f.searchType && (f.searchType === 'int' || f.searchType === 'boolean')) {
scope[iterator + 'SearchParams'] += 'int=';
} else if (f.searchType && f.searchType === 'gtzero') {
scope[iterator + 'SearchParams'] += 'gt=0';
} else {
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchType'] + '=';
scope[iterator + 'SearchFieldLabel'] = label;
scope[iterator + 'SearchField'] = fld;
scope[iterator + 'SearchValue'] = '';
scope[iterator + 'SelectShow'] = false;
//scope[iterator + 'HideSearchType'] = false;
scope[iterator + 'InputHide'] = false;
scope[iterator + 'ShowStartBtn'] = true;
if (f.searchType !== undefined && f.searchType === 'gtzero') {
scope[iterator + "InputHide"] = true;
scope[iterator + 'ShowStartBtn'] = false;
}
if (f.searchType !== undefined && (f.searchType === 'boolean' || f.searchType === 'select')) {
scope[iterator + 'SelectShow'] = true;
scope[iterator + 'SearchSelectOpts'] = f.searchOptions;
}
if (f.searchType && (f.searchType === 'boolean' || f.searchType === 'select')) {
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchSelectValue'].value;
} else if (f.searchType === undefined || f.searchType === 'gtzero') {
scope[iterator + 'SearchParams'] += encodeURI(scope[iterator + 'SearchValue']);
if (f.searchType !== undefined && f.searchType === 'int') {
//scope[iterator + 'HideSearchType'] = true;
scope[iterator + 'SearchType'] = 'int';
}
scope[iterator + 'SearchParams'] += (sort_order) ? '&order_by=' + encodeURI(sort_order) : '';
} else {
scope[iterator + 'SearchParams'] = (sort_order) ? 'order_by=' + encodeURI(sort_order) : '';
}
scope[iterator + '_page'] = 1;
url += (url.match(/\/$/)) ? '?' : '&';
url += scope[iterator + 'SearchParams'];
url += (scope[iterator + '_page_size']) ? '&page_size=' + scope[iterator + '_page_size'] : "";
RefreshRelated({ scope: scope, set: set, iterator: iterator, url: url });
};
setSelectedItem(iterator, label);
scope.sort = function (iterator, fld) {
var sort_order, icon, direction, set;
scope.search(iterator);
// reset sort icons back to 'icon-sort' on all columns
// except the one clicked
$('.' + iterator + ' .list-header').each(function () {
if ($(this).attr('id') !== iterator + '-' + fld + '-header') {
var icon = $(this).find('i');
icon.attr('class', 'fa fa-sort');
};
scope.setSearchType = function (model, type, label) {
scope[model + 'SearchTypeLabel'] = label;
scope[model + 'SearchType'] = type;
scope.search(model);
};
scope.startSearch = function (e, iterator) {
// If use clicks enter while on input field, start the search
if (e.keyCode === 13) {
scope.search(iterator);
}
});
};
// Toggle the icon for the clicked column
// and set the sort direction
icon = $('#' + iterator + '-' + fld + '-header i');
direction = '';
if (icon.hasClass('fa-sort')) {
icon.removeClass('fa-sort');
icon.addClass('fa-sort-up');
} else if (icon.hasClass('fa-sort-up')) {
icon.removeClass('fa-sort-up');
icon.addClass('fa-sort-down');
direction = '-';
} else if (icon.hasClass('fa-sort-down')) {
icon.removeClass('fa-sort-down');
icon.addClass('fa-sort-up');
}
scope.search = function (iterator) {
//scope[iterator + 'SearchSpin'] = true;
Wait('start');
scope[iterator + 'Loading'] = false;
scope[iterator + 'HoldInput'] = true;
// Set the sorder order value and call the API to refresh the list with the new order
for (set in form.related) {
if (form.related[set].iterator === iterator) {
if (form.related[set].fields[fld].sourceModel) {
sort_order = direction + form.related[set].fields[fld].sourceModel + '__' +
form.related[set].fields[fld].sourceField;
if (scope[iterator + 'SearchValue']) {
// User typed a value in input field
scope[iterator + 'ShowStartBtn'] = false;
}
if (iterator === 'host') {
if (scope.hostSearchField === 'has_active_failures') {
if (scope.hostSearchSelectValue && scope.hostSearchSelectValue.value === 1) {
scope.hostFailureFilter = true;
} else {
scope.hostFailureFilter = false;
}
}
}
var fld, key, set, url, sort_order;
for (key in relatedSets) {
if (relatedSets[key].iterator === iterator) {
set = key;
url = relatedSets[key].url;
for (fld in form.related[key].fields) {
if (form.related[key].fields[fld].key) {
if (form.related[key].fields[fld].desc) {
sort_order = '-' + fld;
} else {
sort_order = fld;
}
}
}
break;
}
}
sort_order = (scope[iterator + 'SortOrder'] === null) ? sort_order : scope[iterator + 'SortOrder'];
f = form.related[set].fields[scope[iterator + 'SearchField']];
if ((scope[iterator + 'SelectShow'] === false && !Empty(scope[iterator + 'SearchValue'])) ||
(scope[iterator + 'SelectShow'] && scope[iterator + 'SearchSelectValue']) ||
(f.searchType && f.searchType === 'gtzero')) {
if (f.sourceModel) {
// handle fields whose source is a related model e.g. inventories.organization
scope[iterator + 'SearchParams'] = f.sourceModel + '__' + f.sourceField + '__';
} else if (f.searchField) {
scope[iterator + 'SearchParams'] = f.searchField + '__';
} else {
sort_order = direction + fld;
scope[iterator + 'SearchParams'] = scope[iterator + 'SearchField'] + '__';
}
if (f.searchType && (f.searchType === 'int' || f.searchType === 'boolean')) {
scope[iterator + 'SearchParams'] += 'int=';
} else if (f.searchType && f.searchType === 'gtzero') {
scope[iterator + 'SearchParams'] += 'gt=0';
} else {
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchType'] + '=';
}
if (f.searchType && (f.searchType === 'boolean' || f.searchType === 'select')) {
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchSelectValue'].value;
} else if (f.searchType === undefined || f.searchType === 'gtzero') {
scope[iterator + 'SearchParams'] += encodeURI(scope[iterator + 'SearchValue']);
}
scope[iterator + 'SearchParams'] += (sort_order) ? '&order_by=' + encodeURI(sort_order) : '';
} else {
scope[iterator + 'SearchParams'] = (sort_order) ? 'order_by=' + encodeURI(sort_order) : '';
}
scope[iterator + '_page'] = 1;
url += (url.match(/\/$/)) ? '?' : '&';
url += scope[iterator + 'SearchParams'];
url += (scope[iterator + '_page_size']) ? '&page_size=' + scope[iterator + '_page_size'] : "";
RefreshRelated({ scope: scope, set: set, iterator: iterator, url: url });
};
scope.sort = function (iterator, fld) {
var sort_order, icon, direction, set;
// reset sort icons back to 'icon-sort' on all columns
// except the one clicked
$('.' + iterator + ' .list-header').each(function () {
if ($(this).attr('id') !== iterator + '-' + fld + '-header') {
var icon = $(this).find('i');
icon.attr('class', 'fa fa-sort');
}
});
// Toggle the icon for the clicked column
// and set the sort direction
icon = $('#' + iterator + '-' + fld + '-header i');
direction = '';
if (icon.hasClass('fa-sort')) {
icon.removeClass('fa-sort');
icon.addClass('fa-sort-up');
} else if (icon.hasClass('fa-sort-up')) {
icon.removeClass('fa-sort-up');
icon.addClass('fa-sort-down');
direction = '-';
} else if (icon.hasClass('fa-sort-down')) {
icon.removeClass('fa-sort-down');
icon.addClass('fa-sort-up');
}
// Set the sorder order value and call the API to refresh the list with the new order
for (set in form.related) {
if (form.related[set].iterator === iterator) {
if (form.related[set].fields[fld].sourceModel) {
sort_order = direction + form.related[set].fields[fld].sourceModel + '__' +
form.related[set].fields[fld].sourceField;
} else {
sort_order = direction + fld;
}
}
}
}
scope[iterator + 'SortOrder'] = sort_order;
scope.search(iterator);
scope[iterator + 'SortOrder'] = sort_order;
scope.search(iterator);
};
};
};
}
]);
}
]);
File diff suppressed because it is too large Load Diff
+107 -107
View File
@@ -10,122 +10,122 @@
*/
export default
angular.module('TeamHelper', ['RestServices', 'Utilities', 'OrganizationListDefinition', 'SearchHelper',
'PaginationHelpers', 'ListGenerator'
])
.factory('SetTeamListeners', ['Alert', 'Rest',
function (Alert, Rest) {
return function (params) {
angular.module('TeamHelper', ['RestServices', 'Utilities', 'OrganizationListDefinition', 'SearchHelper',
'PaginationHelpers', 'ListGenerator'
])
.factory('SetTeamListeners', ['Alert', 'Rest',
function (Alert, Rest) {
return function (params) {
var scope = params.scope,
set = params.set,
iterator = params.iterator;
var scope = params.scope,
set = params.set,
iterator = params.iterator;
// Listeners to perform lookups after main inventory list loads
// Listeners to perform lookups after main inventory list loads
scope.$on('TeamResultFound', function (e, results, lookup_results) {
var i, j, key, property;
if (lookup_results.length === results.length) {
key = 'organization';
property = 'organization_name';
for (i = 0; i < results.length; i++) {
for (j = 0; j < lookup_results.length; j++) {
if (results[i][key] === lookup_results[j].id) {
results[i][property] = lookup_results[j].value;
scope.$on('TeamResultFound', function (e, results, lookup_results) {
var i, j, key, property;
if (lookup_results.length === results.length) {
key = 'organization';
property = 'organization_name';
for (i = 0; i < results.length; i++) {
for (j = 0; j < lookup_results.length; j++) {
if (results[i][key] === lookup_results[j].id) {
results[i][property] = lookup_results[j].value;
}
}
}
scope[iterator + 'SearchSpin'] = false;
scope[set] = results;
}
scope[iterator + 'SearchSpin'] = false;
scope[set] = results;
}
});
});
scope.$on('TeamRefreshFinished', function (e, results) {
// Loop through the result set (sent to us by the search helper) and
// lookup the id and name of each organization. After each lookup
// completes, call resultFound.
scope.$on('TeamRefreshFinished', function (e, results) {
// Loop through the result set (sent to us by the search helper) and
// lookup the id and name of each organization. After each lookup
// completes, call resultFound.
var i, lookup_results = [], url;
var i, lookup_results = [], url;
function getOrganization(url) {
Rest.setUrl(url);
Rest.get()
.success(function (data) {
lookup_results.push({ id: data.id, value: data.name });
scope.$emit('TeamResultFound', results, lookup_results);
})
.error(function () {
lookup_results.push({ id: 'error' });
scope.$emit('TeamResultFound', results, lookup_results);
});
}
function getOrganization(url) {
Rest.setUrl(url);
Rest.get()
.success(function (data) {
lookup_results.push({ id: data.id, value: data.name });
scope.$emit('TeamResultFound', results, lookup_results);
})
.error(function () {
lookup_results.push({ id: 'error' });
scope.$emit('TeamResultFound', results, lookup_results);
});
}
for (i = 0; i < results.length; i++) {
url = '/api/v1/organizations/' + results[i].organization + '/';
getOrganization(url);
}
});
for (i = 0; i < results.length; i++) {
url = '/api/v1/organizations/' + results[i].organization + '/';
getOrganization(url);
}
});
};
}
])
.factory('TeamLookUpOrganizationInit', ['Alert', 'Rest', 'OrganizationList', 'GenerateList', 'SearchInit', 'PaginateInit',
function (Alert, Rest, OrganizationList, GenerateList, SearchInit, PaginateInit) {
return function (params) {
var scope = params.scope;
// Show pop-up to select organization
scope.lookUpOrganization = function () {
var list = OrganizationList,
listGenerator = GenerateList,
listScope = listGenerator.inject(list, { mode: 'lookup', hdr: 'Select Organization' }),
defaultUrl = '/api/v1/organizations/';
listScope.selectAction = function () {
var i, found = false;
for (i = 0; i < listScope[list.name].length; i++) {
if (listScope[list.iterator + "_" + listScope[list.name][i].id + "_class"] === "success") {
found = true;
scope.organization = listScope[list.name][i].id;
scope.organization_name = listScope[list.name][i].name;
scope.team_form.$setDirty();
listGenerator.hide();
}
}
if (found === false) {
Alert('No Selection', 'Click on a row to select an Organization before clicking the Select button.');
}
};
listScope.toggle_organization = function (id) {
// when user clicks a row, remove 'success' class from all rows except clicked-on row
if (listScope[list.name]) {
for (var i = 0; i < listScope[list.name].length; i++) {
listScope[list.iterator + "_" + listScope[list.name][i].id + "_class"] = "";
}
}
if (id !== null && id !== undefined) {
listScope[list.iterator + "_" + id + "_class"] = "success";
}
};
SearchInit({
scope: listScope,
set: list.name,
list: list,
url: defaultUrl
});
PaginateInit({
scope: listScope,
list: list,
url: defaultUrl,
mode: 'lookup'
});
scope.search(list.iterator);
listScope.toggle_organization(scope.organization);
};
};
}
])
.factory('TeamLookUpOrganizationInit', ['Alert', 'Rest', 'OrganizationList', 'GenerateList', 'SearchInit', 'PaginateInit',
function (Alert, Rest, OrganizationList, GenerateList, SearchInit, PaginateInit) {
return function (params) {
var scope = params.scope;
// Show pop-up to select organization
scope.lookUpOrganization = function () {
var list = OrganizationList,
listGenerator = GenerateList,
listScope = listGenerator.inject(list, { mode: 'lookup', hdr: 'Select Organization' }),
defaultUrl = '/api/v1/organizations/';
listScope.selectAction = function () {
var i, found = false;
for (i = 0; i < listScope[list.name].length; i++) {
if (listScope[list.iterator + "_" + listScope[list.name][i].id + "_class"] === "success") {
found = true;
scope.organization = listScope[list.name][i].id;
scope.organization_name = listScope[list.name][i].name;
scope.team_form.$setDirty();
listGenerator.hide();
}
}
if (found === false) {
Alert('No Selection', 'Click on a row to select an Organization before clicking the Select button.');
}
};
listScope.toggle_organization = function (id) {
// when user clicks a row, remove 'success' class from all rows except clicked-on row
if (listScope[list.name]) {
for (var i = 0; i < listScope[list.name].length; i++) {
listScope[list.iterator + "_" + listScope[list.name][i].id + "_class"] = "";
}
}
if (id !== null && id !== undefined) {
listScope[list.iterator + "_" + id + "_class"] = "success";
}
};
SearchInit({
scope: listScope,
set: list.name,
list: list,
url: defaultUrl
});
PaginateInit({
scope: listScope,
list: list,
url: defaultUrl,
mode: 'lookup'
});
scope.search(list.iterator);
listScope.toggle_organization(scope.organization);
};
};
}
]);
]);
+61
View File
@@ -0,0 +1,61 @@
import Admins from "tower/lists/Admins";
import CloudCredentials from "tower/lists/CloudCredentials";
import CompletedJobs from "tower/lists/CompletedJobs";
import ConfigureTowerJobs from "tower/lists/ConfigureTowerJobs";
import Credentials from "tower/lists/Credentials";
import CustomInventory from "tower/lists/CustomInventory";
import Groups from "tower/lists/Groups";
import HomeGroups from "tower/lists/HomeGroups";
import HomeHosts from "tower/lists/HomeHosts";
import Hosts from "tower/lists/Hosts";
import Inventories from "tower/lists/Inventories";
import InventoryGroups from "tower/lists/InventoryGroups";
import InventoryHosts from "tower/lists/InventoryHosts";
import JobEvents from "tower/lists/JobEvents";
import JobHosts from "tower/lists/JobHosts";
import JobTemplates from "tower/lists/JobTemplates";
import Jobs from "tower/lists/Jobs";
import Organizations from "tower/lists/Organizations";
import Permissions from "tower/lists/Permissions";
import PortalJobTemplates from "tower/lists/PortalJobTemplates";
import PortalJobs from "tower/lists/PortalJobs";
import Projects from "tower/lists/Projects";
import QueuedJobs from "tower/lists/QueuedJobs";
import RunningJobs from "tower/lists/RunningJobs";
import ScheduledJobs from "tower/lists/ScheduledJobs";
import Schedules from "tower/lists/Schedules";
import Streams from "tower/lists/Streams";
import Teams from "tower/lists/Teams";
import Users from "tower/lists/Users";
export
{ Admins,
CloudCredentials,
CompletedJobs,
ConfigureTowerJobs,
Credentials,
CustomInventory,
Groups,
HomeGroups,
HomeHosts,
Hosts,
Inventories,
InventoryGroups,
InventoryHosts,
JobEvents,
JobHosts,
JobTemplates,
Jobs,
Organizations,
Permissions,
PortalJobTemplates,
PortalJobs,
Projects,
QueuedJobs,
RunningJobs,
ScheduledJobs,
Schedules,
Streams,
Teams,
Users
}
+2 -1
View File
@@ -9,7 +9,8 @@
angular.module('AdminListDefinition', [])
export default
angular.module('AdminListDefinition', [])
.value('AdminList', {
name: 'admins',
+2 -1
View File
@@ -9,7 +9,8 @@
angular.module('CloudCredentialsListDefinition', [])
export default
angular.module('CloudCredentialsListDefinition', [])
.value('CloudCredentialList', {
name: 'cloudcredentials',
+2 -1
View File
@@ -8,7 +8,8 @@
angular.module('CompletedJobsDefinition', [])
export default
angular.module('CompletedJobsDefinition', [])
.value( 'CompletedJobsList', {
name: 'completed_jobs',

Some files were not shown because too many files have changed in this diff Show More