Skip to content

Commit

Permalink
Merge pull request #790 from neozhu/toolbar
Browse files Browse the repository at this point in the history
Datagrid toolbar improvement
  • Loading branch information
neozhu authored Oct 22, 2024
2 parents 2bc24f6 + 465c78c commit cca406f
Show file tree
Hide file tree
Showing 18 changed files with 459 additions and 787 deletions.
11 changes: 0 additions & 11 deletions src/Application/Common/Interfaces/MultiTenant/ITenantProvider.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class PicklistSetsWithPaginationQuery : PicklistSetAdvancedFilter, ICache

public override string ToString()
{
return $"Picklist:{Picklist},Search:{Keyword},OrderBy:{OrderBy} {SortDirection},{PageNumber},{PageSize}";
return $"ListView:{ListView}-{Picklist}-{CurrentUser?.UserId},Search:{Keyword},OrderBy:{OrderBy} {SortDirection},{PageNumber},{PageSize}";
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
namespace CleanArchitecture.Blazor.Application.Features.PicklistSets.Specifications;

public enum PickListView
{
[Description("All")]
All,
[Description("My")]
My,
[Description("Created Toady")]
TODAY,
[Description("Created within the last 30 days")]
LAST_30_DAYS
}
public class PicklistSetAdvancedFilter : PaginationFilter
{
public PickListView ListView { get; set; } = PickListView.All;
public UserProfile? CurrentUser { get; set; }
public Picklist? Picklist { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ public class PicklistSetAdvancedSpecification : Specification<PicklistSet>
{
public PicklistSetAdvancedSpecification(PicklistSetAdvancedFilter filter)
{
DateTime today = DateTime.UtcNow;
var todayrange = today.GetDateRange(PickListView.TODAY.ToString(), filter.CurrentUser.LocalTimeOffset);
var last30daysrange = today.GetDateRange(PickListView.LAST_30_DAYS.ToString(), filter.CurrentUser.LocalTimeOffset);

Query.Where(p => p.Name == filter.Picklist, filter.Picklist is not null)
.Where(
.Where(q => q.CreatedBy == filter.CurrentUser.UserId, filter.ListView == PickListView.My && filter.CurrentUser is not null)
.Where(x => x.Created >= todayrange.Start && x.Created < todayrange.End.AddDays(1), filter.ListView == PickListView.TODAY)
.Where(x => x.Created >= last30daysrange.Start, filter.ListView == PickListView.LAST_30_DAYS)
.Where(
x => x.Description.Contains(filter.Keyword) || x.Text.Contains(filter.Keyword) ||
x.Value.Contains(filter.Keyword), !string.IsNullOrEmpty(filter.Keyword));
}
Expand Down
4 changes: 2 additions & 2 deletions src/Infrastructure/DependencyInjection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@ private static IServiceCollection AddFusionCacheService(this IServiceCollection
FailSafeMaxDuration = TimeSpan.FromHours(8),
FailSafeThrottleDuration = TimeSpan.FromSeconds(30),
// FACTORY TIMEOUTS
FactorySoftTimeout = TimeSpan.FromMilliseconds(1500),
FactoryHardTimeout = TimeSpan.FromMilliseconds(3000),
FactorySoftTimeout = TimeSpan.FromSeconds(10),
FactoryHardTimeout = TimeSpan.FromSeconds(30),
AllowTimedOutFactoryBackgroundCompletion = true,
});
return services;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public override async Task<IdentityResult> AddToRoleAsync(ApplicationUser user,
});
}

if (await IsInRoleAsync(user, role.Name, tenantId))
if (await IsInRoleAsync(user, role.Name))

Check warning on line 106 in src/Infrastructure/Services/MultiTenant/MultiTenantUserManager.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'roleName' in 'Task<bool> MultiTenantUserManager.IsInRoleAsync(ApplicationUser user, string roleName)'.

Check warning on line 106 in src/Infrastructure/Services/MultiTenant/MultiTenantUserManager.cs

View workflow job for this annotation

GitHub Actions / Analyze

Possible null reference argument for parameter 'roleName' in 'Task<bool> MultiTenantUserManager.IsInRoleAsync(ApplicationUser user, string roleName)'.
{
return IdentityResult.Failed(new IdentityError
{
Expand All @@ -123,21 +123,19 @@ public override async Task<IdentityResult> AddToRoleAsync(ApplicationUser user,
/// </summary>
/// <param name="user">The user to check.</param>
/// <param name="roleName">The name of the role to check.</param>
/// <param name="tenantId">The tenant ID.</param>
/// <returns><c>true</c> if the user is in the role, otherwise <c>false</c>.</returns>
public async Task<bool> IsInRoleAsync(ApplicationUser user, string roleName, string tenantId)
public override async Task<bool> IsInRoleAsync(ApplicationUser user, string roleName)
{
if (user == null) throw new ArgumentNullException(nameof(user));
if (string.IsNullOrEmpty(roleName)) throw new ArgumentException("Value cannot be null or empty.", nameof(roleName));

var normalizedRoleName = NormalizeName(roleName);
var roles = await GetUserRoleStore().GetRolesAsync(user, CancellationToken.None);

return await _roleManager.Roles.AnyAsync(r =>
r.NormalizedName == normalizedRoleName &&
r.TenantId == tenantId &&
r.TenantId == user.TenantId &&
Context.UserRoles.Any(ur => ur.UserId == user.Id && ur.RoleId == r.Id));
}


/// <summary>
/// Removes the specified user from the given role.
Expand Down
32 changes: 0 additions & 32 deletions src/Infrastructure/Services/MultiTenant/TenantProvider.cs

This file was deleted.

142 changes: 52 additions & 90 deletions src/Server.UI/Pages/Contacts/Contacts.razor
Original file line number Diff line number Diff line change
Expand Up @@ -35,114 +35,76 @@
@bind-SelectedItem="_currentDto"
Hover="true" @ref="_table">
<ToolBarContent>
<div class="d-flex align-start flex-grow-1">
<div class="d-flex gap-4">
<MudStack Row Spacing="0" Class="flex-grow-1" Justify="Justify.SpaceBetween">
<MudStack Row AlignItems="AlignItems.Start">
<MudIcon Icon="@Icons.Material.Filled.Window" Size="Size.Large" />
<div class="d-flex flex-column">
<MudStack Spacing="0">
<MudText Typo="Typo.caption" Class="mb-2">@Title</MudText>
<MudEnumSelect Style="min-width:120px" TEnum="ContactListView" ValueChanged="OnChangedListView" Value="Query.ListView" Dense="true" Label="List View">
<MudEnumSelect Style="min-width:120px" TEnum="ContactListView" ValueChanged="OnChangedListView" Value="Query.ListView" Dense="true" Label="@L["List View"]">
</MudEnumSelect>
</div>
</div>
<div class="flex-grow-1" />

<div class="d-flex flex-column justify-end">
<div class="d-flex gap-1">
<MudHidden Breakpoint="Breakpoint.SmAndDown">
</MudStack>
</MudStack>
<MudStack Spacing="0" AlignItems="AlignItems.End">
<MudToolBar Dense WrapContent="true" Class="py-1 px-0">
<MudButton Variant="Variant.Outlined"
Disabled="@_loading"
OnClick="@(() => OnRefresh())"
StartIcon="@Icons.Material.Outlined.Refresh">
@ConstantString.Refresh
</MudButton>
@if (_canCreate)
{
<MudButton Variant="Variant.Outlined"
Size="Size.Small"
Disabled="@_loading"
OnClick="@(()=>OnRefresh())"
StartIcon="@Icons.Material.Filled.Refresh" IconColor="Color.Surface" Color="Color.Primary">@ConstantString.Refresh</MudButton>
StartIcon="@Icons.Material.Outlined.Add"
OnClick="OnCreate">
@ConstantString.New
</MudButton>
}
<MudMenu Variant="Variant.Outlined" TransformOrigin="Origin.BottomRight" AnchorOrigin="Origin.BottomRight" EndIcon="@Icons.Material.Filled.MoreVert" Label="@ConstantString.More">
@if (_canCreate)
{
<MudButton Variant="Variant.Outlined" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
Size="Size.Small"
Disabled="@_loading"
OnClick="OnCreate"
IconColor="Color.Surface">@ConstantString.New</MudButton>
<MudButton Variant="Variant.Outlined" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.ContentCopy"
Size="Size.Small"
Disabled="@(_selectedItems.Count!=1)"
OnClick="OnClone"
IconColor="Color.Surface">@ConstantString.Clone</MudButton>
<MudMenuItem Disabled="@(_selectedItems.Count != 1)" OnClick="OnClone">@ConstantString.Clone</MudMenuItem>
}
@if (_canDelete)
{
<MudButton Variant="Variant.Outlined" Color="Color.Error"
StartIcon="@Icons.Material.Filled.Delete"
Disabled="@(!(_selectedItems.Count>0))"
Size="Size.Small"
OnClick="OnDeleteChecked"
IconColor="Color.Surface">@ConstantString.Delete</MudButton>
<MudMenuItem Disabled="@(!(_selectedItems.Count > 0))"
OnClick="OnDeleteChecked">
@ConstantString.Delete
</MudMenuItem>
}
@if (_canExport)
{
<MudLoadingButton @bind-Loading="_exporting" Variant="Variant.Outlined" Color="Color.Primary"
Label="@ConstantString.Export"
Disabled="@_loading"
StartIcon="@Icons.Custom.FileFormats.FileExcel"
Size="Size.Small"
OnClick="OnExport"
IconColor="Color.Surface">
<MudMenuItem Disabled="@_exporting"
OnClick="OnExport">
@ConstantString.Export
</MudLoadingButton>
</MudMenuItem>
}
@if (_canImport)
{
<MudFileUpload T="IBrowserFile" FilesChanged="OnImportData" Accept=".xlsx" Style="margin-top:0px">
<ActivatorContent>
<MudButton HtmlTag="label"
Size="Size.Small"
Variant="Variant.Outlined"
Color="Color.Primary"
Disabled="@_loading"
StartIcon="@Icons.Material.Filled.Upload">
@if (_uploading)
{
<MudProgressCircular Size="Size.Small" Indeterminate="true" />
@ConstantString.Uploading
}
else
{
<MudMenuItem>
<MudFileUpload T="IBrowserFile" FilesChanged="OnImportData" Accept=".xlsx">
<ActivatorContent>
<MudButton Class="pa-0 ma-0" Style="font-weight:400;text-transform:none;"
Variant="Variant.Text"
Disabled="@_uploading">
@ConstantString.Import
}
</MudButton>
</ActivatorContent>
</MudFileUpload>
</MudButton>
</ActivatorContent>
</MudFileUpload>
</MudMenuItem>
}
</MudHidden>
<MudHidden Breakpoint="Breakpoint.SmAndDown" Invert="true">
@if (_canCreate)
{
<MudButton Variant="Variant.Outlined" Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
Size="Size.Small"
Disabled="@_loading"
OnClick="OnCreate"
IconColor="Color.Surface">@ConstantString.New</MudButton>
}
@if (_canDelete)
{
<MudButton Variant="Variant.Outlined" Color="Color.Error"
StartIcon="@Icons.Material.Filled.Delete"
Disabled="@(!(_selectedItems.Count>0))"
Size="Size.Small"
OnClick="OnDeleteChecked"
IconColor="Color.Surface">@ConstantString.Delete</MudButton>
}
</MudHidden>
</div>
@if (_canSearch)
{
<MudTextField T="string" ValueChanged="@(s=>OnSearch(s))" Value="@Query.Keyword" Placeholder="@ConstantString.Search" Adornment="Adornment.End"
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Small"></MudTextField>
}

</div>
</div>
</MudMenu>
</MudToolBar>
<MudStack Row Spacing="1">
@if (_canSearch)
{
<MudTextField T="string" ValueChanged="@(s => OnSearch(s))" Value="@Query.Keyword" Placeholder="@ConstantString.Search" Adornment="Adornment.End"
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Small">
</MudTextField>
}
</MudStack>
</MudStack>
</MudStack>
</ToolBarContent>
<Columns>
<SelectColumn ShowInFooter="false"></SelectColumn>
Expand Down
Loading

0 comments on commit cca406f

Please sign in to comment.