Browse Source

Merge pull request #2927 from abpframework/feature/angular-9

feat: updated Angular versions of Angular UI app template to v9
pull/2937/head
Yasin Aydın 7 years ago
committed by GitHub
parent
commit
14e87c6904
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 45
      npm/ng-packs/angular.json
  2. 8
      npm/ng-packs/apps/dev-app/src/app/app.component.ts
  3. 43
      npm/ng-packs/package.json
  4. 5
      npm/ng-packs/packages/account-config/src/lib/services/account-config.service.ts
  5. 2
      npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts
  6. 1
      npm/ng-packs/packages/core/ng-package.json
  7. 7
      npm/ng-packs/packages/core/package.json
  8. 21
      npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
  9. 21
      npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts
  10. 2
      npm/ng-packs/packages/core/src/lib/states/config.state.ts
  11. 2
      npm/ng-packs/packages/core/src/lib/states/profile.state.ts
  12. 2
      npm/ng-packs/packages/core/src/lib/states/replaceable-components.state.ts
  13. 2
      npm/ng-packs/packages/core/src/lib/states/session.state.ts
  14. 2
      npm/ng-packs/packages/feature-management/src/lib/states/feature-management.state.ts
  15. 20
      npm/ng-packs/packages/identity-config/src/lib/services/identity-config.service.ts
  16. 2
      npm/ng-packs/packages/identity/src/lib/states/identity.state.ts
  17. 7
      npm/ng-packs/packages/permission-management/src/lib/states/permission-management.state.ts
  18. 12
      npm/ng-packs/packages/setting-management-config/src/lib/services/setting-management-config.service.ts
  19. 16
      npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.ts
  20. 7
      npm/ng-packs/packages/setting-management/src/lib/states/setting-management.state.ts
  21. 2
      npm/ng-packs/packages/tenant-management/src/lib/states/tenant-management.state.ts
  22. 4
      npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html
  23. 4
      npm/ng-packs/packages/theme-basic/src/lib/constants/styles.ts
  24. 2
      npm/ng-packs/packages/theme-basic/src/lib/states/layout.state.ts
  25. 3
      npm/ng-packs/packages/theme-shared/ng-package.json
  26. 12
      npm/ng-packs/packages/theme-shared/package.json
  27. 3
      npm/ng-packs/packages/theme-shared/src/lib/components/pagination/pagination.component.ts
  28. 17
      npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html
  29. 339
      npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.scss
  30. 18
      npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts
  31. 3
      npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts
  32. 63
      npm/ng-packs/packages/theme-shared/src/lib/tests/pagination.component.spec.ts
  33. 2
      npm/ng-packs/packages/theme-shared/src/lib/tests/table-sort.directive.spec.ts
  34. 2
      npm/ng-packs/packages/theme-shared/src/lib/tests/table.component.spec.ts
  35. 4
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
  36. 59
      npm/ng-packs/scripts/yarn.lock
  37. 3098
      npm/ng-packs/yarn.lock
  38. 6
      templates/app/angular/.gitignore
  39. 4
      templates/app/angular/.prettierrc
  40. 8
      templates/app/angular/.vscode/extensions.json
  41. 62
      templates/app/angular/angular.json
  42. 2
      templates/app/angular/e2e/protractor.conf.js
  43. 2
      templates/app/angular/e2e/src/app.e2e-spec.ts
  44. 8
      templates/app/angular/e2e/src/app.po.ts
  45. 2
      templates/app/angular/karma.conf.js
  46. 70
      templates/app/angular/package.json
  47. 20
      templates/app/angular/src/app/app-routing.module.ts
  48. 68
      templates/app/angular/src/app/app.component.spec.ts
  49. 15
      templates/app/angular/src/app/app.component.ts
  50. 8
      templates/app/angular/src/app/app.module.ts
  51. 51
      templates/app/angular/src/app/home/home.component.spec.ts
  52. 7
      templates/app/angular/src/app/lazy-libs/account-wrapper.module.ts
  53. 7
      templates/app/angular/src/app/lazy-libs/identity-wrapper.module.ts
  54. 7
      templates/app/angular/src/app/lazy-libs/setting-management-wrapper.module.ts
  55. 7
      templates/app/angular/src/app/lazy-libs/tenant-management-wrapper.module.ts
  56. 9
      templates/app/angular/src/app/shared/shared.module.ts
  57. 25
      templates/app/angular/src/environments/environment.hmr.ts
  58. 13
      templates/app/angular/src/environments/environment.prod.ts
  59. 13
      templates/app/angular/src/environments/environment.ts
  60. 13
      templates/app/angular/src/main.ts
  61. 6
      templates/app/angular/src/polyfills.ts
  62. 7
      templates/app/angular/src/test.ts
  63. 6
      templates/app/angular/tsconfig.app.json
  64. 15
      templates/app/angular/tsconfig.json
  65. 3
      templates/app/angular/tslint.json

45
npm/ng-packs/angular.json

@ -56,7 +56,10 @@
"lint": { "lint": {
"builder": "@angular-devkit/build-angular:tslint", "builder": "@angular-devkit/build-angular:tslint",
"options": { "options": {
"tsConfig": ["packages/theme-shared/tsconfig.lib.json", "packages/theme-shared/tsconfig.spec.json"], "tsConfig": [
"packages/theme-shared/tsconfig.lib.json",
"packages/theme-shared/tsconfig.spec.json"
],
"exclude": ["**/node_modules/**"] "exclude": ["**/node_modules/**"]
} }
} }
@ -86,7 +89,10 @@
"lint": { "lint": {
"builder": "@angular-devkit/build-angular:tslint", "builder": "@angular-devkit/build-angular:tslint",
"options": { "options": {
"tsConfig": ["packages/theme-basic/tsconfig.lib.json", "packages/theme-basic/tsconfig.spec.json"], "tsConfig": [
"packages/theme-basic/tsconfig.lib.json",
"packages/theme-basic/tsconfig.spec.json"
],
"exclude": ["**/node_modules/**"] "exclude": ["**/node_modules/**"]
} }
} }
@ -115,7 +121,10 @@
"lint": { "lint": {
"builder": "@angular-devkit/build-angular:tslint", "builder": "@angular-devkit/build-angular:tslint",
"options": { "options": {
"tsConfig": ["packages/account/tsconfig.lib.json", "packages/account/tsconfig.spec.json"], "tsConfig": [
"packages/account/tsconfig.lib.json",
"packages/account/tsconfig.spec.json"
],
"exclude": ["**/node_modules/**"] "exclude": ["**/node_modules/**"]
} }
} }
@ -176,7 +185,10 @@
"lint": { "lint": {
"builder": "@angular-devkit/build-angular:tslint", "builder": "@angular-devkit/build-angular:tslint",
"options": { "options": {
"tsConfig": ["packages/identity/tsconfig.lib.json", "packages/identity/tsconfig.spec.json"], "tsConfig": [
"packages/identity/tsconfig.lib.json",
"packages/identity/tsconfig.spec.json"
],
"exclude": ["**/node_modules/**"] "exclude": ["**/node_modules/**"]
} }
} }
@ -333,7 +345,10 @@
"lint": { "lint": {
"builder": "@angular-devkit/build-angular:tslint", "builder": "@angular-devkit/build-angular:tslint",
"options": { "options": {
"tsConfig": ["packages/identity-config/tsconfig.lib.json", "packages/identity-config/tsconfig.spec.json"], "tsConfig": [
"packages/identity-config/tsconfig.lib.json",
"packages/identity-config/tsconfig.spec.json"
],
"exclude": ["**/node_modules/**"] "exclude": ["**/node_modules/**"]
} }
} }
@ -362,7 +377,10 @@
"lint": { "lint": {
"builder": "@angular-devkit/build-angular:tslint", "builder": "@angular-devkit/build-angular:tslint",
"options": { "options": {
"tsConfig": ["packages/account-config/tsconfig.lib.json", "packages/account-config/tsconfig.spec.json"], "tsConfig": [
"packages/account-config/tsconfig.lib.json",
"packages/account-config/tsconfig.spec.json"
],
"exclude": ["**/node_modules/**"] "exclude": ["**/node_modules/**"]
} }
} }
@ -434,21 +452,6 @@
"input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css", "input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css",
"lazy": true, "lazy": true,
"bundleName": "fontawesome-v4-shims.min" "bundleName": "fontawesome-v4-shims.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": [] "scripts": []

8
npm/ng-packs/apps/dev-app/src/app/app.component.ts

