Browse Source

Refactor role search methods to use names instead of IDs and update related components

pull/24184/head
maliming 2 months ago
parent
commit
534695d57c
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 2
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs
  2. 4
      modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs
  3. 2
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs
  4. 6
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs
  5. 4
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs
  6. 7
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs
  7. 6
      modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs
  8. 26
      modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json
  9. 4
      modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs
  10. 6
      modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs
  11. 7
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs
  12. 6
      modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js
  13. 8
      modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionProviderKeyLookupService.cs
  14. 1
      modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserResourcePermissionProviderKeyLookupService.cs
  15. 4
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/UserRoleFinder_Tests.cs
  16. 2
      modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionGrantInfoDto.cs
  17. 1
      modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs
  18. 3
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionProviderWithPermissions.cs
  19. 6
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs
  20. 2
      modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/AddResourcePermissionManagementModal.cshtml
  21. 1
      modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml
  22. 4
      modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml.cs
  23. 4
      modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/add-resource-permission-management-modal.js
  24. 2
      modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/resource-permission-management-modal.js

2
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs

@ -23,7 +23,7 @@ public interface IIdentityUserIntegrationService : IApplicationService
Task<ListResultDto<RoleData>> SearchRoleAsync(RoleLookupSearchInputDto input);
Task<ListResultDto<RoleData>> SearchRoleByIdsAsync(Guid[] ids);
Task<ListResultDto<RoleData>> SearchRoleByNamesAsync(string[] ids);
Task<long> GetRoleCountAsync(RoleLookupCountInputDto input);
}

4
modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs

@ -105,11 +105,11 @@ public class IdentityUserIntegrationService : IdentityAppServiceBase, IIdentityU
}
}
public virtual async Task<ListResultDto<RoleData>> SearchRoleByIdsAsync(Guid[] ids)
public virtual async Task<ListResultDto<RoleData>> SearchRoleByNamesAsync(string[] names)
{
using (RoleRepository.DisableTracking())
{
var roles = await RoleRepository.GetListAsync(ids);
var roles = await RoleRepository.GetListAsync(names);
return new ListResultDto<RoleData>(roles.Select(r => new RoleData(r.Id, r.Name, r.IsDefault, r.IsStatic, r.IsPublic, r.TenantId, r.ExtraProperties)).ToList());
}
}

2
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs

@ -18,5 +18,5 @@ public interface IUserRoleFinder
Task<List<UserFinderResult>> SearchUserByIdsAsync(Guid[] ids);
Task<List<RoleFinderResult>> SearchRoleByIdsAsync(Guid[] ids);
Task<List<RoleFinderResult>> SearchRoleByNamesAsync(string[] names);
}

6
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs

