Browse Source

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

pull/3580/head
liangshiwei 7 years ago
parent
commit
e796d352e5
  1. 62
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json
  2. 2
      modules/blogging/app/Volo.BloggingTestApp/Volo.BloggingTestApp.csproj
  3. 2
      modules/docs/app/VoloDocs.Web/VoloDocs.Web.csproj
  4. 12
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-container.component.ts
  5. 67
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html
  6. 60
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts
  7. 1
      npm/ng-packs/packages/theme-shared/src/lib/services/index.ts
  8. 47
      npm/ng-packs/packages/theme-shared/src/lib/services/modal.service.ts
  9. 34
      npm/ng-packs/packages/theme-shared/src/lib/tests/modal-container.component.spec.ts
  10. 224
      npm/ng-packs/packages/theme-shared/src/lib/tests/modal.component.spec.ts
  11. 87
      npm/ng-packs/packages/theme-shared/src/lib/tests/modal.service.spec.ts
  12. 16
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
  13. 2
      samples/MicroserviceDemo/applications/BackendAdminApp.Host/BackendAdminApp.Host.csproj
  14. 2
      samples/MicroserviceDemo/gateways/BackendAdminAppGateway.Host/BackendAdminAppGateway.Host.csproj
  15. 2
      samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGateway.Host.csproj
  16. 2
      samples/MicroserviceDemo/gateways/PublicWebSiteGateway.Host/PublicWebSiteGateway.Host.csproj
  17. 2
      samples/MicroserviceDemo/microservices/BloggingService.Host/BloggingService.Host.csproj
  18. 2
      samples/MicroserviceDemo/microservices/IdentityService.Host/IdentityService.Host.csproj
  19. 2
      samples/MicroserviceDemo/microservices/ProductService.Host/ProductService.Host.csproj
  20. 2
      samples/MicroserviceDemo/microservices/TenantManagementService.Host/TenantManagementService.Host.csproj
  21. 9
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/DbMigratorHostedService.cs
  22. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj
  23. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj
  24. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj
  25. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj
  26. 14
      templates/app/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBaseModule.cs
  27. 2
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj
  28. 2
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj
  29. 2
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj
  30. 2
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyCompanyName.MyProjectName.Web.Unified.csproj

62
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json

@ -0,0 +1,62 @@
{
"culture": "sl",
"texts": {
"InternalServerErrorMessage": "Zgodila se je napaka na strežniku!",
"ValidationErrorMessage": "Vaš zahtevek ni veljaven!",
"ValidationNarrativeErrorMessageTitle": "Pri preverjanju so bile zaznane sledeče napake.",
"DefaultErrorMessage": "Zgodila se je napaka!",
"DefaultErrorMessageDetail": "Strežnik ni poslal podrobnosti o napaki.",
"DefaultErrorMessage401": "Niste prijavljeni!",
"DefaultErrorMessage401Detail": "Za izvedbo te operacije se morate prijaviti.",
"DefaultErrorMessage403": "Nimate pravic!",
"DefaultErrorMessage403Detail": "Nimate dovoljenja za izvedbo te operacije!",
"DefaultErrorMessage404": "Vir ni bil najden!",
"DefaultErrorMessage404Detail": "Zahtevanega vira ni bilo mogoče najti na strežniku!",
"EntityNotFoundErrorMessage": "Ni entitete {0} z id-jem = {1}!",
"Languages": "Jeziki",
"Error": "Napaka",
"AreYouSure": "Ali ste prepričani?",
"Cancel": "Prekliči",
"Yes": "Da",
"No": "Ne",
"Ok": "V redu",
"Close": "Zapri",
"Save": "Shrani",
"SavingWithThreeDot": "Shranjujem...",
"Actions": "Dejanja",
"Delete": "Izbriši",
"Edit": "Uredi",
"Refresh": "Osveži",
"Language": "Jezik",
"LoadMore": "Naloži več",
"ProcessingWithThreeDot": "Procesiram...",
"LoadingWithThreeDot": "Nalagam...",
"Welcome": "Dobrodošli",
"Login": "Prijava",
"Register": "Registracija",
"Logout": "Odjava",
"Submit": "Pošlji",
"Back": "Nazaj",
"PagerSearch": "Iskanje",
"PagerNext": "Naslednja",
"PagerPrevious": "Prejšnja",
"PagerFirst": "Prva",
"PagerLast": "Zadnja",
"PagerInfo": "Prikazanih _START_ do _END_ od _TOTAL_ zapisov",
"PagerInfoEmpty": "Prikazanih 0 do 0 od 0 zapisov",
"PagerInfoFiltered": "(filtrirano od vseh _MAX_ zapisov)",
"NoDataAvailableInDatatable": "V tabeli ni na voljo podatkov",
"PagerShowMenuEntries": "Prikaži _MENU_ zapise",
"DatatableActionDropdownDefaultText": "Dejanja",
"ChangePassword": "Zamenjaj geslo",
"PersonalInfo": "Moj profil",
"AreYouSureYouWantToCancelEditingWarningMessage": "Imate neshranjene spremembe.",
"UnhandledException": "Neobravnavana napaka!",
"401Message": "Nepooblaščeno",
"403Message": "Prepovedano",
"404Message": "Strani ni mogoče najti",
"500Message": "Napaka na strani strežnika",
"GoHomePage": "Pojdi na osnovno stran",
"GoBack": "Nazaj"
}
}

