Merge remote-tracking branch 'abpframework/dev' into Translate

pull/2172/head
liangshiwei 6 years ago
commit 388ec601c2

@ -0,0 +1,24 @@
name: 'Angular'
on:
pull_request:
paths:
- 'npm/ng-packs/**'
branches:
#- master
- dev
push:
paths:
- 'npm/ng-packs/**'
branches:
#- master
- dev
jobs:
build-test-lint:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: '10.x'
- run: yarn && yarn ci
working-directory: npm/ng-packs

@ -1,60 +0,0 @@
language: csharp
mono: none
dotnet: 2.1.300
script:
- dotnet build framework
- dotnet build modules/users
- dotnet build modules/permission-management
- dotnet build modules/setting-management
- dotnet build modules/identity
- dotnet build modules/tenant-management
- dotnet build modules/account
- dotnet build modules/docs
- dotnet build modules/blogging
- dotnet test framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests
- dotnet test framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests
- dotnet test framework/test/Volo.Abp.AspNetCore.Mvc.Tests
- dotnet test framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests
- dotnet test framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests
- dotnet test framework/test/Volo.Abp.AspNetCore.Tests
- dotnet test framework/test/Volo.Abp.Auditing.Tests
- dotnet test framework/test/Volo.Abp.Authorization.Tests
- dotnet test framework/test/Volo.Abp.Autofac.Tests
- dotnet test framework/test/Volo.Abp.AutoMapper.Tests
- dotnet test framework/test/Volo.Abp.Caching.Tests
- dotnet test framework/test/Volo.Abp.Castle.Core.Tests
- dotnet test framework/test/Volo.Abp.Core.Tests
- dotnet test framework/test/Volo.Abp.Data.Tests
- dotnet test framework/test/Volo.Abp.Ddd.Tests
- dotnet test framework/test/Volo.Abp.EntityFrameworkCore.Tests
- dotnet test framework/test/Volo.Abp.EventBus.Distributed.Tests
- dotnet test framework/test/Volo.Abp.EventBus.Tests
- dotnet test framework/test/Volo.Abp.Http.Client.Tests
- dotnet test framework/test/Volo.Abp.Localization.Tests
- dotnet test framework/test/Volo.Abp.MemoryDb.Tests
- dotnet test framework/test/Volo.Abp.MongoDB.Tests
- dotnet test framework/test/Volo.Abp.MultiTenancy.Tests
- dotnet test framework/test/Volo.Abp.Serialization.Tests
- dotnet test framework/test/Volo.Abp.TestApp.Tests
- dotnet test framework/test/Volo.Abp.UI.Navigation.Tests
- dotnet test framework/test/Volo.Abp.Uow.Tests
- dotnet test framework/test/Volo.Abp.Validation.Tests
- dotnet test framework/test/Volo.Abp.VirtualFileSystem.Tests
- dotnet test modules/blogging/test/Volo.Blogging.Application.Tests
- dotnet test modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests
- dotnet test modules/identity/test/Volo.Abp.Identity.Domain.Tests
- dotnet test modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests
- dotnet test modules/identity/test/Volo.Abp.Identity.MongoDB.Tests
- dotnet test modules/identity/test/Volo.Abp.Identity.Application.Tests
- dotnet test modules/permission-management/test/Volo.Abp.PermissionManagement.Tests
- dotnet test modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests
- dotnet test modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests
- dotnet test modules/setting-management/test/Volo.Abp.SettingManagement.EntityFrameworkCore.Tests
- dotnet test modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests
- dotnet test modules/setting-management/test/Volo.Abp.SettingManagement.Tests
- dotnet test modules/tenant-management/test/Volo.Abp.TenantManagement.EntityFrameworkCore.Tests
- dotnet test modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests
- dotnet test modules/tenant-management/test/Volo.Abp.TenantManagement.Application.Tests
- dotnet test modules/users/test/Volo.Abp.Users.MongoDB.Tests
- dotnet test modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests

@ -3,3 +3,4 @@
"singleQuote": true,
"trailingComma": "all"
}

