Browse Source

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

pull/3622/head
liangshiwei 6 years ago
parent
commit
144b11186b
  1. 3
      docs/en/Customizing-Application-Modules-Overriding-Services.md
  2. 6
      docs/en/Tutorials/Part-1.md
  3. 3
      docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md
  4. 16
      docs/zh-Hans/Nightly-Builds.md
  5. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs
  6. 5
      framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreTestBaseModule.cs
  7. 2
      framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionConventionalRegistrationExtensions.cs
  8. 4
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  9. 4
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  10. 2
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Consent.cshtml.cs
  11. 4
      modules/blogging/app/Volo.BloggingTestApp/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  12. 4
      modules/client-simulation/demo/Volo.ClientSimulation.Demo/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  13. 4
      modules/docs/app/VoloDocs.Web/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  14. 4
      npm/ng-packs/apps/dev-app/src/index.html
  15. 25
      npm/ng-packs/apps/dev-app/src/styles.scss
  16. 24
      npm/ng-packs/package.json
  17. 13
      npm/ng-packs/packages/core/src/lib/core.module.ts
  18. 1
      npm/ng-packs/packages/core/src/lib/models/common.ts
  19. 3
      npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts
  20. 18
      npm/ng-packs/packages/core/src/lib/tokens/common.token.ts
  21. 2
      npm/ng-packs/packages/core/src/lib/tokens/index.ts
  22. 4
      npm/ng-packs/packages/core/src/lib/tokens/options.token.ts
  23. 10
      npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts
  24. 3
      npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html
  25. 21
      npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts
  26. 19
      npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts
  27. 6
      npm/ng-packs/packages/theme-shared/src/lib/tests/confirmation.service.spec.ts
  28. 28
      npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts
  29. 12
      npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts
  30. 8
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
  31. 15
      npm/ng-packs/scripts/install-new-dependencies.ts
  32. 1356
      npm/ng-packs/yarn.lock
  33. 3
      npm/packs/select2/abp.resourcemapping.js
  34. 4
      npm/packs/select2/src/select2-bootstrap-modal-patch.js
  35. 4
      samples/MicroserviceDemo/applications/AuthServer.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  36. 4
      samples/MicroserviceDemo/applications/BackendAdminApp.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  37. 4
      samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  38. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  39. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  40. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  41. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  42. 4
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  43. 4
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js
  44. 4
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

3
docs/en/Customizing-Application-Modules-Overriding-Services.md

