From 13082811a8ebf799aa11bc63fad1cc042c07fcc1 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Fri, 20 Mar 2020 13:55:19 +0300 Subject: [PATCH 01/52] added-modal tag documentation --- docs/en/UI/AspNetCore/Tag-Helpers/Modals.md | 89 +++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 docs/en/UI/AspNetCore/Tag-Helpers/Modals.md diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Modals.md b/docs/en/UI/AspNetCore/Tag-Helpers/Modals.md new file mode 100644 index 0000000000..560c4374f0 --- /dev/null +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Modals.md @@ -0,0 +1,89 @@ +# Modals + +## Introduction + +`abp-modal` is a main element to create a modal. + +Basic usage: + +````xml +Launch modal + + + + + Woohoo, you're reading this text in a modal! + + + +```` + + + +## Demo + +See the [modals demo page](https://bootstrap-taghelpers.abp.io/Components/Modals) to see it in action. + +## Attributes + +### centered + +A value indicates the positioning of the modal. Should be one of the following values: + +* `false` (default value) +* `true` + +Example: + +````xml + + A simple warning alert—check it out! + +```` + +### size + +A value indicates the size of the modal. Should be one of the following values: + +* `Default` (default value) +* `Small` +* `Large` +* `ExtraLarge` + +### static + +A value indicates if the modal will be static. Should be one of the following values: + +* `false` (default value) +* `true` + +### Additional content + +`abp-modal-footer` can have multiple buttons with alignment option. + +Add `@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal` to your page. + +Example: + +````xml +Launch modal + + + + + Woohoo, you're reading this text in a modal! + + + +```` + +### button-alignment + +A value indicates the positioning of your modal footer buttons. Should be one of the following values: + +* `Default` (default value) +* `Start` +* `Center` +* `Around` +* `Between` +* `End` \ No newline at end of file From 5655ce433189efd6d93a58fe3719fd32164eb88d Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 20 Mar 2020 14:00:00 +0300 Subject: [PATCH 02/52] feat(core): add a utility function that checks if a value is undefined or empty string --- .../core/src/lib/tests/common-utils.spec.ts | 18 +++++++++++++++++- .../core/src/lib/utils/common-utils.ts | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/core/src/lib/tests/common-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/common-utils.spec.ts index 98c6614987..60280e396b 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/common-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/common-utils.spec.ts @@ -1,4 +1,4 @@ -import { noop } from '../utils'; +import { isUndefinedOrEmptyString, noop } from '../utils'; describe('CommonUtils', () => { describe('#noop', () => { @@ -7,4 +7,20 @@ describe('CommonUtils', () => { expect(noop()()).toBeUndefined(); }); }); + + describe('#isUndefinedOrEmptyString', () => { + test.each` + value | expected + ${null} | ${false} + ${0} | ${false} + ${true} | ${false} + ${'x'} | ${false} + ${{}} | ${false} + ${[]} | ${false} + ${undefined} | ${true} + ${''} | ${true} + `('should return $expected when given parameter is $value', ({ value, expected }) => { + expect(isUndefinedOrEmptyString(value)).toBe(expected); + }); + }); }); diff --git a/npm/ng-packs/packages/core/src/lib/utils/common-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/common-utils.ts index 756d3a34dd..b8609be130 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/common-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/common-utils.ts @@ -3,3 +3,7 @@ export function noop() { const fn = function() {}; return fn; } + +export function isUndefinedOrEmptyString(value: unknown): boolean { + return value === undefined || value === ''; +} From ddf286d47760be173d1e14097c5c8a2f7c49e579 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 20 Mar 2020 14:22:58 +0300 Subject: [PATCH 03/52] refactor(core): change internals of request method of RestService --- .../core/src/lib/services/rest.service.ts | 42 ++++++++--------- .../core/src/lib/tests/rest.service.spec.ts | 46 ++++++++----------- 2 files changed, 36 insertions(+), 52 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/rest.service.ts b/npm/ng-packs/packages/core/src/lib/services/rest.service.ts index 15cc13cf50..eaebecf994 100644 --- a/npm/ng-packs/packages/core/src/lib/services/rest.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/rest.service.ts @@ -2,10 +2,11 @@ import { HttpClient, HttpRequest } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Store } from '@ngxs/store'; import { Observable, throwError } from 'rxjs'; -import { catchError, take, tap } from 'rxjs/operators'; +import { catchError } from 'rxjs/operators'; import { RestOccurError } from '../actions/rest.actions'; import { Rest } from '../models/rest'; import { ConfigState } from '../states/config.state'; +import { isUndefinedOrEmptyString } from '../utils'; @Injectable({ providedIn: 'root', @@ -13,47 +14,40 @@ import { ConfigState } from '../states/config.state'; export class RestService { constructor(private http: HttpClient, private store: Store) {} + private getApiFromStore(apiName: string): string { + return this.store.selectSnapshot(ConfigState.getApiUrl(apiName)); + } + handleError(err: any): Observable { this.store.dispatch(new RestOccurError(err)); - console.error(err); return throwError(err); } + // TODO: Deprecate service or improve interface in v3.0 request( request: HttpRequest | Rest.Request, config?: Rest.Config, api?: string, ): Observable { config = config || ({} as Rest.Config); - const { observe = Rest.Observe.Body, skipHandleError } = config; - const url = - (api || this.store.selectSnapshot(ConfigState.getApiUrl(config.apiName))) + request.url; + api = api || this.getApiFromStore(config.apiName); const { method, params, ...options } = request; + const { observe = Rest.Observe.Body, skipHandleError } = config; return this.http - .request(method, url, { + .request(method, api + request.url, { observe, ...(params && { - params: Object.keys(params).reduce( - (acc, key) => ({ - ...acc, - ...(typeof params[key] !== 'undefined' && - params[key] !== '' && { [key]: params[key] }), - }), - {}, - ), + params: Object.keys(params).reduce((acc, key) => { + const value = params[key]; + + if (!isUndefinedOrEmptyString(value)) acc[key] = value; + + return acc; + }, {}), }), ...options, } as any) - .pipe( - observe === Rest.Observe.Body ? take(1) : tap(), - catchError(err => { - if (skipHandleError) { - return throwError(err); - } - - return this.handleError(err); - }), - ); + .pipe(catchError(err => (skipHandleError ? throwError(err) : this.handleError(err)))); } } diff --git a/npm/ng-packs/packages/core/src/lib/tests/rest.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/rest.service.spec.ts index ecc8e9dce8..8251bcabb4 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/rest.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/rest.service.spec.ts @@ -1,9 +1,8 @@ import { ConfigState } from '@abp/ng.core'; import { createHttpFactory, HttpMethod, SpectatorHttp, SpyObject } from '@ngneat/spectator/jest'; import { NgxsModule, Store } from '@ngxs/store'; -import { interval, of, Subscription, throwError, timer } from 'rxjs'; +import { of, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; -import { RestOccurError } from '../actions'; import { Rest } from '../models'; import { RestService } from '../services/rest.service'; @@ -36,6 +35,10 @@ describe('HttpClient testing', () => { }); }); + afterEach(() => { + spectator.controller.verify(); + }); + test('should send a GET request with params', () => { spectator.service .request({ method: HttpMethod.GET, url: '/test', params: { id: 1 } }) @@ -66,34 +69,16 @@ describe('HttpClient testing', () => { spectator.expectOne('bar' + '/test', HttpMethod.GET); }); - test('should close the subscriber when observe equal to body', done => { - jest.spyOn(spectator.httpClient, 'request').mockReturnValue(interval(50)); + test('should complete upon successful request', done => { + const complete = jest.fn(done); - const subscriber: Subscription = spectator.service - .request({ method: HttpMethod.GET, url: '/test' }, { observe: Rest.Observe.Body }) - .subscribe(); + spectator.service.request({ method: HttpMethod.GET, url: '/test' }).subscribe({ complete }); - timer(51).subscribe(() => { - expect(subscriber.closed).toBe(true); - done(); - }); - }); - - test('should open the subscriber when observe not equal to body', done => { - jest.spyOn(spectator.httpClient, 'request').mockReturnValue(interval(50)); - - const subscriber: Subscription = spectator.service - .request({ method: HttpMethod.GET, url: '/test' }, { observe: Rest.Observe.Events }) - .subscribe(); - - timer(51).subscribe(() => { - expect(subscriber.closed).toBe(false); - done(); - }); + const req = spectator.expectOne(api + '/test', HttpMethod.GET); + spectator.flushAll([req], [{}]); }); test('should handle the error', () => { - jest.spyOn(spectator.httpClient, 'request').mockReturnValue(throwError('Testing error')); const spy = jest.spyOn(store, 'dispatch'); spectator.service @@ -101,15 +86,17 @@ describe('HttpClient testing', () => { .pipe( catchError(err => { expect(err).toBeTruthy(); - expect(spy.mock.calls[0][0] instanceof RestOccurError).toBe(true); + expect(spy).toHaveBeenCalled(); return of(null); }), ) .subscribe(); + + const req = spectator.expectOne(api + '/test', HttpMethod.GET); + spectator.flushAll([req], [throwError('Testing error')]); }); test('should not handle the error when skipHandleError is true', () => { - jest.spyOn(spectator.httpClient, 'request').mockReturnValue(throwError('Testing error')); const spy = jest.spyOn(store, 'dispatch'); spectator.service @@ -120,10 +107,13 @@ describe('HttpClient testing', () => { .pipe( catchError(err => { expect(err).toBeTruthy(); - expect(spy.mock.calls).toHaveLength(0); + expect(spy).toHaveBeenCalledTimes(0); return of(null); }), ) .subscribe(); + + const req = spectator.expectOne(api + '/test', HttpMethod.GET); + spectator.flushAll([req], [throwError('Testing error')]); }); }); From 94789c97077d4037baac9cd297db3d891d76a10c Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Fri, 20 Mar 2020 14:48:16 +0300 Subject: [PATCH 04/52] added collapse documentation --- docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md b/docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md new file mode 100644 index 0000000000..44416ceba6 --- /dev/null +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md @@ -0,0 +1,92 @@ +# Collapse + +## Introduction + +`abp-collapse-body` is the main container for showing and hiding content. `abp-collapse-id` is used to show and hide the content container. Can be triggered with both `abp-button` and `a` tags. + +Basic usage: + +````xml + + Link with href + + + Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + +```` + + + +## Demo + +See the [collapse demo page](https://bootstrap-taghelpers.abp.io/Components/Collapse) to see it in action. + +## Attributes + +### show + +A value indicates if the collapse body will be initialized visible or hidden. Should be one of the following values: + +* `false` (default value) +* `true` + +### multi + +A value indicates if an `abp-button` or `a` can show and hide multiple collapse body element. Should be one of the following values: + +* `false` (default value) +* `true` + +Sample: + +````xml + Toggle first element + + + + + + + Curabitur porta porttitor libero eu luctus. Praesent ultrices mattis commodo. Integer sodales massa risus, in molestie enim sagittis blandit + + + + + Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. + + + +```` + +## Accordion example + +`abp-accordion` is the main container for the accordion items. + +Basic usage: + +````xml + + + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry rtat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + + + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + + + Anim pariatur wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + + +```` + +## Attributes + +### active + +A value indicates if the accordion item will be initialized visible or hidden. Should be one of the following values: + +* `false` (default value) +* `true` + +### title + +A value indicates the visible title of the accordion item. Should be a string value. From 11b809d61cde41358e682f900b9df3ef0ad1ba6b Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Fri, 20 Mar 2020 15:35:30 +0300 Subject: [PATCH 05/52] added dropdowns documentation --- .../en/UI/AspNetCore/Tag-Helpers/Dropdowns.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/en/UI/AspNetCore/Tag-Helpers/Dropdowns.md diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Dropdowns.md b/docs/en/UI/AspNetCore/Tag-Helpers/Dropdowns.md new file mode 100644 index 0000000000..1c062b5f73 --- /dev/null +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Dropdowns.md @@ -0,0 +1,97 @@ +# Dropdowns + +## Introduction + +`abp-dropdown` is the main container for dropdown content. + +Basic usage: + +````xml + + + + Action + Another action + Something else here + + +```` + + + +## Demo + +See the [dropdown demo page](https://bootstrap-taghelpers.abp.io/Components/Dropdowns) to see it in action. + +## Attributes + +### direction + +A value indicates which direction the dropdown buttons will be displayed to. Should be one of the following values: + +* `Down` (default value) +* `Up` +* `Right` +* `Left` + +### dropdown-style + +A value indicates if an `abp-dropdown-button` will have split icon for dropdown. Should be one of the following values: + +* `Single` (default value) +* `Split` + + + +## Menu items + +`abp-dropdown-menu` is the main container for dropdown menu items. + +Basic usage: + +````xml + + + + Dropdown Header + Action + Active action + Disabled action + + Dropdown Item Text + Something else here + + +```` + +## Attributes + +### align + +A value indicates which direction `abp-dropdown-menu` items will be aligned to. Should be one of the following values: + +* `Left` (default value) +* `Right` + +### Additional content + +`abp-dropdown-menu` can also contain additional HTML elements like headings, paragraphs, dividers or form element. + +Example: + +````xml + + + +
+ + + + + + + New around here? Sign up + Forgot password? +
+
+```` From a4731f76fb91b4126e4fd5251b6bcb167629a576 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 20 Mar 2020 15:56:23 +0300 Subject: [PATCH 06/52] refactor docs --- .../Documents/DocumentAdminAppService.cs | 18 ++++++-- .../Elastic/ElasticDocumentFullSearch.cs | 17 ++++--- .../Pages/Documents/Project/Index.cshtml | 44 ++++++++++++++----- 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs index 4bc793f799..57ade1bb4b 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs @@ -23,8 +23,8 @@ namespace Volo.Docs.Admin.Documents public DocumentAdminAppService(IProjectRepository projectRepository, IDocumentRepository documentRepository, - IDocumentSourceFactory documentStoreFactory, - IDistributedCache documentUpdateCache, + IDocumentSourceFactory documentStoreFactory, + IDistributedCache documentUpdateCache, IDocumentFullSearch documentFullSearch) { _projectRepository = projectRepository; @@ -91,11 +91,21 @@ namespace Volo.Docs.Admin.Documents foreach (var doc in docs) { var project = projects.FirstOrDefault(x => x.Id == doc.ProjectId); - if (project != null && (doc.FileName == project.NavigationDocumentName || doc.FileName == project.ParametersDocumentName)) + if (project == null) { continue; } - + + if (doc.FileName == project.NavigationDocumentName) + { + continue; + } + + if (doc.FileName == project.ParametersDocumentName) + { + continue; + } + await _documentFullSearch.AddOrUpdateAsync(doc); } } diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs index 4574633318..51ecd817b5 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs @@ -23,7 +23,7 @@ namespace Volo.Docs.Documents.FullSearch.Elastic public async Task CreateIndexIfNeededAsync(CancellationToken cancellationToken = default) { - CheckEsEnabled(); + ValidateElasticSearchEnabled(); var client = _clientProvider.GetClient(); @@ -51,11 +51,11 @@ namespace Volo.Docs.Documents.FullSearch.Elastic public async Task AddOrUpdateAsync(Document document, CancellationToken cancellationToken = default) { - CheckEsEnabled(); + ValidateElasticSearchEnabled(); var client = _clientProvider.GetClient(); - var existsResponse = await client.DocumentExistsAsync(DocumentPath.Id(document.Id), + var existsResponse = await client.DocumentExistsAsync(DocumentPath.Id(document.Id), x => x.Index(_options.IndexName), cancellationToken); HandleError(existsResponse); @@ -73,12 +73,12 @@ namespace Volo.Docs.Documents.FullSearch.Elastic if (!existsResponse.Exists) { - HandleError(await client.IndexAsync(esDocument, + HandleError(await client.IndexAsync(esDocument, x => x.Id(document.Id).Index(_options.IndexName), cancellationToken)); } else { - HandleError(await client.UpdateAsync(DocumentPath.Id(document.Id), + HandleError(await client.UpdateAsync(DocumentPath.Id(document.Id), x => x.Doc(esDocument).Index(_options.IndexName), cancellationToken)); } @@ -86,7 +86,7 @@ namespace Volo.Docs.Documents.FullSearch.Elastic public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default) { - CheckEsEnabled(); + ValidateElasticSearchEnabled(); HandleError(await _clientProvider.GetClient() .DeleteAsync(DocumentPath.Id(id), x => x.Index(_options.IndexName), cancellationToken)); @@ -96,7 +96,7 @@ namespace Volo.Docs.Documents.FullSearch.Elastic string version, int? skipCount = null, int? maxResultCount = null, CancellationToken cancellationToken = default) { - CheckEsEnabled(); + ValidateElasticSearchEnabled(); var request = new SearchRequest { @@ -150,7 +150,6 @@ namespace Volo.Docs.Documents.FullSearch.Elastic } }; - //var json = _clientProvider.GetClient().RequestResponseSerializer.SerializeToString(request); var response = await _clientProvider.GetClient().SearchAsync(request, cancellationToken); HandleError(response); @@ -178,7 +177,7 @@ namespace Volo.Docs.Documents.FullSearch.Elastic } } - protected void CheckEsEnabled() + protected void ValidateElasticSearchEnabled() { if (!_options.Enable) { diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index 68ba541938..67e5352e22 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -90,7 +90,10 @@ - + @@ -109,7 +112,10 @@ - + @@ -127,7 +133,10 @@ - + @@ -142,7 +151,12 @@ - + @@ -156,7 +170,12 @@ - + @@ -204,7 +223,9 @@ @@ -216,7 +237,11 @@ { + class="rounded-circle" + alt="Avatar" + height="21" + width="21" + title="@contributor.Username" /> } } @@ -290,9 +315,7 @@
-
-
@L["InThisDocument"]
@@ -302,10 +325,8 @@ @L["GoToTop"]
- - } else { @@ -318,7 +339,6 @@ } - } From 6b15fbe1de064dcb055c995f85ef8a47b03db314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Fri, 20 Mar 2020 16:23:22 +0300 Subject: [PATCH 07/52] blogging module updated --- .../Volo/Blogging/BloggingRemoteServiceConsts.cs | 7 +++++++ .../Volo/Blogging/BloggingHttpApiClientModule.cs | 5 ++--- .../Volo/Blogging/BlogFilesController.cs | 2 +- .../Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs | 2 +- .../Volo/Blogging/CommentsController.cs | 2 +- .../Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs | 2 +- .../Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs | 2 +- 7 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingRemoteServiceConsts.cs diff --git a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingRemoteServiceConsts.cs b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingRemoteServiceConsts.cs new file mode 100644 index 0000000000..e11f75adfb --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingRemoteServiceConsts.cs @@ -0,0 +1,7 @@ +namespace Volo.Blogging +{ + public static class BloggingRemoteServiceConsts + { + public const string RemoteServiceName = "Blogging"; + } +} diff --git a/modules/blogging/src/Volo.Blogging.HttpApi.Client/Volo/Blogging/BloggingHttpApiClientModule.cs b/modules/blogging/src/Volo.Blogging.HttpApi.Client/Volo/Blogging/BloggingHttpApiClientModule.cs index 7e1418cbb0..0b33ff3367 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi.Client/Volo/Blogging/BloggingHttpApiClientModule.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi.Client/Volo/Blogging/BloggingHttpApiClientModule.cs @@ -9,11 +9,10 @@ namespace Volo.Blogging typeof(AbpHttpClientModule))] public class BloggingHttpApiClientModule : AbpModule { - public const string RemoteServiceName = "Blogging"; - public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.AddHttpClientProxies(typeof(BloggingApplicationContractsModule).Assembly, RemoteServiceName); + context.Services.AddHttpClientProxies(typeof(BloggingApplicationContractsModule).Assembly, + BloggingRemoteServiceConsts.RemoteServiceName); } } diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs index 818435a78c..f71a0af6c2 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs @@ -10,7 +10,7 @@ using Volo.Blogging.Files; namespace Volo.Blogging { - [RemoteService] + [RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)] [Area("blogging")] [Route("api/blogging/files")] public class BlogFilesController : AbpController, IFileAppService diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs index 084afb958a..cb67ac3fb7 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs @@ -9,7 +9,7 @@ using Volo.Blogging.Blogs.Dtos; namespace Volo.Blogging { - [RemoteService] + [RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)] [Area("blogging")] [Route("api/blogging/blogs")] public class BlogsController : AbpController, IBlogAppService diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/CommentsController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/CommentsController.cs index 270d8f1e13..caea1cfa2f 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/CommentsController.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/CommentsController.cs @@ -9,7 +9,7 @@ using Volo.Blogging.Comments.Dtos; namespace Volo.Blogging { - [RemoteService] + [RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)] [Area("blogging")] [Route("api/blogging/comments")] public class CommentsController : AbpController, ICommentAppService diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs index 332f60c256..f7a1c01703 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs @@ -8,7 +8,7 @@ using Volo.Blogging.Posts; namespace Volo.Blogging { - [RemoteService] + [RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)] [Area("blogging")] [Route("api/blogging/posts")] public class PostsController : AbpController, IPostAppService diff --git a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs index ede42dd264..6f17623a5e 100644 --- a/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs +++ b/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/TagsController.cs @@ -9,7 +9,7 @@ using Volo.Blogging.Tagging.Dtos; namespace Volo.Blogging { - [RemoteService] + [RemoteService(Name = BloggingRemoteServiceConsts.RemoteServiceName)] [Area("blogging")] [Route("api/blogging/tags")] public class TagsController : AbpController, ITagAppService From a2049e19490920ae0e1009f60a4a98e72a3249a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Fri, 20 Mar 2020 16:32:22 +0300 Subject: [PATCH 08/52] feature management module updated --- .../FeatureManagementRemoteServiceConsts.cs | 7 +++++++ .../AbpFeatureManagementHttpApiClientModule.cs | 4 +--- .../Volo/Abp/FeatureManagement/FeaturesController.cs | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementRemoteServiceConsts.cs diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementRemoteServiceConsts.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementRemoteServiceConsts.cs new file mode 100644 index 0000000000..749805da05 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementRemoteServiceConsts.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.FeatureManagement +{ + public class FeatureManagementRemoteServiceConsts + { + public const string RemoteServiceName = "FeatureManagement"; + } +} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/Volo/Abp/FeatureManagement/AbpFeatureManagementHttpApiClientModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/Volo/Abp/FeatureManagement/AbpFeatureManagementHttpApiClientModule.cs index 002a7c3a9a..1bfd2a752c 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/Volo/Abp/FeatureManagement/AbpFeatureManagementHttpApiClientModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi.Client/Volo/Abp/FeatureManagement/AbpFeatureManagementHttpApiClientModule.cs @@ -9,13 +9,11 @@ namespace Volo.Abp.FeatureManagement typeof(AbpHttpClientModule))] public class AbpFeatureManagementHttpApiClientModule : AbpModule { - public const string RemoteServiceName = "AbpFeatureManagement"; - public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddHttpClientProxies( typeof(AbpFeatureManagementApplicationContractsModule).Assembly, - RemoteServiceName + FeatureManagementRemoteServiceConsts.RemoteServiceName ); } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs index a56ff24275..e3eda46033 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs @@ -4,7 +4,7 @@ using Volo.Abp.AspNetCore.Mvc; namespace Volo.Abp.FeatureManagement { - [RemoteService] + [RemoteService(Name = FeatureManagementRemoteServiceConsts.RemoteServiceName)] [Area("abp")] public class FeaturesController : AbpController, IFeatureAppService { From 4844ca8b53252e64e158804e43ffd33b1b5eaac5 Mon Sep 17 00:00:00 2001 From: Mehmet Erim <34455572+mehmet-erim@users.noreply.github.com> Date: Fri, 20 Mar 2020 16:44:00 +0300 Subject: [PATCH 09/52] Update rest.service.ts --- npm/ng-packs/packages/core/src/lib/services/rest.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/rest.service.ts b/npm/ng-packs/packages/core/src/lib/services/rest.service.ts index eaebecf994..936bc2a768 100644 --- a/npm/ng-packs/packages/core/src/lib/services/rest.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/rest.service.ts @@ -6,7 +6,7 @@ import { catchError } from 'rxjs/operators'; import { RestOccurError } from '../actions/rest.actions'; import { Rest } from '../models/rest'; import { ConfigState } from '../states/config.state'; -import { isUndefinedOrEmptyString } from '../utils'; +import { isUndefinedOrEmptyString } from '../utils/common-utils'; @Injectable({ providedIn: 'root', From 2c63877a889836895c4caf89575a34b0d9fa1f1d Mon Sep 17 00:00:00 2001 From: Arkat Erol Date: Fri, 20 Mar 2020 16:50:38 +0300 Subject: [PATCH 10/52] apiName added for generate proxy --- .../Volo/Abp/Cli/Commands/GenerateProxyCommand.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs index 17fe2d3781..12fc5af525 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs @@ -67,7 +67,8 @@ namespace Volo.Abp.Cli.Commands var data = JObject.Parse(json); Logger.LogInformation("Modules are combining"); - var moduleList = GetCombinedModules(data, module); + var apiNameList = new Dictionary(); + var moduleList = GetCombinedModules(data, module, out apiNameList); if (moduleList.Count < 1) { @@ -85,6 +86,7 @@ namespace Volo.Abp.Cli.Commands var moduleValue = JObject.Parse(moduleItem.Value); var rootPath = moduleItem.Key; + var apiName = apiNameList.Where(p => p.Key == rootPath).Select(p => p.Value).FirstOrDefault(); Logger.LogInformation($"{rootPath} directory is creating"); @@ -105,6 +107,8 @@ namespace Volo.Abp.Cli.Commands serviceFileText.AppendLine(""); serviceFileText.AppendLine("@Injectable({providedIn: 'root'})"); serviceFileText.AppendLine("export class [controllerName]Service {"); + serviceFileText.AppendLine(" apiName = '"+ apiName + "';"); + serviceFileText.AppendLine(""); serviceFileText.AppendLine(" constructor(private restService: RestService) {}"); serviceFileText.AppendLine(""); @@ -309,8 +313,8 @@ namespace Volo.Abp.Cli.Commands serviceFileText.AppendLine( url.Contains("${") - ? $" return this.restService.request({{ url: `/{url}`, method: '{httpMethod}'{bodyExtra}{modelBindingExtra} }});" - : $" return this.restService.request({{ url: '/{url}', method: '{httpMethod}'{bodyExtra}{modelBindingExtra} }});"); + ? $" return this.restService.request({{ url: `/{url}`, method: '{httpMethod}'{bodyExtra}{modelBindingExtra} }},{{ apiName: this.apiName }});" + : $" return this.restService.request({{ url: '/{url}', method: '{httpMethod}'{bodyExtra}{modelBindingExtra} }},{{ apiName: this.apiName }});"); serviceFileText.AppendLine(" }"); @@ -369,13 +373,15 @@ namespace Volo.Abp.Cli.Commands Logger.LogInformation("Completed!"); } - private Dictionary GetCombinedModules(JToken data, string module) + private Dictionary GetCombinedModules(JToken data, string module, out Dictionary apiNameList) { var moduleList = new Dictionary(); + apiNameList = new Dictionary(); foreach (var moduleItem in data["modules"]) { var rootPath = ((string)moduleItem.First["rootPath"]).ToLower(); + var apiName = (string)moduleItem.First["remoteServiceName"]; if (moduleList.Any(p => p.Key == rootPath)) { @@ -385,6 +391,7 @@ namespace Volo.Abp.Cli.Commands } else { + apiNameList.Add(rootPath, apiName); moduleList.Add(rootPath, moduleItem.First["controllers"].ToString()); } } From 8277fd06fff75e278cd0a01e32e2bfae16a3f8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Fri, 20 Mar 2020 16:56:40 +0300 Subject: [PATCH 11/52] permission management module updated --- .../PermissionManagementRemoteServiceConsts.cs | 7 +++++++ .../AbpPermissionManagementHttpApiClientModule.cs | 4 +--- .../Volo/Abp/PermissionManagement/PermissionsController.cs | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/PermissionManagementRemoteServiceConsts.cs diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/PermissionManagementRemoteServiceConsts.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/PermissionManagementRemoteServiceConsts.cs new file mode 100644 index 0000000000..4a9644b061 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/PermissionManagementRemoteServiceConsts.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.PermissionManagement +{ + public class PermissionManagementRemoteServiceConsts + { + public const string RemoteServiceName = "AbpPermissionManagement"; + } +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/AbpPermissionManagementHttpApiClientModule.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/AbpPermissionManagementHttpApiClientModule.cs index 6bdc958780..35932bba56 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/AbpPermissionManagementHttpApiClientModule.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/Volo/Abp/PermissionManagement/AbpPermissionManagementHttpApiClientModule.cs @@ -9,13 +9,11 @@ namespace Volo.Abp.PermissionManagement typeof(AbpHttpClientModule))] public class AbpPermissionManagementHttpApiClientModule : AbpModule { - public const string RemoteServiceName = "AbpPermissionManagement"; - public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddHttpClientProxies( typeof(AbpPermissionManagementApplicationContractsModule).Assembly, - RemoteServiceName + PermissionManagementRemoteServiceConsts.RemoteServiceName ); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs index 2dacd79d1f..2ed9a4d044 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/PermissionsController.cs @@ -4,7 +4,7 @@ using Volo.Abp.AspNetCore.Mvc; namespace Volo.Abp.PermissionManagement { - [RemoteService] + [RemoteService(Name = PermissionManagementRemoteServiceConsts.RemoteServiceName)] [Area("abp")] public class PermissionsController : AbpController, IPermissionAppService { From c1429f1f09727d211a358ac8d6860f78240d33e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Fri, 20 Mar 2020 17:01:41 +0300 Subject: [PATCH 12/52] tenant management module updated --- .../TenantManagementRemoteServiceConsts.cs | 7 +++++++ .../AbpTenantManagementHttpApiClientModule.cs | 4 +--- .../Volo/Abp/TenantManagement/TenantController.cs | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/TenantManagementRemoteServiceConsts.cs diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/TenantManagementRemoteServiceConsts.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/TenantManagementRemoteServiceConsts.cs new file mode 100644 index 0000000000..c820c1bd49 --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/TenantManagementRemoteServiceConsts.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.TenantManagement +{ + public class TenantManagementRemoteServiceConsts + { + public const string RemoteServiceName = "AbpTenantManagement"; + } +} \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/Volo/Abp/TenantManagement/AbpTenantManagementHttpApiClientModule.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/Volo/Abp/TenantManagement/AbpTenantManagementHttpApiClientModule.cs index 1cbdb36a10..7be0b53a72 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/Volo/Abp/TenantManagement/AbpTenantManagementHttpApiClientModule.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi.Client/Volo/Abp/TenantManagement/AbpTenantManagementHttpApiClientModule.cs @@ -9,13 +9,11 @@ namespace Volo.Abp.TenantManagement typeof(AbpHttpClientModule))] public class AbpTenantManagementHttpApiClientModule : AbpModule { - public const string RemoteServiceName = "AbpTenantManagement"; - public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddHttpClientProxies( typeof(AbpTenantManagementApplicationContractsModule).Assembly, - RemoteServiceName + TenantManagementRemoteServiceConsts.RemoteServiceName ); } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs index 5b821fbc71..317e7e62d0 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs @@ -7,7 +7,7 @@ using Volo.Abp.AspNetCore.Mvc; namespace Volo.Abp.TenantManagement { [Controller] - [RemoteService] + [RemoteService(Name = TenantManagementRemoteServiceConsts.RemoteServiceName)] [Area("multi-tenancy")] [Route("api/multi-tenancy/tenants")] public class TenantController : AbpController, ITenantAppService //TODO: Throws exception on validation if we inherit from Controller From 5d191c3e6fb2276f5a9bb33ed7d9a95d080f8f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ak=C4=B1n=20Sabri=20=C3=87am?= Date: Fri, 20 Mar 2020 17:39:44 +0300 Subject: [PATCH 13/52] added localization keys for abpio admin and commercial --- .../AbpIoLocalization/Admin/Localization/Resources/en.json | 1 + .../AbpIoLocalization/Commercial/Localization/Resources/en.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 5ebdf0b2eb..cb79af1665 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -81,6 +81,7 @@ "LastSeenDate": "Last seen date", "{0}Computer{1}WillBeRemovedFromRecords": "Computer of {0} ({1}) will be removed from records", "OrganizationDeletionWarningMessage": "Organization will be deleted", + "DeletingLastOwnerWarningMessage": "An organization must have at least one owner! Therefore you cannot remove this owner", "This{0}AlreadyExistInThisOrganization": "This {0} already exist in this organization", "AreYouSureYouWantToDeleteAllComputers": "Are you sure you want to delete all computers?", "DeleteAll": "Delete all", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 3df70437b4..2a57c6b25d 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -29,7 +29,7 @@ "ApiKey": "API key", "UserNameNotFound": "There is no user with username {0}", "SuccessfullyAddedToNewsletter": "Thanks you for subscribing to our newsletter!", - "ManageProfile": "Manage your profile", + "MyProfile": "My profile", "EmailNotValid": "Please enter a valid email address." } } \ No newline at end of file From d65543e02aae52810fe2efbe8083142f2aa11e95 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Fri, 20 Mar 2020 22:57:14 +0800 Subject: [PATCH 14/52] Translate customizing application modules overriding service doc --- ...Application-Modules-Overriding-Services.md | 2 +- ...Application-Modules-Overriding-Services.md | 167 +++++++++++++++++- 2 files changed, 166 insertions(+), 3 deletions(-) diff --git a/docs/en/Customizing-Application-Modules-Overriding-Services.md b/docs/en/Customizing-Application-Modules-Overriding-Services.md index 16fbc9d2a4..b735d51f6f 100644 --- a/docs/en/Customizing-Application-Modules-Overriding-Services.md +++ b/docs/en/Customizing-Application-Modules-Overriding-Services.md @@ -10,7 +10,7 @@ You have different options can be used based on your requirement those will be e ## Replacing an Interface -If given service defines an interface, like the `IdentityUserAppService` class implements the `IIdentityAppService`, you can re-implement the same interface and replace the current implementation by your class. Example: +If given service defines an interface, like the `IdentityUserAppService` class implements the `IIdentityUserAppService`, you can re-implement the same interface and replace the current implementation by your class. Example: ````csharp public class MyIdentityUserAppService : IIdentityUserAppService, ITransientDependency diff --git a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md index 083321f7be..cb40de9bdb 100644 --- a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md +++ b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md @@ -1,3 +1,166 @@ -# 自定义应用模块: 覆盖服务 +# 自定义应用模块: 重写服务 -TODO... \ No newline at end of file +你可能想要**更改**依赖模块的**行为(业务逻辑)**. 在这种情况下,你可以使用[依赖注入](Dependency-Injection.md)的能力替换服务,控制器甚至页面模型到你自己的实现. + +注册到依赖注入的任何类,包括ABP框架的服务都可以被**替换**. + +你可以根据自己的需求使用不同的选项,下面的章节中将介绍这些选项. + +> 请注意,某些服务方法可能不是virtual,你可能无法override,我们会通过设计将其virtual,如果你发现任何方法不可以被覆盖,请[创建一个issue](https://github.com/abpframework/abp/issues/new)或者你直接修改后并发送**pull request**到GitHub. + +## 替换接口 + +如果给定的服务定义了接口,像 `IdentityUserAppService` 类实现了 `IIdentityUserAppService` 接口,你可以为这个接口创建自己的实现并且替换当前的实现. 例如: + +````csharp +public class MyIdentityUserAppService : IIdentityUserAppService, ITransientDependency +{ + //... +} +```` + +`MyIdentityUserAppService` 通过命名约定替换了 `IIdentityUserAppService` 的当前实现. 如果你的类名不匹配,你需要手动公开服务接口: + +````csharp +[ExposeServices(typeof(IIdentityUserAppService))] +public class TestAppService : IIdentityUserAppService, ITransientDependency +{ + //... +} +```` + +依赖注入系统允许为一个接口注册多个服务. 注入接口时会解析最后一个注入的服务. 显式的替换服务是一个好习惯. + +示例: + +````csharp +[Dependency(ReplaceServices = true)] +[ExposeServices(typeof(IIdentityUserAppService))] +public class TestAppService : IIdentityUserAppService, ITransientDependency +{ + //... +} +```` + +使用这种方法, `IIdentityUserAppService` 接口将只会有一个实现. 也可以使用以下方法替换服务: + +````csharp +context.Services.Replace( + ServiceDescriptor.Transient() +); +```` + +你可以在[模块](Module-Development-Basics.md)类的 `ConfigureServices` 方法编写替换服务代码. + +## 重写一个服务类 + +大多数情况下,你会仅想改变服务当前实现的一个或几个方法. 重新实现完整的接口变的繁琐,更好的方法是继承原始类并重写方法。 + +### 示例: 重写服务方法 + +````csharp +[Dependency(ReplaceServices = true)] +public class MyIdentityUserAppService : IdentityUserAppService +{ + //... + public MyIdentityUserAppService( + IdentityUserManager userManager, + IIdentityUserRepository userRepository, + IGuidGenerator guidGenerator + ) : base( + userManager, + userRepository, + guidGenerator) + { + } + + public override async Task CreateAsync(IdentityUserCreateDto input) + { + if (input.PhoneNumber.IsNullOrWhiteSpace()) + { + throw new AbpValidationException( + "Phone number is required for new users!", + new List + { + new ValidationResult( + "Phone number can not be empty!", + new []{"PhoneNumber"} + ) + } + ); } + + return await base.CreateAsync(input); + } +} +```` + +示例中**重写**了 `IdentityUserAppService` [应用程序](Application-Services.md) `CreateAsync` 方法检查手机号码. 然后调用了基类方法继续**基本业务逻辑**. 通过这种方法你可以在基本业务逻辑**之前**和**之后**执行其他业务逻辑. + +你也可以完全**重写**整个业务逻辑去创建用户,而不是调用基类方法. + +### 示例: 重写领域服务 + +````csharp +[Dependency(ReplaceServices = true)] +[ExposeServices(typeof(IdentityUserManager))] +public class MyIdentityUserManager : IdentityUserManager +{ + public MyIdentityUserManager( + IdentityUserStore store, + IOptions optionsAccessor, + IPasswordHasher passwordHasher, + IEnumerable> userValidators, + IEnumerable> passwordValidators, + ILookupNormalizer keyNormalizer, + IdentityErrorDescriber errors, + IServiceProvider services, + ILogger logger, + ICancellationTokenProvider cancellationTokenProvider + ) : base( + store, + optionsAccessor, + passwordHasher, + userValidators, + passwordValidators, + keyNormalizer, + errors, + services, + logger, + cancellationTokenProvider) + { + } + + public override async Task CreateAsync(IdentityUser user) + { + if (user.PhoneNumber.IsNullOrWhiteSpace()) + { + throw new AbpValidationException( + "Phone number is required for new users!", + new List + { + new ValidationResult( + "Phone number can not be empty!", + new []{"PhoneNumber"} + ) + } + ); + } + + return await base.CreateAsync(user); + } +} +```` + +示例中类继承了 `IdentityUserManager` [领域服务](Domain-Services.md),并且重写了 `CreateAsync` 方法进行了与之前相同的手机号码检查. 结果也是一样的,但是这次我们在领域服务实现了它,假设这是我们系统的**核心领域逻辑**. + +> 这里需要 `[ExposeServices(typeof(IdentityUserManager))]` attribute,因为 `IdentityUserManager` 没有定义接口 (像 `IIdentityUserManager`) ,依赖注入系统并不会按照约定公开继承类的服务(如已实现的接口). + +参阅[本地化系统](Localization.md)了解如何自定义错误消息. + +### 重写其他服务 + +控制器,框架服务,视图组件类以及其他类型注册到依赖注入的类都可以像上面的示例那样被重写. + +## 如何找到服务? + +[模块文档](Modules/Index.md) 包含了定义的主要服务列表. 另外 你也可以查看[源码](https://github.com/abpframework/abp/tree/dev/modules)找到所有的服务. \ No newline at end of file From 1bcc4481643ced2f7bc142f12473675d1df3bb9e Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Fri, 20 Mar 2020 22:52:20 +0300 Subject: [PATCH 15/52] added list groups documentation --- .../UI/AspNetCore/Tag-Helpers/List-Groups.md | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 docs/en/UI/AspNetCore/Tag-Helpers/List-Groups.md diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/List-Groups.md b/docs/en/UI/AspNetCore/Tag-Helpers/List-Groups.md new file mode 100644 index 0000000000..b1e6e7f499 --- /dev/null +++ b/docs/en/UI/AspNetCore/Tag-Helpers/List-Groups.md @@ -0,0 +1,78 @@ +# List Groups + +## Introduction + +`abp-list-group` is the main container for list group content. + +Basic usage: + +````xml + + Cras justo odio + Dapibus ac facilisis in + Morbi leo risus + Vestibulum at eros + +```` + + + +## Demo + +See the [list groups demo page](https://bootstrap-taghelpers.abp.io/Components/ListGroups) to see it in action. + +## Attributes + +### flush + +A value indicates `abp-list-group` items to remove some borders and rounded corners to render list group items edge-to-edge in a parent container. Should be one of the following values: + +* `false` (default value) +* `true` + +### active + +A value indicates if an `abp-list-group-item` to be active. Should be one of the following values: + +* `false` (default value) +* `true` + +### disabled + +A value indicates if an `abp-list-group-item` to be disabled. Should be one of the following values: + +* `false` (default value) +* `true` + +### href + +A value indicates if an `abp-list-group-item` has a link. Should be a string link value. + +### type + +A value indicates an `abp-list-group-item` style class with a stateful background and color. Should be one of the following values: + +* `Default` (default value) +* `Primary` +* `Secondary` +* `Success` +* `Danger` +* `Warning` +* `Info` +* `Light` +* `Dark` +* `Link` + +### Additional content + +`abp-list-group-item` can also contain additional HTML elements like spans. + +Example: + +````xml + + Cras justo odio 14 + Dapibus ac facilisis in 2 + Morbi leo risus 1 + +```` From 0239317b1d7804e7505d2e36b9538d5d2fd45c5e Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 21 Mar 2020 00:16:40 +0300 Subject: [PATCH 16/52] added paginator documentation --- .../en/UI/AspNetCore/Tag-Helpers/Paginator.md | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 docs/en/UI/AspNetCore/Tag-Helpers/Paginator.md diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Paginator.md b/docs/en/UI/AspNetCore/Tag-Helpers/Paginator.md new file mode 100644 index 0000000000..0cc63d49e8 --- /dev/null +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Paginator.md @@ -0,0 +1,57 @@ +# Paginator + +## Introduction + +`abp-paginator` is the abp tag for pagination. Requires `Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination.PagerModel` type of model. + +Basic usage: + +````xml + +```` + +Model: + +````xml +using Microsoft.AspNetCore.Mvc.RazorPages; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components +{ + public class PaginatorModel : PageModel + { + public PagerModel PagerModel { get; set; } + + public void OnGet(int currentPage, string sort) + { + PagerModel = new PagerModel(100, 10, currentPage, 10, "Paginator", sort); + } + } +} +```` + + + +## Demo + +See the [paginator demo page](https://bootstrap-taghelpers.abp.io/Components/Paginator) to see it in action. + +## Attributes + +### model + +`Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination.PagerModel` type of model can be initialized with the following data: + +* `totalCount` +* `shownItemsCount` +* `currentPage` +* `pageSize` +* `pageUrl` +* `sort` (default null) + +### show-info + +A value indicates if an extra information about start, end and total records will be displayed. Should be one of the following values: + +* `false` (default value) +* `true` From 2088b62caf5cc0216fc9c87ba8d176d512c5ee2a Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 21 Mar 2020 00:24:14 +0300 Subject: [PATCH 17/52] fixed bootstrap popover link --- .../Pages/Components/Popovers.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml index 7f43407831..b221ebc4f6 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml @@ -25,7 +25,7 @@

Popovers

-

Based on Bootstrap Popovers.

+

Based on Bootstrap Popovers.

Example

From 9e932d8457d128d20ad970058dd9cbeae6db9dde Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 21 Mar 2020 03:09:36 +0300 Subject: [PATCH 18/52] added progress bars documentation --- .../AspNetCore/Tag-Helpers/Progress-Bars.md | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 docs/en/UI/AspNetCore/Tag-Helpers/Progress-Bars.md diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Progress-Bars.md b/docs/en/UI/AspNetCore/Tag-Helpers/Progress-Bars.md new file mode 100644 index 0000000000..dc69f7e47e --- /dev/null +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Progress-Bars.md @@ -0,0 +1,70 @@ +# Progress Bars + +## Introduction + +`abp-progress-bar` is the abp tag for progress bar status. + +Basic usage: + +````xml + + + %25 + + + + %50 + + + + %10 + + +```` + + + +## Demo + +See the [progress bars demo page](https://bootstrap-taghelpers.abp.io/Components/Progress-Bars) to see it in action. + +## Attributes + +### value + +A value indicates the current progress of the bar. + +### type + +A value indicates the background color of the progress bar. Should be one of the following values: + +* `Default` (default value) +* `Secondary` +* `Success` +* `Danger` +* `Warning` +* `Info` +* `Light` +* `Dark` + +### min-value + +Minimum value of the progress bar. Default is 0. + +### max-value + +Maximum value of the progress bar. Default is 100. + +### strip + +A value indicates if the background style of the progress bar is stripped. Should be one of the following values: + +* `false` (default value) +* `true` + +### animation + +A value indicates if the stripped background style of the progress bar is animated. Should be one of the following values: + +* `false` (default value) +* `true` \ No newline at end of file From 58fcc87e3a231845058fd23c67d4ff47ce20f724 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 21 Mar 2020 03:36:38 +0300 Subject: [PATCH 19/52] added tooltips documentation --- docs/en/UI/AspNetCore/Tag-Helpers/Tooltips.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 docs/en/UI/AspNetCore/Tag-Helpers/Tooltips.md diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Tooltips.md b/docs/en/UI/AspNetCore/Tag-Helpers/Tooltips.md new file mode 100644 index 0000000000..55b6e574e8 --- /dev/null +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Tooltips.md @@ -0,0 +1,35 @@ +# Tooltips + +## Introduction + +`abp-tooltip` is the abp tag for tooltips. + +Basic usage: + +````xml + + Tooltip Default + + + + Tooltip on top + + + + Tooltip on right + + + + Tooltip on bottom + + + + Disabled button Tooltip + +```` + + + +## Demo + +See the [tooltips demo page](https://bootstrap-taghelpers.abp.io/Components/Tooltips) to see it in action. From 0fee27b9c494762c02595bd58791807e9f038a30 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 21 Mar 2020 03:43:09 +0300 Subject: [PATCH 20/52] updated tag helpers index links --- docs/en/UI/AspNetCore/Tag-Helpers/Index.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Index.md b/docs/en/UI/AspNetCore/Tag-Helpers/Index.md index 5f36395c00..a7aa0b65d2 100644 --- a/docs/en/UI/AspNetCore/Tag-Helpers/Index.md +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Index.md @@ -15,6 +15,16 @@ Here, the list of components those are wrapped by the ABP Framework: * [Buttons](Buttons.md) * [Cards](Cards.md) * [Alerts](Alerts.md) +* [Tabs](Tabs.md) +* [Grids](Grids.md) +* [Modals](Modals.md) +* [Collapse](Collapse.md) +* [Dropdowns](Dropdowns.md) +* [List Groups](List-Groups.md) +* [Paginator](Paginator.md) +* [Popovers](Popovers.md) +* [Progress Bars](Progress-Bars.md) +* [Tooltips](Tooltips.md) * ... > Until all the tag helpers are documented, you can visit https://bootstrap-taghelpers.abp.io/ to see them with live samples. From 840f55932f5f7115ed9c60071d09ed0f362825c3 Mon Sep 17 00:00:00 2001 From: ChangYinShung Date: Sat, 21 Mar 2020 16:51:35 +0800 Subject: [PATCH 21/52] feat: localization updated zh-Hant --- .../Abp/TenantManagement/Localization/Resources/zh-Hant.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json index 858d7d6f9b..30c58cbc6d 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json @@ -15,6 +15,8 @@ "Permission:Edit": "編輯", "Permission:Delete": "刪除", "Permission:ManageConnectionStrings": "管理資料庫連線字串", - "Permission:ManageFeatures": "管理功能" + "Permission:ManageFeatures": "管理功能", + "DisplayName:AdminEmailAddress": "管理者信箱", + "DisplayName:AdminPassword": "管理者密碼" } } \ No newline at end of file From 46bb595e93a3bb50f54497d09abe796788b814d4 Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 21 Mar 2020 17:02:09 +0800 Subject: [PATCH 22/52] Update zh-Hant.json --- .../Abp/TenantManagement/Localization/Resources/zh-Hant.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json index 30c58cbc6d..ea8be8ae0e 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json @@ -16,7 +16,7 @@ "Permission:Delete": "刪除", "Permission:ManageConnectionStrings": "管理資料庫連線字串", "Permission:ManageFeatures": "管理功能", - "DisplayName:AdminEmailAddress": "管理者信箱", + "DisplayName:AdminEmailAddress": "管理者信箱", "DisplayName:AdminPassword": "管理者密碼" } -} \ No newline at end of file +} From cf5852c83e1cbe5dcef3f712ed4b61aaa09bbef9 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Sat, 21 Mar 2020 21:03:02 +0800 Subject: [PATCH 23/52] Update CLI.md --- docs/zh-Hans/CLI.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/zh-Hans/CLI.md b/docs/zh-Hans/CLI.md index ab1eba8fe7..dcd951a5c0 100644 --- a/docs/zh-Hans/CLI.md +++ b/docs/zh-Hans/CLI.md @@ -22,7 +22,7 @@ dotnet tool update -g Volo.Abp.Cli 生成基于ABP[启动模板](Startup-Templates/Index.md)的新解决方案. -基本用法: +用法: ````bash abp new <解决方案名称> [options] @@ -70,7 +70,7 @@ abp new Acme.BookStore > 需要注意的是添加的模块可能需要额外的配置,通常会在包的文档中指出. -基本用法: +用法: ````bash abp add-package <包名> [options] @@ -94,7 +94,7 @@ abp add-package Volo.Abp.MongoDB > 由于分层,不同的数据库提供程序选项或其他原因,业务模块通常由多个包组成. 使用`add-module`命令可以大大简化向模块添加模块的过程. 但是每个模块可能需要一些其他配置,这些配置通常在相关模块的文档中指出. -基本用法: +用法: ````bash abp add-module <模块名称> [options] @@ -174,26 +174,26 @@ abp logout ### generate-proxy -生成typescript服务和DTO代理 +为你的HTTP API生成客户端代码,简化客户端使用服务的成本. 在运行 `generate-proxy` 命令之前,你的host必须启动正在运行. -基本用法: +用法: ````bash -abp generate-proxy [options] +abp generate-proxy [options] ```` +#### Options + +* `--apiUrl` 或者 `-a`:指定HTTP API的根URL. 如果未指定这个选项,默认使用你Angular应用程序的`environment.ts`文件API URL. 在运行 `generate-proxy` 命令之前,你的host必须启动正在运行. +* `--ui` 或者 `-u`: 指定UI框架,默认框架是angular.当前只有angular一个选项, 但我们会通过更改CLI增加新的选项. 尽请关注! +* `--module` 或者 `-m`:指定模块名. 默认模块名称为app. 如果你想所有模块,你可以指定 `--module all` 命令. + 示例: ````bash abp generate-proxy --apiUrl https://localhost:44305 --ui angular --module all ```` -#### Options - -* `--apiUrl` 或者 `-a`:如果未指定这个选项,默认使用你的environment.ts文件的API URL, 你可以随时使用这个选项指定API源. -* `--ui` 或者 `-u`: 指定UI框架,默认框架是angular.当前只有angular一个选项, 但我们会通过更改CLI增加新的选项. 尽请关注! -* `--module` 或者 `-m`:指定模块名. 默认模块名称为app. 如果你想所有模块,你可以指定 `--module all` 命令. - ### help CLI的基本用法信息. From 8117629aed863b55ab37945ec7e4a059d73fbc9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sun, 22 Mar 2020 15:29:10 +0300 Subject: [PATCH 24/52] Add Customize/Extend the UI to the navigation menu. --- docs/en/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index c273e59346..5c2c3a8e64 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -302,6 +302,10 @@ { "text": "Theming", "path": "UI/AspNetCore/Theming.md" + }, + { + "text": "Customize/Extend the UI", + "path": "UI/AspNetCore/Customization-User-Interface.md" } ] }, From a7d42cb9320c9768ec486cbeddfed7e762eedf45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sun, 22 Mar 2020 17:14:55 +0300 Subject: [PATCH 25/52] Create datatables.md --- docs/en/UI/AspNetCore/Libraries/datatables.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 docs/en/UI/AspNetCore/Libraries/datatables.md diff --git a/docs/en/UI/AspNetCore/Libraries/datatables.md b/docs/en/UI/AspNetCore/Libraries/datatables.md new file mode 100644 index 0000000000..a5a66e9e19 --- /dev/null +++ b/docs/en/UI/AspNetCore/Libraries/datatables.md @@ -0,0 +1,3 @@ +# ABP Datatables.Net Integration for ASP.NET Core UI + +TODO \ No newline at end of file From 261f3adb1b59ea093b2db77524fe711be964b9f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sun, 22 Mar 2020 17:15:33 +0300 Subject: [PATCH 26/52] rename datatables --- docs/en/UI/AspNetCore/Libraries/{datatables.md => datatable1s.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/en/UI/AspNetCore/Libraries/{datatables.md => datatable1s.md} (100%) diff --git a/docs/en/UI/AspNetCore/Libraries/datatables.md b/docs/en/UI/AspNetCore/Libraries/datatable1s.md similarity index 100% rename from docs/en/UI/AspNetCore/Libraries/datatables.md rename to docs/en/UI/AspNetCore/Libraries/datatable1s.md From af2c478fdc8bad29f430a5cb236e9c0fcfe78bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sun, 22 Mar 2020 17:15:55 +0300 Subject: [PATCH 27/52] Rename DatatablesNet.md --- .../UI/AspNetCore/Libraries/{datatable1s.md => DatatablesNet.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/en/UI/AspNetCore/Libraries/{datatable1s.md => DatatablesNet.md} (100%) diff --git a/docs/en/UI/AspNetCore/Libraries/datatable1s.md b/docs/en/UI/AspNetCore/Libraries/DatatablesNet.md similarity index 100% rename from docs/en/UI/AspNetCore/Libraries/datatable1s.md rename to docs/en/UI/AspNetCore/Libraries/DatatablesNet.md From aaaed046378ad0c677927fca27aa36f249f80df6 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 23 Mar 2020 11:35:32 +0800 Subject: [PATCH 28/52] Keep the hash of the url in the setQueryString method. Resolve #3234 --- .../Volo.Docs.Web/Pages/Documents/Project/index.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index 8f53f1cf6e..1b3d5ac7c3 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -119,16 +119,17 @@ }; var setQueryString = function () { - clearQueryString(); - - var uri = window.location.href.toString(); - var comboboxes = $(".doc-section-combobox"); - if (comboboxes.length < 1) { return; } + var hash = document.location.hash; + + clearQueryString(); + + var uri = window.location.href.toString(); + var new_uri = uri + "?"; for (var i = 0; i < comboboxes.length; i++) { @@ -142,7 +143,7 @@ } } - window.history.replaceState({}, document.title, new_uri); + window.history.replaceState({}, document.title, new_uri + hash); }; var getTenYearsLater = function () { From 9cc51474c34fc38ef160aa9749997da12a5b788f Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 23 Mar 2020 13:48:08 +0800 Subject: [PATCH 29/52] Migrate only tenants with connection strings. Resolve #3292 --- .../Data/MyProjectNameDbMigrationService.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs index bf0a315c93..6c09ffd233 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -38,15 +39,14 @@ namespace MyCompanyName.MyProjectName.Data await MigrateHostDatabaseAsync(); + var tenants = await _tenantRepository.GetListAsync(includeDetails: true); + var i = 0; - var tenants = await _tenantRepository.GetListAsync(); - foreach (var tenant in tenants) + foreach (var tenant in tenants.Where(t => t.ConnectionStrings.Any())) { - i++; - using (_currentTenant.Change(tenant.Id)) { - Logger.LogInformation($"Migrating {tenant.Name} database schema... ({i} of {tenants.Count})"); + Logger.LogInformation($"Migrating {tenant.Name} database schema... ({++i} of {tenants.Count})"); await MigrateTenantDatabasesAsync(tenant); Logger.LogInformation($"Successfully completed {tenant.Name} database migrations."); } From 4f3687dbd819f047942fd7c0b88f6c9508feab12 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 23 Mar 2020 09:50:12 +0300 Subject: [PATCH 30/52] Update NpmGlobalPackagesChecker.cs --- .../Abp/Cli/ProjectModification/NpmGlobalPackagesChecker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmGlobalPackagesChecker.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmGlobalPackagesChecker.cs index 8140b73b64..59c262e065 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmGlobalPackagesChecker.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmGlobalPackagesChecker.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.Cli.ProjectModification { public ILogger Logger { get; set; } - public NpmGlobalPackagesChecker(PackageJsonFileFinder packageJsonFileFinder) + public NpmGlobalPackagesChecker() { Logger = NullLogger.Instance; } From 1ea03cc179a496574422e44fc814fc3c1d9f2a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Mon, 23 Mar 2020 14:45:02 +0300 Subject: [PATCH 31/52] Update CreateModal.cshtml.cs --- .../Pages/TenantManagement/Tenants/CreateModal.cshtml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs index 45e86e2985..098f7e1393 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs @@ -44,6 +44,7 @@ namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants public string AdminEmailAddress { get; set; } [Required] + [DataType(DataType.Password)] [MaxLength(128)] public string AdminPassword { get; set; } } From be017f8ea78e734244127c1508a8a87a8a320f22 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Mon, 23 Mar 2020 15:07:34 +0300 Subject: [PATCH 32/52] corrected multi attribute explanation --- docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md b/docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md index 44416ceba6..38fab4d44b 100644 --- a/docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Collapse.md @@ -32,7 +32,7 @@ A value indicates if the collapse body will be initialized visible or hidden. Sh ### multi -A value indicates if an `abp-button` or `a` can show and hide multiple collapse body element. Should be one of the following values: +A value indicates if an `abp-collapse-body` can be shown or hidden by an element that can show/hide multiple collapse bodies. Basically, this attribute adds "multi-collapse" class to `abp-collapse-body`. Should be one of the following values: * `false` (default value) * `true` From d420980f3e250b92549825ae454a253fc9cb8c74 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Mon, 23 Mar 2020 15:10:36 +0300 Subject: [PATCH 33/52] removed wrong alert sample --- docs/en/UI/AspNetCore/Tag-Helpers/Modals.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Modals.md b/docs/en/UI/AspNetCore/Tag-Helpers/Modals.md index 560c4374f0..9cf1258373 100644 --- a/docs/en/UI/AspNetCore/Tag-Helpers/Modals.md +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Modals.md @@ -33,14 +33,6 @@ A value indicates the positioning of the modal. Should be one of the following v * `false` (default value) * `true` -Example: - -````xml - - A simple warning alert—check it out! - -```` - ### size A value indicates the size of the modal. Should be one of the following values: From 5d2db4beb438135796ce4587ac97a70d0b31e600 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 23 Mar 2020 16:23:56 +0300 Subject: [PATCH 34/52] docs: add how to make HTTP requests using RestService --- docs/en/UI/Angular/Rest-Service.md | 206 +++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 docs/en/UI/Angular/Rest-Service.md diff --git a/docs/en/UI/Angular/Rest-Service.md b/docs/en/UI/Angular/Rest-Service.md new file mode 100644 index 0000000000..f932face22 --- /dev/null +++ b/docs/en/UI/Angular/Rest-Service.md @@ -0,0 +1,206 @@ +# How to Make HTTP Requests + + + +## About HttpClient + +Angular has the amazing [HttpClient](https://angular.io/guide/http) for communication with backend services. It is a layer on top and a simplified representation of [XMLHttpRequest Web API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest). It also is the recommended agent by Angular for any HTTP request. There is nothing wrong with using the `HttpClient` in your ABP project. + +However, `HttpClient` leaves error handling to the caller (method). In other words, HTTP errors are handled manually and by hooking into the observer of the `Observable` returned. + +```js +getConfig() { + this.http.get(this.configUrl).subscribe( + config => this.updateConfig(config), + error => { + // Handle error here + }, + ); +} +``` + +Although clear and flexible, handling errors this way is repetitive work, even when error processing is delegated to the store or any other injectable. + +An `HttpInterceptor` is able to catch `HttpErrorResponse`  and can be used for a centralized error handling. Nevertheless, cases where default error handler, therefore the interceptor, must be disabled require additional work and comprehension of Angular internals. Check [this issue](https://github.com/angular/angular/issues/20203) for details. + + + +## RestService + +ABP core module has a utility service for HTTP requests: `RestService`. Unless explicitly configured otherwise, it catches HTTP errors and dispatches a `RestOccurError` action. This action is then captured by the `ErrorHandler` introduced by the `ThemeSharedModule`. Since you should already import this module in your app, when the `RestService` is used, all HTTP errors get automatically handled by deafult. + + + +### Getting Started with RestService + +In order to use the `RestService`, you must inject it in your class as a dependency. + +```js +import { RestService } from '@abp/ng.core'; + +@Injectable({ + /* class metadata here */ +}) +class DemoService { + constructor(private rest: RestService) {} +} +``` + +You do not have to provide the RestService` at module or component/directive level, because it is already **provided in root**. + + + +### How to Make a Request with RestService + +You can use the `request` method of the `RestService` is for HTTP requests. Here is an example: + +```js +getFoo(id: number) { + const request: Rest.Request = { + method: 'GET', + url: '/api/some/path/to/foo/' + id, + }; + + return this.rest.request(request); +} +``` + + + +The `request` method always returns an `Observable`. Therefore you can do the following wherever you use `getFoo` method: + +```js +doSomethingWithFoo(id: number) { + this.demoService.getFoo(id).subscribe( + foo => { + // Do something with foo. + } + ) +} +``` + + + +**You do not have to worry about unsubscription.** The `RestService` uses `HttpClient` behind the scenes, so every observable it returns is a finite observable, i.e. it closes subscriptions automatically upon success or error. + + + +As you see, `request` method gets a request options object with `Rest.Request` type. This generic type expects the interface of the request body. You may pass `null` when there is no body, like in a `GET` or a `DELETE` request. Here is an example where there is one: + +```js +postFoo(body: Foo) { + const request: Rest.Request = { + method: 'POST', + url: '/api/some/path/to/foo', + body + }; + + return this.rest.request(request); +} +``` + + + +You may [check here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L23) for complete `Rest.Request` type, which has only a few chages compared to [HttpRequest](https://angular.io/api/common/http/HttpRequest) class in Angular. + + + +### How to Disable Default Error Handler of RestService + +The `request` method, used with defaults, always handles errors. Let's see how you can change that behavior and handle errors yourself: + +```js +deleteFoo(id: number) { + const request: Rest.Request = { + method: 'DELETE', + url: '/api/some/path/to/foo/' + id, + }; + + return this.rest.request(request, { skipHandleError: true }); +} +``` + + + +`skipHandleError` config option, when set to `true`, disables the error handler and the returned observable starts throwing an error that you can catch in your subscription. + +```js +removeFooFromList(id: number) { + this.demoService.deleteFoo(id).subscribe( + foo => { + // Do something with foo. + }, + error => { + // Do something with error. + } + ) +} +``` + + + +### How to Get a Specific API Endpoint From Application Config + +Another nice config option that `request` method receives is `apiName` (available as of v2.4), which can be used to get a specific module endpoint from application configuration. + + + +```js +putFoo(body: Foo) { + const request: Rest.Request = { + method: 'PUT', + url: '/' + id, + body + }; + + return this.rest.request(request, {apiName: 'foo'}); +} +``` + + + +`putFoo` above will request `https://localhost:44305/api/some/path/to/foo/{id}` as long as the environment variables are as follows: + +```js +// environment.ts + +export const environment = { + apis: { + default: { + url: 'https://localhost:44305', + }, + foo: { + url: 'https://localhost:44305/api/some/path/to/foo', + }, + }, + + /* rest of the environment variables here */ +} +``` + + + +### How to Observe Response Object or HTTP Events Instead of Body + +`RestService` assumes you are generally interested in the body of a response and, by default, sets `observe` property as `'body'`. However, there may be times you are rather interested in something else, such as a custom proprietary header. For that, the `request` method receives `observe` property in its config object. + +```js +getSomeCustomHeaderValue() { + const request: Rest.Request = { + method: 'GET', + url: '/api/some/path/that/sends/some-custom-header', + }; + + return this.rest.request>( + request, + {observe: Rest.Observe.Response}, + ).pipe( + map(response => response.headers.get('Some-Custom-Header')) + ); +} +``` + + + +You may find `Rest.Observe` enum [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L10). + From ecb930dda264a26495e87d1bbfa748d0f9ba8241 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 23 Mar 2020 17:35:18 +0300 Subject: [PATCH 35/52] build(npm): add ts-toolbelt to devDependencies --- npm/ng-packs/package.json | 1 + npm/ng-packs/yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index c3e26038f0..37621afb49 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -83,6 +83,7 @@ "snq": "^1.0.3", "symlink-manager": "^1.4.2", "ts-node": "~7.0.0", + "ts-toolbelt": "^6.3.6", "tsickle": "^0.37.0", "tslint": "~5.20.0", "typescript": "~3.5.3", diff --git a/npm/ng-packs/yarn.lock b/npm/ng-packs/yarn.lock index db911bfb55..8c2e4c37d2 100644 --- a/npm/ng-packs/yarn.lock +++ b/npm/ng-packs/yarn.lock @@ -11685,6 +11685,11 @@ ts-node@~7.0.0: source-map-support "^0.5.6" yn "^2.0.0" +ts-toolbelt@^6.3.6: + version "6.3.6" + resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.3.6.tgz#2bde29106c013ed520c32f30e1248daf8fd4f5f9" + integrity sha512-eVzym+LyQodOCfyVyQDQ6FGYbO2Xf9Nc4dGLRKlKSUpAs+8qQWHG+grDiA3ciEuNPNZ0qJnNIYkdqBW1rCWuUA== + tsickle@^0.37.0: version "0.37.1" resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.37.1.tgz#2f8a87c1b15766e866457bd06fb6c0e0d84eed09" From 007421aae13446c63bd2b23f0f3e9f9d535bc61c Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 23 Mar 2020 18:55:29 +0300 Subject: [PATCH 36/52] feat(core): use Object.Paths in byDeep method of TrackByService --- .../core/src/lib/services/track-by.service.ts | 9 +++++---- .../core/src/lib/tests/track-by.service.spec.ts | 16 +++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts b/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts index ca2b92db5f..4f7cc6f7c8 100644 --- a/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts @@ -1,18 +1,19 @@ import { Injectable, TrackByFunction } from '@angular/core'; +import { O } from 'ts-toolbelt'; @Injectable({ providedIn: 'root', }) export class TrackByService { by(key: keyof T): TrackByFunction { - return ({}, item) => item[key]; + return (_, item) => item[key]; } - byDeep(...keys: (string | number)[]): TrackByFunction { - return ({}, item) => keys.reduce((acc, key) => acc[key], item); + byDeep(...keys: T extends object ? O.Paths : never): TrackByFunction { + return (_, item) => keys.reduce((acc, key) => acc[key], item); } bySelf(): TrackByFunction { - return ({}, item) => item; + return (_, item) => item; } } diff --git a/npm/ng-packs/packages/core/src/lib/tests/track-by.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/track-by.service.spec.ts index 19868e8ad5..c1125d2930 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/track-by.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/track-by.service.spec.ts @@ -11,17 +11,11 @@ describe('TrackByService', () => { describe('#byDeep', () => { it('should return a function which tracks a deeply-nested property', () => { - expect( - service.byDeep( - 'a', - 'b', - 'c', - 1, - 'x', - )(284, { - a: { b: { c: [{ x: 1035 }, { x: 1036 }, { x: 1037 }] } }, - }), - ).toBe(1036); + const obj = { + a: { b: { c: { x: 1036 } } }, + }; + + expect(service.byDeep('a', 'b', 'c', 'x')(284, obj)).toBe(1036); }); }); From 25204e5d34d4850514e417273e57b984d3156659 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 23 Mar 2020 20:00:10 +0300 Subject: [PATCH 37/52] refactor: remove bySelf method --- .../packages/core/src/lib/services/track-by.service.ts | 4 ---- .../packages/core/src/lib/tests/track-by.service.spec.ts | 6 ------ 2 files changed, 10 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts b/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts index 4f7cc6f7c8..9576a287f2 100644 --- a/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts @@ -12,8 +12,4 @@ export class TrackByService { byDeep(...keys: T extends object ? O.Paths : never): TrackByFunction { return (_, item) => keys.reduce((acc, key) => acc[key], item); } - - bySelf(): TrackByFunction { - return (_, item) => item; - } } diff --git a/npm/ng-packs/packages/core/src/lib/tests/track-by.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/track-by.service.spec.ts index c1125d2930..377f129ff5 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/track-by.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/track-by.service.spec.ts @@ -18,10 +18,4 @@ describe('TrackByService', () => { expect(service.byDeep('a', 'b', 'c', 'x')(284, obj)).toBe(1036); }); }); - - describe('#bySelf', () => { - it('should return a function which tracks the item', () => { - expect(service.bySelf()(284, 'X')).toBe('X'); - }); - }); }); From 15b93c3199084f92a6a337aa3909861a97e4a398 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 23 Mar 2020 20:08:08 +0300 Subject: [PATCH 38/52] feat(core): export trackBy and trackByDeep separately --- .../core/src/lib/services/track-by.service.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts b/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts index 9576a287f2..aa72942ec0 100644 --- a/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/track-by.service.ts @@ -1,15 +1,17 @@ import { Injectable, TrackByFunction } from '@angular/core'; import { O } from 'ts-toolbelt'; +export const trackBy = (key: keyof T): TrackByFunction => (_, item) => item[key]; + +export const trackByDeep = ( + ...keys: T extends object ? O.Paths : never +): TrackByFunction => (_, item) => keys.reduce((acc, key) => acc[key], item); + @Injectable({ providedIn: 'root', }) export class TrackByService { - by(key: keyof T): TrackByFunction { - return (_, item) => item[key]; - } + by = trackBy; - byDeep(...keys: T extends object ? O.Paths : never): TrackByFunction { - return (_, item) => keys.reduce((acc, key) => acc[key], item); - } + byDeep = trackByDeep; } From 56295b730704121c2c6734920136e7e167569494 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 23 Mar 2020 21:08:44 +0300 Subject: [PATCH 39/52] docs(core): add how to create TrackByFunction using TrackByService --- docs/en/UI/Angular/Track-By-Service.md | 114 +++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 docs/en/UI/Angular/Track-By-Service.md diff --git a/docs/en/UI/Angular/Track-By-Service.md b/docs/en/UI/Angular/Track-By-Service.md new file mode 100644 index 0000000000..4b8d2d8a1e --- /dev/null +++ b/docs/en/UI/Angular/Track-By-Service.md @@ -0,0 +1,114 @@ +# Easy TrackByFunction Implementation + +`TrackByService` is a utility service to provide an easy implementation for one of the most frequent needs in Angular templates: `TrackByFunction`. Please see [this page in Angular docs](https://angular.io/guide/template-syntax#ngfor-with-trackby) for its purpose. + + + +## Getting Started + +You do not have to provide the `TrackByService` at module or component level, because it is already **provided in root**. You can inject and start using it immediately in your components. For better type support, you may pass in the type of the iterated item to it. + +```js +import { TrackByService } from '@abp/ng.core'; + +@Component({ + /* class metadata here */ +}) +class DemoComponent { + list: Item[]; + + constructor(public readonly track: TrackByService) {} +} +``` + + + +> Noticed `track` is `public` and `readonly`? That is because we will see some examples where methods of `TrackByService` instance are directly called in the component's template. That may be considered as an anti-pattern, but it has its own advantage, especially when component inheritance is leveraged. You can always use public component properties instead. + + + +**The members are also exported as separate functions.** If you do not want to inject `TrackByService`, you can always import and use those functions directly in your classes. + + + +## Usage + +There are two approaches available. + +1. You may inject `TrackByService` to your component and use its members. +2. You may use exported higher-order functions directly on component properties. + + + +### How to Track Items by a Key + +You can use `by` to get a `TrackByFunction` that tracks the iterated object based on one of its keys. For type support, you may pass in the type of the iterated item to it. + +```html + + +
{{ item.name }}
+``` + + + +`by` is exported as a stand-alone function and is named `trackBy`. + +```js +import { trackBy } from "@abp/ng.core"; + +@Component({ + template: ` +
+ {{ item.name }} +
+ `, +}) +class DemoComponent { + list: Item[]; + + trackById = trackBy('id'); +} +``` + + + +### How to Track by a Deeply Nested Key + +You can use `byDeep` to get a `TrackByFunction` that tracks the iterated object based on a deeply nested key. For type support, you may pass in the type of the iterated item to it. + +```html + + +
+ {{ item.tenant.name }} +
+``` + + + +`byDeep` is exported as a stand-alone function and is named `trackByDeep`. + +```js +import { trackByDeep } from "@abp/ng.core"; + +@Component({ + template: ` +
+ {{ item.name }} +
+ `, +}) +class DemoComponent { + list: Item[]; + + trackByTenantAccountId = trackByDeep('tenant', 'account', 'id'); +} +``` + From 9defbd82b9e71a1d1a44b1f88501acf860d3ccf3 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Tue, 24 Mar 2020 09:12:12 +0300 Subject: [PATCH 40/52] docs: rename http request document as Http-Requests.md --- docs/en/UI/Angular/{Rest-Service.md => Http-Requests.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/en/UI/Angular/{Rest-Service.md => Http-Requests.md} (100%) diff --git a/docs/en/UI/Angular/Rest-Service.md b/docs/en/UI/Angular/Http-Requests.md similarity index 100% rename from docs/en/UI/Angular/Rest-Service.md rename to docs/en/UI/Angular/Http-Requests.md From 09cb5ec600c3597742553c39cfa62c34d0c06093 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 09:41:41 +0300 Subject: [PATCH 41/52] docs: add what's next to Http-Requests.md --- docs/en/UI/Angular/Http-Requests.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Http-Requests.md b/docs/en/UI/Angular/Http-Requests.md index f932face22..71878c8045 100644 --- a/docs/en/UI/Angular/Http-Requests.md +++ b/docs/en/UI/Angular/Http-Requests.md @@ -46,7 +46,7 @@ class DemoService { } ``` -You do not have to provide the RestService` at module or component/directive level, because it is already **provided in root**. +You do not have to provide the `RestService` at module or component/directive level, because it is already **provided in root**. @@ -146,7 +146,7 @@ Another nice config option that `request` method receives is `apiName` (availabl ```js -putFoo(body: Foo) { +putFoo(body: Foo, id: string) { const request: Rest.Request = { method: 'PUT', url: '/' + id, @@ -204,3 +204,6 @@ getSomeCustomHeaderValue() { You may find `Rest.Observe` enum [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L10). +## What's Next? + +* [Localization](./Localization.md) \ No newline at end of file From 4a7bd00eed4f324059dd382aa291cdfbd3253b55 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 09:41:57 +0300 Subject: [PATCH 42/52] docs: add what's next to Localization.md --- docs/en/UI/Angular/Localization.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Localization.md b/docs/en/UI/Angular/Localization.md index 01394a3fea..d627f466ba 100644 --- a/docs/en/UI/Angular/Localization.md +++ b/docs/en/UI/Angular/Localization.md @@ -133,4 +133,8 @@ Localization resources are stored in the `localization` property of `ConfigState ## See Also -* [Localization in ASP.NET Core](../../Localization.md) \ No newline at end of file +* [Localization in ASP.NET Core](../../Localization.md) + +## What's Next? + +* [Permission Management](./Permission-Management.md) \ No newline at end of file From b626a9170f86069cc01e1ad14954c1d2327af57f Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 09:42:24 +0300 Subject: [PATCH 43/52] docs: add Http Requests to navigation as a menu item --- docs/en/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 5c2c3a8e64..a96fb911d2 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -312,6 +312,10 @@ { "text": "Angular", "items": [ + { + "text": "HTTP Requests", + "path": "UI/Angular/HTTP-Requests.md" + }, { "text": "Localization", "path": "UI/Angular/Localization.md" From 6dda74a8dd3301ef430090161ac5373c9fde693b Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 09:56:17 +0300 Subject: [PATCH 44/52] refactor(core): take precaution for type error in config state --- npm/ng-packs/packages/core/src/lib/states/config.state.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/core/src/lib/states/config.state.ts b/npm/ng-packs/packages/core/src/lib/states/config.state.ts index 5269946391..8ce206dd76 100644 --- a/npm/ng-packs/packages/core/src/lib/states/config.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/config.state.ts @@ -262,7 +262,8 @@ export class ConfigState { route.url = `/${route.path}`; } - route.order = route.order || route.order === 0 ? route.order : parent.children.length; + route.children = route.children || []; + route.order = route.order || route.order === 0 ? route.order : (parent.children || []).length; parent.children = [...(parent.children || []), route].sort((a, b) => a.order - b.order); flattedRoutes[index] = parent; From 9309d05e08e87d5ebee7e3a118ba1a07132f532d Mon Sep 17 00:00:00 2001 From: John Barrett <40014477+274188A@users.noreply.github.com> Date: Tue, 24 Mar 2020 15:13:13 +0800 Subject: [PATCH 45/52] grammar grammar --- docs/en/Multi-Tenancy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md index 1e1e4e9f81..27fe70086c 100644 --- a/docs/en/Multi-Tenancy.md +++ b/docs/en/Multi-Tenancy.md @@ -4,7 +4,7 @@ ABP Multi-tenancy module provides base functionality to create multi tenant appl Wikipedia [defines](https://en.wikipedia.org/wiki/Multitenancy) multi-tenancy as like that: -> Software **Multi-tenancy** refers to a software **architecture** in which a **single instance** of a software runs on a server and serves **multiple tenants**. A tenant is a group of users who share a common access with specific privileges to the software instance. With a multitenant architecture, a software application is designed to provide every tenant a **dedicated share of the instance including its data**, configuration, user management, tenant individual functionality and non-functional properties. Multi-tenancy contrasts with multi-instance architectures, where separate software instances operate on behalf of different tenants. +> Software **Multi-tenancy** refers to a software **architecture** in which a **single instance** of software runs on a server and serves **multiple tenants**. A tenant is a group of users who share a common access with specific privileges to the software instance. With a multitenant architecture, a software application is designed to provide every tenant a **dedicated share of the instance including its data**, configuration, user management, tenant individual functionality and non-functional properties. Multi-tenancy contrasts with multi-instance architectures, where separate software instances operate on behalf of different tenants. ### Volo.Abp.MultiTenancy Package From 42367498c8dc9fb48d83489f6e65d0b9211a32eb Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 10:25:20 +0300 Subject: [PATCH 46/52] test(core): fix config-state testing error --- npm/ng-packs/packages/core/src/lib/tests/config.state.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/npm/ng-packs/packages/core/src/lib/tests/config.state.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/config.state.spec.ts index 07baed4c14..1ff9ad817e 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/config.state.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/config.state.spec.ts @@ -375,6 +375,7 @@ describe('ConfigState', () => { describe('#AddRoute', () => { const newRoute = { name: 'My new page', + children: [], iconClass: 'fa fa-dashboard', path: 'page', invisible: false, From 9da3a6b99b942e95160226065021080559814def Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 10:25:30 +0300 Subject: [PATCH 47/52] chore: update NPM versions --- npm/ng-packs/.vscode/settings.json | 1 + npm/ng-packs/package.json | 26 +++--- npm/ng-packs/yarn.lock | 132 ++++++++++++++--------------- 3 files changed, 80 insertions(+), 79 deletions(-) diff --git a/npm/ng-packs/.vscode/settings.json b/npm/ng-packs/.vscode/settings.json index 37d9a1e403..9c2678df08 100644 --- a/npm/ng-packs/.vscode/settings.json +++ b/npm/ng-packs/.vscode/settings.json @@ -6,6 +6,7 @@ "typescript.tsdk": "../node_modules/typescript/lib", "workbench.colorCustomizations": { "activityBar.background": "#258ecd", + "activityBar.activeBackground": "#258ecd", "activityBar.activeBorder": "#f0aed7", "activityBar.foreground": "#e7e7e7", "activityBar.inactiveForeground": "#e7e7e799", diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index 37621afb49..a4a3045b0a 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -21,19 +21,19 @@ "generate:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" }, "devDependencies": { - "@abp/ng.account": "~2.2.0", - "@abp/ng.account.config": "~2.2.0", - "@abp/ng.core": "~2.2.0", - "@abp/ng.feature-management": "~2.2.0", - "@abp/ng.identity": "~2.2.0", - "@abp/ng.identity.config": "~2.2.0", - "@abp/ng.permission-management": "~2.2.0", - "@abp/ng.setting-management": "~2.2.0", - "@abp/ng.setting-management.config": "~2.2.0", - "@abp/ng.tenant-management": "~2.2.0", - "@abp/ng.tenant-management.config": "~2.2.0", - "@abp/ng.theme.basic": "~2.2.0", - "@abp/ng.theme.shared": "~2.2.0", + "@abp/ng.account": "~2.3.0", + "@abp/ng.account.config": "~2.3.0", + "@abp/ng.core": "^2.3.0", + "@abp/ng.feature-management": "^2.3.0", + "@abp/ng.identity": "~2.3.0", + "@abp/ng.identity.config": "~2.3.0", + "@abp/ng.permission-management": "^2.3.0", + "@abp/ng.setting-management": "~2.3.0", + "@abp/ng.setting-management.config": "~2.3.0", + "@abp/ng.tenant-management": "~2.3.0", + "@abp/ng.tenant-management.config": "~2.3.0", + "@abp/ng.theme.basic": "~2.3.0", + "@abp/ng.theme.shared": "^2.3.0", "@angular-builders/jest": "^8.2.0", "@angular-devkit/build-angular": "~0.803.21", "@angular-devkit/build-ng-packagr": "~0.803.21", diff --git a/npm/ng-packs/yarn.lock b/npm/ng-packs/yarn.lock index 8c2e4c37d2..a9d0291af1 100644 --- a/npm/ng-packs/yarn.lock +++ b/npm/ng-packs/yarn.lock @@ -2,26 +2,26 @@ # yarn lockfile v1 -"@abp/ng.account.config@^2.2.0", "@abp/ng.account.config@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.account.config/-/ng.account.config-2.2.0.tgz#420396fc55eadd9a5c179e87075a51437ebc964c" - integrity sha512-5BpxFnXCeCDR+m3qGMKn8rSMGwBb4mkwtejVAJXCVYoMXL8x2J9uRgDf9fkdudqpls+BIgB8BX1tRyJiY+Bg8Q== +"@abp/ng.account.config@^2.3.0", "@abp/ng.account.config@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.account.config/-/ng.account.config-2.3.0.tgz#28d65e2eb889d8b44fc726edbed7509214e8034a" + integrity sha512-Vg4+8PvGfgUC+pFtPIS53ZekJM+O4JZ8wGPGaZ/ySLpk2oSfzC/5RFS2rKq3cmySeRCJunmQinCAlBCm5zir8A== dependencies: tslib "^1.9.0" -"@abp/ng.account@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.account/-/ng.account-2.2.0.tgz#3a200a46f83c36ae89a6724a6a2226a5f846641b" - integrity sha512-OwTOxXDI3BJ1MrlR6WtvDmNIkqi1OCWlq7MvUhuFPVmIIUI3OjxHNASk1NfWMSlu6amXDxuFEey4ItrMKnAJog== +"@abp/ng.account@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.account/-/ng.account-2.3.0.tgz#9ca2a564c177c43b53f69f141405914baefbc7b2" + integrity sha512-kJCek8woGGEC1WTgo75Qr2ucyD5VV1nqqnkw8UMJ96/pqASpBJHczGTL8R4ug961i4vexKDnMbiv0SmfMlBDig== dependencies: - "@abp/ng.account.config" "^2.2.0" - "@abp/ng.theme.shared" "^2.2.0" + "@abp/ng.account.config" "^2.3.0" + "@abp/ng.theme.shared" "^2.3.0" tslib "^1.9.0" -"@abp/ng.core@^2.2.0", "@abp/ng.core@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.core/-/ng.core-2.2.0.tgz#a553e845f7bc43838704eb15d8684869dfcb053b" - integrity sha512-HtyHJYPY6kKqySt/afgFT5j6yaN7Bx4MMvIGWHqFqZsQChWceagLk5SBFTOjCE1FgsewX2a7OT452bKjgsWsrg== +"@abp/ng.core@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.core/-/ng.core-2.3.0.tgz#96bad951da07e589f11a0345171e1a142463671e" + integrity sha512-6SsgcRJQWjXvyEZ7VO2ekOoVmKkFB17vJgTvQLiyB+j2t9guAo3LPDcMGGKNum/oInkiYczf8MY7sculrElyKQ== dependencies: "@angular/localize" "~9.0.2" "@ngxs/router-plugin" "^3.6.2" @@ -33,86 +33,86 @@ snq "^1.0.3" tslib "^1.9.0" -"@abp/ng.feature-management@^2.2.0", "@abp/ng.feature-management@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.feature-management/-/ng.feature-management-2.2.0.tgz#04f959ddb62a0abd99a84fb4e6ec935a796418d4" - integrity sha512-Cw0GRi+6LX5oKDwEvJJyUoh7M4hvaUE5TsuP1E3Hicg/1mMSyUDXVrLBOvAeWWolyfFTpFKLppAvoEEMpUt2eg== +"@abp/ng.feature-management@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.feature-management/-/ng.feature-management-2.3.0.tgz#91172fa9f308b3a792a2bf1e762e24560556f412" + integrity sha512-ShytiV1SC3PwP4Hs8Ss3bk2UAZBXteHKWcrIhAvqtWsOQ2aql6e7t+FutRA3wtUuRdX6PTrMRXbMRvhCwGZUKQ== dependencies: - "@abp/ng.theme.shared" "^2.2.0" + "@abp/ng.theme.shared" "^2.3.0" tslib "^1.9.0" -"@abp/ng.identity.config@^2.2.0", "@abp/ng.identity.config@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.identity.config/-/ng.identity.config-2.2.0.tgz#ac050ed632624c490d8957a18606622637d1d6f3" - integrity sha512-sHRG0iRFrGtF2pNnKcjBaeupg39V8easzUFPU42/SVPi0XyAumrOZRbKkN2CBl0WYedqARTZxE5/nejRMXX4Fg== +"@abp/ng.identity.config@^2.3.0", "@abp/ng.identity.config@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.identity.config/-/ng.identity.config-2.3.0.tgz#e9f4904d60f94cc01b3254e0221d7cdb2274aa3b" + integrity sha512-bqCaPHCwaHUfAfNfFskGTJHGvv+hPK9Tmm7PouVa884AmeQs2j0Gwl3o93YHK2VwXENV09qb01feXapSVPsmTw== dependencies: tslib "^1.9.0" -"@abp/ng.identity@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.identity/-/ng.identity-2.2.0.tgz#1cc7ffa4e2aae462d8ce2399f94cf5ad047fefae" - integrity sha512-G/hrMg/PaN0tA871D52AuKlUhsLWfWSblK0XqQiRmMp/ozsEYSvAV91n/pEScm7qx0RF01K0J5K5V8Cjb4LTyA== +"@abp/ng.identity@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.identity/-/ng.identity-2.3.0.tgz#c973f12f5490b1d29c80f510540b18343f998b8d" + integrity sha512-vBLLxCax7MoHilakpW9XMRFGUXcdMM0syiz0PtkgKmYADIQIQ9AzcfwslK2D6wwy447s6NIoGnThtfbshoRtLw== dependencies: - "@abp/ng.identity.config" "^2.2.0" - "@abp/ng.permission-management" "^2.2.0" - "@abp/ng.theme.shared" "^2.2.0" + "@abp/ng.identity.config" "^2.3.0" + "@abp/ng.permission-management" "^2.3.0" + "@abp/ng.theme.shared" "^2.3.0" tslib "^1.9.0" -"@abp/ng.permission-management@^2.2.0", "@abp/ng.permission-management@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.permission-management/-/ng.permission-management-2.2.0.tgz#56bece037aa094400f8d5585db0bfd5718437ae0" - integrity sha512-OeUZzZV+2TTWOhmpwFTvar9/4IpKz5EhI/6uabu3pOtIsU2Ms2OBbjwVUSKbhLT7e0+z5MM1nPCDoXIlYv22wA== +"@abp/ng.permission-management@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.permission-management/-/ng.permission-management-2.3.0.tgz#16599a2e1583c9d6769edb1dc9b78a45b75b7402" + integrity sha512-vJSfcmXCXpBHMjeRb/0QoKlAcvpCQ/qS2quHFUr23nriXIeNxgEdCVHkTBZU8FMxfyTfwwrFRzF2oxn33gubbg== dependencies: - "@abp/ng.theme.shared" "^2.2.0" + "@abp/ng.theme.shared" "^2.3.0" tslib "^1.9.0" -"@abp/ng.setting-management.config@^2.2.0", "@abp/ng.setting-management.config@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.setting-management.config/-/ng.setting-management.config-2.2.0.tgz#31cf94a785fc2d5c3f1bcfe2c79afc0f1ab419ee" - integrity sha512-vZhBvKFZ6puWwujkzEEhqyQiMKdTmAeJjSxlUPRyIuwowrZhPnUk1r0ghyOLTC5fC1TDaUXF1mZ2UsBFMDvuiw== +"@abp/ng.setting-management.config@^2.3.0", "@abp/ng.setting-management.config@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.setting-management.config/-/ng.setting-management.config-2.3.0.tgz#80b9ebc659c34be4c4c45cc6f2fe2b593f491aab" + integrity sha512-nj6Hl8hlzrGJFJZo4d9DWQtf1PCSFnXup/3ajqMOCPPE+oBItY3aNY05jDyGgdr2wEdyWo/u9Invy3Jsvq8itQ== dependencies: tslib "^1.9.0" -"@abp/ng.setting-management@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.setting-management/-/ng.setting-management-2.2.0.tgz#e1c976bf69bbfaa452489b8968b8669c3fba7710" - integrity sha512-LL6CUi0qpS0+9kPz/T0n1U+Kpu9gwI49+d/+xVDG+lIziGqukgwgoUwlEv+Lk0ak+RC5noLurvvJaaKd3l3mPw== +"@abp/ng.setting-management@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.setting-management/-/ng.setting-management-2.3.0.tgz#478c603f67416df763228bc958b6ea05e7d13dd7" + integrity sha512-xJk09NdpXeg3/KezvKl+h0B4T08Hy1SofOATQpVTrE4TIsFxyXKmasMcSY4i/3+wwE1umH+6TZJwPE+pXTu9Ng== dependencies: - "@abp/ng.setting-management.config" "^2.2.0" - "@abp/ng.theme.shared" "^2.2.0" + "@abp/ng.setting-management.config" "^2.3.0" + "@abp/ng.theme.shared" "^2.3.0" tslib "^1.9.0" -"@abp/ng.tenant-management.config@^2.2.0", "@abp/ng.tenant-management.config@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management.config/-/ng.tenant-management.config-2.2.0.tgz#16d87f31ec069e1f3a8351ef3be9a05a3002ed26" - integrity sha512-lfW9lGERn9PBIRseJajQ0GSxo1+wfRxO7Ic/lSSPxhUbsmwg6afquYTcGiU0d+4QQOBY47ga3n0IVrNqWq1pmw== +"@abp/ng.tenant-management.config@^2.3.0", "@abp/ng.tenant-management.config@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management.config/-/ng.tenant-management.config-2.3.0.tgz#8501a3a53f1abac8a65a87782752afb2ba648bb1" + integrity sha512-gGqg7rZd5X37z9glYF2lSiFpJ3Lyi1NdqHnaxdCTui+3/weMo/5RKlf+ilUAPqR5YAMVSLi4mBYYsuShWEBBIQ== dependencies: tslib "^1.9.0" -"@abp/ng.tenant-management@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management/-/ng.tenant-management-2.2.0.tgz#0ce498eaf9f65ef0255fc23949a47f8ae36cf5c8" - integrity sha512-v9Y5F9fm2EXYteCWKI8QODN4ETmSdh6K7gC5Y3+/N+QaUAod8JxFNX0EIXzFGnSLbiZ0O1xA/TRJruQTv1m3SA== +"@abp/ng.tenant-management@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management/-/ng.tenant-management-2.3.0.tgz#5ec092ad9c597d4aa9f2f849fc12e955d2d24696" + integrity sha512-LyJaXuzgZr2tfFPknuGz1spOzfxfaEhPuQ6zHBOhVfQ6KtMBeagsQQoEiLJMtcygR0MRox0kzmUiyTKm4H5DoA== dependencies: - "@abp/ng.feature-management" "^2.2.0" - "@abp/ng.tenant-management.config" "^2.2.0" - "@abp/ng.theme.shared" "^2.2.0" + "@abp/ng.feature-management" "^2.3.0" + "@abp/ng.tenant-management.config" "^2.3.0" + "@abp/ng.theme.shared" "^2.3.0" tslib "^1.9.0" -"@abp/ng.theme.basic@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.theme.basic/-/ng.theme.basic-2.2.0.tgz#7a086a27daa3bec16962dd62dfb2f39a1538e82f" - integrity sha512-fpdDjjhEQZtaZvFkVi5uhqZoYyrxCWJeQgGFvLS36TqYqvJVyoMeJBlVw0CgbY3F+u5V/GmZSVxvZAAJDpUYhg== +"@abp/ng.theme.basic@~2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.basic/-/ng.theme.basic-2.3.0.tgz#e5857864ae4c3274a57cc785b06cccd0ff3515a8" + integrity sha512-LuAlKqmqEFUUwI/ruB6aO1rhfsCD19Pt7PCE3M+vr/KvlYAKb89K1U8nphIfMV8PCz9IU07BwvTn/T2qIt39HQ== dependencies: - "@abp/ng.theme.shared" "^2.2.0" + "@abp/ng.theme.shared" "^2.3.0" tslib "^1.9.0" -"@abp/ng.theme.shared@^2.2.0", "@abp/ng.theme.shared@~2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-2.2.0.tgz#438f77498df3e2f25a1ecf9adb77a9ee5a71d2c5" - integrity sha512-w7TnDbdHpOFcT12wt/9nZDH9PkyZdTP6W+tJIGeH6zOgWC8V4MDX8Ulc9e/ZvQ8u0qRLOEmk3aE5odFQUHSlJw== +"@abp/ng.theme.shared@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-2.3.0.tgz#5b13b8e170fb0c2a4afca34434bd455ee8dfb9d6" + integrity sha512-keYnD17K8QkdSLqBbsATfeh7KwKNoUj/XsHZO8hawE3OfRuy4qYY9xghGFZUUqdIE5kF6gKlLKj4ZTZmuCvOmQ== dependencies: - "@abp/ng.core" "^2.2.0" + "@abp/ng.core" "^2.3.0" "@fortawesome/fontawesome-free" "^5.12.1" "@ng-bootstrap/ng-bootstrap" "^5.3.0" "@ngx-validate/core" "^0.0.7" From a709c4ff8b30f1bc067d2065418da90b2b20fb9e Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 10:42:06 +0300 Subject: [PATCH 48/52] docs: escape curly braces --- docs/en/UI/Angular/Track-By-Service.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/UI/Angular/Track-By-Service.md b/docs/en/UI/Angular/Track-By-Service.md index 4b8d2d8a1e..4506f77e47 100644 --- a/docs/en/UI/Angular/Track-By-Service.md +++ b/docs/en/UI/Angular/Track-By-Service.md @@ -47,7 +47,7 @@ You can use `by` to get a `TrackByFunction` that tracks the iterated object base ```html -
{{ item.name }}
+
{%{{{ item.name }}}%}
``` @@ -62,7 +62,7 @@ import { trackBy } from "@abp/ng.core";
- {{ item.name }} + {%{{{ item.name }}}%}
`, }) @@ -85,7 +85,7 @@ You can use `byDeep` to get a `TrackByFunction` that tracks the iterated object
- {{ item.tenant.name }} + {%{{{ item.tenant.name }}}%}
``` @@ -101,7 +101,7 @@ import { trackByDeep } from "@abp/ng.core";
- {{ item.name }} + {%{{{ item.name }}}%}
`, }) From 90c37f2019dfa3357893f49e9ffa4fd4ea50f428 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 10:42:20 +0300 Subject: [PATCH 49/52] docs: add what's next to custom setting page document --- docs/en/UI/Angular/Custom-Setting-Page.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/UI/Angular/Custom-Setting-Page.md b/docs/en/UI/Angular/Custom-Setting-Page.md index 7c51cf2cca..6aa5d8a3cc 100644 --- a/docs/en/UI/Angular/Custom-Setting-Page.md +++ b/docs/en/UI/Angular/Custom-Setting-Page.md @@ -40,3 +40,7 @@ ngOnInit() { Navigate to `/setting-management` route to see the changes: ![Custom Settings Tab](./images/custom-settings.png) + +## What's Next? + +- [TrackByService](./Track-By-Service.md) From df898213f34cbad9b9bfaa34aa24deeb6a4340f0 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 24 Mar 2020 10:42:36 +0300 Subject: [PATCH 50/52] docs: add TrackByService to the menu --- docs/en/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index a96fb911d2..425b8c526a 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -335,6 +335,10 @@ { "text": "Custom Setting Page", "path": "UI/Angular/Custom-Setting-Page.md" + }, + { + "text": "TrackByService", + "path": "UI/Angular/Track-By-Service.md" } ] } From 38e241dfe012b75ce917cf48d35c8c6afa94d5ee Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Tue, 24 Mar 2020 10:57:53 +0300 Subject: [PATCH 51/52] Test module signingcredential update to prevent multiple tempkey.rsa access at the same time. --- .../AbpIdentityServerTestBaseModule.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs index 29c748361a..ad64ec22fa 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs @@ -12,6 +12,18 @@ namespace Volo.Abp.IdentityServer )] public class AbpIdentityServerTestBaseModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(options => + { + options.AddDeveloperSigningCredential = false; + }); + + PreConfigure(identityServerBuilder => + { + identityServerBuilder.AddDeveloperSigningCredential(false); + }); + } public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAlwaysAllowAuthorization(); From 2f68c19304fe811cd07ee04c5e63eed568149df0 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Tue, 24 Mar 2020 11:16:11 +0300 Subject: [PATCH 52/52] added prevention for existing tempkey.rsa reading --- .../Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs index ad64ec22fa..94624dce0b 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestBaseModule.cs @@ -21,7 +21,7 @@ namespace Volo.Abp.IdentityServer PreConfigure(identityServerBuilder => { - identityServerBuilder.AddDeveloperSigningCredential(false); + identityServerBuilder.AddDeveloperSigningCredential(false, System.Guid.NewGuid().ToString()); }); } public override void ConfigureServices(ServiceConfigurationContext context)