2
modules/blogging/app/Volo.BloggingTestApp/Volo.BloggingTestApp.csproj

@ -17,7 +17,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.2" />
</ItemGroup> </ItemGroup>

2
modules/docs/app/VoloDocs.Web/VoloDocs.Web.csproj

@ -19,7 +19,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.1"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.1">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

12
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-container.component.ts

@ -0,0 +1,12 @@
import { Component, ViewChild, ViewContainerRef } from '@angular/core';
@Component({
selector: 'abp-modal-container',
template: `
<ng-container #container></ng-container>
`,
})
export class ModalContainerComponent {
@ViewChild('container', { static: true, read: ViewContainerRef })
container: ViewContainerRef;
}

67
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html

@ -1,34 +1,43 @@
<div <ng-template #template>
*ngIf="visible"
[@fade]="isModalOpen"
id="modal-container"
class="modal show {{ modalClass }}"
tabindex="-1"
role="dialog"
>
<div class="modal-backdrop" (click)="close()"></div>
<div <div
id="abp-modal-dialog" *ngIf="visible"
class="modal-dialog modal-{{ size }}" [@fade]="isModalOpen"
role="document" id="modal-container"
[class.modal-dialog-centered]="centered" class="modal show {{ modalClass }}"
#abpModalContent tabindex="-1"
role="dialog"
> >
<div id="abp-modal-content" class="modal-content"> <div class="modal-backdrop" (click)="close()"></div>
<div id="abp-modal-header" class="modal-header"> <div
<ng-container *ngTemplateOutlet="abpHeader"></ng-container> id="abp-modal-dialog"
​ class="modal-dialog modal-{{ size }}"
<button id="abp-modal-close-button" type="button" class="close" aria-label="Close" (click)="close()"> role="document"
<span aria-hidden="true">&times;</span> [class.modal-dialog-centered]="centered"
</button> #abpModalContent
</div> >
<div id="abp-modal-body" class="modal-body"> <div id="abp-modal-content" class="modal-content">
<ng-container *ngTemplateOutlet="abpBody"></ng-container> <div id="abp-modal-header" class="modal-header">
</div> <ng-container *ngTemplateOutlet="abpHeader"></ng-container>
<div id="abp-modal-footer" class="modal-footer"> ​
<ng-container *ngTemplateOutlet="abpFooter"></ng-container> <button
id="abp-modal-close-button"
type="button"
class="close"
aria-label="Close"
(click)="close()"
>
<span aria-hidden="true">&times;</span>
</button>
</div>
<div id="abp-modal-body" class="modal-body">
<ng-container *ngTemplateOutlet="abpBody"></ng-container>
</div>
<div id="abp-modal-footer" class="modal-footer">
<ng-container *ngTemplateOutlet="abpFooter"></ng-container>
</div>
</div> </div>
</div> </div>
</div> </div>
<ng-content></ng-content> </ng-template>
</div>
<ng-content></ng-content>

60
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts

