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

Added resource pipe and service for libraries #12

Merged
merged 8 commits into from
Oct 17, 2018
Merged
Show file tree
Hide file tree
Changes from 7 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
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"skyux": "skyux",
"start": "skyux serve --hmr",
"test": "skyux test --coverage library --logFormat none",
"test:visual": "skyux e2e --logFormat none"
"test:visual": "skyux e2e --logFormat none",
"watch": "skyux watch --coverage library"
},
"keywords": [],
"author": "Blackbaud",
Expand Down Expand Up @@ -44,9 +45,10 @@
"@angular/platform-browser": "4.3.6",
"@angular/platform-browser-dynamic": "4.3.6",
"@angular/router": "4.3.6",
"@blackbaud/auth-client": "2.7.0",
"@blackbaud/skyux": "2.25.0",
"@blackbaud/skyux-builder": "1.22.0",
"@blackbaud/auth-client": "2.10.0",
"@blackbaud/skyux": "2.26.0",
"@blackbaud/skyux-builder": "blackbaud/skyux-builder#host-locale-provider",
"@skyux-sdk/builder-plugin-skyux": "blackbaud/skyux-builder-plugin-skyux#lib-resources",
"@skyux-sdk/testing": "3.0.0",
"@skyux/assets": "3.0.0",
"@skyux/core": "3.0.2",
Expand Down
3 changes: 3 additions & 0 deletions skyuxconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"name": "skyux-i18n",
"mode": "easy",
"compileMode": "aot",
"plugins": [
"@skyux-sdk/builder-plugin-skyux"
],
"testSettings": {
"unit": {
"browserSet": "paranoid"
Expand Down
11 changes: 7 additions & 4 deletions src/app/app-extras.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import {
NgModule
} from '@angular/core';

import {
SkySampleResourcesModule
} from './demos';

@NgModule({
imports: [],
exports: [],
providers: [],
entryComponents: []
exports: [
SkySampleResourcesModule
]
})
export class AppExtrasModule { }
1 change: 1 addition & 0 deletions src/app/demos/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './sample-resources.module';
14 changes: 14 additions & 0 deletions src/app/demos/sample-resources.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<table>
<tr>
<td>Pipe result:</td>
<td>{{ 'greeting' | skyLibResources }}</td>
</tr>
<tr>
<td>Default greeting (service):</td>
<td>{{ defaultGreeting }}</td>
</tr>
<tr>
<td>Localized greeting (service):</td>
<td>{{ localizedGreeting }}</td>
</tr>
</table>
36 changes: 36 additions & 0 deletions src/app/demos/sample-resources.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
ChangeDetectionStrategy,
Component,
OnInit
} from '@angular/core';

import {
SkyLibResourcesService
} from '../public';

@Component({
selector: 'sky-sample-resources',
templateUrl: './sample-resources.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SkySampleResourcesComponent implements OnInit {
public defaultGreeting: string;
public localizedGreeting: string;

constructor(
private resourcesService: SkyLibResourcesService
) { }

public ngOnInit(): void {
this.defaultGreeting = this.resourcesService.getStringForLocale(
{ locale: 'en_US' },
'greeting'
);

this.resourcesService
.getString('greeting')
.subscribe((localizedValue: string) => {
this.localizedGreeting = localizedValue;
});
}
}
24 changes: 24 additions & 0 deletions src/app/demos/sample-resources.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
NgModule
} from '@angular/core';

import {
SKY_LIB_RESOURCES_PROVIDERS,
SkyI18nModule
} from '../public';

import {
SkySampleResourcesProvider
} from '../public/plugin-resources/sample-resources-provider';

@NgModule({
exports: [
SkyI18nModule
],
providers: [{
provide: SKY_LIB_RESOURCES_PROVIDERS,
useClass: SkySampleResourcesProvider,
multi: true
}]
})
export class SkySampleResourcesModule { }
1 change: 1 addition & 0 deletions src/app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<sky-sample-resources></sky-sample-resources>
5 changes: 5 additions & 0 deletions src/app/public/modules/i18n/host-locale-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export class SkyAppHostLocaleProvider extends SkyAppLocaleProvider {
}

public getLocaleInfo(): Observable<SkyAppLocaleInfo> {
console.warn([
'The class `SkyAppHostLocaleProvider`, imported from `@skyux/i18n`',
'is deprecated. Please import from `@blackbaud/skyux-builder/runtime/i18n`.'
].join(' '));

if (this.localeProvider) {
return this.localeProvider.getLocaleInfo();
}
Expand Down
27 changes: 19 additions & 8 deletions src/app/public/modules/i18n/i18n.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ import {
SkyAppWindowRef
} from '@skyux/core';

import {
SkyAppHostLocaleProvider
} from './host-locale-provider';

import {
SkyAppResourcesPipe
} from './resources.pipe';
Expand All @@ -26,12 +22,26 @@ import {
SkyAppResourcesService
} from './resources.service';

import {
SkyLibResourcesPipe
} from './lib-resources.pipe';

import {
SkyLibResourcesService
} from './lib-resources.service';

import {
SkyAppLocaleProvider
} from './locale-provider';

@NgModule({
declarations: [
SkyAppResourcesPipe
SkyAppResourcesPipe,
SkyLibResourcesPipe
],
exports: [
SkyAppResourcesPipe
SkyAppResourcesPipe,
SkyLibResourcesPipe
],
imports: [
HttpModule
Expand All @@ -43,9 +53,10 @@ import {
provide: SkyAppAssetsService,
useValue: SkyAppAssetsService
},
SkyAppHostLocaleProvider,
SkyAppLocaleProvider,
SkyAppResourcesService,
SkyAppWindowRef
SkyAppWindowRef,
SkyLibResourcesService
]
})
export class SkyI18nModule { }
5 changes: 5 additions & 0 deletions src/app/public/modules/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
export * from './host-locale-provider';
export * from './i18n.module';
export * from './lib-resources-provider';
export * from './lib-resources-providers-token';
export * from './lib-resources.pipe';
export * from './lib-resources.service';
export * from './locale-info';
export * from './locale-provider';
export * from './resources.pipe';
export * from './resources.service';
Expand Down
7 changes: 7 additions & 0 deletions src/app/public/modules/i18n/lib-resources-provider.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// import {
// SkyLibResourcesProvider
// } from './lib-resources-provider';

// describe('Library resources provider', () => {
// it('should ');
// });
16 changes: 16 additions & 0 deletions src/app/public/modules/i18n/lib-resources-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// #region imports
import {
Injectable
} from '@angular/core';

import {
SkyAppLocaleInfo
} from './locale-info';
// #endregion

@Injectable()
export abstract class SkyLibResourcesProvider {

public getString: (localeInfo: SkyAppLocaleInfo, name: string) => string;

}
12 changes: 12 additions & 0 deletions src/app/public/modules/i18n/lib-resources-providers-token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// #region imports
import {
InjectionToken
} from '@angular/core';

import {
SkyLibResourcesProvider
} from './lib-resources-provider';
// #endregion

export const SKY_LIB_RESOURCES_PROVIDERS =
new InjectionToken<SkyLibResourcesProvider>('SKY_LIB_RESOURCES_PROVIDERS');
84 changes: 84 additions & 0 deletions src/app/public/modules/i18n/lib-resources.pipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// #region imports
import {
Observable
} from 'rxjs/Observable';

import {
SkyLibResourcesPipe
} from './lib-resources.pipe';

import {
SkyLibResourcesService
} from './lib-resources.service';
// #endregion

describe('Library resources pipe', () => {
let resources: SkyLibResourcesService;
let changeDetector: any;

beforeEach(() => {
changeDetector = {
markForCheck: jasmine.createSpy('markForCheck')
};

resources = {
getString: (name: string, ...args: any[]) => {
let value: string;

if (args && args.length > 0) {
value = 'format me ' + args.join(' ');
} else {
value = 'hello';
}

return Observable.of(value);
}
} as SkyLibResourcesService;
});

it('should return the expected string', () => {
const pipe = new SkyLibResourcesPipe(changeDetector, resources);
expect(pipe.transform('hi')).toBe('hello');
});

it('should return the expected string formatted with the specified parameters', () => {
const pipe = new SkyLibResourcesPipe(changeDetector, resources);
expect(pipe.transform('hi', 'abc', 'def')).toBe('format me abc def');
});

it('should cache strings that have been retrieved via the resource service', () => {
const pipe = new SkyLibResourcesPipe(changeDetector, resources);

const getStringSpy = spyOn(resources, 'getString').and.callThrough();

pipe.transform('hi');
pipe.transform('hi');
pipe.transform('hi');

expect(getStringSpy).toHaveBeenCalledTimes(1);
});

it('should consider format args as part of the cache key', () => {
const pipe = new SkyLibResourcesPipe(changeDetector, resources);
const getStringSpy = spyOn(resources, 'getString').and.callThrough();

expect(pipe.transform('hi')).toBe('hello');
expect(pipe.transform('hi', 'abc')).toBe('format me abc');
expect(pipe.transform('hi')).toBe('hello');
expect(pipe.transform('hi', 'abc')).toBe('format me abc');
expect(pipe.transform('hi')).toBe('hello');
expect(pipe.transform('hi', 'abc')).toBe('format me abc');

expect(getStringSpy).toHaveBeenCalledTimes(2);
});

it('should mark the change detector for check when the string is loaded asynchronously', () => {
const pipe = new SkyLibResourcesPipe(changeDetector, resources);

pipe.transform('hi');
pipe.transform('hi');
pipe.transform('hi');

expect(changeDetector.markForCheck).toHaveBeenCalledTimes(1);
});
});
38 changes: 38 additions & 0 deletions src/app/public/modules/i18n/lib-resources.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// #region imports
import {
ChangeDetectorRef,
Pipe,
PipeTransform
} from '@angular/core';

import {
SkyLibResourcesService
} from './lib-resources.service';
// #endregion

@Pipe({
name: 'skyLibResources',
pure: false
})
export class SkyLibResourcesPipe implements PipeTransform {
private resourceCache: {[key: string]: any} = {};

constructor(
private changeDetector: ChangeDetectorRef,
private resourcesService: SkyLibResourcesService
) { }

public transform(name: string, ...args: any[]): string {
const cacheKey = name + JSON.stringify(args);

if (!(cacheKey in this.resourceCache)) {
this.resourcesService.getString(name, ...args)
.subscribe((value: string) => {
this.resourceCache[cacheKey] = value;
this.changeDetector.markForCheck();
});
}

return this.resourceCache[cacheKey];
}
}
Loading