@ -14,13 +14,7 @@ export class AppComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.lazyLoadService this.lazyLoadService
.load( .load(
[ ['fontawesome-all.min.css', 'fontawesome-v4-shims.min.css'],
'primeng.min.css',
'primeicons.css',
'primeng-nova-light-theme.css',
'fontawesome-all.min.css',
'fontawesome-v4-shims.min.css',
],
'style', 'style',
null, null,
'head', 'head',

43
npm/ng-packs/package.json

@ -21,24 +21,23 @@
"generate:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" "generate:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
}, },
"devDependencies": { "devDependencies": {
"@abp/ng.account": "^2.0.1", "@abp/ng.account": "^2.1.0",
"@abp/ng.account.config": "^2.0.1", "@abp/ng.account.config": "^2.1.0",
"@abp/ng.core": "^2.0.1", "@abp/ng.core": "^2.1.0",
"@abp/ng.feature-management": "^2.0.1", "@abp/ng.feature-management": "^2.1.0",
"@abp/ng.identity": "^2.0.1", "@abp/ng.identity": "^2.1.0",
"@abp/ng.identity.config": "^2.0.1", "@abp/ng.identity.config": "^2.1.0",
"@abp/ng.permission-management": "^2.0.1", "@abp/ng.permission-management": "^2.1.0",
"@abp/ng.setting-management": "^2.0.1", "@abp/ng.setting-management": "^2.1.0",
"@abp/ng.setting-management.config": "^2.0.1", "@abp/ng.setting-management.config": "^2.1.0",
"@abp/ng.tenant-management": "^2.0.1", "@abp/ng.tenant-management": "^2.1.0",
"@abp/ng.tenant-management.config": "^2.0.1", "@abp/ng.tenant-management.config": "^2.1.0",
"@abp/ng.theme.basic": "^2.0.1", "@abp/ng.theme.basic": "^2.1.0",
"@abp/ng.theme.shared": "^2.0.1", "@abp/ng.theme.shared": "^2.1.0",
"@angular-builders/jest": "^8.2.0", "@angular-builders/jest": "^8.2.0",
"@angular-devkit/build-angular": "~0.803.21", "@angular-devkit/build-angular": "~0.803.21",
"@angular-devkit/build-ng-packagr": "~0.803.21", "@angular-devkit/build-ng-packagr": "~0.803.21",
"@angular/animations": "~8.2.14", "@angular/animations": "~8.2.14",
"@angular/cdk": "^8.2.3",
"@angular/cli": "~8.3.21", "@angular/cli": "~8.3.21",
"@angular/common": "~8.2.14", "@angular/common": "~8.2.14",
"@angular/compiler": "~8.2.14", "@angular/compiler": "~8.2.14",
@ -46,23 +45,24 @@
"@angular/core": "~8.2.14", "@angular/core": "~8.2.14",
"@angular/forms": "~8.2.14", "@angular/forms": "~8.2.14",
"@angular/language-service": "~8.2.14", "@angular/language-service": "~8.2.14",
"@angular/localize": "~9.0.2",
"@angular/platform-browser": "~8.2.14", "@angular/platform-browser": "~8.2.14",
"@angular/platform-browser-dynamic": "~8.2.14", "@angular/platform-browser-dynamic": "~8.2.14",
"@angular/router": "~8.2.14", "@angular/router": "~8.2.14",
"@fortawesome/fontawesome-free": "^5.11.2", "@fortawesome/fontawesome-free": "^5.12.1",
"@ng-bootstrap/ng-bootstrap": "^5.1.4", "@ng-bootstrap/ng-bootstrap": "^5.3.0",
"@ngneat/spectator": "^4.5.0", "@ngneat/spectator": "^4.5.0",
"@ngx-validate/core": "^0.0.7", "@ngx-validate/core": "^0.0.7",
"@ngxs/devtools-plugin": "^3.5.1", "@ngxs/devtools-plugin": "^3.5.1",
"@ngxs/logger-plugin": "^3.5.1", "@ngxs/logger-plugin": "^3.5.1",
"@ngxs/router-plugin": "^3.5.1", "@ngxs/router-plugin": "^3.6.2",
"@ngxs/storage-plugin": "^3.5.1", "@ngxs/storage-plugin": "^3.6.2",
"@ngxs/store": "^3.5.1", "@ngxs/store": "^3.6.2",
"@types/jest": "^24.0.18", "@types/jest": "^24.0.18",
"@types/node": "~8.9.4", "@types/node": "~8.9.4",
"angular-oauth2-oidc": "^8.0.4", "angular-oauth2-oidc": "^8.0.4",
"bootstrap": "^4.3.1", "bootstrap": "^4.4.1",
"chart.js": "^2.9.2", "chart.js": "^2.9.3",
"codelyzer": "^5.1.2", "codelyzer": "^5.1.2",
"conventional-changelog-cli": "^2.0.31", "conventional-changelog-cli": "^2.0.31",
"cz-conventional-changelog": "3.0.2", "cz-conventional-changelog": "3.0.2",
@ -78,7 +78,6 @@
"ngxs-schematic": "^1.1.9", "ngxs-schematic": "^1.1.9",
"prettier": "^1.18.2", "prettier": "^1.18.2",
"primeicons": "^2.0.0", "primeicons": "^2.0.0",
"primeng": "^8.1.1",
"protractor": "~5.4.0", "protractor": "~5.4.0",
"rxjs": "~6.4.0", "rxjs": "~6.4.0",
"snq": "^1.0.3", "snq": "^1.0.3",

5
npm/ng-packs/packages/account-config/src/lib/services/account-config.service.ts

@ -1,12 +1,11 @@
import { eLayoutType, RestService, addAbpRoutes } from '@abp/ng.core'; import { addAbpRoutes, eLayoutType } from '@abp/ng.core';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class AccountConfigService { export class AccountConfigService {
constructor(private router: Router, private restService: RestService) { constructor() {
addAbpRoutes({ addAbpRoutes({
name: 'AbpAccount::Menu:Account', name: 'AbpAccount::Menu:Account',
path: 'account', path: 'account',

2
npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts

@ -24,7 +24,7 @@ export class ChangePasswordComponent
inProgress: boolean; inProgress: boolean;
mapErrorsFn: Validation.MapErrorsFn = (errors, groupErrors, control) => { mapErrorsFn: Validation.MapErrorsFn = (errors, groupErrors, control) => {
if (PASSWORD_FIELDS.indexOf(control.name) < 0) return errors; if (PASSWORD_FIELDS.indexOf(String(control.name)) < 0) return errors;
return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch')); return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch'));
}; };

1
npm/ng-packs/packages/core/ng-package.json

@ -6,6 +6,7 @@
}, },
"deleteDestPath": false, "deleteDestPath": false,
"whitelistedNonPeerDependencies": [ "whitelistedNonPeerDependencies": [
"@angular/localize",
"@ngxs/router-plugin", "@ngxs/router-plugin",
"@ngxs/storage-plugin", "@ngxs/storage-plugin",
"@ngxs/store", "@ngxs/store",

7
npm/ng-packs/packages/core/package.json

@ -7,9 +7,10 @@
"url": "https://github.com/abpframework/abp.git" "url": "https://github.com/abpframework/abp.git"
}, },
"dependencies": { "dependencies": {
"@ngxs/router-plugin": "^3.5.1", "@angular/localize": "~9.0.2",
"@ngxs/storage-plugin": "^3.5.1", "@ngxs/router-plugin": "^3.6.2",
"@ngxs/store": "^3.5.1", "@ngxs/storage-plugin": "^3.6.2",
"@ngxs/store": "^3.6.2",
"angular-oauth2-oidc": "^8.0.4", "angular-oauth2-oidc": "^8.0.4",
"just-clone": "3.1.0", "just-clone": "3.1.0",
"just-compare": "^1.3.0", "just-compare": "^1.3.0",

21
npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts

@ -1,4 +1,4 @@
import { Component, Input, OnDestroy, Type } from '@angular/core'; import { Component, Input, OnDestroy, Type, Injector } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router, UrlSegment } from '@angular/router'; import { ActivatedRoute, NavigationEnd, Router, UrlSegment } from '@angular/router';
import { Select, Store } from '@ngxs/store'; import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@ -14,8 +14,10 @@ import { takeUntilDestroy } from '../utils/rxjs-utils';
template: ` template: `
<ng-container *ngTemplateOutlet="layout ? componentOutlet : routerOutlet"></ng-container> <ng-container *ngTemplateOutlet="layout ? componentOutlet : routerOutlet"></ng-container>
<ng-template #routerOutlet><router-outlet></router-outlet></ng-template> <ng-template #routerOutlet><router-outlet></router-outlet></ng-template>
<ng-template #componentOutlet><ng-container *ngComponentOutlet="layout"></ng-container></ng-template> <ng-template #componentOutlet
` ><ng-container *ngComponentOutlet="layout"></ng-container
></ng-template>
`,
}) })
export class DynamicLayoutComponent implements OnDestroy { export class DynamicLayoutComponent implements OnDestroy {
@Select(ConfigState.getOne('requirements')) requirements$: Observable<Config.Requirements>; @Select(ConfigState.getOne('requirements')) requirements$: Observable<Config.Requirements>;
@ -25,18 +27,23 @@ export class DynamicLayoutComponent implements OnDestroy {
constructor(private router: Router, private route: ActivatedRoute, private store: Store) { constructor(private router: Router, private route: ActivatedRoute, private store: Store) {
const { const {
requirements: { layouts }, requirements: { layouts },
routes routes,
} = this.store.selectSnapshot(ConfigState.getAll); } = this.store.selectSnapshot(ConfigState.getAll);
if ((this.route.snapshot.data || {}).layout) { if ((this.route.snapshot.data || {}).layout) {
this.layout = layouts this.layout = layouts
.filter(l => !!l) .filter(l => !!l)
.find((l: any) => snq(() => l.type.toLowerCase().indexOf(this.route.snapshot.data.layout), -1) > -1); .find(
(l: any) =>
snq(() => l.type.toLowerCase().indexOf(this.route.snapshot.data.layout), -1) > -1,
);
} }
this.router.events.pipe(takeUntilDestroy(this)).subscribe(event => { router.events.pipe(takeUntilDestroy(this)).subscribe(event => {
if (event instanceof NavigationEnd) { if (event instanceof NavigationEnd) {
const { segments } = this.router.parseUrl(event.url).root.children.primary; const segments = snq(() => router.parseUrl(event.url).root.children.primary.segments, [
{ path: router.url.replace('/', '') },
] as any);
const layout = (this.route.snapshot.data || {}).layout || findLayout(segments, routes); const layout = (this.route.snapshot.data || {}).layout || findLayout(segments, routes);

21
npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts

@ -1,5 +1,11 @@
import { Injectable } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router'; import {
ActivatedRouteSnapshot,
CanActivate,
Router,
RouterStateSnapshot,
UrlTree,
} from '@angular/router';
import { OAuthService } from 'angular-oauth2-oidc'; import { OAuthService } from 'angular-oauth2-oidc';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@ -7,14 +13,19 @@ import { Observable } from 'rxjs';
providedIn: 'root', providedIn: 'root',
}) })
export class AuthGuard implements CanActivate { export class AuthGuard implements CanActivate {
constructor(private oauthService: OAuthService, private router: Router) {} constructor(private oauthService: OAuthService, private injector: Injector) {}
canActivate(
_: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> | boolean | UrlTree {
const router = this.injector.get(Router);
canActivate(_: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean | UrlTree {
const hasValidAccessToken = this.oauthService.hasValidAccessToken(); const hasValidAccessToken = this.oauthService.hasValidAccessToken();
if (hasValidAccessToken) { if (hasValidAccessToken) {
return hasValidAccessToken; return hasValidAccessToken;
} }
return this.router.createUrlTree(['/account/login'], { state: { redirectUrl: state.url } }); return router.createUrlTree(['/account/login'], { state: { redirectUrl: state.url } });
} }
} }

2
npm/ng-packs/packages/core/src/lib/states/config.state.ts

@ -14,11 +14,13 @@ import { Config } from '../models/config';
import { ApplicationConfigurationService } from '../services/application-configuration.service'; import { ApplicationConfigurationService } from '../services/application-configuration.service';
import { organizeRoutes } from '../utils/route-utils'; import { organizeRoutes } from '../utils/route-utils';
import { SessionState } from './session.state'; import { SessionState } from './session.state';
import { Injectable } from '@angular/core';
@State<Config.State>({ @State<Config.State>({
name: 'ConfigState', name: 'ConfigState',
defaults: {} as Config.State, defaults: {} as Config.State,
}) })
@Injectable()
export class ConfigState { export class ConfigState {
@Selector() @Selector()
static getAll(state: Config.State) { static getAll(state: Config.State) {

2
npm/ng-packs/packages/core/src/lib/states/profile.state.ts

@ -3,11 +3,13 @@ import { tap } from 'rxjs/operators';
import { ChangePassword, GetProfile, UpdateProfile } from '../actions/profile.actions'; import { ChangePassword, GetProfile, UpdateProfile } from '../actions/profile.actions';
import { Profile } from '../models/profile'; import { Profile } from '../models/profile';
import { ProfileService } from '../services/profile.service'; import { ProfileService } from '../services/profile.service';
import { Injectable } from '@angular/core';
@State<Profile.State>({ @State<Profile.State>({
name: 'ProfileState', name: 'ProfileState',
defaults: {} as Profile.State, defaults: {} as Profile.State,
}) })
@Injectable()
export class ProfileState { export class ProfileState {
@Selector() @Selector()
static getProfile({ profile }: Profile.State): Profile.Response { static getProfile({ profile }: Profile.State): Profile.Response {

2
npm/ng-packs/packages/core/src/lib/states/replaceable-components.state.ts

@ -2,11 +2,13 @@ import { State, Action, StateContext, Selector, createSelector } from '@ngxs/sto
import { AddReplaceableComponent } from '../actions/replaceable-components.actions'; import { AddReplaceableComponent } from '../actions/replaceable-components.actions';
import { ReplaceableComponents } from '../models/replaceable-components'; import { ReplaceableComponents } from '../models/replaceable-components';
import snq from 'snq'; import snq from 'snq';
import { Injectable } from '@angular/core';
@State<ReplaceableComponents.State>({ @State<ReplaceableComponents.State>({
name: 'ReplaceableComponentsState', name: 'ReplaceableComponentsState',
defaults: { replaceableComponents: [] } as ReplaceableComponents.State, defaults: { replaceableComponents: [] } as ReplaceableComponents.State,
}) })
@Injectable()
export class ReplaceableComponentsState { export class ReplaceableComponentsState {
@Selector() @Selector()
static getAll({ static getAll({

2
npm/ng-packs/packages/core/src/lib/states/session.state.ts

@ -20,11 +20,13 @@ import {
import { ABP, Session } from '../models'; import { ABP, Session } from '../models';
import { LocalizationService } from '../services/localization.service'; import { LocalizationService } from '../services/localization.service';
import { OAuthService } from 'angular-oauth2-oidc'; import { OAuthService } from 'angular-oauth2-oidc';
import { Injectable } from '@angular/core';
@State<Session.State>({ @State<Session.State>({
name: 'SessionState', name: 'SessionState',
defaults: { sessionDetail: { openedTabCount: 0 } } as Session.State, defaults: { sessionDetail: { openedTabCount: 0 } } as Session.State,
}) })
@Injectable()
export class SessionState { export class SessionState {
@Selector() @Selector()
static getLanguage({ language }: Session.State): string { static getLanguage({ language }: Session.State): string {

2
npm/ng-packs/packages/feature-management/src/lib/states/feature-management.state.ts

@ -3,11 +3,13 @@ import { tap } from 'rxjs/operators';
import { GetFeatures, UpdateFeatures } from '../actions/feature-management.actions'; import { GetFeatures, UpdateFeatures } from '../actions/feature-management.actions';
import { FeatureManagement } from '../models/feature-management'; import { FeatureManagement } from '../models/feature-management';
import { FeatureManagementService } from '../services/feature-management.service'; import { FeatureManagementService } from '../services/feature-management.service';
import { Injectable } from '@angular/core';
@State<FeatureManagement.State>({ @State<FeatureManagement.State>({
name: 'FeatureManagementState', name: 'FeatureManagementState',
defaults: { features: {} } as FeatureManagement.State, defaults: { features: {} } as FeatureManagement.State,
}) })
@Injectable()
export class FeatureManagementState { export class FeatureManagementState {
@Selector() @Selector()
static getFeatures({ features }: FeatureManagement.State) { static getFeatures({ features }: FeatureManagement.State) {

20
npm/ng-packs/packages/identity-config/src/lib/services/identity-config.service.ts

@ -1,13 +1,11 @@
import { addAbpRoutes, eLayoutType, RestService } from '@abp/ng.core'; import { addAbpRoutes, eLayoutType } from '@abp/ng.core';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class IdentityConfigService { export class IdentityConfigService {
constructor(private router: Router, private restService: RestService) { constructor() {
addAbpRoutes([ addAbpRoutes([
{ {
name: 'AbpUiNavigation::Menu:Administration', name: 'AbpUiNavigation::Menu:Administration',
@ -24,8 +22,18 @@ export class IdentityConfigService {
layout: eLayoutType.application, layout: eLayoutType.application,
iconClass: 'fa fa-id-card-o', iconClass: 'fa fa-id-card-o',
children: [ children: [
{ path: 'roles', name: 'AbpIdentity::Roles', order: 1, requiredPolicy: 'AbpIdentity.Roles' }, {
{ path: 'users', name: 'AbpIdentity::Users', order: 2, requiredPolicy: 'AbpIdentity.Users' }, path: 'roles',
name: 'AbpIdentity::Roles',
order: 1,
requiredPolicy: 'AbpIdentity.Roles',
},
{
path: 'users',
name: 'AbpIdentity::Users',
order: 2,
requiredPolicy: 'AbpIdentity.Users',
},
], ],
}, },
]); ]);

2
npm/ng-packs/packages/identity/src/lib/states/identity.state.ts

@ -15,11 +15,13 @@ import {
} from '../actions/identity.actions'; } from '../actions/identity.actions';
import { Identity } from '../models/identity'; import { Identity } from '../models/identity';
import { IdentityService } from '../services/identity.service'; import { IdentityService } from '../services/identity.service';
import { Injectable } from '@angular/core';
@State<Identity.State>({ @State<Identity.State>({
name: 'IdentityState', name: 'IdentityState',
defaults: { roles: {}, selectedRole: {}, users: {}, selectedUser: {} } as Identity.State, defaults: { roles: {}, selectedRole: {}, users: {}, selectedUser: {} } as Identity.State,
}) })
@Injectable()
export class IdentityState { export class IdentityState {
@Selector() @Selector()
static getRoles({ roles }: Identity.State): Identity.RoleItem[] { static getRoles({ roles }: Identity.State): Identity.RoleItem[] {

7
npm/ng-packs/packages/permission-management/src/lib/states/permission-management.state.ts

@ -3,11 +3,13 @@ import { GetPermissions, UpdatePermissions } from '../actions/permission-managem
import { PermissionManagement } from '../models/permission-management'; import { PermissionManagement } from '../models/permission-management';
import { PermissionManagementService } from '../services/permission-management.service'; import { PermissionManagementService } from '../services/permission-management.service';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
@State<PermissionManagement.State>({ @State<PermissionManagement.State>({
name: 'PermissionManagementState', name: 'PermissionManagementState',
defaults: { permissionRes: {} } as PermissionManagement.State, defaults: { permissionRes: {} } as PermissionManagement.State,
}) })
@Injectable()
export class PermissionManagementState { export class PermissionManagementState {
@Selector() @Selector()
static getPermissionGroups({ permissionRes }: PermissionManagement.State) { static getPermissionGroups({ permissionRes }: PermissionManagement.State) {
@ -22,7 +24,10 @@ export class PermissionManagementState {
constructor(private permissionManagementService: PermissionManagementService) {} constructor(private permissionManagementService: PermissionManagementService) {}
@Action(GetPermissions) @Action(GetPermissions)
permissionManagementGet({ patchState }: StateContext<PermissionManagement.State>, { payload }: GetPermissions) { permissionManagementGet(
{ patchState }: StateContext<PermissionManagement.State>,
{ payload }: GetPermissions,
) {
return this.permissionManagementService.getPermissions(payload).pipe( return this.permissionManagementService.getPermissions(payload).pipe(
tap(permissionResponse => tap(permissionResponse =>
patchState({ patchState({

12
npm/ng-packs/packages/setting-management-config/src/lib/services/setting-management-config.service.ts

@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { addAbpRoutes, eLayoutType, PatchRouteByName, ABP } from '@abp/ng.core'; import { addAbpRoutes, eLayoutType, PatchRouteByName, ABP } from '@abp/ng.core';
import { getSettingTabs } from '@abp/ng.theme.shared'; import { getSettingTabs } from '@abp/ng.theme.shared';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
@ -7,7 +7,11 @@ import { Store } from '@ngxs/store';
providedIn: 'root', providedIn: 'root',
}) })
export class SettingManagementConfigService { export class SettingManagementConfigService {
constructor(private store: Store) { get store(): Store {
return this.injector.get(Store);
}
constructor(private injector: Injector) {
const route = { const route = {
name: 'AbpSettingManagement::Settings', name: 'AbpSettingManagement::Settings',
path: 'setting-management', path: 'setting-management',
@ -23,7 +27,9 @@ export class SettingManagementConfigService {
setTimeout(() => { setTimeout(() => {
const tabs = getSettingTabs(); const tabs = getSettingTabs();
if (!tabs || !tabs.length) { if (!tabs || !tabs.length) {
this.store.dispatch(new PatchRouteByName('AbpSettingManagement::Settings', { ...route, invisible: true })); this.store.dispatch(
new PatchRouteByName('AbpSettingManagement::Settings', { ...route, invisible: true }),
);
} }
}); });
} }

16
npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.ts

@ -1,11 +1,9 @@
import { Component, TrackByFunction, OnInit } from '@angular/core';
import { SettingTab, getSettingTabs } from '@abp/ng.theme.shared';
import { Router } from '@angular/router';
import { Store } from '@ngxs/store';
import { ConfigState } from '@abp/ng.core'; import { ConfigState } from '@abp/ng.core';
import { SettingManagementState } from '../states/setting-management.state'; import { getSettingTabs, SettingTab } from '@abp/ng.theme.shared';
import { Component, OnInit, TrackByFunction } from '@angular/core';
import { Store } from '@ngxs/store';
import { SetSelectedSettingTab } from '../actions/setting-management.actions'; import { SetSelectedSettingTab } from '../actions/setting-management.actions';
import { RouterState } from '@ngxs/router-plugin'; import { SettingManagementState } from '../states/setting-management.state';
@Component({ @Component({
selector: 'abp-setting-management', selector: 'abp-setting-management',
@ -29,11 +27,13 @@ export class SettingManagementComponent implements OnInit {
trackByFn: TrackByFunction<SettingTab> = (_, item) => item.name; trackByFn: TrackByFunction<SettingTab> = (_, item) => item.name;
constructor(private router: Router, private store: Store) {} constructor(private store: Store) {}
ngOnInit() { ngOnInit() {
this.settings = getSettingTabs() this.settings = getSettingTabs()
.filter(setting => this.store.selectSnapshot(ConfigState.getGrantedPolicy(setting.requiredPolicy))) .filter(setting =>
this.store.selectSnapshot(ConfigState.getGrantedPolicy(setting.requiredPolicy)),
)
.sort((a, b) => a.order - b.order); .sort((a, b) => a.order - b.order);
if (!this.selected && this.settings.length) { if (!this.selected && this.settings.length) {

7
npm/ng-packs/packages/setting-management/src/lib/states/setting-management.state.ts

@ -1,11 +1,13 @@
import { Action, Selector, State, StateContext } from '@ngxs/store'; import { Action, Selector, State, StateContext } from '@ngxs/store';
import { SetSelectedSettingTab } from '../actions/setting-management.actions'; import { SetSelectedSettingTab } from '../actions/setting-management.actions';
import { SettingManagement } from '../models/setting-management'; import { SettingManagement } from '../models/setting-management';
import { Injectable } from '@angular/core';
@State<SettingManagement.State>({ @State<SettingManagement.State>({
name: 'SettingManagementState', name: 'SettingManagementState',
defaults: { selectedTab: {} } as SettingManagement.State, defaults: { selectedTab: {} } as SettingManagement.State,
}) })
@Injectable()
export class SettingManagementState { export class SettingManagementState {
@Selector() @Selector()
static getSelectedTab({ selectedTab }: SettingManagement.State) { static getSelectedTab({ selectedTab }: SettingManagement.State) {
@ -13,7 +15,10 @@ export class SettingManagementState {
} }
@Action(SetSelectedSettingTab) @Action(SetSelectedSettingTab)
settingManagementAction({ patchState }: StateContext<SettingManagement.State>, { payload }: SetSelectedSettingTab) { settingManagementAction(
{ patchState }: StateContext<SettingManagement.State>,
{ payload }: SetSelectedSettingTab,
) {
patchState({ patchState({
selectedTab: payload, selectedTab: payload,
}); });

2
npm/ng-packs/packages/tenant-management/src/lib/states/tenant-management.state.ts

@ -10,11 +10,13 @@ import {
} from '../actions/tenant-management.actions'; } from '../actions/tenant-management.actions';
import { TenantManagement } from '../models/tenant-management'; import { TenantManagement } from '../models/tenant-management';
import { TenantManagementService } from '../services/tenant-management.service'; import { TenantManagementService } from '../services/tenant-management.service';
import { Injectable } from '@angular/core';
@State<TenantManagement.State>({ @State<TenantManagement.State>({
name: 'TenantManagementState', name: 'TenantManagementState',
defaults: { result: {}, selectedItem: {} } as TenantManagement.State, defaults: { result: {}, selectedItem: {} } as TenantManagement.State,
}) })
@Injectable()
export class TenantManagementState { export class TenantManagementState {
@Selector() @Selector()
static get({ result }: TenantManagement.State): ABP.BasicItem[] { static get({ result }: TenantManagement.State): ABP.BasicItem[] {

4
npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html

@ -147,7 +147,9 @@
</nav> </nav>
<div <div
[@slideFromBottom]="outlet && outlet.activatedRoute && outlet.activatedRoute.routeConfig.path" [@slideFromBottom]="
outlet && outlet.isActivated && outlet.activatedRoute && outlet.activatedRoute.routeConfig.path
"
class="container" class="container"
> >
<router-outlet #outlet="outlet"></router-outlet> <router-outlet #outlet="outlet"></router-outlet>

4
npm/ng-packs/packages/theme-basic/src/lib/constants/styles.ts

@ -123,4 +123,8 @@ background-color: rgba(0, 0, 0, 0.6);
.confirmation .confirmation-dialog .footer .confirmation-button--confirm:hover { .confirmation .confirmation-dialog .footer .confirmation-button--confirm:hover {
background-color: #2e819b; background-color: #2e819b;
} }
.ui-table .pagination-wrapper {
background-color: #f4f4f4;
border: 1px solid #c8c8c8;
}
`; `;

2
npm/ng-packs/packages/theme-basic/src/lib/states/layout.state.ts

@ -2,11 +2,13 @@ import { Action, Selector, State, StateContext } from '@ngxs/store';
import snq from 'snq'; import snq from 'snq';
import { AddNavigationElement, RemoveNavigationElementByName } from '../actions/layout.actions'; import { AddNavigationElement, RemoveNavigationElementByName } from '../actions/layout.actions';
import { Layout } from '../models/layout'; import { Layout } from '../models/layout';
import { Injectable } from '@angular/core';
@State<Layout.State>({ @State<Layout.State>({
name: 'LayoutState', name: 'LayoutState',
defaults: { navigationElements: [] } as Layout.State, defaults: { navigationElements: [] } as Layout.State,
}) })
@Injectable()
export class LayoutState { export class LayoutState {
@Selector() @Selector()
static getNavigationElements({ navigationElements }: Layout.State): Layout.NavigationElement[] { static getNavigationElements({ navigationElements }: Layout.State): Layout.NavigationElement[] {

3
npm/ng-packs/packages/theme-shared/ng-package.json

@ -6,14 +6,11 @@
}, },
"whitelistedNonPeerDependencies": [ "whitelistedNonPeerDependencies": [
"@abp/ng.core", "@abp/ng.core",
"@angular/cdk",
"@fortawesome/fontawesome-free", "@fortawesome/fontawesome-free",
"@ng-bootstrap/ng-bootstrap", "@ng-bootstrap/ng-bootstrap",
"@ngx-validate/core", "@ngx-validate/core",
"bootstrap", "bootstrap",
"font-awesome", "font-awesome",
"primeicons",
"primeng",
"chart.js" "chart.js"
] ]
} }

12
npm/ng-packs/packages/theme-shared/package.json

@ -8,15 +8,11 @@
}, },
"dependencies": { "dependencies": {
"@abp/ng.core": "^2.1.0", "@abp/ng.core": "^2.1.0",
"@angular/cdk": "^8.2.3", "@fortawesome/fontawesome-free": "^5.12.1",
"@fortawesome/fontawesome-free": "^5.11.2", "@ng-bootstrap/ng-bootstrap": "^5.3.0",
"@ng-bootstrap/ng-bootstrap": "^5.1.4",
"@ngx-validate/core": "^0.0.7", "@ngx-validate/core": "^0.0.7",
"bootstrap": "^4.3.1", "bootstrap": "^4.4.1",
"chart.js": "^2.9.2", "chart.js": "^2.9.3"
"font-awesome": "^4.7.0",
"primeicons": "^2.0.0",
"primeng": "^8.1.1"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

3
npm/ng-packs/packages/theme-shared/src/lib/components/pagination/pagination.component.ts

@ -4,6 +4,9 @@ import { Component, Input, OnInit, Output, EventEmitter, TrackByFunction } from
selector: 'abp-pagination', selector: 'abp-pagination',
templateUrl: 'pagination.component.html', templateUrl: 'pagination.component.html',
}) })
/**
* @deprecated
*/
export class PaginationComponent implements OnInit { export class PaginationComponent implements OnInit {
private _value = 1; private _value = 1;
@Input() @Input()

17
npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html

@ -3,12 +3,17 @@
<ng-container <ng-container
*ngTemplateOutlet="scrollable ? scrollableTemplate : defaultTemplate" *ngTemplateOutlet="scrollable ? scrollableTemplate : defaultTemplate"
></ng-container> ></ng-container>
<abp-pagination <div class="pagination-wrapper">
*ngIf="rows" <ngb-pagination
[totalPages]="totalPages" [class.op-0]="!totalPages"
[(value)]="page" [collectionSize]="totalPages"
(valueChange)="pageChange.emit($event)" [pageSize]="1"
></abp-pagination> [page]="page"
(pageChange)="pageChange.emit($event)"
[maxSize]="3"
[rotate]="true"
></ngb-pagination>
</div>
</div> </div>
</div> </div>

339
npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.scss

@ -0,0 +1,339 @@
.ui-table {
position: relative;
.ui-table-tbody > tr:nth-child(even):hover,
.ui-table-tbody > tr:hover {
filter: brightness(90%);
}
.ui-table-tbody > tr.empty-row:hover {
filter: none;
}
.ui-table-tbody > tr.empty-row > div.empty-row-content {
padding: 10px;
text-align: center;
}
.ui-table-caption,
.ui-table-summary {
background-color: #f4f4f4;
color: #333333;
border: 1px solid #c8c8c8;
padding: 0.571em 1em;
text-align: center;
}
.ui-table-caption {
border-bottom: 0 none;
font-weight: 700;
}
.ui-table-summary {
border-top: 0 none;
font-weight: 700;
}
.ui-table-thead > tr > th {
padding: 0.571em 0.857em;
border: 1px solid #c8c8c8;
font-weight: 700;
color: #333333;
background-color: #f4f4f4;
}
.ui-table-tbody > tr > td {
padding: 0.571em 0.857em;
}
.ui-table-tfoot > tr > td {
padding: 0.571em 0.857em;
border: 1px solid #c8c8c8;
font-weight: 700;
color: #333333;
background-color: #ffffff;
}
.ui-sortable-column {
-moz-transition: box-shadow 0.2s;
-o-transition: box-shadow 0.2s;
-webkit-transition: box-shadow 0.2s;
transition: box-shadow 0.2s;
}
.ui-sortable-column:focus {
outline: 0 none;
outline-offset: 0;
-webkit-box-shadow: inset 0 0 0 0.2em #8dcdff;
-moz-box-shadow: inset 0 0 0 0.2em #8dcdff;
box-shadow: inset 0 0 0 0.2em #8dcdff;
}
.ui-sortable-column .ui-sortable-column-icon {
color: #848484;
}
.ui-sortable-column:not(.ui-state-highlight):hover {
background-color: #e0e0e0;
color: #333333;
}
.ui-sortable-column:not(.ui-state-highlight):hover .ui-sortable-column-icon {
color: #333333;
}
.ui-sortable-column.ui-state-highlight {
background-color: #007ad9;
color: #ffffff;
}
.ui-sortable-column.ui-state-highlight .ui-sortable-column-icon {
color: #ffffff;
}
.ui-editable-column input {
font-size: 14px;
font-family: 'Open Sans', 'Helvetica Neue', sans-serif;
}
.ui-editable-column input:focus {
outline: 1px solid #007ad9;
outline-offset: 2px;
}
.ui-table-tbody > tr {
background-color: #ffffff;
color: #333333;
}
.ui-table-tbody > tr > td {
background-color: inherit;
border: 1px solid #c8c8c8;
}
.ui-table-tbody > tr.ui-state-highlight {
background-color: #007ad9;
color: #ffffff;
}
.ui-table-tbody > tr.ui-state-highlight a {
color: #ffffff;
}
.ui-table-tbody > tr.ui-contextmenu-selected {
background-color: #007ad9;
color: #ffffff;
}
.ui-table-tbody > tr.ui-table-dragpoint-top > td {
-webkit-box-shadow: inset 0 2px 0 0 #007ad9;
-moz-box-shadow: inset 0 2px 0 0 #007ad9;
box-shadow: inset 0 2px 0 0 #007ad9;
}
.ui-table-tbody > tr.ui-table-dragpoint-bottom > td {
-webkit-box-shadow: inset 0 -2px 0 0 #007ad9;
-moz-box-shadow: inset 0 -2px 0 0 #007ad9;
box-shadow: inset 0 -2px 0 0 #007ad9;
}
.ui-table-tbody > tr:nth-child(even) {
background-color: #f9f9f9;
}
.ui-table-tbody > tr:nth-child(even).ui-state-highlight {
background-color: #007ad9;
color: #ffffff;
}
.ui-table-tbody > tr:nth-child(even).ui-state-highlight a {
color: #ffffff;
}
.ui-table-tbody > tr:nth-child(even).ui-contextmenu-selected {
background-color: #007ad9;
color: #ffffff;
}
&.ui-table-hoverable-rows
.ui-table-tbody
> tr.ui-selectable-row:not(.ui-state-highlight):not(.ui-contextmenu-selected):hover {
cursor: pointer;
background-color: #eaeaea;
color: #333333;
}
.ui-column-resizer-helper {
background-color: #007ad9;
}
@media screen and (max-width: 40em) {
&.ui-table-responsive .ui-table-tbody > tr > td {
border: 0 none;
}
}
table {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
}
.ui-table-tbody > tr > td,
.ui-table-tfoot > tr > td,
.ui-table-thead > tr > th {
padding: 0.571em 0.857em;
}
.ui-sortable-column {
cursor: pointer;
}
p-sorticon {
vertical-align: middle;
}
.ui-table-auto-layout > .ui-table-wrapper {
overflow-x: auto;
}
.ui-table-auto-layout > .ui-table-wrapper > table {
table-layout: auto;
}
.ui-table-caption,
.ui-table-summary {
padding: 0.25em 0.5em;
text-align: center;
font-weight: 700;
}
.ui-table-caption {
border-bottom: 0;
}
.ui-table-summary {
border-top: 0;
}
.ui-table-scrollable-wrapper {
position: relative;
}
.ui-table-scrollable-footer,
.ui-table-scrollable-header {
overflow: hidden;
border: 0;
}
.ui-table-scrollable-body {
overflow: auto;
position: relative;
}
.ui-table-virtual-table {
position: absolute;
}
.ui-table-loading-virtual-table {
display: none;
}
.ui-table-frozen-view .ui-table-scrollable-body {
overflow: hidden;
}
.ui-table-frozen-view > .ui-table-scrollable-body > table > .ui-table-tbody > tr > td:last-child {
border-right: 0;
}
.ui-table-unfrozen-view {
position: absolute;
top: 0;
}
.ui-table-resizable > .ui-table-wrapper {
overflow-x: auto;
}
.ui-table-resizable .ui-table-tbody > tr > td,
.ui-table-resizable .ui-table-tfoot > tr > td,
.ui-table-resizable .ui-table-thead > tr > th {
overflow: hidden;
}
.ui-table-resizable .ui-resizable-column {
background-clip: padding-box;
position: relative;
}
.ui-table-resizable-fit .ui-resizable-column:last-child .ui-column-resizer {
display: none;
}
.ui-column-resizer {
display: block;
position: absolute !important;
top: 0;
right: 0;
margin: 0;
width: 0.5em;
height: 100%;
padding: 0;
cursor: col-resize;
border: 1px solid rgba(0, 0, 0, 0);
}
.ui-column-resizer-helper {
width: 1px;
position: absolute;
z-index: 10;
display: none;
}
.ui-table-tbody > tr > td.ui-editing-cell {
padding: 0;
}
.ui-table-tbody > tr > td.ui-editing-cell p-celleditor > * {
width: 100%;
}
.ui-table-reorder-indicator-down,
.ui-table-reorder-indicator-up {
position: absolute;
display: none;
}
.ui-table-responsive .ui-table-tbody > tr > td .ui-column-title {
display: none;
}
@media screen and (max-width: 40em) {
.ui-table-responsive .ui-table-tfoot > tr > td,
.ui-table-responsive .ui-table-thead > tr > th,
.ui-table-responsive colgroup {
display: none !important;
}
.ui-table-responsive .ui-table-tbody > tr > td {
text-align: left;
display: block;
border: 0;
width: 100% !important;
box-sizing: border-box;
float: left;
clear: left;
}
.ui-table-responsive .ui-table-tbody > tr > td .ui-column-title {
padding: 0.4em;
min-width: 30%;
display: inline-block;
margin: -0.4em 1em -0.4em -0.4em;
font-weight: 700;
}
}
.ui-widget {
font-family: 'Open Sans', 'Helvetica Neue', sans-serif;
font-size: 14px;
text-decoration: none;
}
.page-item.disabled .page-link,
.page-link {
background-color: transparent;
border: none;
}
.page-item.disabled .page-link {
box-shadow: none;
}
.pagination {
margin-bottom: 0;
}
.pagination-wrapper {
display: flex;
justify-content: center;
border-top: 0;
padding: 0;
}
.op-0 {
opacity: 0;
}
}

18
npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts

@ -14,23 +14,7 @@ import {
@Component({ @Component({
selector: 'abp-table', selector: 'abp-table',
templateUrl: 'table.component.html', templateUrl: 'table.component.html',
styles: [ styleUrls: ['table.component.scss'],
`
.ui-table .ui-table-tbody > tr:nth-child(even):hover,
.ui-table .ui-table-tbody > tr:hover {
filter: brightness(90%);
}
.ui-table .ui-table-tbody > tr.empty-row:hover {
filter: none;
}
.ui-table .ui-table-tbody > tr.empty-row > div.empty-row-content {
padding: 10px;
text-align: center;
}
`,
],
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
}) })
export class TableComponent { export class TableComponent {

3
npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts

@ -220,11 +220,12 @@ export class ErrorHandler {
.resolveComponentFactory(HttpErrorWrapperComponent) .resolveComponentFactory(HttpErrorWrapperComponent)
.create(this.injector); .create(this.injector);
for (const key in this.componentRef.instance) { for (const key in instance) {
if (this.componentRef.instance.hasOwnProperty(key)) { if (this.componentRef.instance.hasOwnProperty(key)) {
this.componentRef.instance[key] = instance[key]; this.componentRef.instance[key] = instance[key];
} }
} }
this.componentRef.instance.hideCloseIcon = this.httpErrorConfig.errorScreen.hideCloseIcon; this.componentRef.instance.hideCloseIcon = this.httpErrorConfig.errorScreen.hideCloseIcon;
if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) { if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) {
this.componentRef.instance.cfRes = this.cfRes; this.componentRef.instance.cfRes = this.cfRes;

63
npm/ng-packs/packages/theme-shared/src/lib/tests/pagination.component.spec.ts

@ -1,63 +0,0 @@
import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest';
import { PaginationComponent } from '../components';
describe('PaginationComponent', () => {
let spectator: SpectatorHost<PaginationComponent>;
const createHost = createHostFactory({
component: PaginationComponent,
});
beforeEach(() => {
spectator = createHost(
'<abp-pagination [totalPages]="totalPages" [value]="value"></abp-pagination>',
{
hostProps: {
value: 5,
totalPages: 12,
},
},
);
});
it('should add ui-state-active class to current page', () => {
expect(spectator.query('.ui-state-active').textContent).toBe('5');
});
it('should display the correct pages', () => {
expect(spectator.queryAll('.ui-paginator-page').map(node => node.textContent)).toEqual([
'3',
'4',
'5',
'6',
'7',
]);
spectator.click('.ui-paginator-first');
expect(spectator.queryAll('.ui-paginator-page').map(node => node.textContent)).toEqual([
'1',
'2',
'3',
'4',
'5',
]);
spectator.setHostInput({ value: 12 });
expect(spectator.queryAll('.ui-paginator-page').map(node => node.textContent)).toEqual([
'8',
'9',
'10',
'11',
'12',
]);
spectator.setHostInput({ value: 1, totalPages: 3 });
expect(spectator.queryAll('.ui-paginator-page').map(node => node.textContent)).toEqual([
'1',
'2',
'3',
]);
});
});

2
npm/ng-packs/packages/theme-shared/src/lib/tests/table-sort.directive.spec.ts

@ -3,6 +3,7 @@ import { TableSortDirective } from '../directives/table-sort.directive';
import { TableComponent } from '../components/table/table.component'; import { TableComponent } from '../components/table/table.component';
import { DummyLocalizationPipe } from './table.component.spec'; import { DummyLocalizationPipe } from './table.component.spec';
import { PaginationComponent } from '../components'; import { PaginationComponent } from '../components';
import { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';
describe('TableSortDirective', () => { describe('TableSortDirective', () => {
let spectator: SpectatorDirective<TableSortDirective>; let spectator: SpectatorDirective<TableSortDirective>;
@ -10,6 +11,7 @@ describe('TableSortDirective', () => {
const createDirective = createDirectiveFactory({ const createDirective = createDirectiveFactory({
directive: TableSortDirective, directive: TableSortDirective,
declarations: [TableComponent, DummyLocalizationPipe, PaginationComponent], declarations: [TableComponent, DummyLocalizationPipe, PaginationComponent],
imports: [NgbPaginationModule],
}); });
beforeEach(() => { beforeEach(() => {

2
npm/ng-packs/packages/theme-shared/src/lib/tests/table.component.spec.ts

@ -2,6 +2,7 @@ import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest';
import { PaginationComponent, TableComponent } from '../components'; import { PaginationComponent, TableComponent } from '../components';
import { Pipe, PipeTransform } from '@angular/core'; import { Pipe, PipeTransform } from '@angular/core';
import { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';
@Pipe({ @Pipe({
name: 'abpLocalization', name: 'abpLocalization',
@ -17,6 +18,7 @@ describe('TableComponent', () => {
const createHost = createHostFactory({ const createHost = createHostFactory({
component: TableComponent, component: TableComponent,
declarations: [PaginationComponent, DummyLocalizationPipe], declarations: [PaginationComponent, DummyLocalizationPipe],
imports: [NgbPaginationModule],
}); });
describe('without value', () => { describe('without value', () => {

4
npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

@ -1,7 +1,7 @@
import { CoreModule, LazyLoadService } from '@abp/ng.core'; import { CoreModule, LazyLoadService } from '@abp/ng.core';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core'; import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core';
import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap'; import { NgbDateParserFormatter, NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxValidateCoreModule } from '@ngx-validate/core'; import { NgxValidateCoreModule } from '@ngx-validate/core';
import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component'; import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component';
import { ButtonComponent } from './components/button/button.component'; import { ButtonComponent } from './components/button/button.component';
@ -38,7 +38,7 @@ export function appendScript(injector: Injector) {
} }
@NgModule({ @NgModule({
imports: [CoreModule, NgxValidateCoreModule], imports: [CoreModule, NgxValidateCoreModule, NgbPaginationModule],
declarations: [ declarations: [
BreadcrumbComponent, BreadcrumbComponent,
ButtonComponent, ButtonComponent,

59
npm/ng-packs/scripts/yarn.lock

@ -3,9 +3,9 @@
"@types/fs-extra@^8.0.1": "@types/fs-extra@^8.0.1":
version "8.0.1" version "8.1.0"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.0.1.tgz#a2378d6e7e8afea1564e44aafa2e207dadf77686" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.0.tgz#1114834b53c3914806cd03b3304b37b3bd221a4d"
integrity sha512-J00cVDALmi/hJOYsunyT52Hva5TnJeKP5yd1r+mH/ZU0mbYZflR0Z5kw5kITtKTRYMhm1JMClOFYdHnQszEvqw== integrity sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
@ -14,15 +14,10 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/node@*": "@types/node@*", "@types/node@^13.1.2":
version "13.7.1" version "13.7.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.1.tgz#238eb34a66431b71d2aaddeaa7db166f25971a0d" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.6.tgz#cb734a7c191472ae6a2b3a502b4dfffcea974113"
integrity sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA== integrity sha512-eyK7MWD0R1HqVTp+PtwRgFeIsemzuj4gBFSQxfPHY5iMjS7474e5wq+VFgTcdpyHeNxyKSaetYAjdMLJlKoWqA==
"@types/node@^13.1.2":
version "13.1.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.1.2.tgz#fe94285bf5e0782e1a9e5a8c482b1c34465fa385"
integrity sha512-B8emQA1qeKerqd1dmIsQYnXi+mmAzTB7flExjmy5X1aVAKFNNNDubkavwR13kR6JnpeLp3aLoJhwn9trWPAyFQ==
ansi-bgblack@^0.1.1: ansi-bgblack@^0.1.1:
version "0.1.1" version "0.1.1"
@ -260,9 +255,9 @@ ansi-yellow@^0.1.1:
ansi-wrap "0.1.0" ansi-wrap "0.1.0"
arg@^4.1.0: arg@^4.1.0:
version "4.1.2" version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.2.tgz#e70c90579e02c63d80e3ad4e31d8bfdb8bd50064" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg== integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
arr-flatten@^1.1.0: arr-flatten@^1.1.0:
version "1.1.0" version "1.1.0"
@ -490,9 +485,9 @@ define-property@^2.0.2:
isobject "^3.0.1" isobject "^3.0.1"
diff@^4.0.1: diff@^4.0.1:
version "4.0.1" version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
end-of-stream@^1.1.0: end-of-stream@^1.1.0:
version "1.4.4" version "1.4.4"
@ -742,9 +737,9 @@ kind-of@^5.0.0, kind-of@^5.0.2:
integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==
kind-of@^6.0.0, kind-of@^6.0.2: kind-of@^6.0.0, kind-of@^6.0.2:
version "6.0.2" version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
koalas@^1.0.2: koalas@^1.0.2:
version "1.0.2" version "1.0.2"
@ -792,9 +787,9 @@ loose-envify@^1.0.0:
js-tokens "^3.0.0 || ^4.0.0" js-tokens "^3.0.0 || ^4.0.0"
make-error@^1.1.1: make-error@^1.1.1:
version "1.3.5" version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
map-visit@^1.0.0: map-visit@^1.0.0:
version "1.0.0" version "1.0.0"
@ -1154,15 +1149,15 @@ toggle-array@^1.0.1:
isobject "^3.0.0" isobject "^3.0.0"
ts-node@^8.5.4: ts-node@^8.5.4:
version "8.5.4" version "8.6.2"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.5.4.tgz#a152add11fa19c221d0b48962c210cf467262ab2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.6.2.tgz#7419a01391a818fbafa6f826a33c1a13e9464e35"
integrity sha512-izbVCRV68EasEPQ8MSIGBNK9dc/4sYJJKYA+IarMQct1RtEot6Xp0bXuClsbUSnKpg50ho+aOAx8en5c+y4OFw== integrity sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==
dependencies: dependencies:
arg "^4.1.0" arg "^4.1.0"
diff "^4.0.1" diff "^4.0.1"
make-error "^1.1.1" make-error "^1.1.1"
source-map-support "^0.5.6" source-map-support "^0.5.6"
yn "^3.0.0" yn "3.1.1"
tsconfig-paths@^3.9.0: tsconfig-paths@^3.9.0:
version "3.9.0" version "3.9.0"
@ -1175,9 +1170,9 @@ tsconfig-paths@^3.9.0:
strip-bom "^3.0.0" strip-bom "^3.0.0"
typescript@^3.7.4: typescript@^3.7.4:
version "3.7.4" version "3.8.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.4.tgz#1743a5ec5fef6a1fa9f3e4708e33c81c73876c19" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.2.tgz#91d6868aaead7da74f493c553aeff76c0c0b1d5a"
integrity sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw== integrity sha512-EgOVgL/4xfVrCMbhYKUQTdF37SQn4Iw73H5BgCrF1Abdun7Kwy/QZsE/ssAy0y4LxBbvua3PIbFsbRczWWnDdQ==
universalify@^0.1.0: universalify@^0.1.0:
version "0.1.2" version "0.1.2"
@ -1209,7 +1204,7 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
yn@^3.0.0: yn@3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==

3098
npm/ng-packs/yarn.lock

File diff suppressed because it is too large

6
templates/app/angular/.gitignore

@ -11,8 +11,8 @@
/node_modules /node_modules
# profiling files # profiling files
chrome-profiler-events.json chrome-profiler-events*.json
speed-measure-plugin.json speed-measure-plugin*.json
# IDEs and editors # IDEs and editors
/.idea /.idea
@ -45,4 +45,4 @@ testem.log
.DS_Store .DS_Store
Thumbs.db Thumbs.db
yarn.lock* yarn.lock

4
templates/app/angular/.prettierrc

@ -0,0 +1,4 @@
{
"singleQuote": true,
"printWidth": 100
}

8
templates/app/angular/.vscode/extensions.json

@ -0,0 +1,8 @@
{
"recommendations": [
"angular.ng-template",
"esbenp.prettier-vscode",
"ms-vscode.vscode-typescript-tslint-plugin",
"visualstudioexptteam.vscodeintellicode"
]
}

62
templates/app/angular/angular.json

@ -3,7 +3,7 @@
"version": 1, "version": 1,
"newProjectRoot": "projects", "newProjectRoot": "projects",
"projects": { "projects": {
"myProjectName": { "MyProjectName": {
"projectType": "application", "projectType": "application",
"schematics": { "schematics": {
"@schematics/angular:component": { "@schematics/angular:component": {
@ -17,12 +17,12 @@
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular-devkit/build-angular:browser",
"options": { "options": {
"outputPath": "dist/myProjectName", "outputPath": "dist/MyProjectName",
"index": "src/index.html", "index": "src/index.html",
"main": "src/main.ts", "main": "src/main.ts",
"polyfills": "src/polyfills.ts", "polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json", "tsConfig": "tsconfig.app.json",
"aot": false, "aot": true,
"extractCss": true, "extractCss": true,
"assets": ["src/favicon.ico", "src/assets"], "assets": ["src/favicon.ico", "src/assets"],
"styles": [ "styles": [
@ -30,28 +30,13 @@
"node_modules/bootstrap/dist/css/bootstrap.min.css", "node_modules/bootstrap/dist/css/bootstrap.min.css",
{ {
"input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css", "input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css",
"lazy": true, "inject": false,
"bundleName": "fontawesome-all.min" "bundleName": "fontawesome-all.min"
}, },
{ {
"input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css", "input": "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css",
"lazy": true, "inject": false,
"bundleName": "fontawesome-v4-shims.min" "bundleName": "fontawesome-v4-shims.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": [] "scripts": []
@ -69,7 +54,6 @@
"sourceMap": false, "sourceMap": false,
"extractCss": true, "extractCss": true,
"namedChunks": false, "namedChunks": false,
"aot": true,
"extractLicenses": true, "extractLicenses": true,
"vendorChunk": false, "vendorChunk": false,
"buildOptimizer": true, "buildOptimizer": true,
@ -78,14 +62,11 @@
"type": "initial", "type": "initial",
"maximumWarning": "2mb", "maximumWarning": "2mb",
"maximumError": "5mb" "maximumError": "5mb"
} },
]
},
"hmr": {
"fileReplacements": [
{ {
"replace": "src/environments/environment.ts", "type": "anyComponentStyle",
"with": "src/environments/environment.hmr.ts" "maximumWarning": "6kb",
"maximumError": "10kb"
} }
] ]
} }
@ -94,22 +75,18 @@
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
"options": { "options": {
"browserTarget": "myProjectName:build" "browserTarget": "MyProjectName:build"
}, },
"configurations": { "configurations": {
"production": { "production": {
"browserTarget": "myProjectName:build:production" "browserTarget": "MyProjectName:build:production"
},
"hmr": {
"hmr": true,
"browserTarget": "myProjectName:build:hmr"
} }
} }
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular-devkit/build-angular:extract-i18n",
"options": { "options": {
"browserTarget": "myProjectName:build" "browserTarget": "MyProjectName:build"
} }
}, },
"test": { "test": {
@ -123,10 +100,8 @@
"styles": [ "styles": [
"src/styles.scss", "src/styles.scss",
"node_modules/bootstrap/dist/css/bootstrap.min.css", "node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/font-awesome/css/font-awesome.min.css", "node_modules/@fortawesome/fontawesome-free/css/all.min.css",
"node_modules/primeng/resources/themes/nova-light/theme.css", "node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css"
"node_modules/primeicons/primeicons.css",
"node_modules/primeng/resources/primeng.min.css"
], ],
"scripts": [] "scripts": []
} }
@ -142,16 +117,19 @@
"builder": "@angular-devkit/build-angular:protractor", "builder": "@angular-devkit/build-angular:protractor",
"options": { "options": {
"protractorConfig": "e2e/protractor.conf.js", "protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "myProjectName:serve" "devServerTarget": "MyProjectName:serve"
}, },
"configurations": { "configurations": {
"production": { "production": {
"devServerTarget": "myProjectName:serve:production" "devServerTarget": "MyProjectName:serve:production"
} }
} }
} }
} }
} }
}, },
"defaultProject": "myProjectName" "defaultProject": "MyProjectName",
"cli": {
"analytics": false
}
} }

2
templates/app/angular/e2e/protractor.conf.js

@ -13,7 +13,7 @@ exports.config = {
'./src/**/*.e2e-spec.ts' './src/**/*.e2e-spec.ts'
], ],
capabilities: { capabilities: {
'browserName': 'chrome' browserName: 'chrome'
}, },
directConnect: true, directConnect: true,
baseUrl: 'http://localhost:4200/', baseUrl: 'http://localhost:4200/',

2
templates/app/angular/e2e/src/app.e2e-spec.ts

@ -10,7 +10,7 @@ describe('workspace-project App', () => {
it('should display welcome message', () => { it('should display welcome message', () => {
page.navigateTo(); page.navigateTo();
expect(page.getTitleText()).toEqual('Welcome to myProjectName!'); expect(page.getTitleText()).toEqual('ng9-abp app is running!');
}); });
afterEach(async () => { afterEach(async () => {

8
templates/app/angular/e2e/src/app.po.ts

@ -1,11 +1,11 @@
import { browser, by, element } from 'protractor'; import { browser, by, element } from 'protractor';
export class AppPage { export class AppPage {
navigateTo() { navigateTo(): Promise<unknown> {
return browser.get(browser.baseUrl) as Promise<any>; return browser.get(browser.baseUrl) as Promise<unknown>;
} }
getTitleText() { getTitleText(): Promise<string> {
return element(by.css('app-root h1')).getText() as Promise<string>; return element(by.css('app-root .content span')).getText() as Promise<string>;
} }
} }

2
templates/app/angular/karma.conf.js

@ -16,7 +16,7 @@ module.exports = function (config) {
clearContext: false // leave Jasmine Spec Runner output visible in browser clearContext: false // leave Jasmine Spec Runner output visible in browser
}, },
coverageIstanbulReporter: { coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage/myProjectName'), dir: require('path').join(__dirname, './coverage/ng9-abp'),
reports: ['html', 'lcovonly', 'text-summary'], reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true fixWebpackSourcePaths: true
}, },

70
templates/app/angular/package.json

@ -1,58 +1,54 @@
{ {
"name": "MyProjectName", "name": "ng9-abp",
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",
"start:hmr": "ng serve --configuration hmr",
"build": "ng build", "build": "ng build",
"build:prod": "ng build --prod",
"test": "ng test", "test": "ng test",
"lint": "ng lint", "lint": "ng lint",
"e2e": "ng e2e" "e2e": "ng e2e"
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@abp/ng.account": "^2.1.0", "@abp/ng.account": "~2.1.0",
"@abp/ng.identity": "^2.1.0", "@abp/ng.identity": "~2.1.0",
"@abp/ng.setting-management": "^2.1.0", "@abp/ng.setting-management": "~2.1.0",
"@abp/ng.tenant-management": "^2.1.0", "@abp/ng.tenant-management": "~2.1.0",
"@abp/ng.theme.basic": "^2.1.0", "@abp/ng.theme.basic": "~2.1.0",
"@angular/animations": "~8.2.14", "@angular/animations": "~9.0.2",
"@angular/common": "~8.2.14", "@angular/common": "~9.0.2",
"@angular/compiler": "~8.2.14", "@angular/compiler": "~9.0.2",
"@angular/core": "~8.2.14", "@angular/core": "~9.0.2",
"@angular/forms": "~8.2.14", "@angular/forms": "~9.0.2",
"@angular/platform-browser": "~8.2.14", "@angular/platform-browser": "~9.0.2",
"@angular/platform-browser-dynamic": "~8.2.14", "@angular/platform-browser-dynamic": "~9.0.2",
"@angular/router": "~8.2.14", "@angular/router": "~9.0.2",
"rxjs": "~6.4.0", "rxjs": "~6.5.4",
"tslib": "^1.10.0", "tslib": "^1.10.0",
"zone.js": "~0.9.1" "zone.js": "~0.10.2"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.803.20", "@angular-devkit/build-angular": "~0.900.3",
"@angular/cli": "~8.3.20", "@angular/cli": "~9.0.3",
"@angular/compiler-cli": "~8.2.14", "@angular/compiler-cli": "~9.0.2",
"@angular/language-service": "~8.2.14", "@angular/language-service": "~9.0.2",
"@angularclass/hmr": "^2.1.3", "@ngxs/logger-plugin": "^3.6.2",
"@ngxs/hmr-plugin": "^3.5.1", "@types/jasmine": "~3.5.0",
"@ngxs/logger-plugin": "^3.5.1",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3", "@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4", "@types/node": "^12.11.1",
"codelyzer": "^5.0.0", "codelyzer": "^5.1.2",
"jasmine-core": "~3.4.0", "jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~4.2.1", "jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0", "karma": "~4.3.0",
"karma-chrome-launcher": "~2.2.0", "karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.0.1", "karma-coverage-istanbul-reporter": "~2.1.0",
"karma-jasmine": "~2.0.1", "karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0", "karma-jasmine-html-reporter": "^1.4.2",
"ngxs-schematic": "^1.1.9", "ngxs-schematic": "^1.1.9",
"protractor": "~5.4.0", "protractor": "~5.4.3",
"ts-node": "~7.0.0", "ts-node": "~8.3.0",
"tslint": "~5.15.0", "tslint": "~5.18.0",
"typescript": "~3.5.3" "typescript": "~3.7.5"
} }
} }

20
templates/app/angular/src/app/app-routing.module.ts

@ -8,32 +8,30 @@ const routes: Routes = [
loadChildren: () => import('./home/home.module').then(m => m.HomeModule), loadChildren: () => import('./home/home.module').then(m => m.HomeModule),
data: { data: {
routes: { routes: {
name: '::Menu:Home', name: '::Menu:Home'
} as ABP.Route, } as ABP.Route
}, }
}, },
{ {
path: 'account', path: 'account',
loadChildren: () => import('./lazy-libs/account-wrapper.module').then(m => m.AccountWrapperModule), loadChildren: () => import('@abp/ng.account').then(m => m.AccountModule)
}, },
{ {
path: 'identity', path: 'identity',
loadChildren: () => import('./lazy-libs/identity-wrapper.module').then(m => m.IdentityWrapperModule), loadChildren: () => import('@abp/ng.identity').then(m => m.IdentityModule)
}, },
{ {
path: 'tenant-management', path: 'tenant-management',
loadChildren: () => loadChildren: () => import('@abp/ng.tenant-management').then(m => m.TenantManagementModule)
import('./lazy-libs/tenant-management-wrapper.module').then(m => m.TenantManagementWrapperModule),
}, },
{ {
path: 'setting-management', path: 'setting-management',
loadChildren: () => loadChildren: () => import('@abp/ng.setting-management').then(m => m.SettingManagementModule)
import('./lazy-libs/setting-management-wrapper.module').then(m => m.SettingManagementWrapperModule), }
},
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(routes)], imports: [RouterModule.forRoot(routes)],
exports: [RouterModule], exports: [RouterModule]
}) })
export class AppRoutingModule {} export class AppRoutingModule {}

68
templates/app/angular/src/app/app.component.spec.ts

@ -1,68 +0,0 @@
import { LazyLoadService } from '@abp/ng.core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { NgxsModule } from '@ngxs/store';
import { OAuthService } from 'angular-oauth2-oidc';
import { AppComponent } from './app.component';
import { LoaderBarComponent } from '@abp/ng.theme.shared';
import { Subject, Observable } from 'rxjs';
import { Component } from '@angular/core';
import { By } from '@angular/platform-browser';
@Component({
template: '',
selector: 'abp-loader-bar',
})
class DummyLoaderBarComponent {}
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let mockLazyLoadService: { load: () => Observable<void> };
let loadResponse$: Subject<void>;
let spy: jasmine.Spy<() => Observable<void>>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent, DummyLoaderBarComponent],
providers: [{ provide: LazyLoadService, useValue: { load: () => loadResponse$ } }],
});
loadResponse$ = new Subject();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
mockLazyLoadService = TestBed.get(LazyLoadService);
spy = spyOn(mockLazyLoadService, 'load');
spy.and.returnValue(loadResponse$);
fixture.detectChanges();
});
describe('LazyLoadService load method', () => {
it('should call', () => {
expect(spy).toHaveBeenCalledWith(
[
'primeng.min.css',
'primeicons.css',
'primeng-nova-light-theme.css',
'fontawesome-all.min.css',
'fontawesome-v4-shims.min.css',
],
'style',
null,
'head',
);
});
});
describe('template', () => {
it('should have the abp-loader-bar', () => {
const abpLoader = fixture.debugElement.query(By.css('abp-loader-bar'));
expect(abpLoader).toBeTruthy();
});
it('should have router-outlet', () => {
const abpLoader = fixture.debugElement.query(By.css('router-outlet'));
expect(abpLoader).toBeTruthy();
});
});
});

15
templates/app/angular/src/app/app.component.ts

@ -6,25 +6,18 @@ import { Component, OnInit } from '@angular/core';
template: ` template: `
<abp-loader-bar></abp-loader-bar> <abp-loader-bar></abp-loader-bar>
<router-outlet></router-outlet> <router-outlet></router-outlet>
`, `
}) })
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
constructor(private lazyLoadService: LazyLoadService) {} constructor(private lazyLoadService: LazyLoadService) {}
async ngOnInit() {
ngOnInit() {
this.lazyLoadService this.lazyLoadService
.load( .load(
[ ['fontawesome-all.min.css', 'fontawesome-v4-shims.min.css'],
'primeng.min.css',
'primeicons.css',
'primeng-nova-light-theme.css',
'fontawesome-all.min.css',
'fontawesome-v4-shims.min.css',
],
'style', 'style',
null, null,
'head', 'head',
'afterbegin', 'afterbegin'
) )
.subscribe(); .subscribe();
} }

8
templates/app/angular/src/app/app.module.ts

@ -22,8 +22,8 @@ const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })];
CoreModule.forRoot({ CoreModule.forRoot({
environment, environment,
requirements: { requirements: {
layouts: LAYOUTS, layouts: LAYOUTS
}, }
}), }),
ThemeSharedModule.forRoot(), ThemeSharedModule.forRoot(),
AccountConfigModule.forRoot({ redirectUrl: '/' }), AccountConfigModule.forRoot({ redirectUrl: '/' }),
@ -35,9 +35,9 @@ const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })];
BrowserAnimationsModule, BrowserAnimationsModule,
AppRoutingModule, AppRoutingModule,
SharedModule, SharedModule,
...(environment.production ? [] : LOGGERS), ...(environment.production ? [] : LOGGERS)
], ],
declarations: [AppComponent], declarations: [AppComponent],
bootstrap: [AppComponent], bootstrap: [AppComponent]
}) })
export class AppModule {} export class AppModule {}

51
templates/app/angular/src/app/home/home.component.spec.ts

@ -1,51 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OAuthService } from 'angular-oauth2-oidc';
import { HomeComponent } from './home.component';
import { HomeModule } from './home.module';
import { RouterTestingModule } from '@angular/router/testing';
import { NgxsModule } from '@ngxs/store';
import { By } from '@angular/platform-browser';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
let mockOAuthService: { hasValidAccessToken: () => boolean };
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ NgxsModule.forRoot(), HomeModule, RouterTestingModule],
providers: [{ provide: OAuthService, useValue: { hasValidAccessToken: () => false } }],
});
fixture = TestBed.createComponent(HomeComponent);
component = fixture.componentInstance;
mockOAuthService = TestBed.get(OAuthService);
fixture.detectChanges();
});
describe('#hasLoggedIn', () => {
it('should return the hasValidAccessToken method of oAuthService', () => {
const spy = spyOn(mockOAuthService, 'hasValidAccessToken');
spy.and.returnValue(false);
expect(component.hasLoggedIn).toBe(false);
expect(spy).toHaveBeenCalled();
});
});
describe('login button', () => {
it('should display', () => {
const button = fixture.debugElement.query(By.css('[routerLink="/account/login"]'));
expect(button).toBeTruthy();
expect(button.nativeElement.textContent).toContain('AbpAccount::Login');
});
it('should not display when user logged in', () => {
const spy = spyOn(mockOAuthService, 'hasValidAccessToken');
spy.and.returnValue(true);
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('#login-button'));
expect(button).toBeFalsy();
});
});
});

7
templates/app/angular/src/app/lazy-libs/account-wrapper.module.ts

@ -1,7 +0,0 @@
import { NgModule } from '@angular/core';
import { AccountModule } from '@abp/ng.account';
@NgModule({
imports: [AccountModule],
})
export class AccountWrapperModule {}

7
templates/app/angular/src/app/lazy-libs/identity-wrapper.module.ts

@ -1,7 +0,0 @@
import { NgModule } from '@angular/core';
import { IdentityModule } from '@abp/ng.identity';
@NgModule({
imports: [IdentityModule],
})
export class IdentityWrapperModule {}

7
templates/app/angular/src/app/lazy-libs/setting-management-wrapper.module.ts

@ -1,7 +0,0 @@
import { NgModule } from '@angular/core';
import { SettingManagementModule } from '@abp/ng.setting-management';
@NgModule({
imports: [SettingManagementModule],
})
export class SettingManagementWrapperModule {}

7
templates/app/angular/src/app/lazy-libs/tenant-management-wrapper.module.ts

@ -1,7 +0,0 @@
import { NgModule } from '@angular/core';
import { TenantManagementModule } from '@abp/ng.tenant-management';
@NgModule({
imports: [TenantManagementModule],
})
export class TenantManagementWrapperModule {}

9
templates/app/angular/src/app/shared/shared.module.ts

@ -3,7 +3,6 @@ import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { ThemeBasicModule } from '@abp/ng.theme.basic'; import { ThemeBasicModule } from '@abp/ng.theme.basic';
import { ThemeSharedModule } from '@abp/ng.theme.shared'; import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { TableModule } from 'primeng/table';
import { NgxValidateCoreModule } from '@ngx-validate/core'; import { NgxValidateCoreModule } from '@ngx-validate/core';
@NgModule({ @NgModule({
@ -12,18 +11,16 @@ import { NgxValidateCoreModule } from '@ngx-validate/core';
CoreModule, CoreModule,
ThemeSharedModule, ThemeSharedModule,
ThemeBasicModule, ThemeBasicModule,
TableModule,
NgbDropdownModule, NgbDropdownModule,
NgxValidateCoreModule, NgxValidateCoreModule
], ],
exports: [ exports: [
CoreModule, CoreModule,
ThemeSharedModule, ThemeSharedModule,
ThemeBasicModule, ThemeBasicModule,
TableModule,
NgbDropdownModule, NgbDropdownModule,
NgxValidateCoreModule, NgxValidateCoreModule
], ],
providers: [], providers: []
}) })
export class SharedModule {} export class SharedModule {}

25
templates/app/angular/src/environments/environment.hmr.ts

@ -1,25 +0,0 @@
export const environment = {
production: false,
hmr: true,
application: {
name: 'MyProjectName',
logoUrl: '',
},
oAuthConfig: {
issuer: 'https://localhost:44305',
clientId: 'MyProjectName_App',
dummyClientSecret: '1q2w3e*',
scope: 'MyProjectName',
showDebugInformation: true,
oidc: false,
requireHttps: true,
},
apis: {
default: {
url: 'https://localhost:44305',
},
},
localization: {
defaultResourceName: 'MyProjectName',
},
};

13
templates/app/angular/src/environments/environment.prod.ts

@ -1,9 +1,8 @@
export const environment = { export const environment = {
production: true, production: true,
hmr: false,
application: { application: {
name: 'MyProjectName', name: 'MyProjectName',
logoUrl: '', logoUrl: ''
}, },
oAuthConfig: { oAuthConfig: {
issuer: 'https://localhost:44305', issuer: 'https://localhost:44305',
@ -12,14 +11,14 @@ export const environment = {
scope: 'MyProjectName', scope: 'MyProjectName',
showDebugInformation: true, showDebugInformation: true,
oidc: false, oidc: false,
requireHttps: true, requireHttps: true
}, },
apis: { apis: {
default: { default: {
url: 'https://localhost:44305', url: 'https://localhost:44305'
}, }
}, },
localization: { localization: {
defaultResourceName: 'MyProjectName', defaultResourceName: 'MyProjectName'
}, }
}; };

13
templates/app/angular/src/environments/environment.ts

@ -1,9 +1,8 @@
export const environment = { export const environment = {
production: false, production: false,
hmr: false,
application: { application: {
name: 'MyProjectName', name: 'MyProjectName',
logoUrl: '', logoUrl: ''
}, },
oAuthConfig: { oAuthConfig: {
issuer: 'https://localhost:44305', issuer: 'https://localhost:44305',
@ -12,14 +11,14 @@ export const environment = {
scope: 'MyProjectName', scope: 'MyProjectName',
showDebugInformation: true, showDebugInformation: true,
oidc: false, oidc: false,
requireHttps: true, requireHttps: true
}, },
apis: { apis: {
default: { default: {
url: 'https://localhost:44305', url: 'https://localhost:44305'
}, }
}, },
localization: { localization: {
defaultResourceName: 'MyProjectName', defaultResourceName: 'MyProjectName'
}, }
}; };

13
templates/app/angular/src/main.ts

@ -1,20 +1,13 @@
import { enableProdMode } from '@angular/core'; import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BootstrapModuleFn as Bootstrap, hmr, WebpackModule } from '@ngxs/hmr-plugin';
import { AppModule } from './app/app.module'; import { AppModule } from './app/app.module';
import { environment } from './environments/environment'; import { environment } from './environments/environment';
declare const module: WebpackModule;
if (environment.production) { if (environment.production) {
enableProdMode(); enableProdMode();
} }
const bootstrap: Bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); platformBrowserDynamic()
.bootstrapModule(AppModule)
if (environment.hmr) { .catch(err => console.error(err));
hmr(module, bootstrap).catch(err => console.error(err));
} else {
bootstrap().catch(err => console.log(err));
}

6
templates/app/angular/src/polyfills.ts

@ -1,3 +1,7 @@
/***************************************************************************************************
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
*/
import '@angular/localize/init';
/** /**
* This file includes polyfills needed by Angular and is loaded before the app. * This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file. * You can add your own extra polyfills to this file.
@ -35,7 +39,7 @@
* will put import in the top of bundle, so user need to create a separate file * will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags * in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js. * into that file, and then add the following code before importing zone.js.
* import './zone-flags.ts'; * import './zone-flags';
* *
* The flags allowed in zone-flags.ts are listed here. * The flags allowed in zone-flags.ts are listed here.
* *

7
templates/app/angular/src/test.ts

@ -7,7 +7,12 @@ import {
platformBrowserDynamicTesting platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing'; } from '@angular/platform-browser-dynamic/testing';
declare const require: any; declare const require: {
context(path: string, deep?: boolean, filter?: RegExp): {
keys(): string[];
<T>(id: string): T;
};
};
// First, initialize the Angular testing environment. // First, initialize the Angular testing environment.
getTestBed().initTestEnvironment( getTestBed().initTestEnvironment(

6
templates/app/angular/tsconfig.app.json

@ -2,8 +2,8 @@
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/app", "outDir": "./out-tsc/app",
"types": ["node"] "types": []
}, },
"include": ["src/**/*.ts"], "files": ["src/main.ts", "src/polyfills.ts"],
"exclude": ["src/test.ts", "src/**/*.spec.ts"] "include": ["src/**/*.d.ts"]
} }

15
templates/app/angular/tsconfig.json

@ -6,18 +6,17 @@
"sourceMap": true, "sourceMap": true,
"declaration": false, "declaration": false,
"downlevelIteration": true, "downlevelIteration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"module": "esnext", "module": "esnext",
"moduleResolution": "node", "moduleResolution": "node",
"importHelpers": true, "importHelpers": true,
"target": "es2015", "target": "es2015",
"typeRoots": [ "typeRoots": ["node_modules/@types"],
"node_modules/@types" "lib": ["es2018", "dom"]
], },
"lib": [ "angularCompilerOptions": {
"es2018", "fullTemplateTypeCheck": true,
"dom" "strictInjectionParameters": true,
] "enableIvy": true
} }
} }

3
templates/app/angular/tslint.json

@ -4,7 +4,7 @@
"array-type": false, "array-type": false,
"arrow-parens": false, "arrow-parens": false,
"deprecation": { "deprecation": {
"severity": "warn" "severity": "warning"
}, },
"component-class-suffix": true, "component-class-suffix": true,
"contextual-lifecycle": true, "contextual-lifecycle": true,
@ -60,7 +60,6 @@
"no-non-null-assertion": true, "no-non-null-assertion": true,
"no-redundant-jsdoc": true, "no-redundant-jsdoc": true,
"no-switch-case-fall-through": true, "no-switch-case-fall-through": true,
"no-use-before-declare": true,
"no-var-requires": false, "no-var-requires": false,
"object-literal-key-quotes": [ "object-literal-key-quotes": [
true, true,

Loading…
Cancel
Save