@ -1,3 +1,4 @@
import { takeUntilDestroy } from '@abp/ng.core';
import { import {
Component, Component,
ContentChild, ContentChild,
@ -12,10 +13,11 @@ import {
ViewChildren, ViewChildren,
} from '@angular/core'; } from '@angular/core';
import { fromEvent, Subject } from 'rxjs'; import { fromEvent, Subject } from 'rxjs';
import { debounceTime, filter, takeUntil } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, filter, takeUntil } from 'rxjs/operators';
import { fadeAnimation } from '../../animations/modal.animations'; import { fadeAnimation } from '../../animations/modal.animations';
import { Confirmation } from '../../models/confirmation'; import { Confirmation } from '../../models/confirmation';
import { ConfirmationService } from '../../services/confirmation.service'; import { ConfirmationService } from '../../services/confirmation.service';
import { ModalService } from '../../services/modal.service';
import { ButtonComponent } from '../button/button.component'; import { ButtonComponent } from '../button/button.component';
export type ModalSize = 'sm' | 'md' | 'lg' | 'xl'; export type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
@ -33,20 +35,7 @@ export class ModalComponent implements OnDestroy {
} }
set visible(value: boolean) { set visible(value: boolean) {
if (typeof value !== 'boolean') return; if (typeof value !== 'boolean') return;
this.toggle$.next(value);
this.isModalOpen = value;
this._visible = value;
this.visibleChange.emit(value);
if (value) {
setTimeout(() => this.listen(), 0);
this.renderer.addClass(document.body, 'modal-open');
this.appear.emit();
} else {
this.renderer.removeClass(document.body, 'modal-open');
this.disappear.emit();
this.destroy$.next();
}
} }
@Input() @Input()
@ -79,6 +68,8 @@ export class ModalComponent implements OnDestroy {
@ContentChild('abpClose', { static: false, read: ElementRef }) @ContentChild('abpClose', { static: false, read: ElementRef })
abpClose: ElementRef<any>; abpClose: ElementRef<any>;
@ViewChild('template', { static: false }) template: TemplateRef<any>;
@ViewChild('abpModalContent', { static: false }) modalContent: ElementRef; @ViewChild('abpModalContent', { static: false }) modalContent: ElementRef;
@ViewChildren('abp-button') abpButtons; @ViewChildren('abp-button') abpButtons;
@ -101,11 +92,43 @@ export class ModalComponent implements OnDestroy {
destroy$ = new Subject<void>(); destroy$ = new Subject<void>();
private toggle$ = new Subject<boolean>();
get isFormDirty(): boolean { get isFormDirty(): boolean {
return Boolean(document.querySelector('.modal-dialog .ng-dirty')); return Boolean(document.querySelector('.modal-dialog .ng-dirty'));
} }
constructor(private renderer: Renderer2, private confirmationService: ConfirmationService) {} constructor(
private renderer: Renderer2,
private confirmationService: ConfirmationService,
private modalService: ModalService,
) {
this.initToggleStream();
}
private initToggleStream() {
this.toggle$
.pipe(takeUntilDestroy(this), debounceTime(0), distinctUntilChanged())
.subscribe(value => this.toggle(value));
}
private toggle(value: boolean) {
this.isModalOpen = value;
this._visible = value;
this.visibleChange.emit(value);
if (value) {
this.modalService.renderTemplate(this.template);
setTimeout(() => this.listen(), 0);
this.renderer.addClass(document.body, 'modal-open');
this.appear.emit();
} else {
this.modalService.clearModal();
this.renderer.removeClass(document.body, 'modal-open');
this.disappear.emit();
this.destroy$.next();
}
}
ngOnDestroy(): void { ngOnDestroy(): void {
this.destroy$.next(); this.destroy$.next();
@ -141,9 +164,7 @@ export class ModalComponent implements OnDestroy {
debounceTime(150), debounceTime(150),
filter((key: KeyboardEvent) => key && key.key === 'Escape'), filter((key: KeyboardEvent) => key && key.key === 'Escape'),
) )
.subscribe(() => { .subscribe(() => this.close());
this.close();
});
fromEvent(window, 'beforeunload') fromEvent(window, 'beforeunload')
.pipe(takeUntil(this.destroy$)) .pipe(takeUntil(this.destroy$))
@ -151,6 +172,7 @@ export class ModalComponent implements OnDestroy {
if (this.isFormDirty) { if (this.isFormDirty) {
event.returnValue = true; event.returnValue = true;
} else { } else {
event.returnValue = false;
delete event.returnValue; delete event.returnValue;
} }
}); });

1
npm/ng-packs/packages/theme-shared/src/lib/services/index.ts

@ -1,2 +1,3 @@
export * from './confirmation.service'; export * from './confirmation.service';
export * from './modal.service';
export * from './toaster.service'; export * from './toaster.service';

