diff --git a/docs/en/UI/Angular/Localization.md b/docs/en/UI/Angular/Localization.md index d627f466ba..c8b73b08f3 100644 --- a/docs/en/UI/Angular/Localization.md +++ b/docs/en/UI/Angular/Localization.md @@ -130,6 +130,68 @@ this.store.selectSnapshot( Localization resources are stored in the `localization` property of `ConfigState`. +## RTL Support + +As of v2.9 ABP has RTL support. If you are generating a new project with v2.9 and above, everything is set, you do not need to do any changes. If you are migrating your project from an earlier version, please follow the 2 steps below: + +#### Step 1. Create Chunks for Bootstrap LTR and RTL + +Find [styles configuration in angular.json](https://angular.io/guide/workspace-config#style-script-config) and make sure the chunks in your project has `bootstrap-rtl.min` and `bootstrap-ltr.min` as shown below. + +```json +{ + "projects": { + "MyProjectName": { + "architect": { + "build": { + "options": { + "styles": [ + { + "input": "node_modules/@abp/ng.theme.shared/styles/bootstrap-rtl.min.css", + "inject": false, + "bundleName": "bootstrap-rtl.min" + }, + { + "input": "node_modules/bootstrap/dist/css/bootstrap.min.css", + "inject": true, + "bundleName": "bootstrap-ltr.min" + }, + { + "input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css", + "inject": true, + "bundleName": "fontawesome-all.min" + }, + { + "input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css", + "inject": true, + "bundleName": "fontawesome-v4-shims.min" + }, + "apps/dev-app/src/styles.scss" + ], + } + } + } + } + } +} + +#### Step 2. Clear Lazy Loaded Fontawesome in AppComponent + +If you have created and injected chunks for Fontawesome as seen above, you no longer need the lazy loading in the `AppComponent` which was implemented before v2.9. Simply remove them. The `AppComponent` in the template of the new version looks like this: + +```js +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` + + + `, +}) +export class AppComponent {} +``` + ## See Also diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json index 39a10f827b..2b876fe21c 100644 --- a/npm/ng-packs/angular.json +++ b/npm/ng-packs/angular.json @@ -440,18 +440,27 @@ "assets": ["apps/dev-app/src/favicon.ico", "apps/dev-app/src/assets"], "extractCss": true, "styles": [ - "apps/dev-app/src/styles.scss", - "node_modules/bootstrap/dist/css/bootstrap.min.css", + { + "input": "node_modules/@abp/ng.theme.shared/styles/bootstrap-rtl.min.css", + "inject": false, + "bundleName": "bootstrap-rtl.min" + }, + { + "input": "node_modules/bootstrap/dist/css/bootstrap.min.css", + "inject": true, + "bundleName": "bootstrap-ltr.min" + }, { "input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css", - "lazy": true, + "inject": true, "bundleName": "fontawesome-all.min" }, { "input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css", - "lazy": true, + "inject": true, "bundleName": "fontawesome-v4-shims.min" - } + }, + "apps/dev-app/src/styles.scss" ], "scripts": [] }, diff --git a/npm/ng-packs/apps/dev-app/src/app/app.component.ts b/npm/ng-packs/apps/dev-app/src/app/app.component.ts index 8187365734..bf2a27962a 100644 --- a/npm/ng-packs/apps/dev-app/src/app/app.component.ts +++ b/npm/ng-packs/apps/dev-app/src/app/app.component.ts @@ -1,6 +1,4 @@ -import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; -import { forkJoin } from 'rxjs'; +import { Component } from '@angular/core'; @Component({ selector: 'app-root', @@ -9,17 +7,4 @@ import { forkJoin } from 'rxjs'; `, }) -export class AppComponent implements OnInit { - constructor(private lazyLoadService: LazyLoadService) {} - - ngOnInit() { - forkJoin( - this.lazyLoadService.load( - LOADING_STRATEGY.PrependAnonymousStyleToHead('fontawesome-v4-shims.min.css'), - ), - this.lazyLoadService.load( - LOADING_STRATEGY.PrependAnonymousStyleToHead('fontawesome-all.min.css'), - ), - ).subscribe(); - } -} +export class AppComponent {} diff --git a/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts b/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts index cec9d4a6cf..4ba89949fd 100644 --- a/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts @@ -8,7 +8,7 @@ import { uuid } from '../utils'; providedIn: 'root', }) export class LazyLoadService { - readonly loaded = new Set(); + readonly loaded = new Map(); loadedLibraries: { [url: string]: ReplaySubject } = {}; @@ -45,7 +45,7 @@ export class LazyLoadService { throwError(new CustomEvent('error')), ), ), - tap(() => this.loaded.add(strategy.path)), + tap(() => this.loaded.set(strategy.path, strategy.element)), delay(100), shareReplay({ bufferSize: 1, refCount: true }), ); @@ -113,4 +113,14 @@ export class LazyLoadService { }); }); } + + remove(path: string): boolean { + const element = this.loaded.get(path); + + if (!element) return false; + + element.parentNode.removeChild(element); + this.loaded.delete(path); + return true; + } } diff --git a/npm/ng-packs/packages/core/src/lib/strategies/loading.strategy.ts b/npm/ng-packs/packages/core/src/lib/strategies/loading.strategy.ts index be89a751ed..f1f3abe30c 100644 --- a/npm/ng-packs/packages/core/src/lib/strategies/loading.strategy.ts +++ b/npm/ng-packs/packages/core/src/lib/strategies/loading.strategy.ts @@ -5,6 +5,8 @@ import { CrossOriginStrategy, CROSS_ORIGIN_STRATEGY } from './cross-origin.strat import { DomStrategy, DOM_STRATEGY } from './dom.strategy'; export abstract class LoadingStrategy { + element: T; + constructor( public path: string, protected domStrategy: DomStrategy = DOM_STRATEGY.AppendToHead(), @@ -14,10 +16,10 @@ export abstract class LoadingStrategy(): Observable { + this.element = this.createElement(); + return of(null).pipe( - switchMap(() => - fromLazyLoad(this.createElement(), this.domStrategy, this.crossOriginStrategy), - ), + switchMap(() => fromLazyLoad(this.element, this.domStrategy, this.crossOriginStrategy)), ); } } diff --git a/npm/ng-packs/packages/core/src/lib/tests/lazy-load.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/lazy-load.service.spec.ts index 3596da2591..4868fb78f3 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/lazy-load.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/lazy-load.service.spec.ts @@ -49,7 +49,7 @@ describe('LazyLoadService', () => { it('should emit a custom load event if loaded if resource is loaded before', done => { const loadEvent = new CustomEvent('load'); - service.loaded.add(strategy.path); + service.loaded.set(strategy.path, null); service.load(strategy).subscribe(event => { expect(event).toEqual(loadEvent); @@ -57,6 +57,32 @@ describe('LazyLoadService', () => { }); }); }); + + describe('#remove', () => { + const service = new LazyLoadService(); + + it('should remove an already lazy loaded element and return true', () => { + const script = document.createElement('script'); + document.body.appendChild(script); + service.loaded.set('x', script); + + expect(document.body.lastElementChild).toBe(script); + + const result = service.remove('x'); + + expect(document.body.lastElementChild).toBeNull(); + expect(service.loaded.has('x')).toBe(false); + expect(result).toBe(true); + }); + + it('should return false when path not found', () => { + service.loaded.set('foo', null); + + const result = service.remove('bar'); + + expect(result).toBe(false); + }); + }); }); describe('LazyLoadService (Deprecated)', () => { diff --git a/npm/ng-packs/packages/core/src/lib/tests/loading.strategy.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/loading.strategy.spec.ts index 4b950cf533..4215e6eee5 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/loading.strategy.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/loading.strategy.spec.ts @@ -39,6 +39,7 @@ describe('ScriptLoadingStrategy', () => { const strategy = new ScriptLoadingStrategy(path, domStrategy, crossOriginStrategy); strategy.createStream().subscribe(event => { + expect(strategy.element.tagName).toBe('SCRIPT'); expect(event.detail.crossOrigin).toBe('use-credentials'); done(); }); @@ -78,6 +79,7 @@ describe('StyleLoadingStrategy', () => { const strategy = new StyleLoadingStrategy(path, domStrategy, crossOriginStrategy); strategy.createStream().subscribe(event => { + expect(strategy.element.tagName).toBe('LINK'); expect(event.detail.crossOrigin).toBe('use-credentials'); done(); }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts index f5319edc2d..1409c0da21 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/localization-utils.spec.ts @@ -2,9 +2,53 @@ import { createLocalizationPipeKeyGenerator, createLocalizer, createLocalizerWithFallback, + getLocaleDirection, } from '../utils/localization-utils'; describe('Localization Utils', () => { + describe('#getLocaleDirection', () => { + test.each` + locale | expected + ${undefined} | ${'ltr'} + ${null} | ${'ltr'} + ${''} | ${'ltr'} + ${'en'} | ${'ltr'} + ${'en-US'} | ${'ltr'} + ${'pt'} | ${'ltr'} + ${'pt-PT'} | ${'ltr'} + ${'ar'} | ${'rtl'} + ${'ar-AE'} | ${'rtl'} + ${'ar-QA'} | ${'rtl'} + ${'ckb'} | ${'rtl'} + ${'ckb-IR'} | ${'rtl'} + ${'fa'} | ${'rtl'} + ${'fa-AF'} | ${'rtl'} + ${'he'} | ${'rtl'} + ${'ks'} | ${'rtl'} + ${'ksb'} | ${'ltr'} + ${'ksf'} | ${'ltr'} + ${'ksh'} | ${'ltr'} + ${'lrc'} | ${'rtl'} + ${'lrc-IQ'} | ${'rtl'} + ${'mzn'} | ${'rtl'} + ${'pa'} | ${'ltr'} + ${'pa-Arab'} | ${'rtl'} + ${'ps'} | ${'rtl'} + ${'ps-PK'} | ${'rtl'} + ${'sd'} | ${'rtl'} + ${'ug'} | ${'rtl'} + ${'ur'} | ${'rtl'} + ${'ur-IN'} | ${'rtl'} + ${'uz'} | ${'ltr'} + ${'uz-Arab'} | ${'rtl'} + ${'yi'} | ${'rtl'} + ${'zh'} | ${'ltr'} + ${'zh-Hans'} | ${'ltr'} + `('should return $expected when $locale is given as parameter', ({ locale, expected }) => { + expect(getLocaleDirection(locale)).toBe(expected); + }); + }); + describe('#createLocalizer', () => { const localize = createLocalizer({ values: { foo: { bar: 'baz' }, x: { y: 'z' } }, diff --git a/npm/ng-packs/packages/core/src/lib/utils/localization-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/localization-utils.ts index ed094f7fc7..09478c8ed8 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/localization-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/localization-utils.ts @@ -1,5 +1,14 @@ import { ApplicationConfiguration } from '../models/application-configuration'; +// This will not be necessary when only Angukar 9.1+ is supported +export function getLocaleDirection(locale: string): 'ltr' | 'rtl' { + return /^(ar(-[A-Z]{2})?|ckb(-IR)?|fa(-AF)?|he|ks|lrc(-IQ)?|mzn|pa-Arab|ps(-PK)?|sd|ug|ur(-IN)?|uz-Arab|yi)$/.test( + locale, + ) + ? 'rtl' + : 'ltr'; +} + export function createLocalizer(localization: ApplicationConfiguration.Localization) { return (resourceName: string, key: string, defaultValue: string) => { if (resourceName === '_') return key; diff --git a/npm/ng-packs/packages/theme-basic/src/lib/constants/styles.ts b/npm/ng-packs/packages/theme-basic/src/lib/constants/styles.ts index 0d9ebcc300..2de9931873 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/constants/styles.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/constants/styles.ts @@ -2,7 +2,6 @@ export default ` .content-header-title { font-size: 24px; } - .entry-row { margin-bottom: 15px; } @@ -26,17 +25,25 @@ export default ` border-radius: 0.25rem; min-height: 44px; } +[dir=rtl] .navbar .dropdown-menu a { + text-align: right!important; +} .navbar .dropdown-submenu a::after { transform: rotate(-90deg); position: absolute; right: 16px; top: 18px; } +[dir=rtl] .navbar .dropdown-submenu a::after { + transform: rotate(90deg); + left: 16px; + right: auto; + top: 20px; +} .navbar .dropdown-submenu .dropdown-menu { top: 0; left: 100%; } - .card-header .btn { padding: 2px 6px; } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html index eeaf0d40d9..6cbea56304 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html @@ -21,7 +21,7 @@
-
+
@@ -31,7 +31,7 @@
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts index da17aab136..a30b4464fc 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts @@ -1,9 +1,9 @@ import { - AfterViewInit, Component, ElementRef, EventEmitter, Input, + OnInit, Output, TemplateRef, TrackByFunction, @@ -17,7 +17,7 @@ import { styleUrls: ['table.component.scss'], encapsulation: ViewEncapsulation.None, }) -export class TableComponent { +export class TableComponent implements OnInit { private _totalRecords: number; bodyScrollLeft = 0; @@ -84,7 +84,23 @@ export class TableComponent { return this.value.slice(start, start + this.rows); } + marginCalculator: MarginCalculator; + trackByFn: TrackByFunction = (_, value) => { return typeof value === 'object' ? value[this.trackingProp] || value : value; }; + + ngOnInit() { + this.marginCalculator = document.body.dir === 'rtl' ? rtlCalculator : ltrCalculator; + } +} + +function ltrCalculator(div: HTMLDivElement): string { + return `0 auto 0 -${div.scrollLeft}px`; +} + +function rtlCalculator(div: HTMLDivElement): string { + return `0 ${-(div.scrollWidth - div.clientWidth - div.scrollLeft)}px 0 auto`; } + +type MarginCalculator = (div: HTMLDivElement) => string; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts b/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts index 4458117d16..a691f96ead 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts @@ -13,6 +13,10 @@ export default ` text-align: right; } +[dir=rtl] .data-tables-filter { + text-align: left; +} + .pointer { cursor: pointer; } @@ -155,3 +159,5 @@ export default ` /* (selector); + return { href, link }; + } + + private listenToLanguageChanges(injector: Injector) { + const l10n = injector.get(LocalizationService); + + // will always listen, no need to unsubscribe + l10n.languageChange + .pipe( + map(({ payload }) => payload), + startWith(l10n.currentLang), + ) + .subscribe(locale => { + this.dir = getLocaleDirection(locale); + }); + } + + private setBodyDir(dir: LocaleDirection) { + document.body.dir = dir; + } + + private setLazyLoad(injector: Injector) { + this.lazyLoad = injector.get(LazyLoadService); + const { href, link } = this.getLoadedBootstrap(); + this.lazyLoad.loaded.set(href, link); + } + + private setStyles(injector: Injector) { + this.styles = injector.get(LAZY_STYLES, [BOOTSTRAP]); + } + + private switchCSS(dir: LocaleDirection) { + this.styles.forEach(style => { + const oldHref = createLazyStyleHref(style, this.dir); + const newHref = createLazyStyleHref(style, dir); + + const strategy = LOADING_STRATEGY.PrependAnonymousStyleToHead(newHref); + this.lazyLoad.load(strategy).subscribe(() => this.lazyLoad.remove(oldHref)); + }); + } +} + +export function createLazyStyleHref(style: string, dir: string): string { + return style.replace(/{{\s*dir\s*}}/g, dir); +} + +export function initLazyStyleHandler(injector: Injector) { + return () => new LazyStyleHandler(injector); +} + +interface LoadedStyle { + href: string; + link: HTMLLinkElement; +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts index d75c854476..09171179c4 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts @@ -14,3 +14,5 @@ export interface HttpErrorConfig { hideCloseIcon?: boolean; }; } + +export type LocaleDirection = 'ltr' | 'rtl'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/lazy-style.handler.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/lazy-style.handler.spec.ts new file mode 100644 index 0000000000..5836bee474 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/lazy-style.handler.spec.ts @@ -0,0 +1,66 @@ +import { LazyLoadService, LOADING_STRATEGY, LocalizationService } from '@abp/ng.core'; +import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; +import { EMPTY, of } from 'rxjs'; +import { BOOTSTRAP } from '../constants/styles'; +import { createLazyStyleHref, initLazyStyleHandler, LazyStyleHandler } from '../handlers'; + +const languageChange = of({ payload: 'en' }); + +describe('LazyStyleHandler', () => { + let spectator: SpectatorService; + let handler: LazyStyleHandler; + let lazyLoad: LazyLoadService; + + const createService = createServiceFactory({ + service: LazyStyleHandler, + providers: [ + { + provide: LocalizationService, + useValue: { currentLang: 'en', languageChange }, + }, + ], + }); + + beforeEach(() => { + spectator = createService(); + handler = spectator.service; + lazyLoad = handler['lazyLoad']; + }); + + describe('#dir', () => { + it('should initially be "ltr"', () => { + expect(handler.dir).toBe('ltr'); + }); + + it('should set bootstrap to rtl', () => { + const oldHref = createLazyStyleHref(BOOTSTRAP, 'ltr'); + const newHref = createLazyStyleHref(BOOTSTRAP, 'rtl'); + lazyLoad.loaded.set(newHref, null); // avoid actual loading + const load = jest.spyOn(lazyLoad, 'load'); + const remove = jest.spyOn(lazyLoad, 'remove'); + const strategy = LOADING_STRATEGY.PrependAnonymousStyleToHead(newHref); + + handler.dir = 'rtl'; + + expect(load).toHaveBeenCalledWith(strategy); + expect(remove).toHaveBeenCalledWith(oldHref); + }); + }); +}); + +describe('initLazyStyleHandler', () => { + it('should return a LazyStyleHandler factory', () => { + const generator = (function*() { + yield undefined; // LAZY_STYLES + yield { loaded: new Map() }; // LazyLoadService + yield { currentLang: 'en', languageChange: EMPTY }; // LocalizationService + })(); + + const injector = { + get: () => generator.next().value as any, + }; + const factory = initLazyStyleHandler(injector); + + expect(factory()).toBeInstanceOf(LazyStyleHandler); + }); +}); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts index 5d53ed2124..72ec96f569 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts @@ -22,6 +22,7 @@ import styles from './constants/styles'; import { LoadingDirective } from './directives/loading.directive'; import { TableSortDirective } from './directives/table-sort.directive'; import { ErrorHandler } from './handlers/error.handler'; +import { initLazyStyleHandler } from './handlers/lazy-style.handler'; import { RootParams } from './models/common'; import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token'; @@ -104,6 +105,12 @@ export class ThemeSharedModule { deps: [THEME_SHARED_APPEND_CONTENT], useFactory: noop, }, + { + provide: APP_INITIALIZER, + multi: true, + deps: [Injector], + useFactory: initLazyStyleHandler, + }, { provide: HTTP_ERROR_CONFIG, useValue: options.httpErrorConfig }, { provide: 'HTTP_ERROR_CONFIG', diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tokens/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/tokens/index.ts index 1bdd74c53e..a923c8fc23 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tokens/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tokens/index.ts @@ -1,2 +1,3 @@ export * from './append-content.token'; export * from './http-error.token'; +export * from './lazy-styles.token'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tokens/lazy-styles.token.ts b/npm/ng-packs/packages/theme-shared/src/lib/tokens/lazy-styles.token.ts new file mode 100644 index 0000000000..73ca3044fc --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/tokens/lazy-styles.token.ts @@ -0,0 +1,3 @@ +import { InjectionToken } from '@angular/core'; + +export const LAZY_STYLES = new InjectionToken('LAZY_STYLES'); diff --git a/npm/ng-packs/packages/theme-shared/src/public-api.ts b/npm/ng-packs/packages/theme-shared/src/public-api.ts index 9df78be2d9..df27b079f4 100644 --- a/npm/ng-packs/packages/theme-shared/src/public-api.ts +++ b/npm/ng-packs/packages/theme-shared/src/public-api.ts @@ -5,8 +5,9 @@ export * from './lib/theme-shared.module'; export * from './lib/animations'; export * from './lib/components'; +export { BOOTSTRAP } from './lib/constants/styles'; export * from './lib/directives'; -export * from './lib/handlers'; +export { ErrorHandler } from './lib/handlers'; export * from './lib/models'; export * from './lib/services'; export * from './lib/tokens'; diff --git a/templates/app/angular/angular.json b/templates/app/angular/angular.json index 567b8f95c7..dfcaa5b9d3 100644 --- a/templates/app/angular/angular.json +++ b/templates/app/angular/angular.json @@ -26,22 +26,27 @@ "extractCss": true, "assets": ["src/favicon.ico", "src/assets"], "styles": [ + { + "input": "node_modules/@abp/ng.theme.shared/styles/bootstrap-rtl.min.css", + "inject": false, + "bundleName": "bootstrap-rtl.min" + }, { "input": "node_modules/bootstrap/dist/css/bootstrap.min.css", "inject": true, - "bundleName": "bootstrap.min" + "bundleName": "bootstrap-ltr.min" }, - "src/styles.scss", { "input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css", - "inject": false, + "inject": true, "bundleName": "fontawesome-all.min" }, { "input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css", - "inject": false, + "inject": true, "bundleName": "fontawesome-v4-shims.min" - } + }, + "src/styles.scss" ], "scripts": [] }, diff --git a/templates/app/angular/src/app/app.component.ts b/templates/app/angular/src/app/app.component.ts index 963806c4f4..bf2a27962a 100644 --- a/templates/app/angular/src/app/app.component.ts +++ b/templates/app/angular/src/app/app.component.ts @@ -1,6 +1,4 @@ -import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; -import { forkJoin } from 'rxjs'; +import { Component } from '@angular/core'; @Component({ selector: 'app-root', @@ -9,17 +7,4 @@ import { forkJoin } from 'rxjs'; `, }) -export class AppComponent implements OnInit { - constructor(private lazyLoadService: LazyLoadService) {} - - ngOnInit() { - forkJoin( - this.lazyLoadService.load( - LOADING_STRATEGY.PrependAnonymousStyleToHead('fontawesome-v4-shims.min.css') - ), - this.lazyLoadService.load( - LOADING_STRATEGY.PrependAnonymousStyleToHead('fontawesome-all.min.css') - ) - ).subscribe(); - } -} +export class AppComponent {}