@ -31,11 +31,17 @@ public interface IIdentityRoleRepository : IBasicRepository<IdentityRole, Guid>
bool includeDetails = false,
CancellationToken cancellationToken = default
);
Task<List<IdentityRole>> GetListAsync(
IEnumerable<Guid> ids,
CancellationToken cancellationToken = default
);
Task<List<IdentityRole>> GetListAsync(
IEnumerable<string> names,
CancellationToken cancellationToken = default
);
Task<List<IdentityRole>> GetDefaultOnesAsync(
bool includeDetails = false,
CancellationToken cancellationToken = default

4
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs

@ -70,11 +70,11 @@ public class UserRoleFinder : IUserRoleFinder, ITransientDependency
}
}
public virtual async Task<List<RoleFinderResult>> SearchRoleByIdsAsync(Guid[] ids)
public virtual async Task<List<RoleFinderResult>> SearchRoleByNamesAsync(string[] names)
{
using (IdentityUserRepository.DisableTracking())
{
var roles = await IdentityRoleRepository.GetListAsync(ids);
var roles = await IdentityRoleRepository.GetListAsync(names);
return roles.Select(user => new RoleFinderResult
{
Id = user.Id,

7
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs

@ -72,6 +72,13 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository<IIdentityDbContext,
.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<IdentityRole>> GetListAsync(IEnumerable<string> names, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.Where(t => names.Contains(t.Name))
.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<IdentityRole>> GetDefaultOnesAsync(
bool includeDetails = false, CancellationToken cancellationToken = default)
{

6
modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs

@ -76,11 +76,11 @@ public partial class IdentityUserIntegrationClientProxy : ClientProxyBase<IIdent
});
}
public virtual async Task<ListResultDto<RoleData>> SearchRoleByIdsAsync(Guid[] ids)
public virtual async Task<ListResultDto<RoleData>> SearchRoleByNamesAsync(String[] names)
{
return await RequestAsync<ListResultDto<RoleData>>(nameof(SearchRoleByIdsAsync), new ClientProxyRequestTypeValue
return await RequestAsync<ListResultDto<RoleData>>(nameof(SearchRoleByNamesAsync), new ClientProxyRequestTypeValue
{
{ typeof(Guid[]), ids }
{ typeof(String[]), names }
});
}

26
modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json

@ -1436,12 +1436,12 @@
}
},
{
"name": "SearchRoleByIdsAsync",
"name": "SearchRoleByNamesAsync",
"parametersOnMethod": [
{
"name": "ids",
"typeAsString": "System.Guid[], System.Private.CoreLib",
"type": "System.Guid[]",
"typeAsString": "System.String[], System.Private.CoreLib",
"type": "System.String[]",
"typeSimple": "[string]",
"isOptional": false,
"defaultValue": null
@ -1828,17 +1828,17 @@
"allowAnonymous": null,
"implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService"
},
"SearchRoleByIdsAsyncByIds": {
"uniqueName": "SearchRoleByIdsAsyncByIds",
"name": "SearchRoleByIdsAsync",
"SearchRoleByNamesAsyncByNames": {
"uniqueName": "SearchRoleByNamesAsyncByNames",
"name": "SearchRoleByNamesAsync",
"httpMethod": "GET",
"url": "integration-api/identity/users/search/roles/by-ids",
"url": "integration-api/identity/users/search/roles/by-names",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "ids",
"typeAsString": "System.Guid[], System.Private.CoreLib",
"type": "System.Guid[]",
"name": "names",
"typeAsString": "System.String[], System.Private.CoreLib",
"type": "System.String[]",
"typeSimple": "[string]",
"isOptional": false,
"defaultValue": null
@ -1846,10 +1846,10 @@
],
"parameters": [
{
"nameOnMethod": "ids",
"name": "ids",
"nameOnMethod": "names",
"name": "names",
"jsonName": null,
"type": "System.Guid[]",
"type": "System.String[]",
"typeSimple": "[string]",
"isOptional": false,
"defaultValue": null,

4
modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs

@ -72,9 +72,9 @@ public class HttpClientUserRoleFinder : IUserRoleFinder, ITransientDependency
}).ToList();
}
public virtual async Task<List<RoleFinderResult>> SearchRoleByIdsAsync(Guid[] ids)
public virtual async Task<List<RoleFinderResult>> SearchRoleByNamesAsync(string[] names)
{
var roles = await _userIntegrationService.SearchRoleByIdsAsync(ids);
var roles = await _userIntegrationService.SearchRoleByNamesAsync(names);
return roles.Items.Select(r => new RoleFinderResult
{
Id = r.Id,

6
modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs

@ -71,10 +71,10 @@ public class IdentityUserIntegrationController : AbpControllerBase, IIdentityUse
}
[HttpGet]
[Route("search/roles/by-ids")]
public virtual Task<ListResultDto<RoleData>> SearchRoleByIdsAsync(Guid[] ids)
[Route("search/roles/by-names")]
public virtual Task<ListResultDto<RoleData>> SearchRoleByNamesAsync(string[] names)
{
return UserIntegrationService.SearchRoleByIdsAsync(ids);
return UserIntegrationService.SearchRoleByNamesAsync(names);
}
[HttpGet]

7
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs

@ -78,6 +78,13 @@ public class MongoIdentityRoleRepository : MongoDbRepository<IAbpIdentityMongoDb
.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<IdentityRole>> GetListAsync(IEnumerable<string> names, CancellationToken cancellationToken = default)
{
return await (await GetQueryableAsync(cancellationToken))
.Where(x => names.Contains(x.Name))
.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<IdentityRole>> GetDefaultOnesAsync(
bool includeDetails = false,
CancellationToken cancellationToken = default)

6
modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js

@ -20,7 +20,7 @@
volo.abp.identity.identityRole.getList = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/identity/roles' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
url: abp.appPath + 'api/identity/roles' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '',
type: 'GET'
}, ajaxParams));
};
@ -73,7 +73,7 @@
volo.abp.identity.identityUser.getList = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/identity/users' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
url: abp.appPath + 'api/identity/users' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '',
type: 'GET'
}, ajaxParams));
};
@ -163,7 +163,7 @@
volo.abp.identity.identityUserLookup.search = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/identity/users/lookup/search' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
url: abp.appPath + 'api/identity/users/lookup/search' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '',
type: 'GET'
}, ajaxParams));
};

