Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Added omnibar provider for determining environment ID and service ID at runtime #323

Merged
merged 3 commits into from
Nov 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ export * from './search-results-provider';
export * from './window-ref';
export * from './style-loader';
export * from './viewport.service';
export * from './omnibar-provider';
export * from './omnibar-ready-args';
14 changes: 14 additions & 0 deletions runtime/omnibar-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {
Injectable
} from '@angular/core';

import {
SkyAppOmnibarReadyArgs
} from './omnibar-ready-args';

@Injectable()
export abstract class SkyAppOmnibarProvider {

public abstract ready(): Promise<SkyAppOmnibarReadyArgs>;

}
7 changes: 7 additions & 0 deletions runtime/omnibar-ready-args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface SkyAppOmnibarReadyArgs {

envId?: string;

svcId?: string;

}
137 changes: 119 additions & 18 deletions src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { NavigationEnd, NavigationStart, Router } from '@angular/router';

import {
SkyAppConfig,
SkyAppOmnibarProvider,
SkyAppOmnibarReadyArgs,
SkyAppSearchResultsProvider,
SkyAppStyleLoader,
SkyAppWindowRef,
Expand Down Expand Up @@ -44,22 +46,6 @@ describe('AppComponent', () => {
let viewport: SkyAppViewportService;

const location = 'my-custom-location';
const defaultSkyAppConfig: any = {
runtime: {
app: {
base: 'app-base'
},
params: {
has: (key: any) => false,
parse: (p: any) => parseParams = p
}
},
skyux: {
host: {
url: 'host-url'
}
}
};

class MockHelpInitService {
public load() { }
Expand All @@ -70,7 +56,8 @@ describe('AppComponent', () => {
function setup(
config: any,
includeSearchProvider?: boolean,
styleLoadPromise?: Promise<any>
styleLoadPromise?: Promise<any>,
omnibarProvider?: any
) {
let providers: any[] = [
{
Expand Down Expand Up @@ -125,6 +112,13 @@ describe('AppComponent', () => {
});
}

if (omnibarProvider) {
providers.push({
provide: SkyAppOmnibarProvider,
useValue: omnibarProvider
});
}

return TestBed.configureTestingModule({
declarations: [
AppComponent
Expand All @@ -141,9 +135,61 @@ describe('AppComponent', () => {
});
}

function validateOmnibarProvider(
readyArgs: SkyAppOmnibarReadyArgs,
expectedNotCalledWith?: any
) {
let spyOmnibar = spyOn(BBOmnibar, 'load');

skyAppConfig.skyux.omnibar = {
experimental: true
};

let readyPromiseResolve: (args: SkyAppOmnibarReadyArgs) => void;

const readyPromise = new Promise<SkyAppOmnibarReadyArgs>((resolve) => {
readyPromiseResolve = resolve;
});

setup(skyAppConfig, undefined, undefined, {
ready: () => readyPromise
}).then(() => {
fixture.detectChanges();

expect(spyOmnibar).not.toHaveBeenCalled();

readyPromiseResolve(readyArgs);

tick();

expect(spyOmnibar).toHaveBeenCalledWith(jasmine.objectContaining(readyArgs));

if (expectedNotCalledWith) {
expect(spyOmnibar).not.toHaveBeenCalledWith(
jasmine.objectContaining(expectedNotCalledWith)
);
}
});
}

// Reset skyAppConfig and scrollCalled
beforeEach(() => {
skyAppConfig = defaultSkyAppConfig;
skyAppConfig = {
runtime: {
app: {
base: 'app-base'
},
params: {
has: (key: any) => false,
parse: (p: any) => parseParams = p
}
},
skyux: {
host: {
url: 'host-url'
}
}
};
scrollCalled = false;
viewport = new SkyAppViewportService();
});
Expand Down Expand Up @@ -427,6 +473,26 @@ describe('AppComponent', () => {
});
}));

it('should enable help for the omnibar when help config is present', async(() => {
let spyOmnibar = spyOn(BBOmnibar, 'load');

skyAppConfig.skyux.omnibar = {
experimental: true
};

skyAppConfig.skyux.help = {
productId: 'test-config'
};

setup(skyAppConfig, false).then(() => {
fixture.detectChanges();

expect(spyOmnibar).toHaveBeenCalledWith(jasmine.objectContaining({
enableHelp: true
}));
});
}));

it('should call navigateByUrl, return false in the beforeNavCallback if local link', async(() => {
let spyOmnibar = spyOn(BBOmnibar, 'load');

Expand Down Expand Up @@ -606,4 +672,39 @@ describe('AppComponent', () => {
expect(console.log).toHaveBeenCalledWith(result.error.message);
});
}));

it(
'should load the omnibar when the omnibar provider\'s ready() promise is resolved',
fakeAsync(() => {
validateOmnibarProvider(
{
envId: '999',
svcId: 'zzz'
}
);
})
);

it('should consider the omnibar provider args envId property optional', fakeAsync(() => {
validateOmnibarProvider(
{
envId: '999'
},
{
svcId: jasmine.anything()
}
);
}));

it('should consider the omnibar provider args svcId property optional', fakeAsync(() => {
validateOmnibarProvider(
{
svcId: 'zzz'
},
{
envId: jasmine.anything()
}
);
}));

});
35 changes: 31 additions & 4 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import { HelpInitializationService } from '@blackbaud/skyux-lib-help';

import {
SkyAppConfig,
SkyAppOmnibarProvider,
SkyAppOmnibarReadyArgs,
SkyAppSearchResultsProvider,
SkyAppWindowRef,
SkyAppStyleLoader,
SkyAppViewportService
SkyAppViewportService,
SkyAppWindowRef
} from '@blackbaud/skyux-builder/runtime';

require('style-loader!@blackbaud/skyux/dist/css/sky.css');
Expand Down Expand Up @@ -80,7 +82,8 @@ export class AppComponent implements OnInit {
@Optional() private helpInitService?: HelpInitializationService,
@Optional() private searchProvider?: SkyAppSearchResultsProvider,
@Optional() viewport?: SkyAppViewportService,
@Optional() private zone?: NgZone
@Optional() private zone?: NgZone,
@Optional() private omnibarProvider?: SkyAppOmnibarProvider
) {
this.styleLoader.loadStyles()
.then((result?: any) => {
Expand Down Expand Up @@ -189,11 +192,25 @@ export class AppComponent implements OnInit {
}
}

private setOmnibarArgsOverrides(omnibarConfig: any, args: SkyAppOmnibarReadyArgs) {
if (args) {
// Eventually this could be expanded to allow any valid config property to be overridden,
// but for now keep it scoped to the two parameters we know consumers will want to override.
if (args.hasOwnProperty('envId')) {
omnibarConfig.envId = args.envId;
}

if (args.hasOwnProperty('svcId')) {
omnibarConfig.svcId = args.svcId;
}
}
}

private initShellComponents() {
const omnibarConfig = this.config.skyux.omnibar;
const helpConfig = this.config.skyux.help;

if (omnibarConfig) {
const loadOmnibar = (args?: SkyAppOmnibarReadyArgs) => {
this.setParamsFromQS(omnibarConfig);
this.setNav(omnibarConfig);
this.setOnSearch(omnibarConfig);
Expand All @@ -204,6 +221,8 @@ export class AppComponent implements OnInit {

omnibarConfig.allowAnonymous = !this.config.skyux.auth;

this.setOmnibarArgsOverrides(omnibarConfig, args);

// The omnibar uses setInterval() to poll for user activity, and setInterval()
// triggers change detection on each interval. Loading the omnibar outside
// Angular will keep change detection from being triggered during each interval.
Expand All @@ -216,6 +235,14 @@ export class AppComponent implements OnInit {
BBOmnibarLegacy.load(omnibarConfig);
}
});
};

if (omnibarConfig) {
if (this.omnibarProvider) {
this.omnibarProvider.ready().then(loadOmnibar);
} else {
loadOmnibar();
}
}

if (helpConfig && this.helpInitService) {
Expand Down