Skip to content

Commit

Permalink
Merge branch 'master' into update-npm-dpes
Browse files Browse the repository at this point in the history
* master:
  Reuse unbound routes (#1223)
  Revert "Added ulimit note to development readme"
  Show services in app summary page, auto pick service plan in add service modal
  Changes following review
  If the value of a 'select-input' is a placeholder always translate
  Fix e2e
  Moved logic into specific cloud-foundry-hosting plugin
  Final bits n bobs - Switch logic from 'disable' flag to 'enable' (true by default) - Updated docs - Prooved cf push with/wuthout flag
  Fix e2e
  Disable the endpoint-dashboard at runtime if env var is present - Plugins can now add config to the console-info call - Add backend component to endpoint-dashboard -- If env var 'DISABLE_ENDPOINT_DASHBOARD' is present add 'disabled' to component config - Handle disabled dashboard in frontend.. -- Do not add to menu -- Do not redirect to dashboard if no endpoints present -- Remove from env.plugins - Fixed endpoint on logged in message for admin's when there are no connected endpoints - Speed up logged in process by making 3 calls async - Improved unit tests
  Testing concourse
  Added ulimit note to development readme
  • Loading branch information
KlapTrap committed Aug 21, 2017
2 parents c534f78 + 7354d03 commit 65ca399
Show file tree
Hide file tree
Showing 31 changed files with 741 additions and 209 deletions.
2 changes: 2 additions & 0 deletions components/app-core/backend/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Info struct {
User *interfaces.ConnectedUser `json:"user"`
Endpoints map[string]map[string]*Endpoint `json:"endpoints"`
CloudFoundry *interfaces.CFInfo `json:"cloud-foundry,omitempty"`
PluginConfig map[string]string `json:"plugin-config,omitempty"`
}

func (p *portalProxy) info(c echo.Context) error {
Expand Down Expand Up @@ -59,6 +60,7 @@ func (p *portalProxy) getInfo(c echo.Context) (*Info, error) {
User: uaaUser,
Endpoints: make(map[string]map[string]*Endpoint),
CloudFoundry: p.Config.CloudFoundryInfo,
PluginConfig: p.Config.PluginConfig,
}
// initialize the Endpoints maps
for _, plugin := range p.Plugins {
Expand Down
1 change: 1 addition & 0 deletions components/app-core/backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ func loadPortalConfig(pc interfaces.PortalConfig) (interfaces.PortalConfig, erro
// Add custom properties
pc.CFAdminIdentifier = CFAdminIdentifier
pc.HTTPS = true
pc.PluginConfig = make(map[string]string)

return pc, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,5 @@ type PortalConfig struct {
LoginHook LoginHookFunc
SessionStore SessionStorer
ConsoleConfig *ConsoleConfig
PluginConfig map[string]string
}
17 changes: 15 additions & 2 deletions components/app-core/frontend/src/utils/logged-in.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

var loggedIn = false;
var lastUserInteraction = moment();
var sessionChecker, dialog;
var sessionChecker, dialog, dashboardRouteFunc;

// Check the session every 30 seconds (Note: this is vey cheap to do unless the session is about to expire)
var checkSessionInterval = 30 * 1000;
Expand Down Expand Up @@ -147,7 +147,9 @@

return {
isLoggedIn: isLoggedIn,
userInteracted: userInteracted
userInteracted: userInteracted,
setDashboardRouteFunc: setDashboardRouteFunc,
getDashboardRoute: getDashboardRoute
};

function isLoggedIn() {
Expand All @@ -158,6 +160,17 @@
lastUserInteraction = moment();
}

function setDashboardRouteFunc(func) {
dashboardRouteFunc = func;
}

function getDashboardRoute() {
// At this point console-info must have been called
if (angular.isFunction(dashboardRouteFunc)) {
return dashboardRouteFunc();
}
}

function _getAccountModel() {
return modelManager.retrieve('app.model.account');
}
Expand Down
91 changes: 46 additions & 45 deletions components/app-core/frontend/src/view/application.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@
* @namespace app.view.application.ApplicationController
* @memberof app.view.application
* @name ApplicationController
* @param {object} $q - Angular $q service
* @param {app.utils.appEventService} appEventService - the event bus service
* @param {app.model.modelManager} modelManager - the application model manager
* @param {app.model.loginManager} loginManager - the login management service
* @param {app.view.appUpgradeCheck} appUpgradeCheck - the upgrade check service
* @param {object} appLocalStorage - the Local Storage In Service
* @param {object} appUtilsService - the App Utils service
* @param {app.view.consoleSetupCheck} consoleSetupCheck - the Console Setup checkservice
* @param {object} $timeout - Angular $timeout service
* @param {$stateParams} $stateParams - Angular ui-router $stateParams service
* @param {$window} $window - Angular $window service
* @param {$rootScope} $rootScope - Angular $rootScope service
* @param {$scope} $scope - Angular $scope service
* @param {appLoggedInService} appLoggedInService - Logged In Service
* @property {app.utils.appEventService} appEventService - the event bus service
* @property {app.model.modelManager} modelManager - the application model manager
* @property {app.view.appUpgradeCheck} appUpgradeCheck - the upgrade check service
Expand All @@ -47,8 +48,21 @@
* @property {boolean} serverErrorOnLogin - a flag indicating if user login failed because of a server error.
* @class
*/
function ApplicationController(appEventService, modelManager, loginManager, appUpgradeCheck, appLocalStorage,
appUtilsService, consoleSetupCheck, $timeout, $stateParams, $window, $rootScope, $scope) {
function ApplicationController(
$q,
appEventService,
modelManager,
loginManager,
appUpgradeCheck,
appLocalStorage,
consoleSetupCheck,
$timeout,
$stateParams,
$window,
$rootScope,
$scope,
appLoggedInService
) {

var vm = this;

Expand All @@ -63,7 +77,6 @@
vm.hideNavigation = $stateParams.hideNavigation;
vm.hideAccount = $stateParams.hideAccount;
vm.navbarIconsOnly = false;
vm.isEndpointsDashboardAvailable = appUtilsService.isPluginAvailable('endpointsDashboard');

vm.login = login;
vm.logout = logout;
Expand Down Expand Up @@ -184,61 +197,49 @@
*/
var account = modelManager.retrieve('app.model.account');

// Fetch the list of services instances
var serviceInstanceModel = modelManager.retrieve('app.model.serviceInstance');
var userServiceInstanceModel = modelManager.retrieve('app.model.serviceInstance.user');
/* eslint-disable */
// TODO: If this fails, we should show a notification message
/* eslint-enable */
modelManager.retrieve('app.model.serviceInstance')
.list()
.then(function onSuccess(data) {
var noEndpoints = data.numAvailable === 0;
// Admin
if (account.isAdmin()) {
// Go the endpoints dashboard if there are no CF clusters
if (noEndpoints) {
vm.redirectState = 'endpoint.dashboard';
if (!vm.isEndpointsDashboardAvailable) {
appEventService.$emit(appEventService.events.TRANSFER, 'error-page', {error: 'notSetup'});
continueLogin = false;
}
$q.all([
serviceInstanceModel.list(),
modelManager.retrieve('app.model.consoleInfo').getConsoleInfo(),
userServiceInstanceModel.list()
])
.then(function () {
var cfOnly = _.filter(serviceInstanceModel.serviceInstances, {cnsi_type: 'cf'}) || [];
var noEndpoints = cfOnly.length === 0;
var dashboardRedirect = appLoggedInService.getDashboardRoute();

if (noEndpoints) {
// Admin
if (account.isAdmin()) {
vm.redirectState = dashboardRedirect;
}
} else {
// Developer or Endpoint Dashboard plugin isn't loaded
if (noEndpoints) {
if (!vm.redirectState) {
// No CF instances, so the system is not setup and the user can't fix this
continueLogin = false;
appEventService.$emit(appEventService.events.TRANSFER, 'error-page', {error: 'notSetup'});
} else {
var userServiceInstanceModel = modelManager.retrieve('app.model.serviceInstance.user');
// Need to get the user's service list to determine if they have any connected
return userServiceInstanceModel.list().then(function () {
// Developer - allow user to connect services, if we have some and none are connected
if (userServiceInstanceModel.getNumValid() === 0) {
vm.redirectState = 'endpoint.dashboard';
if (!vm.isEndpointsDashboardAvailable) {
appEventService.$emit(appEventService.events.TRANSFER, 'error-page', {error: 'notConnected'});
continueLogin = false;
}
}
});
}
} else {
// Need to get the user's service list to determine if they have any connected
// Developer - allow user to connect services, if we have some and none are connected
if (userServiceInstanceModel.getNumValid() === 0) {
vm.redirectState = dashboardRedirect;
if (!vm.redirectState) {
appEventService.$emit(appEventService.events.TRANSFER, 'error-page', {error: 'notConnected'});
continueLogin = false;
}
}
}
})
.then(function () {
// Update consoleInfo
return modelManager.retrieve('app.model.consoleInfo').getConsoleInfo();
})
.then(function () {
// Get the user registered services once at login - only refreshed in endpoints dashboard
var userServiceInstanceModel = modelManager.retrieve('app.model.serviceInstance.user');
return userServiceInstanceModel.list();
})
.finally(function () {
vm.showGlobalSpinner = false;
if (continueLogin) {
// When we notify listeners that login has completed, in some cases we don't want them
// to redirect tp their page - we might want to control that the go to the endpoints dahsboard (for exmample).
// So, we pass this flag to tell them login happenned, but that they should not redirect
// to redirect to their page - we might want to control that they go to the endpoints dashboard (for example).
// So, we pass this flag to tell them login happened, but that they should not redirect
appEventService.$emit(appEventService.events.LOGIN, !!vm.redirectState);
// We need to do this after the login events are handled, so that ui-router states we might go to are registered
if (vm.redirectState) {
Expand Down
6 changes: 3 additions & 3 deletions components/app-core/frontend/src/view/navbar/navbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ nav.secondary-nav {
}
}
}

.secondary-navbar {
flex: 1 1 0;
background-color: $navbar-bottom-border-color;
Expand Down Expand Up @@ -198,7 +198,7 @@ nav.secondary-nav {
svg {
width: 28px;
height: 28px;

> path {
fill: $navbar-text-color;
}
Expand All @@ -221,8 +221,8 @@ nav.secondary-nav {
}

&:hover {
color: $navbar-hover-fg;
background-color: $navbar-hover-bg;
color: $navbar-hover-fg;
}

&.active {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
applicationCtrl = $element.controller('application');
$httpBackend.when('GET', '/pp/v1/proxy/v2/info').respond(200, {});
$httpBackend.when('GET', '/pp/v1/proxy/v2/apps?page=1&results-per-page=48').respond(200, {guid: {}});
$httpBackend.when('GET', '/pp/v1/cnsis/registered').respond([]);

// For some tests, the redirected state depends on whether the endpoints dashboard is available
redirectStateName = $state.get('endpoint.dashboard') ? 'endpoint.dashboard' : 'error-page';
Expand Down Expand Up @@ -98,10 +97,11 @@
$httpBackend.when('POST', '/pp/v1/auth/login/uaa').respond(200, {account: 'dev', scope: 'foo'});
$httpBackend.when('GET', '/pp/v1/cnsis').respond(200, []);
$httpBackend.when('GET', '/pp/v1/info').respond(200, {});
$httpBackend.when('GET', '/pp/v1/cnsis/registered').respond(200, []);

$httpBackend.expectPOST('/pp/v1/auth/login/uaa');
// No endpoints are set up, so we should go to error page
$httpBackend.expectGET('/pp/v1/cnsis/registered').respond(200, []);
$httpBackend.expectGET('/pp/v1/cnsis/registered');

applicationCtrl.login('dev', 'dev');
$httpBackend.flush();
Expand Down Expand Up @@ -241,7 +241,7 @@
expect($state.current.name).toBe(redirectStateName);
});

it('should not show cluster registration if cluster count > 0', function () {
it('should go to endpoints dashboard if cluster count > 0 and none connected', function () {
var responseData = [
{id: 1, name: 'name', api_endpoint: {Scheme: 'http', Host: 'api.host.com'}, cnsi_type: 'cf'}
];
Expand All @@ -253,6 +253,27 @@
applicationCtrl.login('admin', 'admin');
$httpBackend.flush();

expect(applicationCtrl.redirectState).toBe('endpoint.dashboard');
expect(applicationCtrl.showGlobalSpinner).toBe(false);
});

it('should not go to endpoints dashboard if cluster count > 0 and at least one connected', function () {
var responseData = [
{id: 1, name: 'name', api_endpoint: {Scheme: 'http', Host: 'api.host.com'}, cnsi_type: 'cf'}
];
$httpBackend.when('GET', '/pp/v1/cnsis')
.respond(200, responseData);

var future = 50000 + (new Date()).getTime() / 1000;

$httpBackend.when('GET', '/pp/v1/info').respond(200, []);
$httpBackend.when('GET', '/pp/v1/cnsis/registered').respond(200, [
{ account: 'test', token_expiry: future, guid: 'service', cnsi_type: 'cf', name: 'test', api_endpoint: testAptEndpoint }
]);

applicationCtrl.login('admin', 'admin');
$httpBackend.flush();

expect(applicationCtrl.redirectState).toBe(false);
expect(applicationCtrl.showGlobalSpinner).toBe(false);
});
Expand All @@ -267,18 +288,35 @@
]);
});

it('should show service instance registration if we dont not have registered services', function () {
it('should show service instance registration if we don\'t have registered services', function () {
$httpBackend.when('GET', '/pp/v1/cnsis').respond(200, []);
$httpBackend.when('GET', '/pp/v1/info').respond(200, []);
$httpBackend.when('GET', '/pp/v1/cnsis/registered').respond(200, []);

applicationCtrl.login('dev', 'dev');
$httpBackend.flush();

expect(applicationCtrl.redirectState).toBe('endpoint.dashboard');
expect(applicationCtrl.showGlobalSpinner).toBe(false);
});

it('should not show service instance registration if we have registered services', function () {
it('should show service instance registration if we don\'t have connected services', function () {
var responseData = [
{id: 1, name: 'name', api_endpoint: {Scheme: 'http', Host: 'api.host.com'}, cnsi_type: 'cf'}
];
$httpBackend.when('GET', '/pp/v1/cnsis')
.respond(200, responseData);
$httpBackend.when('GET', '/pp/v1/info').respond(200, []);
$httpBackend.when('GET', '/pp/v1/cnsis/registered').respond(200, []);

applicationCtrl.login('dev', 'dev');
$httpBackend.flush();

expect(applicationCtrl.redirectState).toBe('endpoint.dashboard');
expect(applicationCtrl.showGlobalSpinner).toBe(false);
});

it('should not show service instance registration if we have connected services', function () {
var future = 50000 + (new Date()).getTime() / 1000;

$httpBackend.when('GET', '/pp/v1/info').respond(200, []);
Expand All @@ -289,6 +327,7 @@
applicationCtrl.login('dev', 'dev');
$httpBackend.flush();

expect(applicationCtrl.redirectState).toBe(false);
expect(applicationCtrl.showGlobalSpinner).toBe(false);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="select-input-field">
<span class="select-input-value"
ng-class="{ 'text-muted': !selectInputCtrl.ngModelCtrl.$modelValue }">
{{ selectInputCtrl.modelLabel || selectInputCtrl.placeholder | conditionalTranslate:selectInputCtrl.translateOptionLabels }}
{{ (selectInputCtrl.modelLabel | conditionalTranslate:selectInputCtrl.translateOptionLabels) || (selectInputCtrl.placeholder | translate) }}
</span>
<i class="dropdown-toggle material-icons">arrow_drop_down</i>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

it('should use default placeholder text when value is not defined', function () {
expect(selectInputCtrl.placeholder).toBe('select-input.placeholder');
expect(element.find('span').text().trim()).toBe('select-input.placeholder');
expect(element.find('span').text().trim()).toBe('Select');
});

it('should toggle menu on click', function () {
Expand Down
Loading

0 comments on commit 65ca399

Please sign in to comment.