8
modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionProviderKeyLookupService.cs

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@ -33,12 +32,7 @@ public class RoleResourcePermissionProviderKeyLookupService : IResourcePermissio
public virtual async Task<List<ResourcePermissionProviderKeyInfo>> SearchAsync(string[] keys, CancellationToken cancellationToken = default)
{
var ids = keys
.Select(key => Guid.TryParse(key, out var id) ? (Guid?)id : null)
.Where(id => id.HasValue)
.Select(id => id.Value)
.ToArray();
var roles = await UserRoleFinder.SearchRoleByIdsAsync(ids.ToArray());
var roles = await UserRoleFinder.SearchRoleByNamesAsync(keys.Distinct().ToArray());
return roles.Select(r => new ResourcePermissionProviderKeyInfo(r.RoleName, r.RoleName)).ToList();
}
}

1
modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/UserResourcePermissionProviderKeyLookupService.cs

@ -37,6 +37,7 @@ public class UserResourcePermissionProviderKeyLookupService : IResourcePermissio
.Select(key => Guid.TryParse(key, out var id) ? (Guid?)id : null)
.Where(id => id.HasValue)
.Select(id => id.Value)
.Distinct()
.ToArray();
var users = await UserRoleFinder.SearchUserByIdsAsync(ids.ToArray());
return users.Select(u => new ResourcePermissionProviderKeyInfo(u.Id.ToString(), u.UserName)).ToList();

4
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/UserRoleFinder_Tests.cs

@ -51,9 +51,9 @@ public class UserRoleFinder_Tests : AbpIdentityDomainTestBase
}
[Fact]
public async Task SearchRoleByIdsAsync()
public async Task SearchRoleByNamesAsync()
{
var roleResults = await _userRoleFinder.SearchRoleByIdsAsync(new[] { _testData.RoleModeratorId, _testData.RoleManagerId });
var roleResults = await _userRoleFinder.SearchRoleByNamesAsync(new[] { "moderator", "manager" });
roleResults.ShouldNotBeEmpty();
roleResults.Count.ShouldBe(2);
roleResults.ShouldContain(x => x.RoleName == "moderator");

2
modules/permission-management/src/Volo.Abp.PermissionManagement.Application.Contracts/Volo/Abp/PermissionManagement/ResourcePermissionGrantInfoDto.cs

@ -10,5 +10,7 @@ public class ResourcePermissionGrantInfoDto
public string ProviderDisplayName { get; set; }
public string ProviderNameDisplayName { get; set; }
public List<GrantedResourcePermissionDto> Permissions { get; set; }
}

1
modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs

@ -259,6 +259,7 @@ public class PermissionAppService : ApplicationService, IPermissionAppService
ProviderName = resourcePermissionGrant.ProviderName,
ProviderKey = resourcePermissionGrant.ProviderKey,
ProviderDisplayName = resourcePermissionGrant.ProviderDisplayName,
ProviderNameDisplayName = resourcePermissionGrant.ProviderNameDisplayName?.Localize(StringLocalizerFactory),
Permissions = new List<GrantedResourcePermissionDto>()
};
foreach (var permission in resourcePermissionGrant.Permissions)

3
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionProviderWithPermissions.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Volo.Abp.Localization;
namespace Volo.Abp.PermissionManagement;
@ -10,6 +11,8 @@ public class PermissionProviderWithPermissions
public string ProviderDisplayName { get; set; }
public ILocalizableString ProviderNameDisplayName { get; set; }
public List<string> Permissions { get; set; }
public PermissionProviderWithPermissions(string providerName, string providerKey, string providerDisplayName)

6
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs

