mirror of
https://github.com/ansible/awx.git
synced 2026-01-20 14:11:24 -03:30
Merge pull request #1370 from leigh-johnson/PortalMode
Restyle Portal Mode, refactor PortalJobs Widget into view/controller pattern
This commit is contained in:
commit
67f42eba8e
@ -40,7 +40,6 @@
|
||||
@import "dashboard.less";
|
||||
@import "jPushMenu.less";
|
||||
@import "survey-maker.less";
|
||||
@import "portal.less";
|
||||
@import "text-label.less";
|
||||
@import "./bootstrap-datepicker.less";
|
||||
@import "awx/ui/client/src/shared/branding/colors.default.less";
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
/*********************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
* portal.css
|
||||
*
|
||||
* custom styles for poral mode
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.portal-container{
|
||||
border: 1px solid @grey;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.portal-header{
|
||||
margin: 5px;
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#portal-jobs{
|
||||
margin-top: 20px;
|
||||
}
|
||||
@media (min-width: 769px) {
|
||||
.left-side {
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
.right-side {
|
||||
padding-left: px;
|
||||
}
|
||||
}
|
||||
|
||||
#job_templates_table,
|
||||
#portal_jobs_table {
|
||||
table-layout:fixed;
|
||||
}
|
||||
#portal_jobs_table .name-column,
|
||||
#job_templates_table .name-column {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
@ -24,7 +24,7 @@ import {Home, HomeGroups, HomeHosts} from './controllers/Home';
|
||||
import {SocketsController} from './controllers/Sockets';
|
||||
import {CredentialsAdd, CredentialsEdit, CredentialsList} from './controllers/Credentials';
|
||||
import {JobsListController} from './controllers/Jobs';
|
||||
import {PortalController} from './controllers/Portal';
|
||||
import portalMode from './portal-mode/main';
|
||||
import systemTracking from './system-tracking/main';
|
||||
import inventories from './inventories/main';
|
||||
import inventoryScripts from './inventory-scripts/main';
|
||||
@ -109,6 +109,7 @@ var tower = angular.module('Tower', [
|
||||
standardOut.name,
|
||||
access.name,
|
||||
JobTemplates.name,
|
||||
portalMode.name,
|
||||
'templates',
|
||||
'Utilities',
|
||||
'OrganizationFormDefinition',
|
||||
@ -164,7 +165,6 @@ var tower = angular.module('Tower', [
|
||||
'md5Helper',
|
||||
'SelectionHelper',
|
||||
'HostGroupsFormDefinition',
|
||||
'PortalJobsWidget',
|
||||
'StreamWidget',
|
||||
'JobsHelper',
|
||||
'InventoryGroupsHelpDefinition',
|
||||
@ -291,20 +291,6 @@ var tower = angular.module('Tower', [
|
||||
}
|
||||
}).
|
||||
|
||||
state('portal', {
|
||||
url: '/portal',
|
||||
templateUrl: urlPrefix + 'partials/portal.html',
|
||||
controller: PortalController,
|
||||
ncyBreadcrumb: {
|
||||
label: "PORTAL"
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
state('projects', {
|
||||
url: '/projects',
|
||||
templateUrl: urlPrefix + 'partials/projects.html',
|
||||
@ -828,7 +814,7 @@ var tower = angular.module('Tower', [
|
||||
$rootScope.$emit('JobStatusChange-jobDetails', data);
|
||||
} else if ($state.is('dashboard')) {
|
||||
$rootScope.$emit('JobStatusChange-home', data);
|
||||
} else if ($state.is('portal')) {
|
||||
} else if ($state.is('portalMode')) {
|
||||
$rootScope.$emit('JobStatusChange-portal', data);
|
||||
} else if ($state.is('projects')) {
|
||||
$rootScope.$emit('JobStatusChange-projects', data);
|
||||
|
||||
@ -1,142 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name controllers.function:Portal
|
||||
* @description This controller's for portal mode
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name controllers.function:Portal#Portal
|
||||
* @methodOf controllers.function:Portal
|
||||
* @description portal mode woohoo
|
||||
*
|
||||
*
|
||||
*/
|
||||
export function PortalController($scope, $compile, $stateParams, $rootScope, $location, $log, Wait, ClearScope, Rest, GetBasePath, ProcessErrors,
|
||||
PortalJobsWidget, GenerateList, PortalJobTemplateList, SearchInit, PaginateInit, PlaybookRun){
|
||||
|
||||
ClearScope('portal');
|
||||
|
||||
var jobs_scope,
|
||||
list = PortalJobTemplateList,
|
||||
view= GenerateList,
|
||||
defaultUrl = GetBasePath('job_templates'),
|
||||
max_rows;
|
||||
|
||||
if ($scope.removeLoadPortal) {
|
||||
$scope.removeLoadPortal();
|
||||
}
|
||||
$scope.removeLoadPortal = $scope.$on('LoadPortal', function () {
|
||||
|
||||
view.inject( list, {
|
||||
id : 'portal-job-templates',
|
||||
mode: 'edit',
|
||||
scope: $scope,
|
||||
searchSize: 'col-lg-6 col-md-6'
|
||||
});
|
||||
|
||||
$scope.job_templatePageSize = $scope.getMaxRows();
|
||||
|
||||
SearchInit({
|
||||
scope: $scope,
|
||||
set: 'job_templates',
|
||||
list: list,
|
||||
url: defaultUrl
|
||||
});
|
||||
PaginateInit({
|
||||
scope: $scope,
|
||||
list: list,
|
||||
url: defaultUrl,
|
||||
pageSize: $scope.job_templatePageSize
|
||||
});
|
||||
|
||||
$scope.search(list.iterator);
|
||||
|
||||
PortalJobsWidget({
|
||||
scope: $scope,
|
||||
target: 'portal-jobs',
|
||||
searchSize: 'col-lg-6 col-md-6'
|
||||
});
|
||||
});
|
||||
if ($scope.removeWidgetLoaded) {
|
||||
$scope.removeWidgetLoaded();
|
||||
}
|
||||
$scope.removeWidgetLoaded = $scope.$on('WidgetLoaded', function (e, label, jobscope) {
|
||||
if(label==="portal_jobs"){
|
||||
jobs_scope = jobscope;
|
||||
}
|
||||
$('.actions-column:eq(0)').text('Launch');
|
||||
$('.actions-column:eq(1)').text('Details');
|
||||
$('.list-well:eq(1)').css('margin-top' , '0px');
|
||||
});
|
||||
|
||||
if ($rootScope.removeJobStatusChange) {
|
||||
$rootScope.removeJobStatusChange();
|
||||
}
|
||||
$rootScope.removeJobStatusChange = $rootScope.$on('JobStatusChange-portal', function() {
|
||||
jobs_scope.search('portal_job'); //processEvent(event);
|
||||
});
|
||||
|
||||
$scope.getMaxRows = function(){
|
||||
var docw = $(window).width(),
|
||||
box_height, available_height, search_row, page_row, height, header, row_height;
|
||||
|
||||
available_height = Math.floor($(window).height() - $('#main-menu-container .navbar').outerHeight() - $('#refresh-row').outerHeight() - 35);
|
||||
$('.portal-job-template-container').height(available_height);
|
||||
$('.portal-container').height(available_height);
|
||||
search_row = Math.max($('.search-row:eq(0)').outerHeight(), 50);
|
||||
page_row = Math.max($('.page-row:eq(0)').outerHeight(), 33);
|
||||
header = 0; //Math.max($('#completed_jobs_table thead').height(), 41);
|
||||
height = Math.floor(available_height) - header - page_row - search_row ;
|
||||
if (docw < 765 && docw >= 493) {
|
||||
row_height = 27;
|
||||
}
|
||||
else if (docw < 493) {
|
||||
row_height = 47;
|
||||
}
|
||||
else if (docw < 865) {
|
||||
row_height = 87;
|
||||
}
|
||||
else if (docw < 925) {
|
||||
row_height = 67;
|
||||
}
|
||||
else if (docw < 1415) {
|
||||
row_height = 47;
|
||||
}
|
||||
else {
|
||||
row_height = 44;
|
||||
}
|
||||
max_rows = Math.floor(height / row_height);
|
||||
if (max_rows < 5){
|
||||
box_height = header+page_row + search_row + 40 + (5 * row_height);
|
||||
if (docw < 1140) {
|
||||
box_height += 40;
|
||||
}
|
||||
// $('.portal-job-template-container').height(box_height);
|
||||
max_rows = 5;
|
||||
}
|
||||
return max_rows;
|
||||
};
|
||||
|
||||
$scope.submitJob = function (id) {
|
||||
PlaybookRun({ scope: $scope, id: id });
|
||||
};
|
||||
|
||||
$scope.refresh = function () {
|
||||
$scope.$emit('LoadPortal');
|
||||
};
|
||||
|
||||
$scope.refresh();
|
||||
|
||||
}
|
||||
|
||||
PortalController.$inject = ['$scope', '$compile', '$stateParams', '$rootScope', '$location', '$log','Wait', 'ClearScope', 'Rest', 'GetBasePath', 'ProcessErrors',
|
||||
'PortalJobsWidget', 'generateList' , 'PortalJobTemplateList', 'SearchInit', 'PaginateInit', 'PlaybookRun'
|
||||
];
|
||||
@ -75,13 +75,7 @@ export default
|
||||
scope.viewJobDetails = function(job) {
|
||||
|
||||
var goToJobDetails = function(state) {
|
||||
if(scope.$parent.portalMode===true){
|
||||
var url = $state.href(state, {id: job.id});
|
||||
$window.open(url, '_blank');
|
||||
}
|
||||
else {
|
||||
$state.go(state, {id: job.id});
|
||||
}
|
||||
$state.go(state, {id: job.id});
|
||||
}
|
||||
|
||||
switch(job.type) {
|
||||
@ -381,8 +375,7 @@ export default
|
||||
mode: 'edit',
|
||||
id: id,
|
||||
scope: scope,
|
||||
showSearch: false,
|
||||
title: false
|
||||
showSearch: false
|
||||
});
|
||||
|
||||
SearchInit({
|
||||
|
||||
@ -45,7 +45,6 @@ export default
|
||||
ngClick: 'addJobTemplate()',
|
||||
basePaths: ['job_templates'],
|
||||
awToolTip: 'Create a new template',
|
||||
ngHide: 'portalMode===true',
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD'
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ export default
|
||||
iterator: 'job_template',
|
||||
// selectTitle: 'Add Job Template',
|
||||
editTitle: 'Job Templates',
|
||||
listTitle: 'Job Templates',
|
||||
// selectInstructions: "Click on a row to select it, and click Finished when done. Use the <i class=\"icon-plus\"></i> " +
|
||||
// "button to create a new job template.",
|
||||
index: false,
|
||||
@ -22,9 +23,9 @@ export default
|
||||
fields: {
|
||||
name: {
|
||||
key: true,
|
||||
noLink: true,
|
||||
label: 'Name',
|
||||
columnClass: 'col-lg-5 col-md-5 col-sm-9 col-xs-8'
|
||||
columnClass: 'col-lg-5 col-md-5 col-sm-9 col-xs-8',
|
||||
linkTo: '/#/job_templates/{{job_template.id}}'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
|
||||
@ -9,20 +9,20 @@ export default
|
||||
angular.module('PortalJobsListDefinition', [])
|
||||
.value( 'PortalJobsList', {
|
||||
|
||||
name: 'portal_jobs',
|
||||
iterator: 'portal_job',
|
||||
name: 'jobs',
|
||||
iterator: 'job',
|
||||
editTitle: 'Jobs',
|
||||
'class': 'table-condensed',
|
||||
index: false,
|
||||
hover: true,
|
||||
well: true,
|
||||
listTitle: 'Jobs',
|
||||
|
||||
fields: {
|
||||
status: {
|
||||
label: '',
|
||||
columnClass: 'List-staticColumn--smallStatus',
|
||||
dataTitle: "{{ portal_job.status_popover_title }}",
|
||||
icon: 'icon-job-{{ portal_job.status }}',
|
||||
dataTitle: "{{ job.status_popover_title }}",
|
||||
icon: 'icon-job-{{ job.status }}',
|
||||
iconOnly: true,
|
||||
searchable: true,
|
||||
nosort: true,
|
||||
@ -34,39 +34,32 @@ export default
|
||||
{ name: "Canceled", value: "canceled" }
|
||||
]
|
||||
},
|
||||
/*
|
||||
id: {
|
||||
label: 'ID',
|
||||
key: true,
|
||||
noLink: true, //undocumented: 'key' above will automatically made the fields a link, but 'noLink' will override this setting
|
||||
desc: true,
|
||||
searchType: 'int',
|
||||
columnClass: 'col-lg-1 col-md-1 col-sm-2 col-xs-2 List-staticColumnAdjacent',
|
||||
columnClass: 'col-xs-2 List-staticColumnAdjacent',
|
||||
},
|
||||
*/
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
columnClass: 'col-lg-4 col-md-4 col-sm-4 col-xs-6',
|
||||
defaultSearchField: true
|
||||
defaultSearchField: true,
|
||||
linkTo: '/#/jobs/{{job.id}}'
|
||||
},
|
||||
started: {
|
||||
label: 'Started',
|
||||
noLink: true,
|
||||
searchable: false,
|
||||
filter: "longDate",
|
||||
columnClass: "col-lg-4 col-md-4 col-sm-3 xs-hidden"
|
||||
nosort: true,
|
||||
columnClass: "col-lg-4 col-md-4 col-sm-3"
|
||||
}
|
||||
},
|
||||
|
||||
actions: { },
|
||||
|
||||
fieldActions: {
|
||||
|
||||
columnClass: 'col-lg-3 col-md-4 col-sm-3 col-xs-4',
|
||||
|
||||
job_details: {
|
||||
mode: 'all',
|
||||
ngClick: "viewJobDetails(portal_job)",
|
||||
awToolTip: 'View job details',
|
||||
dataPlacement: 'top'
|
||||
}
|
||||
}
|
||||
actions: { }
|
||||
});
|
||||
|
||||
@ -35,7 +35,6 @@ export default
|
||||
ngClick: 'addScanJobTemplate()',
|
||||
basePaths: ['job_templates'],
|
||||
awToolTip: 'Create a new template',
|
||||
ngHide: 'portalMode===true',
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD'
|
||||
}
|
||||
|
||||
@ -1,36 +1,14 @@
|
||||
/* jshint unused: vars */
|
||||
|
||||
export default
|
||||
[ '$location', 'templateUrl', '$rootScope', function($location, templateUrl, $rootScope) {
|
||||
[ '$state', 'templateUrl', '$rootScope', function($state, templateUrl, $rootScope) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: templateUrl('main-menu/main-menu'),
|
||||
link: function(scope, element, attrs) {
|
||||
// check to see if this is the current route
|
||||
scope.isCurrentRoute = function(route) {
|
||||
if ($location.url().split('/')[1] === route) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// check to see if the current route is the currently
|
||||
// logged in user
|
||||
scope.isCurrentRouteUser = function() {
|
||||
if ($rootScope && $rootScope.current_user) {
|
||||
if ($location.url().split('/')[1] === 'users') {
|
||||
if ($location.url().split('/')[2] === ($rootScope.current_user.id + "")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
scope.isCurrentState = function(name){
|
||||
return $state.current.name == name
|
||||
};
|
||||
|
||||
// set up the user tooltip
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_projects_mobile_link"
|
||||
href="/#/projects"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('projects')}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('projects')}">
|
||||
<span class="MainMenu-itemText">
|
||||
PROJECTS
|
||||
</span>
|
||||
@ -21,7 +21,7 @@
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_inventories_mobile_link"
|
||||
href="/#/inventories"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('inventories')}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('inventories')}">
|
||||
<span class="MainMenu-itemText">
|
||||
INVENTORIES
|
||||
</span>
|
||||
@ -29,7 +29,7 @@
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_job_templates_mobile_link"
|
||||
href="/#/job_templates"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('job_templates')}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('jobTemplates')}">
|
||||
<span class="MainMenu-itemText">
|
||||
JOB TEMPLATES
|
||||
</span>
|
||||
@ -37,7 +37,7 @@
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_jobs_mobile_link"
|
||||
href="/#/jobs"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('jobs')}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('jobs')}">
|
||||
<span class="MainMenu-itemText">
|
||||
JOBS
|
||||
</span>
|
||||
@ -45,7 +45,7 @@
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_current_user_mobile_link"
|
||||
ng-href="/#/users/{{ $root.current_user.id }}"
|
||||
ng-class="{'is-currentRoute' : isCurrentRouteUser()}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('users.edit')}">
|
||||
<span class="MainMenu-itemText">
|
||||
VIEW USER PAGE FOR {{ $root.current_user.username | uppercase }}
|
||||
</span>
|
||||
@ -53,11 +53,19 @@
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_setup_mobile_link"
|
||||
ng-href="/#/setup"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('setup')}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('setup')}">
|
||||
<span class="MainMenu-itemText">
|
||||
SETTINGS
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_setup_mobile_link"
|
||||
ui-sref="portalMode"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('portalMode')}">
|
||||
<span class="MainMenu-itemText">
|
||||
PORTAL MODE
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_docs_mobile_link"
|
||||
ng-href="http://docs.ansible.com/ansible-tower/"
|
||||
@ -69,7 +77,7 @@
|
||||
<a class="MainMenu-item"
|
||||
id="main_menu_logout_mobile_link"
|
||||
ng-href="/#/logout"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('logout')}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('logout')}">
|
||||
<span class="MainMenu-itemText">
|
||||
LOG OUT
|
||||
</span>
|
||||
@ -80,7 +88,7 @@
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left"
|
||||
id="main_menu_projects_link"
|
||||
href="/#/projects"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('projects'), 'is-loggedOut' : !$root.current_user.username}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('projects'), 'is-loggedOut' : !$root.current_user.username}">
|
||||
<span class="MainMenu-itemText">
|
||||
PROJECTS
|
||||
</span>
|
||||
@ -88,7 +96,7 @@
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left"
|
||||
id="main_menu_inventories_link"
|
||||
href="/#/inventories"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('inventories'), 'is-loggedOut' : !$root.current_user.username}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('inventories'), 'is-loggedOut' : !$root.current_user.username}">
|
||||
<span class="MainMenu-itemText">
|
||||
INVENTORIES
|
||||
</span>
|
||||
@ -96,7 +104,7 @@
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left"
|
||||
id="main_menu_job_templates_link"
|
||||
href="/#/job_templates"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('job_templates'), 'is-loggedOut' : !$root.current_user.username}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('jobTemplates'), 'is-loggedOut' : !$root.current_user.username}">
|
||||
<span class="MainMenu-itemText">
|
||||
JOB TEMPLATES
|
||||
</span>
|
||||
@ -104,7 +112,7 @@
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left MainMenu-item--lastLeft"
|
||||
id="main_menu_jobs_link"
|
||||
href="/#/jobs"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('jobs'), 'is-loggedOut' : !$root.current_user.username}">
|
||||
ng-class="{'is-currentRoute' : isCurrentState('jobs'), 'is-loggedOut' : !$root.current_user.username}">
|
||||
<span class="MainMenu-itemText">
|
||||
JOBS
|
||||
</span>
|
||||
@ -112,7 +120,7 @@
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--user MainMenu-item--right"
|
||||
id="main_menu_current_user_link"
|
||||
ng-href="/#/users/{{ $root.current_user.id }}"
|
||||
ng-class="{'is-currentRoute' : isCurrentRouteUser(), 'is-loggedOut' : !$root.current_user.username}"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('users.edit'), 'is-loggedOut' : !$root.current_user.username}"
|
||||
aw-tool-tip="{{currentUserTip}}"
|
||||
aw-tip-watch="currentUserTip"
|
||||
data-placement="bottom"
|
||||
@ -128,7 +136,7 @@
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right"
|
||||
id="main_menu_setup_link"
|
||||
ng-href="/#/setup"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('setup'), 'is-loggedOut' : !$root.current_user.username}"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('setup'), 'is-loggedOut' : !$root.current_user.username}"
|
||||
aw-tool-tip="Settings"
|
||||
data-placement="bottom"
|
||||
data-trigger="hover"
|
||||
@ -137,6 +145,18 @@
|
||||
alt="Settings">
|
||||
</i>
|
||||
</a>
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right"
|
||||
id="main_menu_portal_link"
|
||||
ng-href="/#/portal"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('portalMode'), 'is-loggedOut' : !$root.current_user.username}"
|
||||
aw-tool-tip="Portal Mode"
|
||||
data-placement="bottom"
|
||||
data-trigger="hover"
|
||||
data-container="body">
|
||||
<i class="MainMenu-itemImage MainMenu-itemImage--settings fa fa-columns"
|
||||
alt="Portal Mode">
|
||||
</i>
|
||||
</a>
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right"
|
||||
id="main_menu_docs_link"
|
||||
ng-href="http://docs.ansible.com/ansible-tower/"
|
||||
@ -153,7 +173,7 @@
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right"
|
||||
id="main_menu_logout_link"
|
||||
ng-href="/#/logout"
|
||||
ng-class="{'is-currentRoute' : isCurrentRoute('logout'), 'is-loggedOut' : !$root.current_user.username}"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('logout'), 'is-loggedOut' : !$root.current_user.username}"
|
||||
aw-tool-tip="Log Out"
|
||||
data-placement="bottom"
|
||||
data-trigger="hover"
|
||||
|
||||
13
awx/ui/client/src/portal-mode/main.js
Normal file
13
awx/ui/client/src/portal-mode/main.js
Normal file
@ -0,0 +1,13 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import route from './portal-mode.route';
|
||||
|
||||
export default
|
||||
angular.module('portalMode', [])
|
||||
.run(['$stateExtender', function($stateExtender){
|
||||
$stateExtender.addState(route);
|
||||
}]);
|
||||
@ -0,0 +1,47 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export function PortalModeJobTemplatesController($scope, $rootScope, GetBasePath, GenerateList, PortalJobTemplateList, SearchInit, PaginateInit, PlaybookRun){
|
||||
|
||||
|
||||
var jobs_scope,
|
||||
list = PortalJobTemplateList,
|
||||
view= GenerateList,
|
||||
defaultUrl = GetBasePath('job_templates'),
|
||||
pageSize = 12;
|
||||
|
||||
$scope.submitJob = function (id) {
|
||||
PlaybookRun({ scope: $scope, id: id });
|
||||
};
|
||||
|
||||
var init = function(){
|
||||
view.inject( list, {
|
||||
id : 'portal-job-templates',
|
||||
mode: 'edit',
|
||||
scope: $scope,
|
||||
searchSize: 'col-md-10 col-xs-12'
|
||||
});
|
||||
|
||||
SearchInit({
|
||||
scope: $scope,
|
||||
set: 'job_templates',
|
||||
list: list,
|
||||
url: defaultUrl
|
||||
});
|
||||
PaginateInit({
|
||||
scope: $scope,
|
||||
list: list,
|
||||
url: defaultUrl,
|
||||
pageSize: pageSize
|
||||
});
|
||||
|
||||
$scope.search(list.iterator);
|
||||
};
|
||||
init()
|
||||
}
|
||||
|
||||
PortalModeJobTemplatesController.$inject = ['$scope', '$rootScope', 'GetBasePath', 'generateList', 'PortalJobTemplateList', 'SearchInit', 'PaginateInit', 'PlaybookRun'
|
||||
];
|
||||
@ -0,0 +1,4 @@
|
||||
<div id="portal-container-job-templates" class="Panel">
|
||||
<div id="portal-job-templates" >
|
||||
</div>
|
||||
</div>
|
||||
60
awx/ui/client/src/portal-mode/portal-mode-jobs.controller.js
Normal file
60
awx/ui/client/src/portal-mode/portal-mode-jobs.controller.js
Normal file
@ -0,0 +1,60 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export function PortalModeJobsController($scope, $state, $rootScope, GetBasePath, GenerateList, PortalJobsList, SearchInit,
|
||||
PaginateInit){
|
||||
|
||||
var list = PortalJobsList,
|
||||
view = GenerateList,
|
||||
// show user jobs by default
|
||||
defaultUrl = GetBasePath('jobs') + '?created_by=' + $rootScope.current_user.id,
|
||||
pageSize = 12;
|
||||
|
||||
$scope.iterator = list.iterator;
|
||||
$scope.activeFilter = 'user';
|
||||
|
||||
var init = function(){
|
||||
view.inject(list, {
|
||||
id: 'portal-jobs',
|
||||
mode: 'edit',
|
||||
scope: $scope,
|
||||
searchSize: 'col-md-10 col-xs-12'
|
||||
});
|
||||
|
||||
SearchInit({
|
||||
scope: $scope,
|
||||
set: 'jobs',
|
||||
list: list,
|
||||
url: defaultUrl
|
||||
});
|
||||
|
||||
PaginateInit({
|
||||
scope: $scope,
|
||||
list: list,
|
||||
url: defaultUrl,
|
||||
pageSize: pageSize
|
||||
});
|
||||
$scope.search (list.iterator);
|
||||
};
|
||||
|
||||
|
||||
$scope.filterUser = function(){
|
||||
$scope.activeFilter = 'user';
|
||||
defaultUrl = GetBasePath('jobs') + '?created_by=' + $rootScope.current_user.id;
|
||||
init();
|
||||
};
|
||||
|
||||
$scope.filterAll = function(){
|
||||
$scope.activeFilter = 'all';
|
||||
defaultUrl = GetBasePath('jobs');
|
||||
init();
|
||||
};
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
PortalModeJobsController.$inject = ['$scope', '$state', '$rootScope', 'GetBasePath', 'generateList', 'PortalJobsList', 'SearchInit',
|
||||
'PaginateInit']
|
||||
11
awx/ui/client/src/portal-mode/portal-mode-jobs.partial.html
Normal file
11
awx/ui/client/src/portal-mode/portal-mode-jobs.partial.html
Normal file
@ -0,0 +1,11 @@
|
||||
<div id="portal-container-jobs" class="Panel">
|
||||
<div class="btn-group PortalMode-filter">
|
||||
<button ng-class="{'btn-primary ': activeFilter == 'user',
|
||||
'btn-default' : activeFilter != 'user' }"
|
||||
ng-click='filterUser()' class="btn btn-xs">My Jobs</button>
|
||||
<button ng-class="{'btn-primary' : activeFilter == 'all',
|
||||
'btn-default' : activeFilter != 'all'}" ng-click='filterAll()' class="btn btn-xs btn-default">All Jobs</button>
|
||||
</div>
|
||||
<div id="portal-jobs" >
|
||||
</div>
|
||||
</div>
|
||||
@ -1,4 +1,4 @@
|
||||
<div class="tab-pane" >
|
||||
<div class="tab-pane PortalMode" >
|
||||
<div ng-cloak id="portal-landing">
|
||||
<div id="refresh-row" class="row">
|
||||
<div class="col-lg-12">
|
||||
@ -14,20 +14,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="left-side col-sm-6 col-xs-12">
|
||||
<div id="portal-container-job-templates" class="portal-container">
|
||||
<span class="portal-header">Job Templates</span>
|
||||
<div id="portal-job-templates" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="PortalMode-container">
|
||||
<div ui-view="job-templates" class="PortalMode-panel--left">
|
||||
</div>
|
||||
<div class="right-side col-sm-6 col-xs-12">
|
||||
<div id="portal-container-jobs" class="portal-container">
|
||||
<span class="portal-header">Jobs</span>
|
||||
<div id="portal-jobs" >
|
||||
</div>
|
||||
</div>
|
||||
<div ui-view="jobs" class="PortalMode-panel--right">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
23
awx/ui/client/src/portal-mode/portal-mode.block.less
Normal file
23
awx/ui/client/src/portal-mode/portal-mode.block.less
Normal file
@ -0,0 +1,23 @@
|
||||
@import "awx/ui/client/src/shared/layouts/one-plus-one.less";
|
||||
|
||||
.PortalMode-container{
|
||||
.OnePlusOne-container;
|
||||
}
|
||||
|
||||
.PortalMode-panel--left{
|
||||
.OnePlusOne-panel--left;
|
||||
}
|
||||
.PortalMode-panel--right{
|
||||
.OnePlusOne-panel--right;
|
||||
.List-tableHeader:last-of-type{
|
||||
text-align:left;
|
||||
}
|
||||
}
|
||||
.PortalMode-panelHeader{
|
||||
.OnePlusOne-panelHeader;
|
||||
}
|
||||
.PortalMode-filter{
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
right: 35px;
|
||||
}
|
||||
33
awx/ui/client/src/portal-mode/portal-mode.route.js
Normal file
33
awx/ui/client/src/portal-mode/portal-mode.route.js
Normal file
@ -0,0 +1,33 @@
|
||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
||||
import {PortalModeJobTemplatesController} from './portal-mode-job-templates.controller';
|
||||
import {PortalModeJobsController} from './portal-mode-jobs.controller';
|
||||
|
||||
// Using multiple named views requires a parent layout
|
||||
// https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
|
||||
export default {
|
||||
name: 'portalMode',
|
||||
url: '/portal',
|
||||
ncyBreadcrumb: {
|
||||
label: "PORTAL MODE"
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
},
|
||||
views: {
|
||||
// the empty parent ui-view
|
||||
"" : {
|
||||
templateUrl: templateUrl('portal-mode/portal-mode-layout'),
|
||||
},
|
||||
// named ui-views inside the above
|
||||
'job-templates@portalMode': {
|
||||
templateUrl: templateUrl('portal-mode/portal-mode-job-templates'),
|
||||
controller: PortalModeJobTemplatesController
|
||||
},
|
||||
'jobs@portalMode': {
|
||||
templateUrl: templateUrl('portal-mode/portal-mode-jobs'),
|
||||
controller: PortalModeJobsController
|
||||
}
|
||||
}
|
||||
};
|
||||
53
awx/ui/client/src/shared/layouts/one-plus-one.less
Normal file
53
awx/ui/client/src/shared/layouts/one-plus-one.less
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Large resolution 1/2 + 1/2 width panels
|
||||
* Small resolution: 100% width panels, stacked
|
||||
* Options: static height, custom breakpoint
|
||||
*/
|
||||
|
||||
@import "awx/ui/client/src/shared/branding/colors.default.less";
|
||||
|
||||
|
||||
.OnePlusOne-container(@height: 100%; @breakpoint: 900px){
|
||||
height: @height;
|
||||
display: flex;
|
||||
flex-diration: row;
|
||||
@media screen and(max-width: @breakpoint){
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.OnePlusOne-panel--left(@height: 100%; @breakpoint: 900px){
|
||||
flex: 1 1;
|
||||
height: @height;
|
||||
width: 100%;
|
||||
margin-right: 20px;
|
||||
.Panel{
|
||||
height: 100%;
|
||||
}
|
||||
@media screen and (max-width @breakpoint){
|
||||
margin-right: 0px;
|
||||
height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.OnePlusOne-panel--right(@height: 100%; @breakpoint: 900px){
|
||||
flex: 1 1;
|
||||
height: @height;
|
||||
width: 100%;
|
||||
margin-right: 0px;
|
||||
.Panel{
|
||||
height: 100%;
|
||||
}
|
||||
@media screen and (max-width @breakpoint){
|
||||
height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.OnePlusOne-panelHeader{
|
||||
color: @default-interface-txt;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
text-transform: uppercase;
|
||||
display: flex;
|
||||
}
|
||||
@ -13,7 +13,8 @@ export default function($stateProvider){
|
||||
data: state.data,
|
||||
ncyBreadcrumb: state.ncyBreadcrumb,
|
||||
onEnter: state.onEnter,
|
||||
onExit: state.onExit
|
||||
onExit: state.onExit,
|
||||
views: state.views
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,6 +7,5 @@
|
||||
import "./widgets/InventorySyncStatus";
|
||||
import "./widgets/JobStatus";
|
||||
import "./widgets/ObjectCount";
|
||||
import "./widgets/PortalJobs";
|
||||
import "./widgets/SCMSyncStatus";
|
||||
import "./widgets/Stream";
|
||||
import "./widgets/Stream";
|
||||
@ -1,199 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name widgets.function:PortalJobs
|
||||
* @description
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
angular.module('PortalJobsWidget', ['RestServices', 'Utilities'])
|
||||
.factory('PortalJobsWidget', ['$rootScope', '$compile', 'LoadSchedulesScope', 'LoadJobsScope', 'PortalJobsList', 'ScheduledJobsList', 'GetChoices', 'GetBasePath', 'PortalJobTemplateList' ,
|
||||
function ($rootScope, $compile, LoadSchedulesScope, LoadJobsScope, PortalJobsList, ScheduledJobsList, GetChoices, GetBasePath, PortalJobTemplateList ) {
|
||||
return function (params) {
|
||||
var scope = params.scope,
|
||||
target = params.target,
|
||||
filter = params.filter || "User" ,
|
||||
choicesCount = 0,
|
||||
listCount = 0,
|
||||
jobs_scope = scope.$new(true),
|
||||
max_rows,
|
||||
user,
|
||||
html, e,
|
||||
url;
|
||||
|
||||
if (scope.removeListLoaded) {
|
||||
scope.removeListLoaded();
|
||||
}
|
||||
scope.removeListLoaded = scope.$on('listLoaded', function() {
|
||||
listCount++;
|
||||
if (listCount === 1) {
|
||||
//api_complete = true;
|
||||
scope.$emit('WidgetLoaded', "portal_jobs", jobs_scope);
|
||||
}
|
||||
});
|
||||
|
||||
// After all choices are ready, load up the lists and populate the page
|
||||
if (scope.removeBuildJobsList) {
|
||||
scope.removeBuildJobsList();
|
||||
}
|
||||
scope.removeBuildJobsList = scope.$on('buildJobsList', function() {
|
||||
if (PortalJobsList.fields.type) {
|
||||
PortalJobsList.fields.type.searchOptions = scope.type_choices;
|
||||
}
|
||||
user = scope.$parent.current_user.id;
|
||||
url = (filter === "All Jobs" ) ? GetBasePath('jobs') : GetBasePath('jobs')+'?created_by='+user ;
|
||||
LoadJobsScope({
|
||||
parent_scope: scope,
|
||||
scope: jobs_scope,
|
||||
list: PortalJobsList,
|
||||
id: 'active-jobs',
|
||||
url: url , //GetBasePath('jobs')+'?created_by='+user,
|
||||
pageSize: max_rows,
|
||||
spinner: true
|
||||
});
|
||||
|
||||
$(window).resize(_.debounce(function() {
|
||||
resizePortalJobsWidget();
|
||||
}, 500));
|
||||
});
|
||||
|
||||
if (scope.removeChoicesReady) {
|
||||
scope.removeChoicesReady();
|
||||
}
|
||||
scope.removeChoicesReady = scope.$on('choicesReady', function() {
|
||||
choicesCount++;
|
||||
if (choicesCount === 2) {
|
||||
setPortalJobsHeight();
|
||||
scope.$emit('buildJobsList');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
scope.filterPortalJobs = function(filter) {
|
||||
$("#active-jobs").empty();
|
||||
$("#active-jobs-search-container").empty();
|
||||
user = scope.$parent.current_user.id;
|
||||
url = (filter === "All Jobs" ) ? GetBasePath('jobs') : GetBasePath('jobs')+'?created_by='+user ;
|
||||
LoadJobsScope({
|
||||
parent_scope: scope,
|
||||
scope: jobs_scope,
|
||||
list: PortalJobsList,
|
||||
id: 'active-jobs',
|
||||
url: url , //GetBasePath('jobs')+'?created_by='+user,
|
||||
pageSize: max_rows,
|
||||
spinner: true
|
||||
});
|
||||
};
|
||||
|
||||
html = '';
|
||||
html += "<div class=\"portal-job-template-container\">\n";
|
||||
html += "<div class=\"tab-pane active\" id=\"active-jobs-tab\">\n";
|
||||
html += "<div class=\"row search-row\" id='portal-job-template-search'>\n";
|
||||
html += "<div class=\"col-md-6 col-xs-12\" id=\"active-jobs-search-container\"></div>\n";
|
||||
html += "<div class=\"form-group col-md-6 col-xs-12\">" ;
|
||||
html += "<div class=\"btn-group\" aw-toggle-button data-after-toggle=\"filterPortalJobs\">" ;
|
||||
html += "<button id='portal-toggle-user' class=\"btn btn-xs btn-primary active\">My Jobs</button>" ;
|
||||
html += "<button id='portal-toggle-all' class=\"btn btn-xs btn-default\">All Jobs</button>" ;
|
||||
html += "</div>" ;
|
||||
html += "</div>" ;
|
||||
html += "</div>\n"; //row
|
||||
|
||||
html += "<div class=\"job-list\" id=\"active-jobs-container\">\n";
|
||||
html += "<div id=\"active-jobs\" class=\"job-list-target\"></div>\n";
|
||||
html += "</div>\n"; //list
|
||||
html += "</div>\n"; //active-jobs-tab
|
||||
html += "</div>\n";
|
||||
|
||||
e = angular.element(document.getElementById(target));
|
||||
e.html(html);
|
||||
$compile(e)(scope);
|
||||
|
||||
|
||||
GetChoices({
|
||||
scope: scope,
|
||||
url: GetBasePath('unified_jobs'),
|
||||
field: 'status',
|
||||
variable: 'status_choices',
|
||||
callback: 'choicesReady'
|
||||
});
|
||||
|
||||
GetChoices({
|
||||
scope: scope,
|
||||
url: GetBasePath('unified_jobs'),
|
||||
field: 'type',
|
||||
variable: 'type_choices',
|
||||
callback: 'choicesReady'
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Set the height of each container and calc max number of rows containers can hold
|
||||
function setPortalJobsHeight() {
|
||||
var docw = $(window).width(),
|
||||
box_height, available_height, search_row, page_row, height, header, row_height;
|
||||
|
||||
available_height = Math.floor($(window).height() - $('#main-menu-container .navbar').outerHeight() - $('#refresh-row').outerHeight() - 35);
|
||||
$('.portal-job-template-container').height(available_height);
|
||||
$('.portal-container').height(available_height);
|
||||
search_row = Math.max($('.search-row:eq(0)').outerHeight(), 50);
|
||||
page_row = Math.max($('.page-row:eq(0)').outerHeight(), 33);
|
||||
header = 100; //Math.max($('#completed_jobs_table thead').height(), 41);
|
||||
height = Math.floor(available_height) - header - page_row - search_row ;
|
||||
if (docw < 765 && docw >= 493) {
|
||||
row_height = 27;
|
||||
}
|
||||
else if (docw < 493) {
|
||||
row_height = 47;
|
||||
}
|
||||
else if (docw < 768) {
|
||||
row_height = 44;
|
||||
}
|
||||
else if (docw < 865) {
|
||||
row_height = 87;
|
||||
}
|
||||
else if (docw < 925) {
|
||||
row_height = 67;
|
||||
}
|
||||
else if (docw < 992) {
|
||||
row_height = 55;
|
||||
}
|
||||
else if (docw < 1415) {
|
||||
row_height = 47;
|
||||
}
|
||||
else {
|
||||
row_height = 44;
|
||||
}
|
||||
max_rows = Math.floor(height / row_height);
|
||||
if (max_rows < 5){
|
||||
box_height = header+page_row + search_row + 40 + (5 * row_height);
|
||||
if (docw < 1140) {
|
||||
box_height += 40;
|
||||
}
|
||||
$('.portal-job-template-container').height(box_height);
|
||||
max_rows = 5;
|
||||
}
|
||||
}
|
||||
|
||||
// Set container height and return the number of allowed rows
|
||||
function resizePortalJobsWidget() {
|
||||
setPortalJobsHeight();
|
||||
jobs_scope[PortalJobsList.iterator + '_page_size'] = max_rows;
|
||||
jobs_scope.changePageSize(PortalJobsList.name, PortalJobsList.iterator, false);
|
||||
scope[PortalJobTemplateList.iterator + '_page_size'] = max_rows;
|
||||
scope[PortalJobTemplateList.iterator + 'PageSize'] = max_rows;
|
||||
scope.changePageSize(PortalJobTemplateList.name, PortalJobTemplateList.iterator, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
]);
|
||||
Loading…
x
Reference in New Issue
Block a user