From 1e36ec0a99018e2d2df55682de3684938f5e4698 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Fri, 1 Mar 2024 16:10:23 +0300 Subject: [PATCH 01/17] Remove header from Permissions modal --- .../PermissionManagementModal.cshtml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml index fbdffa806c..15fbc9b1f8 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml @@ -16,7 +16,7 @@ -
+
@@ -24,10 +24,8 @@ { var group = Model.Groups[i]; -

@group.DisplayName

-
-
+
Date: Fri, 1 Mar 2024 16:20:29 +0300 Subject: [PATCH 02/17] Remove header from Permissions modal - Blazor --- .../Components/PermissionManagementModal.razor | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor index 88d023a906..0e0b2aa480 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor @@ -43,9 +43,6 @@ @foreach (var group in _groups) { -

@group.DisplayName

- - Date: Mon, 4 Mar 2024 09:33:32 +0300 Subject: [PATCH 03/17] Update CreateModal.cshtml --- .../Pages/Identity/Users/CreateModal.cshtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml index 2a4216d5d7..fdf33444de 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml @@ -21,7 +21,7 @@ -
+
@* TODO: Can we use dynamic form? *@ @@ -72,7 +72,7 @@
-
+
@for (var i = 0; i < Model.Roles.Length; i++) { var role = Model.Roles[i]; From b5a365fb38f8a9824e317705e5ff83163c4a8850 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 4 Mar 2024 20:17:28 +0800 Subject: [PATCH 04/17] Only `GetEntitiesAsync` on page 1. --- .../src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs index 58867d6e5d..a70c93f3ac 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs +++ b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs @@ -306,10 +306,12 @@ public abstract class AbpCrudPageBase< protected virtual async Task SearchEntitiesAsync() { + var currentPage = CurrentPage; CurrentPage = 1; - - await GetEntitiesAsync(); - + if (currentPage == 1) + { + await GetEntitiesAsync(); + } await InvokeAsync(StateHasChanged); } @@ -596,12 +598,12 @@ public abstract class AbpCrudPageBase< await SetEntityActionsAsync(); } - + protected virtual ValueTask SetEntityActionsAsync() { return ValueTask.CompletedTask; } - + private async ValueTask TrySetTableColumnsAsync() { if (IsDisposed) @@ -614,7 +616,7 @@ public abstract class AbpCrudPageBase< protected virtual ValueTask SetTableColumnsAsync() { - + return ValueTask.CompletedTask; } From daaa770a69915e013bebcee37bb30247ac32c5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Mon, 4 Mar 2024 15:27:47 +0300 Subject: [PATCH 05/17] Add tooltip functionality to grid actions component --- .../grid-actions/grid-actions.component.html | 37 +++++++++++++------ .../grid-actions/grid-actions.component.ts | 3 +- .../src/lib/models/entity-actions.ts | 3 ++ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.html b/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.html index 70809a8975..4fcf67fcfc 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.html +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.html @@ -53,16 +53,31 @@ @if (action.visible(data)) { - + @if (action.tooltip) { + + } @else { + + } } diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts index 6937b93d8a..f74d36dd79 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts @@ -8,7 +8,7 @@ import { import { EntityAction, EntityActionList } from '../../models/entity-actions'; import { EXTENSIONS_ACTION_TYPE } from '../../tokens/extensions.token'; import { AbstractActionsComponent } from '../abstract-actions/abstract-actions.component'; -import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; import { LocalizationModule, PermissionDirective } from '@abp/ng.core'; import { EllipsisDirective } from '@abp/ng.theme.shared'; import { NgClass, NgTemplateOutlet } from '@angular/common'; @@ -23,6 +23,7 @@ import { NgClass, NgTemplateOutlet } from '@angular/common'; NgClass, LocalizationModule, NgTemplateOutlet, + NgbTooltipModule ], selector: 'abp-grid-actions', templateUrl: './grid-actions.component.html', diff --git a/npm/ng-packs/packages/components/extensible/src/lib/models/entity-actions.ts b/npm/ng-packs/packages/components/extensible/src/lib/models/entity-actions.ts index f49b6fcf2c..eb103cb1bd 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/models/entity-actions.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/models/entity-actions.ts @@ -8,6 +8,7 @@ import { Actions, ActionsFactory, } from './actions'; +import { FormPropTooltip } from './form-props'; export class EntityActionList extends ActionList> {} @@ -25,6 +26,7 @@ export class EntityAction extends Action { readonly btnClass?: string; readonly btnStyle?: string; readonly showOnlyIcon?: boolean; + readonly tooltip?: FormPropTooltip; constructor(options: EntityActionOptions) { super(options.permission || '', options.visible, options.action); @@ -33,6 +35,7 @@ export class EntityAction extends Action { this.btnClass = options.btnClass || 'btn btn-primary text-center'; this.btnStyle = options.btnStyle; this.showOnlyIcon = options.showOnlyIcon || false; + this.tooltip = options.tooltip; } static create(options: EntityActionOptions) { From 5e68a58b5f78657f0196aebc0157b1264e01b2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Mon, 4 Mar 2024 19:09:49 +0300 Subject: [PATCH 06/17] Fix pagination issue in ExtensibleTableComponent --- .../extensible-table/extensible-table.component.ts | 14 +++++++++++++- .../packages/core/src/lib/services/list.service.ts | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts index 5670ca7343..3e1ddedb49 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts @@ -175,7 +175,19 @@ export class ExtensibleTableComponent implements OnChanges { ); } - ngOnChanges({ data }: SimpleChanges) { + ngOnChanges({ data, recordsTotal }: SimpleChanges) { + if (data?.currentValue.length === 0 && recordsTotal?.currentValue) { + console.log(recordsTotal?.currentValue); + let maxPage = Number(Number(recordsTotal?.currentValue / this.list.maxResultCount).toFixed()); + + if(recordsTotal?.currentValue % this.list.maxResultCount === 0){ + maxPage -= 1; + } + + this.list.page = maxPage; + return; + } + if (!data?.currentValue) return; if (data.currentValue.length < 1) { diff --git a/npm/ng-packs/packages/core/src/lib/services/list.service.ts b/npm/ng-packs/packages/core/src/lib/services/list.service.ts index 48996bade1..ef835e9fcd 100644 --- a/npm/ng-packs/packages/core/src/lib/services/list.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/list.service.ts @@ -150,7 +150,7 @@ export class ListService implements this._query$.next({ filter: this._filter || undefined, maxResultCount: this._maxResultCount, - skipCount: this._filter ? 0 : this._page * this._maxResultCount, + skipCount: this._page * this._maxResultCount, sorting: this._sortOrder ? `${this._sortKey} ${this._sortOrder}` : undefined, } as any as QueryParamsType); } From 81265271e05152f17b2b6c7cfb769fd8e8bf9f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Mon, 4 Mar 2024 19:11:19 +0300 Subject: [PATCH 07/17] Remove console.log statement in ngOnChanges method --- .../components/extensible-table/extensible-table.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts index 3e1ddedb49..b400b09628 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts @@ -177,7 +177,6 @@ export class ExtensibleTableComponent implements OnChanges { ngOnChanges({ data, recordsTotal }: SimpleChanges) { if (data?.currentValue.length === 0 && recordsTotal?.currentValue) { - console.log(recordsTotal?.currentValue); let maxPage = Number(Number(recordsTotal?.currentValue / this.list.maxResultCount).toFixed()); if(recordsTotal?.currentValue % this.list.maxResultCount === 0){ From 9dddd9a4d9a194edec70be2a62fff18ddbb67188 Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Tue, 5 Mar 2024 08:32:51 +0300 Subject: [PATCH 08/17] TenantStore list method added --- .../Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs | 6 ++++++ .../Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs | 6 ++++++ .../Volo/Abp/MultiTenancy/ITenantStore.cs | 3 +++ .../MultiTenancy/ConfigurationStore/DefaultTenantStore.cs | 6 ++++++ .../Volo/Abp/TenantManagement/TenantStore.cs | 7 +++++++ 5 files changed, 28 insertions(+) diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs index 3873b48db3..73fe9e6999 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Distributed; using Pages.Abp.MultiTenancy.ClientProxies; @@ -57,6 +58,11 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency return tenantConfiguration; } + public Task> GetListAsync(bool includeDetails = false) + { + return Task.FromResult>(Array.Empty()); + } + public TenantConfiguration? Find(string normalizedName) { var cacheKey = CreateCacheKey(normalizedName); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs index dce80a3099..ed4739c93c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; @@ -79,6 +80,11 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency return tenantConfiguration?.Value; } + public Task> GetListAsync(bool includeDetails = false) + { + return Task.FromResult>(Array.Empty()); + } + public TenantConfiguration? Find(string normalizedName) { var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName); diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs index d97d438b01..0e992211ca 100644 --- a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace Volo.Abp.MultiTenancy; @@ -9,6 +10,8 @@ public interface ITenantStore Task FindAsync(Guid id); + Task> GetListAsync(bool includeDetails = false); + [Obsolete("Use FindAsync method.")] TenantConfiguration? Find(string normalizedName); diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs index e91e749fe3..78e902bd06 100644 --- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs +++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Options; @@ -26,6 +27,11 @@ public class DefaultTenantStore : ITenantStore, ITransientDependency return Task.FromResult(Find(id)); } + public Task> GetListAsync(bool includeDetails = false) + { + return Task.FromResult>(_options.Tenants); + } + public TenantConfiguration? Find(string normalizedName) { return _options.Tenants?.FirstOrDefault(t => t.NormalizedName == normalizedName); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs index 808a9684cd..8f494ff45c 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using JetBrains.Annotations; using Volo.Abp.Caching; @@ -37,6 +38,12 @@ public class TenantStore : ITenantStore, ITransientDependency return (await GetCacheItemAsync(id, null)).Value; } + public virtual async Task> GetListAsync(bool includeDetails = false) + { + return ObjectMapper.Map, List>( + await TenantRepository.GetListAsync(includeDetails)); + } + [Obsolete("Use FindAsync method.")] public virtual TenantConfiguration Find(string normalizedName) { From 36633299f3d18e72f67f59fcceec5e2ef6343fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 5 Mar 2024 11:18:22 +0300 Subject: [PATCH 09/17] Fix pagination issue in extensible table component --- .../extensible-table.component.html | 2 ++ .../extensible-table.component.ts | 20 ++++++++++++------- .../ngx-datatable-list.directive.ts | 9 --------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html index 0ba4b22d45..ff44690076 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html @@ -3,6 +3,8 @@ [rows]="data" [count]="recordsTotal" [list]="list" + [offset]="list?.page" + (page)="setPage($event)" (activate)="tableActivate.emit($event)" > @if (actionsTemplate || (actionList.length && hasAtLeastOnePermittedAction)) { diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts index b400b09628..ef9af1631d 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts @@ -1,7 +1,6 @@ import { ABP, - ConfigStateService, - CoreModule, + ConfigStateService, getShortDateFormat, getShortDateShortTimeFormat, getShortTimeFormat, @@ -13,9 +12,7 @@ import { import { AsyncPipe, formatDate, - NgComponentOutlet, - NgFor, - NgIf, + NgComponentOutlet, NgTemplateOutlet, } from '@angular/common'; import { @@ -175,14 +172,23 @@ export class ExtensibleTableComponent implements OnChanges { ); } + setPage({ offset }) { + this.list.page = offset; + } + ngOnChanges({ data, recordsTotal }: SimpleChanges) { - if (data?.currentValue.length === 0 && recordsTotal?.currentValue) { + if (data?.currentValue.length < 1 && recordsTotal?.currentValue > 0) { let maxPage = Number(Number(recordsTotal?.currentValue / this.list.maxResultCount).toFixed()); - if(recordsTotal?.currentValue % this.list.maxResultCount === 0){ + if (recordsTotal?.currentValue % this.list.maxResultCount === 0) { maxPage -= 1; } + if (this.list.page < maxPage) { + this.list.page = this.list.page; + return; + } + this.list.page = maxPage; return; } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts index 9ce5d1d860..3769a3aa3d 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts @@ -53,14 +53,6 @@ export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit { }; } - private subscribeToPage() { - const sub = this.table.page.subscribe(({ offset }) => { - this.list.page = offset; - this.table.offset = offset; - }); - this.subscription.add(sub); - } - private subscribeToSort() { const sub = this.table.sort.subscribe(({ sorts: [{ prop, dir }] }) => { if (prop === this.list.sortKey && this.list.sortOrder === 'desc') { @@ -101,7 +93,6 @@ export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit { } ngOnInit() { - this.subscribeToPage(); this.subscribeToSort(); } } From d7fa0f5c364c05b925b2c0a72cbff6ecf4b71ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 5 Mar 2024 11:51:09 +0300 Subject: [PATCH 10/17] use math.floor method instead of toFixed() --- .../extensible-table/extensible-table.component.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts index ef9af1631d..c8283792fc 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts @@ -178,7 +178,12 @@ export class ExtensibleTableComponent implements OnChanges { ngOnChanges({ data, recordsTotal }: SimpleChanges) { if (data?.currentValue.length < 1 && recordsTotal?.currentValue > 0) { - let maxPage = Number(Number(recordsTotal?.currentValue / this.list.maxResultCount).toFixed()); + let maxPage = Math.floor(Number(Number(recordsTotal?.currentValue / this.list.maxResultCount))); + + if(recordsTotal?.currentValue < this.list.maxResultCount) { + this.list.page = 0; + return; + } if (recordsTotal?.currentValue % this.list.maxResultCount === 0) { maxPage -= 1; From fac19dbdac117691cee5096cc2b93f80f4d4b691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 5 Mar 2024 11:55:13 +0300 Subject: [PATCH 11/17] Remove duplicated Number() convertion --- .../components/extensible-table/extensible-table.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts index c8283792fc..a65a3925b1 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts @@ -178,7 +178,7 @@ export class ExtensibleTableComponent implements OnChanges { ngOnChanges({ data, recordsTotal }: SimpleChanges) { if (data?.currentValue.length < 1 && recordsTotal?.currentValue > 0) { - let maxPage = Math.floor(Number(Number(recordsTotal?.currentValue / this.list.maxResultCount))); + let maxPage = Math.floor(Number(recordsTotal?.currentValue / this.list.maxResultCount)); if(recordsTotal?.currentValue < this.list.maxResultCount) { this.list.page = 0; From c2119f758426adf4f82a5424ea4c53dcc19323e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 5 Mar 2024 14:50:36 +0300 Subject: [PATCH 12/17] update documentation for newly created properties in extensions --- docs/en/UI/Angular/Data-Table-Column-Extensions.md | 3 +++ docs/en/UI/Angular/Dynamic-Form-Extensions.md | 8 +++++++- docs/en/UI/Angular/Entity-Action-Extensions.md | 8 +++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Data-Table-Column-Extensions.md b/docs/en/UI/Angular/Data-Table-Column-Extensions.md index babb329feb..ca4320c203 100644 --- a/docs/en/UI/Angular/Data-Table-Column-Extensions.md +++ b/docs/en/UI/Angular/Data-Table-Column-Extensions.md @@ -220,6 +220,7 @@ type EntityPropOptions = { permission?: string; visible?: PropPredicate; columnVisible?: ColumnPredicate; + tooltip?: FormPropTooltip; }; ``` @@ -234,6 +235,7 @@ As you see, passing `type` and `name` is enough to create an entity prop. Here i - **permission** is the permission context which will be used to decide if a column for this entity prop should be displayed to the user or not. (_default:_ `undefined`) - **visible** is a predicate that will be used to decide if the cell content of this entity prop should be displayed on the table or not based on the data record. (_default:_ `() => true`) - **columnVisible** is a predicate that will be used to decide if the column of this entity prop should be displayed on the table or not. (_default:_ `() => true`) +- **tooltip** . is a tooltip for table column (_default:_ `undefined`) > Important Note: Do not use record in visibility predicates. First of all, the table header checks it too and the record will be `undefined`. Second, if some cells are displayed and others are not, the table will be broken. Use the `valueResolver` and render an empty cell when you need to hide a specific cell. > @@ -272,6 +274,7 @@ const options: EntityPropOptions = { const sessionStateService = getInjected(SessionStateService); return !sessionStateService.getTenant()?.isAvailable; // hide this column when the tenant is available. }, + tooltip: { text: 'AbpIdentity::EmailAddress_Tooltip', placement: 'top' } }; const prop = new EntityProp(options); diff --git a/docs/en/UI/Angular/Dynamic-Form-Extensions.md b/docs/en/UI/Angular/Dynamic-Form-Extensions.md index 52a1f6cb86..bef36049c1 100644 --- a/docs/en/UI/Angular/Dynamic-Form-Extensions.md +++ b/docs/en/UI/Angular/Dynamic-Form-Extensions.md @@ -163,6 +163,8 @@ type FormPropOptions = { options?: PropCallback[]>>; autocomplete?: string; isExtra? boolean; + formText?: string; + tooltip?: FormPropTooltip; }; ``` @@ -182,6 +184,8 @@ As you see, passing `type` and `name` is enough to create a form prop. Here is w - **options** is a callback that is called when a dropdown is needed. It must return an observable. (_default:_ `undefined`) - **autocomplete** will be set as the `autocomplete` attribute of the input for the field. Please check [possible values](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#Values). (_default:_ `'off'`) - **isExtra** indicates this prop is an object extension. When `true`, the value of the field will be mapped from and to `extraProperties` of the entity. (_default:_ `undefined`) +- - **formText** is the definition placed under the field . (_default:_ `undefined`) +- - **tooltip** is the tooltip for the field placed near of the label (_default:_ `undefined`) > Important Note: Do not use `record` property of `PropData` in create form predicates and callbacks, because it will be `undefined`. You can use it on edit form contributors though. @@ -235,7 +239,9 @@ const options: FormPropOptions = { }, autocomplete: 'off', isExtra: true, - template: undefined | Type // Custom angular component + template: undefined | Type, + tooltip: { text: 'Default::MyPropName_Tooltip', placement: 'top' }, + formText: 'Default::MyPropName_Description', }; const prop = new FormProp(options); diff --git a/docs/en/UI/Angular/Entity-Action-Extensions.md b/docs/en/UI/Angular/Entity-Action-Extensions.md index b715479f12..ead1a39b72 100644 --- a/docs/en/UI/Angular/Entity-Action-Extensions.md +++ b/docs/en/UI/Angular/Entity-Action-Extensions.md @@ -311,6 +311,8 @@ type EntityActionOptions = { visible?: ActionPredicate, btnClass?: string, btnStyle?: string, + showOnlyIcon?: boolean, + tooltip?: FormPropTooltip; }; ``` @@ -323,7 +325,9 @@ As you see, passing `action` and `text` is enough to create an entity action. He - **visible** is a predicate that will be used to decide if the current record should have this grid action or not. (_default:_ `() => true`) - **btnClass** is the classes that will be applied to the button. (_default:_ `'btn btn-primary text-center'`) - **btnStyle** is the styles that will be applied to the button. (_default:_ `''`) - +- **showOnlyIcon** is shows only the icon itself. (_default:_ `false`) +- **tooltip** is only available in single entity action button. Adds an tooltip for button. (_default:_ undefined) + You may find a full example below. ### EntityAction\ @@ -342,6 +346,8 @@ const options: EntityActionOptions = { visible: data => data.record.isLockedOut, btnClass:'btn btn-warning text-center', btnStyle: '', //Adds inline style + showOnlyIcon: true, + tooltip: { text: 'AbpIdentity::Edit', placement: 'top' } }; const action = new EntityAction(options); From 4e3310708e59593eb8659121f9037ca2e6aa6904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sinan=20=C3=96zt=C3=BCrk?= Date: Tue, 5 Mar 2024 14:55:35 +0300 Subject: [PATCH 13/17] Update formText and tooltip properties in Dynamic-Form-Extensions.md --- docs/en/UI/Angular/Dynamic-Form-Extensions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/UI/Angular/Dynamic-Form-Extensions.md b/docs/en/UI/Angular/Dynamic-Form-Extensions.md index bef36049c1..2fb73a6fac 100644 --- a/docs/en/UI/Angular/Dynamic-Form-Extensions.md +++ b/docs/en/UI/Angular/Dynamic-Form-Extensions.md @@ -184,8 +184,8 @@ As you see, passing `type` and `name` is enough to create a form prop. Here is w - **options** is a callback that is called when a dropdown is needed. It must return an observable. (_default:_ `undefined`) - **autocomplete** will be set as the `autocomplete` attribute of the input for the field. Please check [possible values](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#Values). (_default:_ `'off'`) - **isExtra** indicates this prop is an object extension. When `true`, the value of the field will be mapped from and to `extraProperties` of the entity. (_default:_ `undefined`) -- - **formText** is the definition placed under the field . (_default:_ `undefined`) -- - **tooltip** is the tooltip for the field placed near of the label (_default:_ `undefined`) +- **formText** is the definition of the field. Placed under the field. (_default:_ `undefined`) +- **tooltip** is the tooltip for the field placed near of the label (_default:_ `undefined`) > Important Note: Do not use `record` property of `PropData` in create form predicates and callbacks, because it will be `undefined`. You can use it on edit form contributors though. @@ -239,7 +239,7 @@ const options: FormPropOptions = { }, autocomplete: 'off', isExtra: true, - template: undefined | Type, + template: undefined | Type, // Custom angular component tooltip: { text: 'Default::MyPropName_Tooltip', placement: 'top' }, formText: 'Default::MyPropName_Description', }; From 6e3ac1d4c85f9dc0b081692536a740eb7c9a4c8c Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Wed, 6 Mar 2024 16:42:23 +0300 Subject: [PATCH 14/17] TenantStore object mapping null check added --- .../AbpTenantManagementDomainMappingProfile.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs index f2458b990c..496095c807 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs @@ -15,6 +15,11 @@ public class AbpTenantManagementDomainMappingProfile : Profile { var connStrings = new ConnectionStrings(); + if (tenant.ConnectionStrings == null) + { + return connStrings; + } + foreach (var connectionString in tenant.ConnectionStrings) { connStrings[connectionString.Name] = connectionString.Value; From 76f8ff56aa2de35ab9b97be7f89b93b9dbd5062d Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 7 Mar 2024 16:40:45 +0800 Subject: [PATCH 15/17] Update Background-Workers document --- docs/en/Background-Workers.md | 2 +- docs/zh-Hans/Background-Workers.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/Background-Workers.md b/docs/en/Background-Workers.md index 6206e2fbd1..06535cccfc 100644 --- a/docs/en/Background-Workers.md +++ b/docs/en/Background-Workers.md @@ -72,7 +72,7 @@ public class PassiveUserCheckerWorker : AsyncPeriodicBackgroundWorkerBase } ```` -* `AsyncPeriodicBackgroundWorkerBase` uses the `AbpTimer` (a thread-safe timer) object to determine **the period**. We can set its `Period` property in the constructor. +* `AsyncPeriodicBackgroundWorkerBase` uses the `AbpAsyncTimer` (a thread-safe timer) object to determine **the period**. We can set its `Period` property in the constructor. * It required to implement the `DoWorkAsync` method to **execute** the periodic work. * It is a good practice to **resolve dependencies** from the `PeriodicBackgroundWorkerContext` instead of constructor injection. Because `AsyncPeriodicBackgroundWorkerBase` uses a `IServiceScope` that is **disposed** when your work finishes. * `AsyncPeriodicBackgroundWorkerBase` **catches and logs exceptions** thrown by the `DoWorkAsync` method. diff --git a/docs/zh-Hans/Background-Workers.md b/docs/zh-Hans/Background-Workers.md index da1e9f9f54..b2cc2a1580 100644 --- a/docs/zh-Hans/Background-Workers.md +++ b/docs/zh-Hans/Background-Workers.md @@ -44,7 +44,7 @@ public class MyWorker : BackgroundWorkerBase public class PassiveUserCheckerWorker : AsyncPeriodicBackgroundWorkerBase { public PassiveUserCheckerWorker( - AbpTimer timer, + AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory ) : base( timer, @@ -71,7 +71,7 @@ public class PassiveUserCheckerWorker : AsyncPeriodicBackgroundWorkerBase } ```` -* `AsyncPeriodicBackgroundWorkerBase` 使用 `AbpTimer`(线程安全定时器)对象来确定**时间段**. 我们可以在构造函数中设置了`Period` 属性. +* `AsyncPeriodicBackgroundWorkerBase` 使用 `AbpAsyncTimer`(线程安全定时器)对象来确定**时间段**. 我们可以在构造函数中设置了`Period` 属性. * 它需要实现 `DoWorkAsync` 方法**执行**定期任务. * 最好使用 `PeriodicBackgroundWorkerContext` **解析依赖** 而不是构造函数. 因为 `AsyncPeriodicBackgroundWorkerBase` 使用 `IServiceScope` 在你的任务执行结束时会对其 **disposed**. * `AsyncPeriodicBackgroundWorkerBase` **捕获并记录** 由 `DoWorkAsync` 方法抛出的 **异常**. From 329fa3e5019473e6e1fe9c8a4f4b722ee50a9b0f Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Thu, 7 Mar 2024 15:07:04 +0300 Subject: [PATCH 16/17] Mongo repository SessionHandle null check added for DeleteDirectAsync method --- .../Repositories/MongoDB/MongoDbRepository.cs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index 443d8f89d3..45629f76e5 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -507,11 +507,21 @@ public class MongoDbRepository var dbContext = await GetDbContextAsync(cancellationToken); var collection = dbContext.Collection(); - await collection.DeleteManyAsync( - dbContext.SessionHandle, - Builders.Filter.Where(predicate), - cancellationToken: cancellationToken - ); + if (dbContext.SessionHandle != null) + { + await collection.DeleteManyAsync( + dbContext.SessionHandle, + Builders.Filter.Where(predicate), + cancellationToken: cancellationToken + ); + } + else + { + await collection.DeleteManyAsync( + Builders.Filter.Where(predicate), + cancellationToken: cancellationToken + ); + } } [Obsolete("Use GetQueryableAsync method.")] From ea9827af1f97f2b6490414684a2bdb9ad062e339 Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Thu, 7 Mar 2024 15:39:48 +0300 Subject: [PATCH 17/17] Tenant store get list test added --- .../Volo/Abp/TenantManagement/TenantStore_Tests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs index 10f203eb43..757d495134 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs @@ -35,4 +35,13 @@ public class TenantStore_Tests : AbpTenantManagementDomainTestBase (await _tenantStore.FindAsync(acme.Id)).ShouldNotBeNull(); } + + [Fact] + public async Task GetListAsync() + { + var tenants = await _tenantRepository.GetListAsync(); + + tenants.ShouldNotBeNull(); + tenants.Count.ShouldBe(3); + } }