47
npm/ng-packs/packages/theme-shared/src/lib/services/modal.service.ts

@ -0,0 +1,47 @@
import { ContentProjectionService, PROJECTION_STRATEGY } from '@abp/ng.core';
import { ComponentRef, Injectable, TemplateRef, ViewContainerRef } from '@angular/core';
import { ModalContainerComponent } from '../components/modal/modal-container.component';
@Injectable({
providedIn: 'root',
})
export class ModalService {
private containerComponentRef: ComponentRef<ModalContainerComponent>;
constructor(private contentProjectionService: ContentProjectionService) {
this.setContainer();
}
private setContainer() {
this.containerComponentRef = this.contentProjectionService.projectContent(
PROJECTION_STRATEGY.AppendComponentToBody(ModalContainerComponent),
);
this.containerComponentRef.changeDetectorRef.detectChanges();
}
clearModal() {
this.getContainer().clear();
this.detectChanges();
}
detectChanges() {
this.containerComponentRef.changeDetectorRef.detectChanges();
}
getContainer(): ViewContainerRef {
return this.containerComponentRef.instance.container;
}
renderTemplate<T extends any>(template: TemplateRef<T>, context?: T) {
const containerRef = this.getContainer();
const strategy = PROJECTION_STRATEGY.ProjectTemplateToContainer(
template,
containerRef,
context,
);
this.contentProjectionService.projectContent(strategy);
}
}

34
npm/ng-packs/packages/theme-shared/src/lib/tests/modal-container.component.spec.ts

@ -0,0 +1,34 @@
import { Component, ComponentFactoryResolver, ComponentRef } from '@angular/core';
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { ModalContainerComponent } from '../components/modal/modal-container.component';
describe('ModalContainerComponent', () => {
@Component({ template: '<div class="foo">bar</div>' })
class TestComponent {}
let componentRef: ComponentRef<TestComponent>;
let spectator: Spectator<ModalContainerComponent>;
const createComponent = createComponentFactory({
component: ModalContainerComponent,
entryComponents: [TestComponent],
});
beforeEach(() => (spectator = createComponent()));
afterEach(() => componentRef.destroy());
describe('#container', () => {
it('should be a ViewContainerRef', () => {
let foo = document.querySelector('div.foo');
expect(foo).toBeNull();
const cfResolver = spectator.get(ComponentFactoryResolver);
const factory = cfResolver.resolveComponentFactory(TestComponent);
componentRef = spectator.component.container.createComponent(factory);
foo = document.querySelector('div.foo');
expect(foo.textContent).toBe('bar');
});
});
});

224
npm/ng-packs/packages/theme-shared/src/lib/tests/modal.component.spec.ts

