From ac71b2fc6f7ae6e6b7d4e632104af330ab8de484 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Mon, 7 Oct 2019 15:41:45 +0300 Subject: [PATCH 1/4] feat: seperate 3th party css files from initial bundle --- npm/ng-packs/.gitignore | 1 + npm/ng-packs/angular.json | 25 +++++++-- .../apps/dev-app/src/app/app.component.ts | 18 ++++++- templates/app/angular/angular.json | 52 ++++++++++--------- .../app/angular/src/app/app.component.ts | 18 ++++++- 5 files changed, 81 insertions(+), 33 deletions(-) diff --git a/npm/ng-packs/.gitignore b/npm/ng-packs/.gitignore index 7f282e1aa3..3915996991 100644 --- a/npm/ng-packs/.gitignore +++ b/npm/ng-packs/.gitignore @@ -3,6 +3,7 @@ # compiled output /tmp /out-tsc +/dist/dev-app # Only exists if Bazel was run /bazel-out diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json index fb32a2d757..a06c34c90e 100644 --- a/npm/ng-packs/angular.json +++ b/npm/ng-packs/angular.json @@ -434,13 +434,30 @@ "tsConfig": "apps/dev-app/tsconfig.app.json", "aot": false, "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", - "node_modules/font-awesome/css/font-awesome.min.css", - "node_modules/primeng/resources/themes/nova-light/theme.css", - "node_modules/primeicons/primeicons.css", - "node_modules/primeng/resources/primeng.min.css" + { + "input": "node_modules/font-awesome/css/font-awesome.min.css", + "lazy": true, + "bundleName": "font-awesome.min" + }, + { + "input": "node_modules/primeng/resources/themes/nova-light/theme.css", + "lazy": true, + "bundleName": "primeng-nova-light-theme" + }, + { + "input": "node_modules/primeicons/primeicons.css", + "lazy": true, + "bundleName": "primeicons" + }, + { + "input": "node_modules/primeng/resources/primeng.min.css", + "lazy": true, + "bundleName": "primeng.min" + } ], "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 bf2a27962a..e89c73184d 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,4 +1,5 @@ -import { Component } from '@angular/core'; +import { LazyLoadService } from '@abp/ng.core'; +import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-root', @@ -7,4 +8,17 @@ import { Component } from '@angular/core'; `, }) -export class AppComponent {} +export class AppComponent implements OnInit { + constructor(private lazyLoadService: LazyLoadService) {} + + ngOnInit() { + this.lazyLoadService + .load( + ['primeng.min.css', 'primeicons.css', 'primeng-nova-light-theme.css', 'font-awesome.min.css'], + 'style', + null, + 'head', + ) + .subscribe(); + } +} diff --git a/templates/app/angular/angular.json b/templates/app/angular/angular.json index 8a844d2562..f7bb4656fe 100644 --- a/templates/app/angular/angular.json +++ b/templates/app/angular/angular.json @@ -23,17 +23,31 @@ "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.app.json", "aot": false, - "assets": [ - "src/favicon.ico", - "src/assets" - ], + "extractCss": true, + "assets": ["src/favicon.ico", "src/assets"], "styles": [ "src/styles.scss", "node_modules/bootstrap/dist/css/bootstrap.min.css", - "node_modules/font-awesome/css/font-awesome.min.css", - "node_modules/primeng/resources/themes/nova-light/theme.css", - "node_modules/primeicons/primeicons.css", - "node_modules/primeng/resources/primeng.min.css" + { + "input": "node_modules/font-awesome/css/font-awesome.min.css", + "lazy": true, + "bundleName": "font-awesome.min" + }, + { + "input": "node_modules/primeng/resources/themes/nova-light/theme.css", + "lazy": true, + "bundleName": "primeng-nova-light-theme" + }, + { + "input": "node_modules/primeicons/primeicons.css", + "lazy": true, + "bundleName": "primeicons" + }, + { + "input": "node_modules/primeng/resources/primeng.min.css", + "lazy": true, + "bundleName": "primeng.min" + } ], "scripts": [] }, @@ -100,10 +114,7 @@ "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/assets" - ], + "assets": ["src/favicon.ico", "src/assets"], "styles": [ "src/styles.scss", "node_modules/bootstrap/dist/css/bootstrap.min.css", @@ -118,14 +129,8 @@ "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "tsconfig.app.json", - "tsconfig.spec.json", - "e2e/tsconfig.json" - ], - "exclude": [ - "**/node_modules/**" - ] + "tsConfig": ["tsconfig.app.json", "tsconfig.spec.json", "e2e/tsconfig.json"], + "exclude": ["**/node_modules/**"] } }, "e2e": { @@ -143,8 +148,5 @@ } } }, - "defaultProject": "myProjectName", - "cli": { - "analytics": "07ef29be-2b85-4919-9f78-44994f63b8b7" - } -} \ No newline at end of file + "defaultProject": "myProjectName" +} diff --git a/templates/app/angular/src/app/app.component.ts b/templates/app/angular/src/app/app.component.ts index bf2a27962a..e89c73184d 100644 --- a/templates/app/angular/src/app/app.component.ts +++ b/templates/app/angular/src/app/app.component.ts @@ -1,4 +1,5 @@ -import { Component } from '@angular/core'; +import { LazyLoadService } from '@abp/ng.core'; +import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-root', @@ -7,4 +8,17 @@ import { Component } from '@angular/core'; `, }) -export class AppComponent {} +export class AppComponent implements OnInit { + constructor(private lazyLoadService: LazyLoadService) {} + + ngOnInit() { + this.lazyLoadService + .load( + ['primeng.min.css', 'primeicons.css', 'primeng-nova-light-theme.css', 'font-awesome.min.css'], + 'style', + null, + 'head', + ) + .subscribe(); + } +} From 220d41149d4824c3341ee5e946a898f159e45a63 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Mon, 7 Oct 2019 15:43:11 +0300 Subject: [PATCH 2/4] feat(core): lazy load service supports url array --- .../src/lib/services/lazy-load.service.ts | 84 +++++++++++-------- 1 file changed, 50 insertions(+), 34 deletions(-) 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 a6e8eb1f5c..a9d1f53429 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 @@ -9,50 +9,66 @@ export class LazyLoadService { loadedLibraries: { [url: string]: ReplaySubject } = {}; load( - url: string, + urlOrUrls: string | string[], type: 'script' | 'style', content: string = '', targetQuery: string = 'body', position: InsertPosition = 'afterend', ): Observable { - if (!url && !content) return; - const key = url ? url.slice(url.lastIndexOf('/') + 1) : uuid(); - - if (this.loadedLibraries[key]) { - return this.loadedLibraries[key].asObservable(); + if (!urlOrUrls && !content) { + return; + } else if (!urlOrUrls && content) { + urlOrUrls = [null]; } - this.loadedLibraries[key] = new ReplaySubject(); - - let library; - if (type === 'script') { - library = document.createElement('script'); - library.type = 'text/javascript'; - if (url) { - (library as HTMLScriptElement).src = url; - } - - (library as HTMLScriptElement).text = content; - } else if (url) { - library = document.createElement('link'); - library.type = 'text/css'; - (library as HTMLLinkElement).rel = 'stylesheet'; - - if (url) { - (library as HTMLLinkElement).href = url; - } - } else { - library = document.createElement('style'); - (library as HTMLStyleElement).textContent = content; + if (!Array.isArray(urlOrUrls)) { + urlOrUrls = [urlOrUrls]; } - library.onload = () => { - this.loadedLibraries[key].next(); - this.loadedLibraries[key].complete(); - }; + return new Observable(subscriber => { + (urlOrUrls as string[]).forEach((url, index) => { + const key = url ? url.slice(url.lastIndexOf('/') + 1) : uuid(); + + if (this.loadedLibraries[key]) { + return this.loadedLibraries[key].asObservable(); + } + + this.loadedLibraries[key] = new ReplaySubject(); + + let library; + if (type === 'script') { + library = document.createElement('script'); + library.type = 'text/javascript'; + if (url) { + (library as HTMLScriptElement).src = url; + } + + (library as HTMLScriptElement).text = content; + } else if (url) { + library = document.createElement('link'); + library.type = 'text/css'; + (library as HTMLLinkElement).rel = 'stylesheet'; + + if (url) { + (library as HTMLLinkElement).href = url; + } + } else { + library = document.createElement('style'); + (library as HTMLStyleElement).textContent = content; + } + + library.onload = () => { + this.loadedLibraries[key].next(); + this.loadedLibraries[key].complete(); - document.querySelector(targetQuery).insertAdjacentElement(position, library); + if (index === urlOrUrls.length - 1) { + subscriber.next(); + subscriber.complete(); + } + }; - return this.loadedLibraries[key].asObservable(); + document.querySelector(targetQuery).insertAdjacentElement(position, library); + }); + }); } } From efb6c456f6453f715d65876722ad636bb024d12e Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Mon, 7 Oct 2019 15:43:49 +0300 Subject: [PATCH 3/4] fix: some bugs --- .../lib/models/application-configuration.ts | 14 ++++---- .../core/src/lib/states/config.state.ts | 35 ++++++++++++++----- .../components/layout/layout.component.html | 2 +- .../src/lib/animations/slide.animations.ts | 9 ++--- .../lib/components/button/button.component.ts | 11 ++++-- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/models/application-configuration.ts b/npm/ng-packs/packages/core/src/lib/models/application-configuration.ts index 9912810399..ad34955dac 100644 --- a/npm/ng-packs/packages/core/src/lib/models/application-configuration.ts +++ b/npm/ng-packs/packages/core/src/lib/models/application-configuration.ts @@ -1,10 +1,12 @@ +import { ABP } from './common'; + export namespace ApplicationConfiguration { export interface Response { localization: Localization; auth: Auth; - setting: Setting; + setting: Value; currentUser: CurrentUser; - features: Features; + features: Value; } export interface Localization { @@ -32,8 +34,8 @@ export namespace ApplicationConfiguration { [key: string]: boolean; } - export interface Setting { - values: { [key: string]: 'Abp.Localization.DefaultLanguage' }; + export interface Value { + values: ABP.Dictionary; } export interface CurrentUser { @@ -42,8 +44,4 @@ export namespace ApplicationConfiguration { tenantId: string; userName: string; } - - export interface Features { - values: Setting; - } } diff --git a/npm/ng-packs/packages/core/src/lib/states/config.state.ts b/npm/ng-packs/packages/core/src/lib/states/config.state.ts index f454be2872..1c0f533079 100644 --- a/npm/ng-packs/packages/core/src/lib/states/config.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/config.state.ts @@ -1,14 +1,14 @@ -import { State, Selector, createSelector, Action, StateContext, Store } from '@ngxs/store'; -import { Config } from '../models/config'; -import { ABP } from '../models/common'; -import { GetAppConfiguration, PatchRouteByName } from '../actions/config.actions'; -import { ApplicationConfigurationService } from '../services/application-configuration.service'; -import { tap, switchMap } from 'rxjs/operators'; +import { Action, createSelector, Selector, State, StateContext, Store } from '@ngxs/store'; +import { of } from 'rxjs'; +import { switchMap, tap } from 'rxjs/operators'; import snq from 'snq'; +import { GetAppConfiguration, PatchRouteByName } from '../actions/config.actions'; import { SetLanguage } from '../actions/session.actions'; +import { ABP } from '../models/common'; +import { Config } from '../models/config'; +import { ApplicationConfigurationService } from '../services/application-configuration.service'; +import { organizeRoutes } from '../utils/route-utils'; import { SessionState } from './session.state'; -import { of } from 'rxjs'; -import { setChildRoute, sortRoutes, organizeRoutes } from '../utils/route-utils'; @State({ name: 'ConfigState', @@ -90,14 +90,31 @@ export class ConfigState { return selector; } - static getSetting(key: string) { + static getSetting(key: string, findContain?: boolean) { const selector = createSelector( [ConfigState], (state: Config.State) => { return snq(() => state.setting.values[key]); }, ); + return selector; + } + + static getSettings(keyword?: string) { + const selector = createSelector( + [ConfigState], + (state: Config.State) => { + if (keyword) { + const keys = snq(() => Object.keys(state.setting.values).filter(key => key.indexOf(keyword) > -1), []); + if (keys.length) { + return keys.reduce((acc, key) => ({ ...acc, [key]: state.setting.values[key] }), {}); + } + } + + return snq(() => state.setting.values, {}); + }, + ); return selector; } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/layout/layout.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/layout/layout.component.html index 3e091aa5a1..89ab7f1b69 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/layout/layout.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/layout/layout.component.html @@ -11,7 +11,7 @@
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/animations/slide.animations.ts b/npm/ng-packs/packages/theme-shared/src/lib/animations/slide.animations.ts index 90f46662be..32ff155e55 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/animations/slide.animations.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/animations/slide.animations.ts @@ -1,6 +1,7 @@ import { animate, state, style, transition, trigger, query } from '@angular/animations'; -export const slideFromBottom = trigger('routeAnimations', [ - state('void', style({ 'margin-top': '20px', opacity: '0' })), - state('*', style({ 'margin-top': '0px', opacity: '1' })), - transition(':enter', [animate('0.2s ease-out', style({ opacity: '1', 'margin-top': '0px' }))]), +export const slideFromBottom = trigger('slideFromBottom', [ + transition('* <=> *', [ + style({ 'margin-top': '20px', opacity: '0' }), + animate('0.2s ease-out', style({ opacity: '1', 'margin-top': '0px' })), + ]), ]); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts index 50dab84c0f..214f2e52de 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts @@ -3,17 +3,17 @@ import { Component, Input } from '@angular/core'; @Component({ selector: 'abp-button', template: ` - - ` + `, }) export class ButtonComponent { @Input() buttonClass = 'btn btn-primary'; @Input() - type = 'button'; + buttonType = 'button'; @Input() iconClass: string; @@ -24,6 +24,11 @@ export class ButtonComponent { @Input() disabled = false; + /** + * @deprecated Use buttonType instead. To be deleted in v1 + */ + @Input() type = 'button'; + get icon(): string { return `${this.loading ? 'fa fa-pulse fa-spinner' : this.iconClass || 'd-none'}`; } From 404eba79c0856be2ff511a44060893996ac66ffc Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Mon, 7 Oct 2019 17:06:35 +0300 Subject: [PATCH 4/4] fix(core): lazy load return --- .../core/src/lib/services/lazy-load.service.ts | 4 +++- .../lib/components/button/button.component.ts | 4 ++-- .../theme-shared/src/lib/contants/styles.ts | 2 +- .../src/lib/theme-shared.module.ts | 18 +++++++++--------- 4 files changed, 15 insertions(+), 13 deletions(-) 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 a9d1f53429..0cdf546ff0 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 @@ -30,7 +30,9 @@ export class LazyLoadService { const key = url ? url.slice(url.lastIndexOf('/') + 1) : uuid(); if (this.loadedLibraries[key]) { - return this.loadedLibraries[key].asObservable(); + subscriber.next(); + subscriber.complete(); + return; } this.loadedLibraries[key] = new ReplaySubject(); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts index 214f2e52de..59c6b3c13d 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts @@ -3,7 +3,7 @@ import { Component, Input } from '@angular/core'; @Component({ selector: 'abp-button', template: ` - `, @@ -13,7 +13,7 @@ export class ButtonComponent { buttonClass = 'btn btn-primary'; @Input() - buttonType = 'button'; + buttonType; // TODO: Add initial value. @Input() iconClass: string; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts b/npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts index c7fa014373..a53bd4573b 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts @@ -38,7 +38,7 @@ export default ` left: 0 !important; width: 100% !important; height: 100% !important; - background-color: rgba(0, 0, 0, .6) !important; + background-color: rgba(0, 0, 0, 0.6) !important; z-index: 1040 !important; } 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 a1839f6217..b4348ca897 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 @@ -32,9 +32,9 @@ export function appendScript(injector: Injector) { 'style', styles, 'head', - 'afterbegin' - ) /* lazyLoadService.load(null, 'script', scripts) */ - ).pipe(take(1)); + 'afterbegin', + ) /* lazyLoadService.load(null, 'script', scripts) */, + ).toPromise(); }; return fn; @@ -53,7 +53,7 @@ export function appendScript(injector: Injector) { ModalComponent, ProfileComponent, TableEmptyMessageComponent, - ToastComponent + ToastComponent, ], exports: [ BreadcrumbComponent, @@ -65,9 +65,9 @@ export function appendScript(injector: Injector) { ModalComponent, ProfileComponent, TableEmptyMessageComponent, - ToastComponent + ToastComponent, ], - entryComponents: [ErrorComponent] + entryComponents: [ErrorComponent], }) export class ThemeSharedModule { static forRoot(): ModuleWithProviders { @@ -78,10 +78,10 @@ export class ThemeSharedModule { provide: APP_INITIALIZER, multi: true, deps: [Injector, ErrorHandler], - useFactory: appendScript + useFactory: appendScript, }, - { provide: MessageService, useClass: MessageService } - ] + { provide: MessageService, useClass: MessageService }, + ], }; } }