Merge pull request #182 from jaredevantabor/license-diff

UI License Feature capability
This commit is contained in:
jaredevantabor 2015-05-05 11:38:26 -04:00
commit 97dd512807
34 changed files with 565 additions and 98 deletions

View File

@ -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();

View File

@ -25,7 +25,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
mode: 'edit',
awFeature: 'activity_streams'
}
},

View File

@ -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',

View File

@ -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=&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,
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>",

View File

@ -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',

View File

@ -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',

View File

@ -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',

View File

@ -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',

View File

@ -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'
}
},

View File

@ -53,7 +53,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
mode: 'edit',
awFeature: 'activity_streams'
}
},

View File

@ -169,7 +169,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'all'
mode: 'all',
awFeature: 'activity_streams'
}
}

View File

@ -102,7 +102,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'all'
mode: 'all',
awFeature: 'activity_streams'
}
}

View File

@ -92,7 +92,8 @@ export default
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
icon: "icon-comments-alt",
mode: 'edit'
mode: 'edit',
awFeature: 'activity_streams'
}
},

View File

@ -112,7 +112,8 @@ export default
stream: {
ngClick: "showGroupActivity()",
awToolTip: "View Activity Stream",
mode: 'all'
mode: 'all',
awFeature: 'activity_streams'
},
help: {
mode: 'all',

View File

@ -101,7 +101,8 @@ export default
stream: {
ngClick: "showHostActivity()",
awToolTip: "View Activity Stream",
mode: 'all'
mode: 'all',
awFeature: 'activity_streams'
}
}

View File

@ -54,6 +54,7 @@ export default
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
icon: "icon-comments-alt",
awFeature: 'activity_streams',
mode: 'edit',
ngHide: 'portalMode===true'
}

View File

@ -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'
}
},

View File

@ -56,7 +56,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
mode: 'edit',
awFeature: 'activity_streams'
}
},

View File

@ -75,7 +75,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
mode: 'edit',
awFeature: 'activity_streams'
}
},

View File

@ -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'
}
},

View File

@ -67,7 +67,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
mode: 'edit',
awFeature: 'activity_streams'
}
},

View File

@ -52,7 +52,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
mode: 'edit',
awFeature: 'activity_streams'
}
},

View File

@ -50,7 +50,8 @@ export default
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
mode: 'edit'
mode: 'edit',
awFeature: 'activity_streams'
}
},

View File

@ -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 () {

View File

@ -0,0 +1,10 @@
export default ['$rootScope', function ($rootScope) {
this.isFeatureEnabled = function(feature){
if($rootScope.features[feature] === false){
return false;
} else {
return true;
}
};
}];

View 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();
}
}
}
};
}];

View 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);
}
}
};
}];

View 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);

View File

@ -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

View File

@ -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

View File

@ -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> -->

View 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;
}]));
})

View 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);
});
}]));
});

View File

@ -6,7 +6,8 @@
"awx/ui/static/docs/**/*"
],
"watch": [
"awx/ui/static"
"awx/ui/static",
"awx/ui/tests"
],
"ext": "js json less html"
}