@ -217,7 +217,7 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD
{
continue;
}
var keys = resourcePermissionProvider.Select(rp => rp.ProviderKey).ToList();
var keys = resourcePermissionProvider.Select(rp => rp.ProviderKey).Distinct().ToList();
providerKeyInfos.Add(resourcePermissionProvider.Key, await providerKeyLookupService.SearchAsync(keys.ToArray()));
}
@ -232,6 +232,8 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD
if (providerKeyInfo != null)
{
item.ProviderDisplayName = providerKeyInfo.ProviderDisplayName;
item.ProviderNameDisplayName = providerKeyLookupServices
.FirstOrDefault(s => s.Name == item.ProviderName)?.DisplayName;
}
}
}
@ -374,7 +376,7 @@ public class ResourcePermissionManager : IResourcePermissionManager, ISingletonD
return multiplePermissionWithGrantedProviders;
}
foreach (var provider in ManagementProviders)
foreach (var provider in ManagementProviders.Where(x => x.Name == providerName))
{
permissionNames = resourcePermissions.Select(x => x.Name).ToArray();
var multiplePermissionValueProviderGrantInfo = await provider.CheckAsync(permissionNames, resourceName, resourceKey, providerName, providerKey);

2
modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/AddResourcePermissionManagementModal.cshtml

@ -34,7 +34,7 @@
<select asp-for="@Model.AddModel.ProviderKey" data-val="true" data-val-required="@L["ThisFieldIsRequired."].Value" id="AddModel_ProviderKey" name="AddModel.ProviderKey" value="" class="form-control"></select>
<span class="text-danger field-validation-valid" data-valmsg-for="AddModel.ProviderKey" data-valmsg-replace="true"></span>
</div>
<div class="mb-3" id="permissionList">
<div class="position-relative mb-3" id="permissionList">
<h4>@L["ResourcePermissionPermissions"]</h4>
<div class="form-check form-switch mb-2">
<input class="form-check-input" id="grantAllresourcePermissions" type="checkbox">

1
modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml

@ -21,7 +21,6 @@
<abp-modal-header title="@(L["ResourcePermissions"].Value)"></abp-modal-header>
<input asp-for="@Model.ResourceName" />
<input asp-for="@Model.ResourceKey" />
<input asp-for="@Model.ResourceDisplayName" />
<abp-modal-body>
<div class="d-grid gap-2 mb-2 d-md-flex justify-content-md-end">
<button class="btn btn-sm btn-primary" id="addPermission" type="button">@L["AddResourcePermission"]</button>

4
modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/ResourcePermissionManagementModal.cshtml.cs

@ -18,10 +18,6 @@ public class ResourcePermissionManagementModal : AbpPageModel
[BindProperty(SupportsGet = true)]
public string ResourceKey { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ResourceDisplayName { get; set; }
public bool HasAnyResourcePermission { get; set; }
public bool HasAnyResourceProviderKeyLookupService { get; set; }

4
modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/add-resource-permission-management-modal.js

@ -61,12 +61,12 @@ var abp = abp || {};
return;
}
$items.prop('disabled', true);
abp.ui.setBusy('#permissionList');
var resourceName = $("#ResourceName").val();
var resourceKey = $("#ResourceKey").val();
var providerName = $('input[name="AddModel.ProviderName"]:checked').val();
volo.abp.permissionManagement.permissions.getResourceByProvider(resourceName, resourceKey, providerName, providerKey).then(function (result) {
$items.prop('disabled', false);
abp.ui.clearBusy();
var grantedPermissionNames = result.permissions.filter(function (p) {
return p.isGranted === true;
}).map(function (p) {

2
modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/resource-permission-management-modal.js

@ -60,7 +60,7 @@ var abp = abp || {};
title: l("ResourcePermissionTarget"),
data: 'providerName',
render: function (data, type, row) {
return '<span class="d-inline-block bg-light rounded-pill px-2 me-1 ms-1 mb-1">' + row.providerName + '</span>' + row.providerDisplayName;
return '<span class="d-inline-block bg-light rounded-pill px-2 me-1 ms-1 mb-1" data-bs-toggle="tooltip" data-bs-placement="right" data-bs-title="' + row.providerNameDisplayName + '">' + row.providerName + '</span>' + row.providerDisplayName;
},
},
{

Loading…
Cancel
Save