mirror of
https://github.com/ansible/awx.git
synced 2026-01-21 06:28:01 -03:30
Merge pull request #182 from jaredevantabor/license-diff
UI License Feature capability
This commit is contained in:
commit
97dd512807
@ -33,7 +33,6 @@ import {PortalController} from 'tower/controllers/Portal';
|
||||
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';
|
||||
@ -58,6 +57,7 @@ import 'tower/shared/Timer';
|
||||
import 'tower/shared/Socket';
|
||||
|
||||
import 'tower/job-templates/main';
|
||||
import 'tower/shared/features/main';
|
||||
|
||||
/*#if DEBUG#*/
|
||||
import {__deferLoadIfEnabled} from 'tower/debug';
|
||||
@ -171,7 +171,8 @@ var tower = angular.module('Tower', [
|
||||
'ConfigureTowerJobsListDefinition',
|
||||
'CreateCustomInventoryHelper',
|
||||
'CustomInventoryListDefinition',
|
||||
'AdhocHelper'
|
||||
'AdhocHelper',
|
||||
'features'
|
||||
])
|
||||
|
||||
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
||||
@ -184,277 +185,552 @@ var tower = angular.module('Tower', [
|
||||
|
||||
when('/jobs', {
|
||||
templateUrl: urlPrefix + 'partials/jobs.html',
|
||||
controller: JobsListController
|
||||
controller: JobsListController,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/portal', {
|
||||
templateUrl: urlPrefix + 'partials/portal.html',
|
||||
controller: PortalController
|
||||
controller: PortalController,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/jobs/:id', {
|
||||
templateUrl: urlPrefix + 'partials/job_detail.html',
|
||||
controller: JobDetailController
|
||||
controller: JobDetailController,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/jobs/:id/stdout', {
|
||||
templateUrl: urlPrefix + 'partials/job_stdout.html',
|
||||
controller: JobStdoutController
|
||||
controller: JobStdoutController,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/ad_hoc_commands/:id', {
|
||||
templateUrl: urlPrefix + 'partials/job_stdout_adhoc.html',
|
||||
controller: JobStdoutController
|
||||
controller: JobStdoutController,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/job_templates', {
|
||||
templateUrl: urlPrefix + 'partials/job_templates.html',
|
||||
controller: JobTemplatesList
|
||||
controller: JobTemplatesList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/job_templates/add', {
|
||||
templateUrl: urlPrefix + 'partials/job_templates.html',
|
||||
controller: JobTemplatesAdd
|
||||
controller: JobTemplatesAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/job_templates/:template_id', {
|
||||
templateUrl: urlPrefix + 'partials/job_templates.html',
|
||||
controller: JobTemplatesEdit
|
||||
controller: JobTemplatesEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/job_templates/:id/schedules', {
|
||||
templateUrl: urlPrefix + 'partials/schedule_detail.html',
|
||||
controller: ScheduleEditController
|
||||
controller: ScheduleEditController,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/projects', {
|
||||
templateUrl: urlPrefix + 'partials/projects.html',
|
||||
controller: ProjectsList
|
||||
controller: ProjectsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/projects/add', {
|
||||
templateUrl: urlPrefix + 'partials/projects.html',
|
||||
controller: ProjectsAdd
|
||||
controller: ProjectsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/projects/:id', {
|
||||
templateUrl: urlPrefix + 'partials/projects.html',
|
||||
controller: ProjectsEdit
|
||||
controller: ProjectsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/projects/:id/schedules', {
|
||||
templateUrl: urlPrefix + 'partials/schedule_detail.html',
|
||||
controller: ScheduleEditController
|
||||
controller: ScheduleEditController,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/projects/:project_id/organizations', {
|
||||
templateUrl: urlPrefix + 'partials/projects.html',
|
||||
controller: OrganizationsList
|
||||
controller: OrganizationsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/projects/:project_id/organizations/add', {
|
||||
templateUrl: urlPrefix + 'partials/projects.html',
|
||||
controller: OrganizationsAdd
|
||||
controller: OrganizationsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/inventories', {
|
||||
templateUrl: urlPrefix + 'partials/inventories.html',
|
||||
controller: InventoriesList
|
||||
controller: InventoriesList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/inventories/add', {
|
||||
templateUrl: urlPrefix + 'partials/inventories.html',
|
||||
controller: InventoriesAdd
|
||||
controller: InventoriesAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/inventories/:inventory_id', {
|
||||
templateUrl: urlPrefix + 'partials/inventories.html',
|
||||
controller: InventoriesEdit
|
||||
controller: InventoriesEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/inventories/:inventory_id/job_templates/add', {
|
||||
templateUrl: urlPrefix + 'partials/job_templates.html',
|
||||
controller: JobTemplatesAdd
|
||||
controller: JobTemplatesAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/inventories/:inventory_id/job_templates/:template_id', {
|
||||
templateUrl: urlPrefix + 'partials/job_templates.html',
|
||||
controller: JobTemplatesEdit
|
||||
controller: JobTemplatesEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/inventories/:inventory_id/manage', {
|
||||
templateUrl: urlPrefix + 'partials/inventory-manage.html',
|
||||
controller: InventoriesManage
|
||||
controller: InventoriesManage,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/inventories/:inventory_id/adhoc', {
|
||||
templateUrl: urlPrefix + 'partials/adhoc.html',
|
||||
controller: AdhocCtrl
|
||||
controller: AdhocCtrl,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/organizations', {
|
||||
templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
controller: OrganizationsList
|
||||
controller: OrganizationsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/organizations/add', {
|
||||
templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
controller: OrganizationsAdd
|
||||
controller: OrganizationsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/organizations/:organization_id', {
|
||||
templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
controller: OrganizationsEdit
|
||||
controller: OrganizationsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/organizations/:organization_id/admins', {
|
||||
templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
controller: AdminsList
|
||||
controller: AdminsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/organizations/:organization_id/users', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: UsersList
|
||||
controller: UsersList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/organizations/:organization_id/users/add', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: UsersAdd
|
||||
controller: UsersAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/organizations/:organization_id/users/:user_id', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: UsersEdit
|
||||
controller: UsersEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: TeamsList
|
||||
controller: TeamsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/add', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: TeamsAdd
|
||||
controller: TeamsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: TeamsEdit
|
||||
controller: TeamsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/permissions/add', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: PermissionsAdd
|
||||
controller: PermissionsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/permissions', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: PermissionsList
|
||||
controller: PermissionsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/permissions/:permission_id', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: PermissionsEdit
|
||||
controller: PermissionsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/users', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: UsersList
|
||||
controller: UsersList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/users/:user_id', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: UsersEdit
|
||||
controller: UsersEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/projects', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: ProjectsList
|
||||
controller: ProjectsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/projects/add', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: ProjectsAdd
|
||||
controller: ProjectsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/projects/:project_id', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: ProjectsEdit
|
||||
controller: ProjectsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/credentials', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: CredentialsList
|
||||
controller: CredentialsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/credentials/add', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: CredentialsAdd
|
||||
controller: CredentialsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:team_id/credentials/:credential_id', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: CredentialsEdit
|
||||
controller: CredentialsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/credentials', {
|
||||
templateUrl: urlPrefix + 'partials/credentials.html',
|
||||
controller: CredentialsList
|
||||
controller: CredentialsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/credentials/add', {
|
||||
templateUrl: urlPrefix + 'partials/credentials.html',
|
||||
controller: CredentialsAdd
|
||||
controller: CredentialsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/credentials/:credential_id', {
|
||||
templateUrl: urlPrefix + 'partials/credentials.html',
|
||||
controller: CredentialsEdit
|
||||
controller: CredentialsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/users', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: UsersList
|
||||
controller: UsersList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/users/add', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: UsersAdd
|
||||
controller: UsersAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/users/:user_id', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: UsersEdit
|
||||
controller: UsersEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/users/:user_id/credentials', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: CredentialsList
|
||||
controller: CredentialsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/users/:user_id/permissions/add', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: PermissionsAdd
|
||||
controller: PermissionsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/users/:user_id/permissions', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: PermissionsList
|
||||
controller: PermissionsList,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/users/:user_id/permissions/:permission_id', {
|
||||
templateUrl: urlPrefix + 'partials/users.html',
|
||||
controller: PermissionsEdit
|
||||
controller: PermissionsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/users/:user_id/credentials/add', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: CredentialsAdd
|
||||
controller: CredentialsAdd,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/teams/:user_id/credentials/:credential_id', {
|
||||
templateUrl: urlPrefix + 'partials/teams.html',
|
||||
controller: CredentialsEdit
|
||||
controller: CredentialsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/login', {
|
||||
@ -464,17 +740,23 @@ var tower = angular.module('Tower', [
|
||||
|
||||
when('/logout', {
|
||||
templateUrl: urlPrefix + 'partials/blank.html',
|
||||
controller: Authenticate
|
||||
controller: Authenticate,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/home', {
|
||||
templateUrl: urlPrefix + 'partials/home.html',
|
||||
controller: Home,
|
||||
resolve: {
|
||||
graphData: ['$q', 'jobStatusGraphData', 'hostCountGraphData', function($q, jobStatusGraphData, hostCountGraphData) {
|
||||
graphData: ['$q', 'jobStatusGraphData', 'hostCountGraphData', 'FeaturesService', function($q, jobStatusGraphData, hostCountGraphData, FeaturesService) {
|
||||
return $q.all({
|
||||
jobStatus: jobStatusGraphData.get("month", "all"),
|
||||
hostCounts: hostCountGraphData.get()
|
||||
hostCounts: hostCountGraphData.get(),
|
||||
features: FeaturesService.get()
|
||||
});
|
||||
}]
|
||||
}
|
||||
@ -482,12 +764,22 @@ var tower = angular.module('Tower', [
|
||||
|
||||
when('/home/groups', {
|
||||
templateUrl: urlPrefix + 'partials/subhome.html',
|
||||
controller: HomeGroups
|
||||
controller: HomeGroups,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/home/hosts', {
|
||||
templateUrl: urlPrefix + 'partials/subhome.html',
|
||||
controller: HomeHosts
|
||||
controller: HomeHosts,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
when('/sockets', {
|
||||
@ -684,7 +976,6 @@ var tower = angular.module('Tower', [
|
||||
if($location.$$url !== '/login'){
|
||||
$rootScope.$emit('OpenSocket');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
activateTab();
|
||||
|
||||
@ -25,7 +25,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ export default
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
awFeature: 'activity_streams',
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit',
|
||||
|
||||
@ -40,6 +40,7 @@ export default
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
awFeature: 'activity_streams',
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit',
|
||||
@ -258,27 +259,12 @@ export default
|
||||
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="popover-footer"><span class="key">esc</span> or click to close</div>" data-placement="right" data-container="body" data-title="Enable Survey" class="help-link" data-original-title="" title="" tabindex="-1">'+
|
||||
// '<i class="fa fa-question-circle"></i></a> </label>'+
|
||||
// '<div class="error api-error ng-binding" id="job_templates-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,
|
||||
awFeature: 'surveys',
|
||||
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>",
|
||||
|
||||
@ -30,6 +30,7 @@ export default
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
awFeature: 'activity_streams',
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit',
|
||||
|
||||
@ -27,6 +27,7 @@ export default
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
awFeature: 'activity_streams',
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit',
|
||||
|
||||
@ -41,6 +41,7 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
awFeature: 'activity_streams',
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit',
|
||||
|
||||
@ -30,6 +30,7 @@ export default
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
awFeature: 'activity_streams',
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit',
|
||||
|
||||
@ -31,6 +31,7 @@ export default
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
awFeature: 'activity_streams',
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit',
|
||||
@ -114,7 +115,8 @@ export default
|
||||
ldap_user: {
|
||||
label: 'Created by LDAP',
|
||||
type: 'checkbox',
|
||||
readonly: true
|
||||
readonly: true,
|
||||
awFeature: 'ldap'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -53,7 +53,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -169,7 +169,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'all'
|
||||
mode: 'all',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -102,7 +102,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'all'
|
||||
mode: 'all',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +92,8 @@ export default
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -112,7 +112,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showGroupActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'all'
|
||||
mode: 'all',
|
||||
awFeature: 'activity_streams'
|
||||
},
|
||||
help: {
|
||||
mode: 'all',
|
||||
|
||||
@ -101,7 +101,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showHostActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'all'
|
||||
mode: 'all',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -54,6 +54,7 @@ export default
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
icon: "icon-comments-alt",
|
||||
awFeature: 'activity_streams',
|
||||
mode: 'edit',
|
||||
ngHide: 'portalMode===true'
|
||||
}
|
||||
|
||||
@ -40,12 +40,14 @@ export default
|
||||
add: {
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addOrganization()',
|
||||
awToolTip: 'Create a new organization'
|
||||
awToolTip: 'Create a new organization',
|
||||
awFeature: 'multiple_organizations'
|
||||
},
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -56,7 +56,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -75,7 +75,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -48,7 +48,8 @@ export default
|
||||
awToolTip: "View Activity Stream",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'edit',
|
||||
ngHide: 'portalMode===true'
|
||||
ngHide: 'portalMode===true',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -67,7 +67,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -52,7 +52,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -50,7 +50,8 @@ export default
|
||||
stream: {
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
mode: 'edit'
|
||||
mode: 'edit',
|
||||
awFeature: 'activity_streams'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -95,6 +95,7 @@ angular.module('AuthService', ['ngCookies', Utilities.name])
|
||||
},
|
||||
|
||||
getLicense: function () {
|
||||
//check in here first to see if license is already obtained, if we do have it, then rootScope.license
|
||||
return $http({
|
||||
method: 'GET',
|
||||
url: GetBasePath('config'),
|
||||
@ -109,6 +110,7 @@ angular.module('AuthService', ['ngCookies', Utilities.name])
|
||||
license.version = data.version;
|
||||
license.tested = false;
|
||||
Store('license', license);
|
||||
$rootScope.features = Store('license').features;
|
||||
},
|
||||
|
||||
licenseTested: function () {
|
||||
|
||||
10
awx/ui/static/js/shared/features/features.controller.js
Normal file
10
awx/ui/static/js/shared/features/features.controller.js
Normal file
@ -0,0 +1,10 @@
|
||||
export default ['$rootScope', function ($rootScope) {
|
||||
|
||||
this.isFeatureEnabled = function(feature){
|
||||
if($rootScope.features[feature] === false){
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}];
|
||||
33
awx/ui/static/js/shared/features/features.directive.js
Normal file
33
awx/ui/static/js/shared/features/features.directive.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name features
|
||||
* @scope
|
||||
* @description enables/disables features based on license
|
||||
*
|
||||
* @ngdoc directive
|
||||
* @name features.directive:awFeature
|
||||
* @description The aw-feature directive works by taking in a string
|
||||
* that maps to a license feature, and removes that feature from the
|
||||
* DOM if it is a feature not supported by the user's license.
|
||||
* For example, adding `aw-feature="system-tracking"` will enable or disable
|
||||
* the system tracking button based on the license configuration on the
|
||||
* /config endpoint.
|
||||
*
|
||||
*
|
||||
*/
|
||||
import featureController from 'tower/shared/features/features.controller';
|
||||
|
||||
export default [ function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
controller: featureController,
|
||||
link: function (scope, element, attrs, controller){
|
||||
if(attrs.awFeature.length > 0){
|
||||
if(!controller.isFeatureEnabled(attrs.awFeature)){
|
||||
element.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}];
|
||||
30
awx/ui/static/js/shared/features/features.service.js
Normal file
30
awx/ui/static/js/shared/features/features.service.js
Normal file
@ -0,0 +1,30 @@
|
||||
export default ['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$http', '$q',
|
||||
function ($rootScope, Rest, GetBasePath, ProcessErrors, $http, $q) {
|
||||
return {
|
||||
getFeatures: function(){
|
||||
var promise;
|
||||
Rest.setUrl(GetBasePath('config'));
|
||||
promise = Rest.get();
|
||||
return promise.then(function (data) {
|
||||
$rootScope.features = data.data.license_info.features;
|
||||
return $rootScope.features;
|
||||
}).catch(function (response) {
|
||||
ProcessErrors($rootScope, response.data, response.status, null, {
|
||||
hdr: 'Error!',
|
||||
msg: 'Failed to get license info. GET returned status: ' +
|
||||
response.status
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
get: function(){
|
||||
if(_.isEmpty($rootScope.features)){
|
||||
return this.getFeatures();
|
||||
} else {
|
||||
// $q.when will ensure that the result is returned
|
||||
// as a resovled promise.
|
||||
return $q.when($rootScope.features);
|
||||
}
|
||||
}
|
||||
};
|
||||
}];
|
||||
7
awx/ui/static/js/shared/features/main.js
Normal file
7
awx/ui/static/js/shared/features/main.js
Normal file
@ -0,0 +1,7 @@
|
||||
import awFeatureDirective from 'tower/shared/features/features.directive';
|
||||
import FeaturesService from 'tower/shared/features/features.service';
|
||||
|
||||
export default
|
||||
angular.module('features', [])
|
||||
.directive('awFeature', awFeatureDirective)
|
||||
.service('FeaturesService', FeaturesService);
|
||||
@ -752,6 +752,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += "'";
|
||||
html += (field.ngShow) ? this.attr(field, 'ngShow') : "";
|
||||
html += (field.ngHide) ? this.attr(field, 'ngHide') : "";
|
||||
html += (field.awFeature) ? "aw-feature=\"" + field.awFeature + "\" " : "";
|
||||
html += ">\n";
|
||||
|
||||
//text fields
|
||||
|
||||
@ -16,8 +16,10 @@
|
||||
ng-hide="isHiddenByOptions(options) ||
|
||||
hiddenOnCurrentPage(options.basePaths) ||
|
||||
hiddenInCurrentMode(options.mode)"
|
||||
toolbar="true">
|
||||
toolbar="true"
|
||||
aw-feature="{{options.awFeature}}">
|
||||
</button>
|
||||
|
||||
</span>
|
||||
<button
|
||||
toolbar-button
|
||||
|
||||
@ -19,7 +19,8 @@
|
||||
ng-click="showActivity()"
|
||||
aw-tool-tip="View Activity Stream"
|
||||
icon-name="stream"
|
||||
toolbar="true">
|
||||
toolbar="true"
|
||||
aw-feature="activity_streams">
|
||||
</button>
|
||||
|
||||
<!-- <button type="button" class="btn btn-xs btn-primary ng-hide" ng-click="refreshJobs()" id="refresh_btn" aw-tool-tip="Refresh the page" data-placement="top" ng-show="socketStatus == 'error'" data-original-title="" title=""><i class="fa fa-refresh fa-lg"></i> </button></div> -->
|
||||
|
||||
25
awx/ui/tests/unit/features/features.controller-test.js
Normal file
25
awx/ui/tests/unit/features/features.controller-test.js
Normal file
@ -0,0 +1,25 @@
|
||||
import featuresController from 'tower/shared/features/features.controller';
|
||||
|
||||
describe('featuresController', function() {
|
||||
|
||||
it('checks if a feature is enabled', inject(['$rootScope', function($rootScope) {
|
||||
var actual;
|
||||
|
||||
$rootScope.features = {
|
||||
activity_streams: true,
|
||||
ldap: false
|
||||
};
|
||||
|
||||
// TODO: extract into test controller in describeModule
|
||||
var Controller = featuresController[1];
|
||||
var controller = new Controller($rootScope);
|
||||
|
||||
actual = controller.isFeatureEnabled('activity_streams');
|
||||
expect(actual).to.be.true;
|
||||
|
||||
actual = controller.isFeatureEnabled('ldap');
|
||||
expect(actual).to.be.false;
|
||||
|
||||
|
||||
}]));
|
||||
})
|
||||
55
awx/ui/tests/unit/features/features.service-test.js
Normal file
55
awx/ui/tests/unit/features/features.service-test.js
Normal file
@ -0,0 +1,55 @@
|
||||
import features from 'tower/shared/features/main';
|
||||
import {describeModule} from '../describe-module';
|
||||
|
||||
//test that it returns features, as well as test that it is returned in rootScope
|
||||
|
||||
describeModule(features.name)
|
||||
.testService('FeaturesService', function(test, restStub) {
|
||||
|
||||
var service;
|
||||
|
||||
test.withService(function(_service) {
|
||||
service = _service;
|
||||
});
|
||||
|
||||
it('returns list of features', function() {
|
||||
var features = {},
|
||||
result = {
|
||||
data: {
|
||||
license_info: {
|
||||
features: features
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var actual = service.get();
|
||||
|
||||
restStub.succeed(result);
|
||||
restStub.flush();
|
||||
|
||||
return expect(actual).to.eventually.equal(features);
|
||||
|
||||
});
|
||||
|
||||
it('caches in rootScope', inject(['$rootScope',
|
||||
function($rootScope){
|
||||
var features = {},
|
||||
result = {
|
||||
data: {
|
||||
license_info: {
|
||||
features: features
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var actual = service.get();
|
||||
|
||||
restStub.succeed(result);
|
||||
restStub.flush();
|
||||
|
||||
return actual.then(function(){
|
||||
expect($rootScope.features).to.equal(features);
|
||||
});
|
||||
}]));
|
||||
|
||||
});
|
||||
@ -6,7 +6,8 @@
|
||||
"awx/ui/static/docs/**/*"
|
||||
],
|
||||
"watch": [
|
||||
"awx/ui/static"
|
||||
"awx/ui/static",
|
||||
"awx/ui/tests"
|
||||
],
|
||||
"ext": "js json less html"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user