initial files for license diff directive

awLicenseFeature with show/hide

changed file locations

changing file location

adjusting controller logic to only return list of features

leveraging $rootScope instead of local storage

adding awFeature directive for lists/forms for activity stream button

Adding route resolvers and service for getting license

In order to get the license info from the API and not from local storage, the UI needs to hit hte API before loading any pages, therefore I've added route resolvers that will ensure that we have the appropriate data (license features) before navigating to a new page. I've also added the awFeature directive to the organizations list -> add-button and the ldap checkbox on the user form page.

adjusting alignment

fixing jshint errors

commting file for testings

adding tests for features service and features controller

adding features controller unit test
This commit is contained in:
Jared Tabor 2015-04-21 09:09:20 -04:00
parent 9d1dc55c5d
commit 79b79f0481
34 changed files with 546 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,15 @@
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,6 @@
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_stream">
</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"
}