@ -1 +1,2 @@
<h1> Abp Ng Packages </h1>
[docs.abp.io](https://docs.abp.io)

@ -19,7 +19,8 @@
"test": {
"builder": "@angular-builders/jest:run",
"options": {
"coverage": true
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -48,7 +49,8 @@
"test": {
"builder": "@angular-builders/jest:run",
"options": {
"coverage": true
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -77,7 +79,8 @@
"test": {
"builder": "@angular-builders/jest:run",
"options": {
"coverage": true
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -103,11 +106,10 @@
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular-builders/jest:run",
"options": {
"main": "packages/account/src/test.ts",
"tsConfig": "packages/account/tsconfig.spec.json",
"karmaConfig": "packages/account/karma.conf.js"
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -135,7 +137,8 @@
"test": {
"builder": "@angular-builders/jest:run",
"options": {
"coverage": true
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -166,7 +169,8 @@
"test": {
"builder": "@angular-builders/jest:run",
"options": {
"coverage": true
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -194,7 +198,8 @@
"test": {
"builder": "@angular-builders/jest:run",
"options": {
"coverage": true
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -225,7 +230,8 @@
"test": {
"builder": "@angular-builders/jest:run",
"options": {
"coverage": true
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -254,11 +260,10 @@
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular-builders/jest:run",
"options": {
"main": "packages/setting-management/src/test.ts",
"tsConfig": "packages/setting-management/tsconfig.spec.json",
"karmaConfig": "packages/setting-management/karma.conf.js"
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -287,11 +292,10 @@
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular-builders/jest:run",
"options": {
"main": "packages/setting-management-config/src/test.ts",
"tsConfig": "packages/setting-management-config/tsconfig.spec.json",
"karmaConfig": "packages/setting-management-config/karma.conf.js"
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -320,11 +324,10 @@
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular-builders/jest:run",
"options": {
"main": "packages/identity-config/src/test.ts",
"tsConfig": "packages/identity-config/tsconfig.spec.json",
"karmaConfig": "packages/identity-config/karma.conf.js"
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -350,11 +353,10 @@
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular-builders/jest:run",
"options": {
"main": "packages/account-config/src/test.ts",
"tsConfig": "packages/account-config/tsconfig.spec.json",
"karmaConfig": "packages/account-config/karma.conf.js"
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -380,11 +382,10 @@
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular-builders/jest:run",
"options": {
"main": "packages/tenant-management-config/src/test.ts",
"tsConfig": "packages/tenant-management-config/tsconfig.spec.json",
"karmaConfig": "packages/tenant-management-config/karma.conf.js"
"coverage": true,
"passWithNoTests": true
}
},
"lint": {
@ -501,25 +502,6 @@
"browserTarget": "dev-app:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "apps/dev-app/src/test.ts",
"polyfills": "apps/dev-app/src/polyfills.ts",
"tsConfig": "apps/dev-app/tsconfig.spec.json",
"karmaConfig": "apps/dev-app/karma.conf.js",
"assets": ["apps/dev-app/src/favicon.ico", "apps/dev-app/src/assets"],
"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"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {

@ -2,7 +2,7 @@ import { Component } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
@Component({
selector: 'abp-home',
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent {

@ -2,12 +2,16 @@
"scripts": {
"start": "ng serve dev-app",
"ng": "ng",
"test": "ng test",
"test": "ng test --watchAll --runInBand",
"symlink": "symlink",
"abpng": "abpng",
"commit": "git-cz",
"lint": "ng lint --fix",
"scripts:build": "cd scripts && npm install && npm run build"
"scripts:build": "cd scripts && npm install && npm run build",
"ci": "yarn ci:build:sync && yarn ci:build:async && yarn ci:test && yarn ng lint",
"ci:build:sync": "symlink copy --angular --no-watch --sync --packages @abp/ng.core,@abp/ng.theme.shared,@abp/ng.feature-management,@abp/ng.permission-management,@abp/ng.account.config,@abp/ng.identity.config,@abp/ng.setting-management.config,@abp/ng.tenant-management.config",
"ci:build:async": "symlink copy --angular --no-watch --all-packages --excluded-packages @abp/ng.core,@abp/ng.theme.shared,@abp/ng.feature-management,@abp/ng.permission-management,@abp/ng.account.config,@abp/ng.identity.config,@abp/ng.setting-management.config,@abp/ng.tenant-management.config",
"ci:test": "ng test --coverage=false"
},
"devDependencies": {
"@abp/ng.account.config": "^1.0.3",
@ -72,7 +76,7 @@
"protractor": "~5.4.0",
"rxjs": "~6.4.0",
"snq": "^1.0.3",
"symlink-manager": "^1.3.0",
"symlink-manager": "^1.4.1",
"ts-node": "~7.0.0",
"tsickle": "^0.37.0",
"tslint": "~5.20.0",

@ -1 +1,3 @@
# @abp/ng.account.config
# @abp/ng.account.config
[docs.abp.io](https://docs.abp.io)

@ -0,0 +1,6 @@
const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'account-config',
};

@ -1,9 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": ["node", "jest"]
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": [],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}

@ -1 +1,3 @@
<h1> @abp/ng.account </h1>
[docs.abp.io](https://docs.abp.io)

@ -0,0 +1,6 @@
const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'account',
};

@ -0,0 +1,35 @@
import { createHttpFactory, HttpMethod, SpectatorHttp } from '@ngneat/spectator/jest';
import { AccountService } from '../services/account.service';
import { Store } from '@ngxs/store';
import { RestService } from '@abp/ng.core';
import { RegisterRequest } from '../models/user';
describe('AccountService', () => {
let spectator: SpectatorHttp<AccountService>;
const createHttp = createHttpFactory({
dataService: AccountService,
providers: [RestService],
mocks: [Store],
});
beforeEach(() => (spectator = createHttp()));
it('should send a GET to find tenant', () => {
spectator.get(Store).selectSnapshot.andReturn('https://abp.io');
spectator.service.findTenant('test').subscribe();
spectator.expectOne('https://abp.io/api/abp/multi-tenancy/tenants/by-name/test', HttpMethod.GET);
});
it('should send a POST to register API', () => {
const mock = {
userName: 'test',
emailAddress: 'test@test.com',
password: 'test1234',
appName: 'Angular',
} as RegisterRequest;
spectator.get(Store).selectSnapshot.andReturn('https://abp.io');
spectator.service.register(mock).subscribe();
const req = spectator.expectOne('https://abp.io/api/account/register', HttpMethod.POST);
expect(req.request.body).toEqual(mock);
});
});

@ -1,9 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": ["node", "jest"]
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": [],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}

@ -1 +1,3 @@
<h1> @abp/ng.core </h1>
[docs.abp.io](https://docs.abp.io)

@ -1,10 +1,6 @@
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.spec');
const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'core',
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths /*, { prefix: '<rootDir>/' } */),
'ts-jest': { allowSyntheticDefaultImports: true },
};

@ -6,7 +6,7 @@ describe('InputEventDebounceDirective', () => {
let spectator: SpectatorDirective<InputEventDebounceDirective>;
let directive: InputEventDebounceDirective;
let input: HTMLInputElement;
let inputEventFn = jest.fn(() => {});
const inputEventFn = jest.fn(() => {});
const createDirective = createDirectiveFactory({
directive: InputEventDebounceDirective,

@ -1,5 +1,4 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
import clone from 'just-clone';
import { LazyLoadService } from '../services/lazy-load.service';
import { catchError } from 'rxjs/operators';
import { of } from 'rxjs';
@ -10,7 +9,7 @@ describe('LazyLoadService', () => {
const scriptElement = document.createElement('script');
const linkElement = document.createElement('link');
const styleElement = document.createElement('style');
const cloneDocument = clone(document);
const cloneDocument = { ...document };
const createService = createServiceFactory({ service: LazyLoadService });
@ -19,7 +18,7 @@ describe('LazyLoadService', () => {
service = spectator.service;
});
afterEach(() => (document = clone(cloneDocument)));
afterEach(() => (document = { ...cloneDocument }));
test('should load script with content just one time', done => {
const spy = jest.spyOn(document, 'createElement');

@ -5,8 +5,8 @@ describe('ClickEventStopPropagationDirective', () => {
let spectator: SpectatorDirective<ClickEventStopPropagationDirective>;
let directive: ClickEventStopPropagationDirective;
let link: HTMLAnchorElement;
let childClickEventFn = jest.fn(() => null);
let parentClickEventFn = jest.fn(() => null);
const childClickEventFn = jest.fn(() => null);
const parentClickEventFn = jest.fn(() => null);
const createDirective = createDirectiveFactory({
directive: ClickEventStopPropagationDirective,
});

@ -5,10 +5,7 @@
"esModuleInterop": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"],
"paths": {
"@abp/ng.core/*": ["packages/core/src/lib/*"]
}
"types": ["jest", "node"]
},
"include": ["**/*.spec.ts", "**/*.d.ts"]
}

@ -1 +1,3 @@
<h1> @abp/ng.feature-management </h1>
[docs.abp.io](https://docs.abp.io)

@ -3,5 +3,4 @@ const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'feature-management',
'ts-jest': { allowSyntheticDefaultImports: true },
};

@ -1 +1,3 @@
# @abp/ng.identity.config
# @abp/ng.identity.config
[docs.abp.io](https://docs.abp.io)

@ -0,0 +1,6 @@
const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'identity-config',
};

@ -1,9 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": ["node", "jest"]
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": [],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}

@ -1 +1,3 @@
<h1> @abp/ng.identity </h1>
[docs.abp.io](https://docs.abp.io)

@ -3,5 +3,4 @@ const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'identity',
'ts-jest': { allowSyntheticDefaultImports: true },
};

@ -1 +1,3 @@
<h1> @abp/ng.permission-management </h1>
[docs.abp.io](https://docs.abp.io)

@ -3,5 +3,4 @@ const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'permission-management',
'ts-jest': { allowSyntheticDefaultImports: true },
};

@ -1,24 +1,3 @@
# SettingManagementConfig
# @abp/ng.setting-management.config
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.7.
## Code scaffolding
Run `ng generate component component-name --project setting-management-config` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project setting-management-config`.
> Note: Don't forget to add `--project setting-management-config` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build setting-management-config` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build setting-management-config`, go to the dist folder `cd dist/setting-management-config` and run `npm publish`.
## Running unit tests
Run `ng test setting-management-config` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
[docs.abp.io](https://docs.abp.io)

@ -0,0 +1,6 @@
const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'setting-management-config',
};

@ -1,9 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": ["node", "jest"]
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": [],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}

@ -1 +1,3 @@
<h1> @abp/ng.setting-management </h1>
<h1> @abp/ng.setting-management </h1>
[docs.abp.io](https://docs.abp.io)

@ -0,0 +1,6 @@
const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'setting-management',
};

@ -19,7 +19,7 @@
<li
*abpFor="let setting of settings; trackBy: trackByFn"
(click)="selected = setting"
class="nav-item"
class="nav-item pointer"
[abpPermission]="setting.requiredPolicy"
>
<a

@ -1,9 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": ["node", "jest"]
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": [],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}

@ -1 +1,3 @@
# @abp/ng.tenant-management.config
# @abp/ng.tenant-management.config
[docs.abp.io](https://docs.abp.io)

@ -0,0 +1,6 @@
const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'tenant-management-config',
};

@ -1,9 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": ["node", "jest"]
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": [],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}

@ -1 +1,3 @@
<h1> @abp/ng.tenant-management </h1>
[docs.abp.io](https://docs.abp.io)

@ -3,5 +3,4 @@ const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'tenant-management',
'ts-jest': { allowSyntheticDefaultImports: true },
};

@ -1 +1,3 @@
<h1> @abp/ng.theme.basic </h1>
[docs.abp.io](https://docs.abp.io)

@ -3,5 +3,4 @@ const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'theme-basic',
'ts-jest': { allowSyntheticDefaultImports: true },
};

@ -1 +1,3 @@
<h1> @abp/ng.theme.shared </h1>
[docs.abp.io](https://docs.abp.io)

@ -1,10 +1,6 @@
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.spec');
const jestConfig = require('../../jest.config');
module.exports = {
...jestConfig,
name: 'theme-shared',
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths /*, { prefix: '<rootDir>/' } */),
'ts-jest': { allowSyntheticDefaultImports: true },
};

@ -1,5 +1,5 @@
<div #container id="abp-error" class="error">
<button id="abp-close-button" type="button" class="close mr-3" (click)="destroy()">
<button *ngIf="!hideCloseIcon" id="abp-close-button" type="button" class="close mr-2" (click)="destroy()">
<span aria-hidden="true">&times;</span>
</button>

@ -8,6 +8,8 @@ import {
OnDestroy,
Type,
ViewChild,
ApplicationRef,
Injector,
} from '@angular/core';
import { fromEvent, Subject } from 'rxjs';
import { debounceTime, filter } from 'rxjs/operators';
@ -18,8 +20,12 @@ import { debounceTime, filter } from 'rxjs/operators';
styleUrls: ['error.component.scss'],
})
export class ErrorComponent implements AfterViewInit, OnDestroy {
appRef: ApplicationRef;
cfRes: ComponentFactoryResolver;
injector: Injector;
status = 0;
title: Config.LocalizationParam = 'Oops!';
@ -30,6 +36,8 @@ export class ErrorComponent implements AfterViewInit, OnDestroy {
destroy$: Subject<void>;
hideCloseIcon = false;
@ViewChild('container', { static: false })
containerRef: ElementRef<HTMLDivElement>;
@ -39,9 +47,10 @@ export class ErrorComponent implements AfterViewInit, OnDestroy {
ngAfterViewInit() {
if (this.customComponent) {
const customComponentRef = this.cfRes.resolveComponentFactory(this.customComponent).create(null);
const customComponentRef = this.cfRes.resolveComponentFactory(this.customComponent).create(this.injector);
customComponentRef.instance.errorStatus = this.status;
customComponentRef.instance.destroy$ = this.destroy$;
this.appRef.attachView(customComponentRef.hostView);
this.containerRef.nativeElement.appendChild((customComponentRef.hostView as EmbeddedViewRef<any>).rootNodes[0]);
customComponentRef.changeDetectorRef.detectChanges();
}

@ -1,5 +1,5 @@
<ng-container *ngIf="visible">
<div class="modal show {{ modalClass }}" tabindex="-1" role="dialog">
<div id="modal-container" class="modal show {{ modalClass }}" tabindex="-1" role="dialog">
<div class="modal-backdrop" [@fade]="isModalOpen" (click)="close()"></div>
<div
id="abp-modal-dialog"

@ -109,8 +109,13 @@ export class ModalComponent implements OnDestroy {
close() {
if (this.busy) return;
let node: HTMLDivElement;
if (!this.modalContent) {
node = document.getElementById('modal-container') as HTMLDivElement;
}
const nodes = getFlatNodes(
(this.modalContent.nativeElement.querySelector('#abp-modal-body') as HTMLElement).childNodes,
((node || this.modalContent.nativeElement).querySelector('#abp-modal-body') as HTMLElement).childNodes,
);
if (hasNgDirty(nodes)) {

@ -19,7 +19,6 @@ import { ErrorComponent } from '../components/error/error.component';
import { HttpErrorConfig, ErrorScreenErrorCodes } from '../models/common';
import { Toaster } from '../models/toaster';
import { ConfirmationService } from '../services/confirmation.service';
import { HTTP_ERROR_CONFIG } from '../tokens/error-pages.token';
export const DEFAULT_ERROR_MESSAGES = {
defaultError: {
@ -56,7 +55,7 @@ export class ErrorHandler {
private cfRes: ComponentFactoryResolver,
private rendererFactory: RendererFactory2,
private injector: Injector,
@Inject(HTTP_ERROR_CONFIG) private httpErrorConfig: HttpErrorConfig,
@Inject('HTTP_ERROR_CONFIG') private httpErrorConfig: HttpErrorConfig,
) {
this.actions.pipe(ofActionSuccessful(RestOccurError, RouterError, RouterDataResolved)).subscribe(res => {
if (res instanceof RestOccurError) {
@ -192,7 +191,6 @@ export class ErrorHandler {
}
private navigateToLogin() {
console.warn(this.store.selectSnapshot(RouterState.url));
this.store.dispatch(
new Navigate(['/account/login'], null, { state: { redirectUrl: this.store.selectSnapshot(RouterState.url) } }),
);
@ -209,9 +207,11 @@ export class ErrorHandler {
this.componentRef.instance[key] = instance[key];
}
}
this.componentRef.instance.hideCloseIcon = this.httpErrorConfig.errorScreen.hideCloseIcon;
if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) {
this.componentRef.instance.cfRes = this.cfRes;
this.componentRef.instance.appRef = this.appRef;
this.componentRef.instance.injector = this.injector;
this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen.component;
}

@ -14,5 +14,6 @@ export interface HttpErrorConfig {
| [ErrorScreenErrorCodes, ErrorScreenErrorCodes]
| [ErrorScreenErrorCodes, ErrorScreenErrorCodes, ErrorScreenErrorCodes]
| [ErrorScreenErrorCodes, ErrorScreenErrorCodes, ErrorScreenErrorCodes, ErrorScreenErrorCodes];
hideCloseIcon?: boolean;
};
}

@ -32,16 +32,17 @@ describe('LoaderBarComponent', () => {
expect(spectator.component.color).toBe('#77b6ff');
});
it('should increase the progressLevel maximum 10 point when value is 0', done => {
it('should increase the progressLevel', done => {
spectator.detectChanges();
spectator.get(Store).dispatch(new StartLoader(new HttpRequest('GET', 'test')));
spectator.detectChanges();
setTimeout(() => {
expect(spectator.component.progressLevel > 0 && spectator.component.progressLevel < 10).toBeTruthy();
expect(spectator.component.progressLevel > 0).toBeTruthy();
done();
}, 2);
}, 10);
});
it('should be interval unsubscribed', done => {
test.skip('should be interval unsubscribed', done => {
spectator.detectChanges();
spectator.get(Store).dispatch(new StartLoader(new HttpRequest('GET', 'test')));
expect(spectator.component.interval.closed).toBe(false);

@ -3,7 +3,8 @@ import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest';
import { Store } from '@ngxs/store';
import { MessageService } from 'primeng/components/common/messageservice';
import { ToastModule } from 'primeng/toast';
import { ConfirmationComponent, ModalComponent, ButtonComponent } from '../components';
import { timer } from 'rxjs';
import { ButtonComponent, ConfirmationComponent, ModalComponent } from '../components';
describe('ModalComponent', () => {
let spectator: SpectatorHost<ModalComponent, { visible: boolean; busy: boolean; ngDirty: boolean }>;
@ -103,13 +104,13 @@ describe('ModalComponent', () => {
it('should close with esc key', done => {
spectator.hostComponent.ngDirty = false;
spectator.detectChanges();
setTimeout(() => {
timer(0).subscribe(() => {
spectator.dispatchKeyboardEvent(document.body, 'keyup', 'Escape');
}, 0);
setTimeout(() => {
});
timer(300).subscribe(() => {
expect(spectator.component.visible).toBe(false);
done();
}, 200);
});
});
it('should not close when busy is true', done => {

@ -19,7 +19,10 @@ import { TableSortDirective } from './directives/table-sort.directive';
import { ErrorHandler } from './handlers/error.handler';
import { chartJsLoaded$ } from './utils/widget-utils';
import { RootParams } from './models/common';
import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/error-pages.token';
import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token';
import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap';
import { DateParserFormatter } from './utils/date-parser-formatter';
import { DatePipe } from '@angular/common';
export function appendScript(injector: Injector) {
const fn = () => {
@ -68,6 +71,7 @@ export function appendScript(injector: Injector) {
SortOrderIconComponent,
TableSortDirective,
],
providers: [DatePipe],
entryComponents: [ErrorComponent],
})
export class ThemeSharedModule {
@ -88,6 +92,7 @@ export class ThemeSharedModule {
useFactory: httpErrorConfigFactory,
deps: [HTTP_ERROR_CONFIG],
},
{ provide: NgbDateParserFormatter, useClass: DateParserFormatter },
],
};
}

@ -0,0 +1,52 @@
import { Injectable, Optional } from '@angular/core';
import { NgbDateParserFormatter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
import { DatePipe } from '@angular/common';
function padNumber(value: number) {
if (isNumber(value)) {
return `0${value}`.slice(-2);
} else {
return '';
}
}
function isNumber(value: any): boolean {
return !isNaN(toInteger(value));
}
function toInteger(value: any): number {
return parseInt(`${value}`, 10);
}
@Injectable()
export class DateParserFormatter extends NgbDateParserFormatter {
constructor(@Optional() private datePipe: DatePipe) {
super();
}
parse(value: string): NgbDateStruct {
if (value) {
const dateParts = value.trim().split('-');
if (dateParts.length === 1 && isNumber(dateParts[0])) {
return { year: toInteger(dateParts[0]), month: null, day: null };
} else if (dateParts.length === 2 && isNumber(dateParts[0]) && isNumber(dateParts[1])) {
return { year: toInteger(dateParts[0]), month: toInteger(dateParts[1]), day: null };
} else if (dateParts.length === 3 && isNumber(dateParts[0]) && isNumber(dateParts[1]) && isNumber(dateParts[2])) {
return { year: toInteger(dateParts[0]), month: toInteger(dateParts[1]), day: toInteger(dateParts[2]) };
}
}
return null;
}
format(date: NgbDateStruct): string {
if (date && this.datePipe) {
return this.datePipe.transform(new Date(date.year, date.month, date.day), 'shortDate');
} else {
return date
? `${date.year}-${isNumber(date.month) ? padNumber(date.month) : ''}-${
isNumber(date.day) ? padNumber(date.day) : ''
}`
: '';
}
}
}

@ -1 +1,2 @@
export * from './widget-utils';
export * from './date-parser-formatter';

@ -5,10 +5,7 @@
"esModuleInterop": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"],
"paths": {
"@abp/ng.theme-shared/*": ["packages/theme-shared/src/lib/*"]
}
"types": ["jest", "node"]
},
"include": ["**/*.spec.ts", "**/*.d.ts"]
}

Loading…
Cancel
Save