@ -60,6 +60,7 @@ In most cases, you will want to change one or a few methods of the current imple
````csharp
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService))]
public class MyIdentityUserAppService : IdentityUserAppService
{
//...
@ -262,4 +263,4 @@ See [Overriding the User Interface](Customizing-Application-Modules-Overriding-U
## How to Find the Services?
[Module documents](Modules/Index.md) includes the list of the major services they define. In addition, you can investigate [their source code](https://github.com/abpframework/abp/tree/dev/modules) to explore all the services.
[Module documents](Modules/Index.md) includes the list of the major services they define. In addition, you can investigate [their source code](https://github.com/abpframework/abp/tree/dev/modules) to explore all the services.

6
docs/en/Tutorials/Part-1.md

@ -22,7 +22,7 @@ end
### About this tutorial:
In this tutorial series, you will build an ABP Commercial application named `Acme.BookStore`. In this sample project, we will manage a list of books and authors. **{{DB_Text}}** will be used as the ORM provider. And on the front-end side {{UI_Value}} and JavaScript will be used.
In this tutorial series, you will build an ABP application named `Acme.BookStore`. In this sample project, we will manage a list of books and authors. **{{DB_Text}}** will be used as the ORM provider. And on the front-end side {{UI_Value}} and JavaScript will be used.
The ASP.NET Core {{UI_Value}} tutorial series consists of 3 parts:
@ -34,11 +34,11 @@ The ASP.NET Core {{UI_Value}} tutorial series consists of 3 parts:
### Creating the project
Create a new project named `Acme.BookStore` where `Acme` is the company name and `BookStore` is the project name. You can check out [creating a new project](../Getting-Started-{{if UI == 'NG'}}Angular{{else}}AspNetCore-MVC{{end}}-Template#creating-a-new-project) document to see how you can create a new project. We will create the project with ABP CLI. But first of all, we need to login to the ABP Platform to create a commercial project.
Create a new project named `Acme.BookStore` where `Acme` is the company name and `BookStore` is the project name. You can check out [creating a new project](../Getting-Started-{{if UI == 'NG'}}Angular{{else}}AspNetCore-MVC{{end}}-Template#creating-a-new-project) document to see how you can create a new project. We will create the project with ABP CLI. But first of all, we need to login to the ABP Platform.
#### Create the project
By running the below command, it creates a new ABP Commercial project with the database provider `{{DB_Text}}` and UI option `MVC`. To see the other CLI options, check out [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) document.
By running the below command, it creates a new ABP project with the database provider `{{DB_Text}}` and UI option `MVC`. To see the other CLI options, check out [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) document.
```bash
abp new Acme.BookStore --template app --database-provider {{DB}} --ui {{UI_Text}}

3
docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md

@ -60,6 +60,7 @@ context.Services.Replace(
````csharp
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService))]
public class MyIdentityUserAppService : IdentityUserAppService
{
//...
@ -262,4 +263,4 @@ ObjectExtensionManager.Instance
## 如何找到服务?
[模块文档](Modules/Index.md) 包含了定义的主要服务列表. 另外 你也可以查看[源码](https://github.com/abpframework/abp/tree/dev/modules)找到所有的服务.
[模块文档](Modules/Index.md) 包含了定义的主要服务列表. 另外 你也可以查看[源码](https://github.com/abpframework/abp/tree/dev/modules)找到所有的服务.

16
docs/zh-Hans/Nightly-Builds.md

@ -23,3 +23,19 @@
2. 将包源更改为`全部`.
3. 搜索nuget包. 你将看到包的预发布格式为`(VERSION)-preview(DATE)` (如本示例中的**v0.16.0-preview20190401**).
4. 你可以单击`安装`按钮将包添加到项目中.
## 安装和卸载预览NPM包
预览NPM包的最新版本可以通过在应用程序的根文件夹命令运行命令安装:
```bash
abp switch-to-preview
```
如果你正在使用ABP框架预览包,你可以使用此命令切换回稳定版本:
```bash
abp switch-to-stable
```
参阅 [ABP CLI 文档](./CLI.md) 了解更多信息.

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs

@ -12,6 +12,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Select2
{
//TODO: Add select2.full.min.js or localize!
context.Files.AddIfNotContains("/libs/select2/js/select2.min.js");
context.Files.AddIfNotContains("/libs/select2/js/select2-bootstrap-modal-patch.js");
}
}
}

5
framework/src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreTestBaseModule.cs

@ -1,10 +1,13 @@
using Volo.Abp.Http.Client;
using Volo.Abp.Autofac;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.TestBase
{
[DependsOn(typeof(AbpHttpClientModule))]
[DependsOn(typeof(AbpAspNetCoreModule))]
[DependsOn(typeof(AbpTestBaseModule))]
[DependsOn(typeof(AbpAutofacModule))]
public class AbpAspNetCoreTestBaseModule : AbpModule
{

2
framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionConventionalRegistrationExtensions.cs

@ -13,7 +13,7 @@ namespace Microsoft.Extensions.DependencyInjection
return services;
}
internal static List<IConventionalRegistrar> GetConventionalRegistrars(this IServiceCollection services)
public static List<IConventionalRegistrar> GetConventionalRegistrars(this IServiceCollection services)
{
return GetOrCreateRegistrarList(services);
}

4
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

2
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Consent.cshtml.cs

@ -188,7 +188,7 @@ namespace Volo.Abp.Account.Web.Pages
public List<string> GetAllowedScopeNames()
{
var identityScopes = IdentityScopes ?? new List<ConsentModel.ScopeViewModel>();
var apiScopes = IdentityScopes ?? new List<ConsentModel.ScopeViewModel>();
var apiScopes = ApiScopes ?? new List<ConsentModel.ScopeViewModel>();
return identityScopes.Union(apiScopes).Where(s => s.Checked).Select(s => s.Name).ToList();
}
}

4
modules/blogging/app/Volo.BloggingTestApp/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
modules/client-simulation/demo/Volo.ClientSimulation.Demo/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
modules/docs/app/VoloDocs.Web/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
npm/ng-packs/apps/dev-app/src/index.html

@ -8,6 +8,8 @@
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body class="bg-light">
<app-root></app-root>
<app-root>
<div class="donut centered"></div>
</app-root>
</body>
</html>

25
npm/ng-packs/apps/dev-app/src/styles.scss

@ -1 +1,26 @@
/* You can add global styles to this file, and also import other style files */
@keyframes donut-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.donut {
display: inline-block;
border: 4px solid rgba(0, 0, 0, 0.1);
border-left-color: #7983ff;
border-radius: 50%;
width: 30px;
height: 30px;
animation: donut-spin 1.2s linear infinite;
&.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}

24
npm/ng-packs/package.json

@ -22,18 +22,18 @@
"generate:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
},
"devDependencies": {
"@abp/ng.account": "~2.5.0",
"@abp/ng.account.config": "~2.5.0",
"@abp/ng.core": "~2.5.0",
"@abp/ng.feature-management": "~2.5.0",
"@abp/ng.identity": "~2.5.0",
"@abp/ng.identity.config": "~2.5.0",
"@abp/ng.permission-management": "~2.5.0",
"@abp/ng.setting-management": "~2.5.0",
"@abp/ng.setting-management.config": "~2.5.0",
"@abp/ng.tenant-management": "~2.5.0",
"@abp/ng.tenant-management.config": "~2.5.0",
"@abp/ng.theme.basic": "~2.5.0",
"@abp/ng.account": "^2.5.0",
"@abp/ng.account.config": "^2.5.0",
"@abp/ng.core": "^2.5.0",
"@abp/ng.feature-management": "^2.5.0",
"@abp/ng.identity": "^2.5.0",
"@abp/ng.identity.config": "^2.5.0",
"@abp/ng.permission-management": "^2.5.0",
"@abp/ng.setting-management": "^2.5.0",
"@abp/ng.setting-management.config": "^2.5.0",
"@abp/ng.tenant-management": "^2.5.0",
"@abp/ng.tenant-management.config": "^2.5.0",
"@abp/ng.theme.basic": "^2.5.0",
"@abp/ng.theme.shared": "~2.5.0",
"@abp/utils": "^2.4.0",
"@angular-builders/jest": "^8.2.0",

13
npm/ng-packs/packages/core/src/lib/core.module.ts

@ -9,13 +9,16 @@ import { NgxsModule, NGXS_PLUGINS } from '@ngxs/store';
import { OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
import { AbstractNgModelComponent } from './abstracts/ng-model.component';
import { DynamicLayoutComponent } from './components/dynamic-layout.component';
import { ReplaceableRouteContainerComponent } from './components/replaceable-route-container.component';
import { RouterOutletComponent } from './components/router-outlet.component';
import { AutofocusDirective } from './directives/autofocus.directive';
import { InputEventDebounceDirective } from './directives/debounce.directive';
import { EllipsisDirective } from './directives/ellipsis.directive';
import { ForDirective } from './directives/for.directive';
import { FormSubmitDirective } from './directives/form-submit.directive';
import { InitDirective } from './directives/init.directive';
import { PermissionDirective } from './directives/permission.directive';
import { ReplaceableTemplateDirective } from './directives/replaceable-template.directive';
import { StopPropagationDirective } from './directives/stop-propagation.directive';
import { VisibilityDirective } from './directives/visibility.directive';
import { ApiInterceptor } from './interceptors/api.interceptor';
@ -26,13 +29,11 @@ import { ConfigPlugin, NGXS_CONFIG_PLUGIN_OPTIONS } from './plugins/config.plugi
import { LocaleProvider } from './providers/locale.provider';
import { ConfigState } from './states/config.state';
import { ProfileState } from './states/profile.state';
import { ReplaceableComponentsState } from './states/replaceable-components.state';
import { SessionState } from './states/session.state';
import { CORE_OPTIONS } from './tokens/options.token';
import { getInitialData, localeInitializer } from './utils/initial-utils';
import './utils/date-extensions';
import { ReplaceableRouteContainerComponent } from './components/replaceable-route-container.component';
import { ReplaceableComponentsState } from './states/replaceable-components.state';
import { InitDirective } from './directives/init.directive';
import { ReplaceableTemplateDirective } from './directives/replaceable-template.directive';
export function storageFactory(): OAuthStorage {
return localStorage;
@ -111,6 +112,10 @@ export class CoreModule {
},
{
provide: NGXS_CONFIG_PLUGIN_OPTIONS,
useValue: { environment: options.environment },
},
{
provide: CORE_OPTIONS,
useValue: options,
},
{

1
npm/ng-packs/packages/core/src/lib/models/common.ts

@ -11,6 +11,7 @@ export namespace ABP {
* @deprecated To be deleted in v3.0
*/
requirements?: Config.Requirements;
skipGetAppConfiguration?: boolean;
}
export type PagedResponse<T> = {

3
npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts

@ -1,7 +1,6 @@
import { Component, Injector } from '@angular/core';
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { Store } from '@ngxs/store';
import { OAuthService } from 'angular-oauth2-oidc';
import { of } from 'rxjs';
import { GetAppConfiguration } from '../actions';
import { getInitialData, localeInitializer } from '../utils';
@ -29,6 +28,7 @@ describe('InitialUtils', () => {
const dispatchSpy = jest.spyOn(store, 'dispatch');
injectorSpy.mockReturnValueOnce(store);
injectorSpy.mockReturnValueOnce({ skipGetAppConfiguration: false });
injectorSpy.mockReturnValueOnce({ hasValidAccessToken: () => false });
dispatchSpy.mockReturnValue(of('test'));
@ -47,6 +47,7 @@ describe('InitialUtils', () => {
const logOutFn = jest.fn();
injectorSpy.mockReturnValueOnce(store);
injectorSpy.mockReturnValueOnce({ skipGetAppConfiguration: false });
injectorSpy.mockReturnValueOnce({ hasValidAccessToken: () => true, logOut: logOutFn });
dispatchSpy.mockReturnValue(of({ currentUser: { id: null } }));

18
npm/ng-packs/packages/core/src/lib/tokens/common.token.ts

@ -1,18 +0,0 @@
import { InjectionToken } from '@angular/core';
import { Config } from '../models';
export function environmentFactory(environment: Config.Environment) {
return {
...environment,
};
}
export function configFactory(config: Config.Requirements) {
return {
...config,
};
}
export const ENVIRONMENT = new InjectionToken('ENVIRONMENT');
export const CONFIG = new InjectionToken('CONFIG');

2
npm/ng-packs/packages/core/src/lib/tokens/index.ts

@ -1 +1 @@
export * from './common.token';
export * from './options.token';

4
npm/ng-packs/packages/core/src/lib/tokens/options.token.ts

@ -0,0 +1,4 @@
import { InjectionToken } from '@angular/core';
import { ABP } from '../models/common';
export const CORE_OPTIONS = new InjectionToken<ABP.Root>('CORE_OPTIONS');

10
npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts

@ -1,16 +1,20 @@
import { registerLocaleData } from '@angular/common';
import { Injector } from '@angular/core';
import { Store } from '@ngxs/store';
import { OAuthService } from 'angular-oauth2-oidc';
import { tap } from 'rxjs/operators';
import { GetAppConfiguration } from '../actions/config.actions';
import differentLocales from '../constants/different-locales';
import { ApplicationConfiguration } from '../models/application-configuration';
import { tap } from 'rxjs/operators';
import { ABP } from '../models/common';
import { ConfigState } from '../states/config.state';
import { OAuthService } from 'angular-oauth2-oidc';
import { CORE_OPTIONS } from '../tokens/options.token';
export function getInitialData(injector: Injector) {
const fn = () => {
const store: Store = injector.get(Store);
const { skipGetAppConfiguration } = injector.get(CORE_OPTIONS) as ABP.Root;
if (skipGetAppConfiguration) return;
return store
.dispatch(new GetAppConfiguration())

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

@ -155,9 +155,6 @@
<router-outlet #outlet="outlet"></router-outlet>
</div>
<abp-confirmation></abp-confirmation>
<abp-toast-container right="30px" bottom="30px"></abp-toast-container>
<ng-template #appName>
{{ appInfo.name }}
</ng-template>

21
npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts

@ -1,14 +1,29 @@
import { Injectable } from '@angular/core';
import { Injectable, ComponentRef } from '@angular/core';
import { Confirmation } from '../models/confirmation';
import { fromEvent, Observable, Subject, ReplaySubject } from 'rxjs';
import { takeUntil, debounceTime, filter } from 'rxjs/operators';
import { Config } from '@abp/ng.core';
import { Config, ContentProjectionService, PROJECTION_STRATEGY } from '@abp/ng.core';
import { ConfirmationComponent } from '../components/confirmation/confirmation.component';
@Injectable({ providedIn: 'root' })
export class ConfirmationService {
status$: Subject<Confirmation.Status>;
confirmation$ = new ReplaySubject<Confirmation.DialogData>(1);
private containerComponentRef: ComponentRef<ConfirmationComponent>;
constructor(private contentProjectionService: ContentProjectionService) {}
private setContainer() {
setTimeout(() => {
this.containerComponentRef = this.contentProjectionService.projectContent(
PROJECTION_STRATEGY.AppendComponentToBody(ConfirmationComponent),
);
this.containerComponentRef.changeDetectorRef.detectChanges();
}, 0);
}
info(
message: Config.LocalizationParam,
title: Config.LocalizationParam,
@ -47,6 +62,8 @@ export class ConfirmationService {
severity?: Confirmation.Severity,
options?: Partial<Confirmation.Options>,
): Observable<Confirmation.Status> {
if (!this.containerComponentRef) this.setContainer();
this.confirmation$.next({
message,
title,

19
npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts

@ -1,8 +1,9 @@
import { Injectable } from '@angular/core';
import { Injectable, ComponentRef } from '@angular/core';
import { Toaster } from '../models';
import { ReplaySubject } from 'rxjs';
import { Config } from '@abp/ng.core';
import { Config, PROJECTION_STRATEGY, ContentProjectionService } from '@abp/ng.core';
import snq from 'snq';
import { ToastContainerComponent } from '../components/toast-container/toast-container.component';
@Injectable({
providedIn: 'root',
@ -14,6 +15,18 @@ export class ToasterService {
private toasts = [] as Toaster.Toast[];
private containerComponentRef: ComponentRef<ToastContainerComponent>;
constructor(private contentProjectionService: ContentProjectionService) {}
private setContainer() {
this.containerComponentRef = this.contentProjectionService.projectContent(
PROJECTION_STRATEGY.AppendComponentToBody(ToastContainerComponent),
);
this.containerComponentRef.changeDetectorRef.detectChanges();
}
/**
* Creates an info toast with given parameters.
* @param message Content of the toast
@ -84,6 +97,8 @@ export class ToasterService {
severity: Toaster.Severity = 'neutral',
options = {} as Partial<Toaster.ToastOptions>,
) {
if (!this.containerComponentRef) this.setContainer();
const id = ++this.lastId;
this.toasts.push({
message,

6
npm/ng-packs/packages/theme-shared/src/lib/tests/confirmation.service.spec.ts

@ -31,7 +31,7 @@ describe('ConfirmationService', () => {
service = spectator.get(ConfirmationService);
});
test('should display a confirmation popup', () => {
test.skip('should display a confirmation popup', () => {
service.info('test', 'title');
spectator.detectChanges();
@ -40,7 +40,7 @@ describe('ConfirmationService', () => {
expect(spectator.query('div.confirmation .message')).toHaveText('test');
});
test('should close with ESC key', done => {
test.skip('should close with ESC key', done => {
service.info('test', 'title').subscribe(() => {
setTimeout(() => {
spectator.detectComponentChanges();
@ -54,7 +54,7 @@ describe('ConfirmationService', () => {
spectator.dispatchKeyboardEvent('div.confirmation', 'keyup', 'Escape');
});
test('should close when click cancel button', done => {
test.skip('should close when click cancel button', done => {
service.info('test', 'title', { yesText: 'Sure', cancelText: 'Exit' }).subscribe(() => {
spectator.detectComponentChanges();
setTimeout(() => {

28
npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts

@ -40,7 +40,7 @@ describe('ErrorHandler', () => {
if (abpError) document.body.removeChild(abpError);
});
it('should display the error component when server error occurs', () => {
test.skip('should display the error component when server error occurs', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 500 })));
expect(document.querySelector('.error-template')).toHaveText(
DEFAULT_ERROR_MESSAGES.defaultError500.title,
@ -50,7 +50,7 @@ describe('ErrorHandler', () => {
);
});
it('should display the error component when authorize error occurs', () => {
test.skip('should display the error component when authorize error occurs', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 403 })));
expect(document.querySelector('.error-template')).toHaveText(
DEFAULT_ERROR_MESSAGES.defaultError403.title,
@ -60,7 +60,7 @@ describe('ErrorHandler', () => {
);
});
it('should display the error component when unknown error occurs', () => {
test.skip('should display the error component when unknown error occurs', () => {
store.dispatch(
new RestOccurError(new HttpErrorResponse({ status: 0, statusText: 'Unknown Error' })),
);
@ -69,7 +69,7 @@ describe('ErrorHandler', () => {
);
});
it('should display the confirmation when not found error occurs', () => {
test.skip('should display the confirmation when not found error occurs', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 404 })));
spectator.detectChanges();
expect(spectator.query('.confirmation .title')).toHaveText(
@ -80,7 +80,7 @@ describe('ErrorHandler', () => {
);
});
it('should display the confirmation when default error occurs', () => {
test.skip('should display the confirmation when default error occurs', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 412 })));
spectator.detectChanges();
expect(spectator.query('.confirmation .title')).toHaveText(
@ -91,7 +91,7 @@ describe('ErrorHandler', () => {
);
});
it('should display the confirmation when authenticated error occurs', async () => {
test.skip('should display the confirmation when authenticated error occurs', async () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 401 })));
spectator.detectChanges();
@ -100,7 +100,7 @@ describe('ErrorHandler', () => {
expect(spectator.get(Location).path()).toBe('/account/login');
});
it('should display the confirmation when authenticated error occurs with _AbpErrorFormat header', async () => {
test.skip('should display the confirmation when authenticated error occurs with _AbpErrorFormat header', async () => {
let headers: HttpHeaders = new HttpHeaders();
headers = headers.append('_AbpErrorFormat', '_AbpErrorFormat');
@ -112,7 +112,7 @@ describe('ErrorHandler', () => {
expect(spectator.get(Location).path()).toBe('/account/login');
});
it('should display the confirmation when error occurs with _AbpErrorFormat header', () => {
test.skip('should display the confirmation when error occurs with _AbpErrorFormat header', () => {
let headers: HttpHeaders = new HttpHeaders();
headers = headers.append('_AbpErrorFormat', '_AbpErrorFormat');
@ -180,34 +180,34 @@ describe('ErrorHandler with custom error component', () => {
});
describe('Custom error component', () => {
it('should create when occur 401', () => {
test.skip('should create when occur 401', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 401 })));
expect(document.querySelector('abp-dummy-error')).toBeTruthy();
expect(document.querySelector('p')).toHaveExactText('401');
});
it('should create when occur 403', () => {
test.skip('should create when occur 403', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 403 })));
expect(document.querySelector('p')).toHaveExactText('403');
});
it('should create when occur 404', () => {
test.skip('should create when occur 404', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 404 })));
expect(document.querySelector('p')).toHaveExactText('404');
});
it('should create when dispatched the RouterError', () => {
test.skip('should create when dispatched the RouterError', () => {
store.dispatch(new RouterError(null, null, new NavigationError(1, 'test', 'Cannot match')));
expect(document.querySelector('p')).toHaveExactText('404');
store.dispatch(new RouterDataResolved(null, new ResolveEnd(1, 'test', 'test', null)));
});
it('should create when occur 500', () => {
test.skip('should create when occur 500', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 500 })));
expect(document.querySelector('p')).toHaveExactText('500');
});
it('should be destroyed when click the close button', () => {
test.skip('should be destroyed when click the close button', () => {
store.dispatch(new RestOccurError(new HttpErrorResponse({ status: 500 })));
document.querySelector<HTMLButtonElement>('#close-dummy').click();
spectator.detectChanges();

12
npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts

@ -31,7 +31,7 @@ describe('ToasterService', () => {
service = spectator.get(ToasterService);
});
test('should display an error toast', () => {
test.skip('should display an error toast', () => {
service.error('test', 'title');
spectator.detectChanges();
@ -42,25 +42,25 @@ describe('ToasterService', () => {
expect(spectator.query('p.toast-message')).toHaveText('test');
});
test('should display a warning toast', () => {
test.skip('should display a warning toast', () => {
service.warn('test', 'title');
spectator.detectChanges();
expect(spectator.query('.toast-icon i')).toHaveClass('fa-exclamation-triangle');
});
test('should display a success toast', () => {
test.skip('should display a success toast', () => {
service.success('test', 'title');
spectator.detectChanges();
expect(spectator.query('.toast-icon i')).toHaveClass('fa-check-circle');
});
test('should display an info toast', () => {
test.skip('should display an info toast', () => {
service.info('test', 'title');
spectator.detectChanges();
expect(spectator.query('.toast-icon i')).toHaveClass('fa-info-circle');
});
test('should display multiple toasts', () => {
test.skip('should display multiple toasts', () => {
service.info('detail1', 'summary1');
service.info('detail2', 'summary2');
@ -75,7 +75,7 @@ describe('ToasterService', () => {
]);
});
test('should remove the opened toasts', () => {
test.skip('should remove the opened toasts', () => {
service.info('test', 'title');
spectator.detectChanges();
expect(spectator.query('div.toast')).toBeTruthy();

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

@ -83,7 +83,13 @@ export function appendScript(injector: Injector) {
TableSortDirective,
],
providers: [DatePipe],
entryComponents: [HttpErrorWrapperComponent, LoadingComponent, ModalContainerComponent],
entryComponents: [
HttpErrorWrapperComponent,
LoadingComponent,
ModalContainerComponent,
ToastContainerComponent,
ConfirmationComponent,
],
})
export class ThemeSharedModule {
constructor(private errorHandler: ErrorHandler) {}

15
npm/ng-packs/scripts/install-new-dependencies.ts

@ -13,15 +13,11 @@ const updateAndInstall = async () => {
`../packages/${project}/package.json`,
);
const isPackageExistOnNPM = !(
execa.sync('npm', ['search', name]).stdout.indexOf('No matches found for') > -1
);
packageJson.devDependencies = {
...packageJson.devDependencies,
...dependencies,
...peerDependencies,
...(isPackageExistOnNPM && { [name]: `~${version}` }),
[name]: `^${version}`,
};
packageJson.devDependencies = Object.keys(packageJson.devDependencies)
@ -29,6 +25,15 @@ const updateAndInstall = async () => {
.reduce((acc, key) => ({ ...acc, [key]: packageJson.devDependencies[key] }), {});
});
console.warn('Searching the packages on NPM to check if it is exist. It takes a while.');
Object.keys(packageJson.devDependencies).forEach(pkg => {
const isPackageExistOnNPM = !(
execa.sync('npm', ['search', pkg]).stdout.indexOf('No matches found for') > -1
);
if (!isPackageExistOnNPM) delete packageJson.devDependencies[pkg];
});
await fse.writeJSON('../package.json', packageJson, { spaces: 2 });
try {

1356
npm/ng-packs/yarn.lock

File diff suppressed because it is too large

3
npm/packs/select2/abp.resourcemapping.js

@ -3,6 +3,7 @@
"@node_modules/select2/dist/css/select2.min.css": "@libs/select2/css/",
"@node_modules/select2/dist/js/select2.min.js": "@libs/select2/js/",
"@node_modules/select2/dist/js/select2.full.min.js": "@libs/select2/js/",
"@node_modules/select2/dist/js/i18n/*.js": "@libs/select2/js/i18n/"
"@node_modules/select2/dist/js/i18n/*.js": "@libs/select2/js/i18n/",
"@node_modules/@abp/select2/src/*.*": "@libs/select2/js/"
}
}

4
npm/packs/select2/src/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
samples/MicroserviceDemo/applications/AuthServer.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
samples/MicroserviceDemo/applications/BackendAdminApp.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

4
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/wwwroot/libs/select2/js/select2-bootstrap-modal-patch.js

@ -0,0 +1,4 @@
/*
https://select2.org/troubleshooting/common-problems
*/
$.fn.modal.Constructor.prototype._enforceFocus = function () { };
Loading…
Cancel
Save