@ -1,9 +1,13 @@
import { LocalizationPipe } from '@abp/ng.core'; import { LocalizationPipe } from '@abp/ng.core';
import { RouterTestingModule } from '@angular/router/testing';
import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest'; import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
import { timer } from 'rxjs'; import { fromEvent, Subject, timer } from 'rxjs';
import { delay, reduce, take } from 'rxjs/operators';
import { ButtonComponent, ConfirmationComponent, ModalComponent } from '../components'; import { ButtonComponent, ConfirmationComponent, ModalComponent } from '../components';
import { RouterTestingModule } from '@angular/router/testing'; import { ModalContainerComponent } from '../components/modal/modal-container.component';
import { Confirmation } from '../models';
import { ConfirmationService, ModalService } from '../services';
describe('ModalComponent', () => { describe('ModalComponent', () => {
let spectator: SpectatorHost< let spectator: SpectatorHost<
@ -12,16 +16,34 @@ describe('ModalComponent', () => {
>; >;
let appearFn; let appearFn;
let disappearFn; let disappearFn;
let mockConfirmation$: Subject<Confirmation.Status>;
const createHost = createHostFactory({ const createHost = createHostFactory({
component: ModalComponent, component: ModalComponent,
imports: [RouterTestingModule], imports: [RouterTestingModule],
declarations: [ConfirmationComponent, LocalizationPipe, ButtonComponent], declarations: [
ConfirmationComponent,
LocalizationPipe,
ButtonComponent,
ModalContainerComponent,
],
entryComponents: [ModalContainerComponent],
providers: [
{
provide: ConfirmationService,
useValue: {
warn() {
mockConfirmation$ = new Subject();
return mockConfirmation$;
},
},
},
],
mocks: [Store], mocks: [Store],
}); });
beforeEach(() => { beforeEach(async () => {
appearFn = jest.fn(() => null); appearFn = jest.fn();
disappearFn = jest.fn(() => null); disappearFn = jest.fn();
spectator = createHost( spectator = createHost(
`<abp-modal [(visible)]="visible" [busy]="busy" [centered]="true" (appear)="appearFn()" (disappear)="disappearFn()" size="sm" modalClass="test"> `<abp-modal [(visible)]="visible" [busy]="busy" [centered]="true" (appear)="appearFn()" (disappear)="disappearFn()" size="sm" modalClass="test">
@ -30,102 +52,170 @@ describe('ModalComponent', () => {
</ng-template> </ng-template>
<ng-template #abpBody> <ng-template #abpBody>
<div class="body"> <div class="body"><input [class.ng-dirty]="ngDirty"></div>
<input [class.ng-dirty]="ngDirty">
</div>
</ng-template> </ng-template>
<ng-template #abpFooter> <ng-template #abpFooter>
<div class="footer"> <div class="footer">
<button id="abp-close" #abpClose></button> <button id="abp-close" #abpClose></button>
<abp-button>Submit</abp-button>
</div> </div>
</ng-template> </ng-template>
<abp-button>Submit</abp-button>
<abp-confirmation></abp-confirmation>
</abp-modal> </abp-modal>
`, `,
{ {
hostProps: { hostProps: {
visible: true, visible: true,
busy: false, busy: false,
ngDirty: true, ngDirty: false,
appearFn, appearFn,
disappearFn, disappearFn,
}, },
}, },
); );
await wait0ms();
});
afterEach(() => {
const modalService = spectator.get(ModalService);
modalService.clearModal();
}); });
it('should be created', () => { it('should project its template to abp-modal-container', () => {
expect(spectator.query('div.modal')).toBeTruthy(); const modal = selectModal();
expect(spectator.query('div.modal-backdrop')).toBeTruthy(); expect(modal).toBeTruthy();
expect(spectator.query('div#abp-modal-dialog')).toBeTruthy(); expect(modal.querySelector('div.modal-backdrop')).toBeTruthy();
expect(modal.querySelector('div#abp-modal-dialog')).toBeTruthy();
}); });
it('should works right the inputs', () => { it('should reflect its input properties to the template', () => {
expect(spectator.query('div.test')).toBeTruthy(); const modal = selectModal('.test');
expect(spectator.query('div.modal-sm')).toBeTruthy(); expect(modal).toBeTruthy();
expect(spectator.query('div.modal-dialog-centered')).toBeTruthy(); expect(modal.querySelector('div.modal-sm')).toBeTruthy();
expect(modal.querySelector('div.modal-dialog-centered')).toBeTruthy();
}); });
it('should emit the appear output', () => { it('should emit the appear output when made visible', () => {
expect(appearFn).toHaveBeenCalled(); expect(appearFn).toHaveBeenCalled();
}); });
it('should emit the disappear output', () => { it('should emit the disappear output when made invisible', async () => {
spectator.hostComponent.visible = false; spectator.hostComponent.visible = false;
spectator.detectChanges(); spectator.detectChanges();
expect(disappearFn).toHaveBeenCalled();
await wait0ms();
expect(disappearFn).toHaveBeenCalledTimes(1);
}); });
it('should open the confirmation popup and works correct', done => { xit('should close with the abpClose', async () => {
setTimeout(() => { await wait0ms();
spectator.click('#abp-modal-close-button');
expect(disappearFn).not.toHaveBeenCalled(); spectator.dispatchMouseEvent(spectator.component.abpClose, 'click');
expect(spectator.query('div.confirmation')).toBeTruthy(); await wait0ms();
spectator.click('button#cancel');
expect(spectator.query('div.modal')).toBeTruthy(); expect(disappearFn).toHaveBeenCalledTimes(1);
spectator.click('#abp-modal-close-button');
spectator.click('button#confirm');
expect(spectator.query('div.modal')).toBeFalsy();
expect(disappearFn).toHaveBeenCalled();
done();
}, 100);
}); });
it('should close with the abpClose', done => { it('should open the confirmation popup and works correct', async () => {
spectator.hostComponent.ngDirty = false; const confirmationService = spectator.get(ConfirmationService);
const warnSpy = jest.spyOn(confirmationService, 'warn');
await wait0ms();
spectator.hostComponent.ngDirty = true;
spectator.detectChanges(); spectator.detectChanges();
setTimeout(() => {
spectator.click('#abp-close'); expect(selectModal()).toBeTruthy();
expect(disappearFn).toHaveBeenCalled(); spectator.component.close(); // 1st try
done();
}, 10); await wait0ms();
spectator.component.close(); // 2nd try
await wait0ms();
expect(selectModal()).toBeTruthy();
expect(warnSpy).toHaveBeenCalledTimes(1);
warnSpy.mockClear();
mockConfirmation$.next(Confirmation.Status.reject);
await wait0ms();
expect(selectModal()).toBeTruthy();
spectator.component.close();
await wait0ms();
expect(selectModal()).toBeTruthy();
expect(warnSpy).toHaveBeenCalledTimes(1);
warnSpy.mockClear();
mockConfirmation$.next(Confirmation.Status.confirm);
await wait0ms();
expect(selectModal()).toBeNull();
expect(disappearFn).toHaveBeenCalledTimes(1);
}); });
it('should close with esc key', done => { it('should close with esc key', async () => {
spectator.hostComponent.ngDirty = false; await wait0ms();
spectator.dispatchKeyboardEvent(document.body, 'keyup', 'Escape');
await wait300ms();
expect(spectator.component.visible).toBe(false);
});
it('should not close when busy is true', async () => {
spectator.hostComponent.busy = true;
spectator.detectChanges(); spectator.detectChanges();
timer(0).subscribe(() => {
spectator.dispatchKeyboardEvent(document.body, 'keyup', 'Escape'); spectator.component.close();
});
timer(300).subscribe(() => { await wait0ms();
expect(spectator.component.visible).toBe(false);
done(); expect(disappearFn).not.toHaveBeenCalled();
});
}); });
it('should not close when busy is true', done => { it('should not let window unload when form is dirty', async done => {
setTimeout(() => { fromEvent(window, 'beforeunload')
spectator.hostComponent.busy = true; .pipe(
spectator.hostComponent.ngDirty = false; take(2),
spectator.detectChanges(); delay(0),
spectator.click('#abp-modal-close-button'); reduce<Event[]>((acc, v) => acc.concat(v), []),
expect(disappearFn).not.toHaveBeenCalled(); )
expect(spectator.component.abpSubmit.loading).toBe(true); .subscribe(([event1, event2]) => {
done(); expect(event1.returnValue).toBe(true);
}, 0); expect(event2.returnValue).toBe(false);
done();
});
spectator.hostComponent.ngDirty = true;
spectator.detectChanges();
spectator.dispatchFakeEvent(window, 'beforeunload');
await wait0ms();
spectator.hostComponent.ngDirty = false;
spectator.detectChanges();
spectator.dispatchFakeEvent(window, 'beforeunload');
}); });
}); });
function selectModal(modalSelector = ''): Element {
return document.querySelector(`abp-modal-container div.modal${modalSelector}`);
}
async function wait0ms() {
await timer(0).toPromise();
}
async function wait300ms() {
await timer(300).toPromise();
}

87
npm/ng-packs/packages/theme-shared/src/lib/tests/modal.service.spec.ts

@ -0,0 +1,87 @@
import { Component, TemplateRef, ViewChild } from '@angular/core';
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { ModalContainerComponent } from '../components/modal/modal-container.component';
import { ModalService } from '../services';
describe('ModalContainerComponent', () => {
@Component({
template: `
<ng-template #ref>
<div class="foo">bar</div>
</ng-template>
`,
})
class TestComponent {
@ViewChild('ref', { static: true })
template: TemplateRef<any>;
constructor(public modalService: ModalService) {}
}
let spectator: Spectator<TestComponent>;
let service: ModalService;
const createComponent = createComponentFactory({
component: TestComponent,
entryComponents: [ModalContainerComponent],
});
beforeEach(() => {
spectator = createComponent();
service = spectator.component.modalService;
});
afterEach(() => {
service.getContainer().clear();
service['containerComponentRef'].changeDetectorRef.detectChanges();
service['containerComponentRef'].destroy();
});
describe('#getContainer', () => {
it('should return the ViewContainerRef of ModalContainerComponent', () => {
let foo = document.querySelector('div.foo');
expect(foo).toBeNull();
const containerRef = service.getContainer();
const embeddedViewRef = containerRef.createEmbeddedView(spectator.component.template);
foo = document.querySelector('div.foo');
expect(foo).toBe(embeddedViewRef.rootNodes[0]);
expect(foo.textContent).toBe('bar');
});
});
describe('#renderTemplate', () => {
it('should render given template using the ViewContainerRef of ModalContainerComponent', () => {
let foo = document.querySelector('div.foo');
expect(foo).toBeNull();
service.renderTemplate(spectator.component.template);
foo = document.querySelector('div.foo');
expect(foo.textContent).toBe('bar');
});
});
describe('#detectChanges', () => {
it('should call detectChanges on the containerComponentRef', () => {
const spy = jest.spyOn(service['containerComponentRef'].changeDetectorRef, 'detectChanges');
service.detectChanges();
expect(spy).toHaveBeenCalledTimes(1);
});
});
describe('#clearModal', () => {
it('should call clear on the ViewContainerRef and detectChanges', () => {
const clear = jest.spyOn(service.getContainer(), 'clear');
const detectChanges = jest.spyOn(service, 'detectChanges');
service.clearModal();
expect(clear).toHaveBeenCalledTimes(1);
expect(detectChanges).toHaveBeenCalledTimes(1);
});
});
});

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

@ -1,4 +1,4 @@
import { CoreModule, noop, LazyLoadService } from '@abp/ng.core'; import { CoreModule, LazyLoadService, noop } 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, NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbDateParserFormatter, NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';
@ -9,23 +9,24 @@ import { ChartComponent } from './components/chart/chart.component';
import { ConfirmationComponent } from './components/confirmation/confirmation.component'; import { ConfirmationComponent } from './components/confirmation/confirmation.component';
import { HttpErrorWrapperComponent } from './components/http-error-wrapper/http-error-wrapper.component'; import { HttpErrorWrapperComponent } from './components/http-error-wrapper/http-error-wrapper.component';
import { LoaderBarComponent } from './components/loader-bar/loader-bar.component'; import { LoaderBarComponent } from './components/loader-bar/loader-bar.component';
import { LoadingComponent } from './components/loading/loading.component';
import { ModalContainerComponent } from './components/modal/modal-container.component';
import { ModalComponent } from './components/modal/modal.component'; import { ModalComponent } from './components/modal/modal.component';
import { PaginationComponent } from './components/pagination/pagination.component';
import { SortOrderIconComponent } from './components/sort-order-icon/sort-order-icon.component'; import { SortOrderIconComponent } from './components/sort-order-icon/sort-order-icon.component';
import { TableEmptyMessageComponent } from './components/table-empty-message/table-empty-message.component'; import { TableEmptyMessageComponent } from './components/table-empty-message/table-empty-message.component';
import { ToastContainerComponent } from './components/toast-container/toast-container.component';
import { TableComponent } from './components/table/table.component'; import { TableComponent } from './components/table/table.component';
import { ToastContainerComponent } from './components/toast-container/toast-container.component';
import { ToastComponent } from './components/toast/toast.component'; import { ToastComponent } from './components/toast/toast.component';
import styles from './constants/styles'; import styles from './constants/styles';
import { LoadingDirective } from './directives/loading.directive';
import { TableSortDirective } from './directives/table-sort.directive'; import { TableSortDirective } from './directives/table-sort.directive';
import { ErrorHandler } from './handlers/error.handler'; import { ErrorHandler } from './handlers/error.handler';
import { RootParams } from './models/common'; import { RootParams } from './models/common';
import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token';
import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token'; import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token';
import { DateParserFormatter } from './utils/date-parser-formatter'; import { DateParserFormatter } from './utils/date-parser-formatter';
import { chartJsLoaded$ } from './utils/widget-utils'; import { chartJsLoaded$ } from './utils/widget-utils';
import { PaginationComponent } from './components/pagination/pagination.component';
import { LoadingComponent } from './components/loading/loading.component';
import { LoadingDirective } from './directives/loading.directive';
import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token';
/** /**
* *
@ -54,6 +55,7 @@ export function appendScript(injector: Injector) {
LoaderBarComponent, LoaderBarComponent,
LoadingComponent, LoadingComponent,
ModalComponent, ModalComponent,
ModalContainerComponent,
PaginationComponent, PaginationComponent,
TableComponent, TableComponent,
TableEmptyMessageComponent, TableEmptyMessageComponent,
@ -81,7 +83,7 @@ export function appendScript(injector: Injector) {
TableSortDirective, TableSortDirective,
], ],
providers: [DatePipe], providers: [DatePipe],
entryComponents: [HttpErrorWrapperComponent, LoadingComponent], entryComponents: [HttpErrorWrapperComponent, LoadingComponent, ModalContainerComponent],
}) })
export class ThemeSharedModule { export class ThemeSharedModule {
constructor(private errorHandler: ErrorHandler) {} constructor(private errorHandler: ErrorHandler) {}

2
samples/MicroserviceDemo/applications/BackendAdminApp.Host/BackendAdminApp.Host.csproj

@ -15,7 +15,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
samples/MicroserviceDemo/gateways/BackendAdminAppGateway.Host/BackendAdminAppGateway.Host.csproj

@ -15,7 +15,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Ocelot" Version="13.8.0" /> <PackageReference Include="Ocelot" Version="13.8.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />

2
samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGateway.Host.csproj

@ -15,7 +15,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Ocelot" Version="13.8.0" /> <PackageReference Include="Ocelot" Version="13.8.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />

2
samples/MicroserviceDemo/gateways/PublicWebSiteGateway.Host/PublicWebSiteGateway.Host.csproj

@ -15,7 +15,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Ocelot" Version="13.8.0" /> <PackageReference Include="Ocelot" Version="13.8.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />

2
samples/MicroserviceDemo/microservices/BloggingService.Host/BloggingService.Host.csproj

@ -15,7 +15,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
samples/MicroserviceDemo/microservices/IdentityService.Host/IdentityService.Host.csproj

@ -15,7 +15,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
samples/MicroserviceDemo/microservices/ProductService.Host/ProductService.Host.csproj

@ -15,7 +15,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
samples/MicroserviceDemo/microservices/TenantManagementService.Host/TenantManagementService.Host.csproj

@ -15,7 +15,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" /> <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

9
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/DbMigratorHostedService.cs

@ -10,6 +10,13 @@ namespace MyCompanyName.MyProjectName.DbMigrator
{ {
public class DbMigratorHostedService : IHostedService public class DbMigratorHostedService : IHostedService
{ {
private readonly IHostApplicationLifetime _hostApplicationLifetime;
public DbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime)
{
_hostApplicationLifetime = hostApplicationLifetime;
}
public async Task StartAsync(CancellationToken cancellationToken) public async Task StartAsync(CancellationToken cancellationToken)
{ {
using (var application = AbpApplicationFactory.Create<MyProjectNameDbMigratorModule>(options => using (var application = AbpApplicationFactory.Create<MyProjectNameDbMigratorModule>(options =>
@ -26,6 +33,8 @@ namespace MyCompanyName.MyProjectName.DbMigrator
.MigrateAsync(); .MigrateAsync();
application.Shutdown(); application.Shutdown();
_hostApplicationLifetime.StopApplication();
} }
} }

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj

@ -13,7 +13,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> <PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj

@ -13,7 +13,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> <PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.MultiTenancy\Volo.Abp.AspNetCore.MultiTenancy.csproj" /> <ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.MultiTenancy\Volo.Abp.AspNetCore.MultiTenancy.csproj" />

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj

@ -19,7 +19,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> <PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj

@ -35,7 +35,7 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> <PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" />
</ItemGroup> </ItemGroup>

14
templates/app/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBaseModule.cs

@ -4,6 +4,7 @@ using Volo.Abp.Authorization;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.BackgroundJobs; using Volo.Abp.BackgroundJobs;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.IdentityServer;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Threading; using Volo.Abp.Threading;
@ -17,6 +18,19 @@ namespace MyCompanyName.MyProjectName
)] )]
public class MyProjectNameTestBaseModule : AbpModule public class MyProjectNameTestBaseModule : AbpModule
{ {
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpIdentityServerBuilderOptions>(options =>
{
options.AddDeveloperSigningCredential = false;
});
PreConfigure<IIdentityServerBuilder>(identityServerBuilder =>
{
identityServerBuilder.AddDeveloperSigningCredential(false, System.Guid.NewGuid().ToString());
});
}
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
Configure<AbpBackgroundJobOptions>(options => Configure<AbpBackgroundJobOptions>(options =>

2
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj

@ -12,7 +12,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj

@ -10,7 +10,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj

@ -12,7 +12,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.2" />

2
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyCompanyName.MyProjectName.Web.Unified.csproj

@ -12,7 +12,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> <ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj" /> <ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj" />

Loading…
Cancel
Save