feat(ProductFilter)

- Add IsEnable filter in products page
subProduct
Amir Hossein Khademi 2024-07-08 17:05:05 +03:30
parent edf22ff1ca
commit 59dad6f038
12 changed files with 127 additions and 209 deletions

View File

@ -311,9 +311,9 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
if (token == null)
throw new Exception("Token is null");
if (product.IsNullOrEmpty())
response = await _restWrapper.ProductRestApi.ReadAll(0,null,null, token);
response = await _restWrapper.ProductRestApi.ReadAll(0,null,null,null);
else
response = await _restWrapper.ProductRestApi.ReadAll(product, token);
response = await _restWrapper.ProductRestApi.ReadAll(product);
_products = response.Products;
return _products;
}

View File

@ -28,7 +28,12 @@
<MudDivider Vertical="true" FlexItem="true" class="mx-1" />
<MudStack class="min-w-[310px] sm:w-full">
<MudText Typo="Typo.h6">1. افزودن محصول به <b> @ViewModel.SelectedCategory?.Name</b></MudText>
<MudStack Row="true">
<MudText Typo="Typo.h6">1. افزودن محصول به <b> @ViewModel.SelectedCategory?.Name</b></MudText>
<MudSpacer/>
<MudButton Disabled="@ViewModel.FormEnable.Not()" Variant="Variant.Outlined" Color="Color.Success" StartIcon="@Icons.Material.Filled.Check" OnClick="@ViewModel.SubmitCreateProduct">ثبت محصول</MudButton>
</MudStack>
<MudGrid Spacing="1" class="-ml-1 w-full">
<MudItem xs="12" md="6">
<MudTextField Disabled="@ViewModel.FormEnable.Not()" @bind-Value="@ViewModel.PageDto.PersianName" Variant="Variant.Outlined" T="string" Label="نام فارسی کالا" />
@ -92,8 +97,8 @@
<MudTextField Disabled="@ViewModel.FormEnable.Not()" @bind-Value="@ViewModel.PageDto.Cost" Format="N0" Variant="Variant.Outlined" T="double" Label="قیمت ( تومان )" />
</MudItem>
</MudGrid>
<MudExpansionPanels>
<MudExpansionPanel Text="ویژگی ها ( اختیاری )">
<MudExpansionPanels DisableBorders="false">
<MudExpansionPanel Text="ویژگی ها ( اختیاری )">
<MudGrid>
@ -164,8 +169,6 @@
</MudPaper>
</ButtonTemplate>
</MudFileUpload>
<MudButton Disabled="@ViewModel.FormEnable.Not()" Color="Color.Success" StartIcon="@Icons.Material.Filled.Check" OnClick="@ViewModel.SubmitCreateProduct">ثبت محصول</MudButton>
</MudStack>

View File

@ -113,45 +113,56 @@ public class FastProductCreateDialogBoxViewModel(ISnackbar snackbar, IRestWrappe
var specifications = Specifications.ToList();
Task.Run(async () =>
{
var token = await userUtility.GetBearerTokenAsync();
if (token == null)
return;
var files = new List<StorageFileSDto>();
foreach (var file in browserFiles)
try
{
using var memoryStream = new MemoryStream();
var stream = file.OpenReadStream();
await stream.CopyToAsync(memoryStream);
var fileUpload = new FileUploadRequest
var token = await userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
var files = new List<StorageFileSDto>();
foreach (var file in browserFiles)
{
ContentType = file.ContentType,
FileName = file.Name,
FileUploadType = FileUploadType.Image,
StringBaseFile = Convert.ToBase64String(memoryStream.ToArray())
using var memoryStream = new MemoryStream();
var stream = file.OpenReadStream();
await stream.CopyToAsync(memoryStream);
var fileUpload = new FileUploadRequest
{
ContentType = file.ContentType,
FileName = file.Name,
FileUploadType = FileUploadType.Image,
StringBaseFile = Convert.ToBase64String(memoryStream.ToArray())
};
var rest = await restWrapper.FileRestApi.UploadFileAsync(fileUpload, token);
files.Add(new StorageFileSDto
{
FileLocation = rest.FileLocation,
FileName = rest.FileName,
FileType = StorageFileType.Image
});
}
product.Cost *= 10;
var command = product.Adapt<CreateProductCommand>() with
{
BeDisplayed = true,
BrandId = brand.Id,
CategoryId = SelectedCategory.Id,
Files = files,
Specifications = specifications
};
var rest = await restWrapper.FileRestApi.UploadFileAsync(fileUpload, token);
files.Add(new StorageFileSDto
{
FileLocation = rest.FileLocation,
FileName = rest.FileName,
FileType = StorageFileType.Image
});
var id = await restWrapper.CrudApiRest<Product, Guid>(Address.ProductController)
.Create(command, token);
}
catch (ApiException ex)
{
snackbar.Add(ex.Message, Severity.Error);
}
catch (Exception e)
{
snackbar.Add(e.Message, Severity.Error);
}
product.Cost *= 10;
var command = product.Adapt<CreateProductCommand>() with
{
BeDisplayed = true,
BrandId = brand.Id,
CategoryId = SelectedCategory.Id,
Files = files,
Specifications = specifications
};
await restWrapper.CrudApiRest<Product, Guid>(Address.ProductController)
.Create(command, token);
});
PageDto = new ProductLDto { Stock = 1 };
PageDto = new ProductLDto { Stock = 10 };
FileNames.Clear();
//Specifications.Clear();
Files.Clear();

View File

@ -5,8 +5,8 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
<AssemblyVersion>1.1.8.11</AssemblyVersion>
<FileVersion>1.1.8.11</FileVersion>
<AssemblyVersion>1.1.10.15</AssemblyVersion>
<FileVersion>1.1.10.15</FileVersion>
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
</PropertyGroup>

View File

@ -133,7 +133,7 @@ public class ManageNavMenuPageViewModel : BaseViewModel<NavMenuSetting>
var token = await _userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
var response = await _restWrapper.ProductRestApi.ReadAll(0,product,null, token);
var response = await _restWrapper.ProductRestApi.ReadAll(0,product,null,null);
var categories = response.Products;
if (product.IsNullOrEmpty())
return categories;

View File

@ -49,7 +49,7 @@
Clearable="true"
ValueChanged="@ViewModel.SearchChanged"
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto"
OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField>
OnAdornmentClick="@ViewModel.GetEntitiesAsync"></MudTextField>
</MudItem>
<MudItem xs="12" sm="6">
@ -86,12 +86,12 @@
<ToolBarContent>
<MudGrid class="collapse md:visible">
<MudItem xs="12" sm="6">
<MudItem xs="12" sm="4">
<MudTextField T="string" Placeholder="جست جو بر اساس نام" Adornment="Adornment.Start" Immediate="true"
Clearable="true"
ValueChanged="@ViewModel.SearchChanged"
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" class="my-auto"
OnAdornmentClick="@ViewModel.SearchAsync"></MudTextField>
OnAdornmentClick="@ViewModel.GetEntitiesAsync"></MudTextField>
</MudItem>
<MudItem xs="12" sm="6">
@ -117,6 +117,12 @@
</ItemTemplate>
</MudAutocomplete>
</MudItem>
<MudItem xs="12" sm="2">
<MudSwitch class="mt-3" T="bool"
Value="ViewModel.IsEnable"
ValueChanged="async(flag)=>await ViewModel.ProductEnableChanged(flag)"
Label="فقط محصولات موجود" Color="Color.Info" />
</MudItem>
</MudGrid>
</ToolBarContent>
<Columns>
@ -142,6 +148,21 @@
}
</CellTemplate>
</TemplateColumn>
<TemplateColumn T="ProductSDto" Title="موجود است">
<CellTemplate>
@if (@context.Item.IsEnable)
{
<p>بلی</p>
}
else
{
<p>خیر</p>
}
</CellTemplate>
</TemplateColumn>
<TemplateColumn T="ProductSDto" Title="قیمتــ">
<CellTemplate>
<p>@context.Item.Cost.ToString("N0") ریالــ</p>

View File

@ -11,16 +11,17 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
private readonly IBrowserViewportService _browserViewportService;
private readonly IRestWrapper _restWrapper;
public string Search = string.Empty;
public string? Search = string.Empty;
public int CurrentPage = 0;
public int PageCount = 1;
public int TotalItems = 0;
public bool IsXs = false;
public bool IsEnable { get; set; } = true;
public ProductsPageViewModel(NavigationManager navigationManager,
ISnackbar snackbar,
IUserUtility userUtility,
IRestWrapper restWrapper,
public ProductsPageViewModel(NavigationManager navigationManager,
ISnackbar snackbar,
IUserUtility userUtility,
IRestWrapper restWrapper,
IDialogService dialogService,
IBrowserViewportService browserViewportService) : base(userUtility)
{
@ -34,6 +35,12 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
}
public override async Task InitializeAsync()
{
await GetEntitiesAsync();
await base.InitializeAsync();
}
public async Task GetEntitiesAsync()
{
try
{
@ -42,10 +49,11 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
throw new Exception("Token is null");
IsProcessing = true;
PageDto.Clear();
var dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage,null,null, token);
var search = Search.IsNullOrEmpty() ? null : Search;
var dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, search, SelectedCategory?.Id, IsEnable);
dto.Products.ForEach(d => PageDto.Add(d));
if (PageDto.Count == 20)
PageCount = 2;
if (PageDto.Count % 20 == 0)
PageCount = CurrentPage + 2;
TotalItems = dto.Pager.TotalItems;
IsXs = (await _browserViewportService.GetCurrentBreakpointAsync()) == Breakpoint.Xs;
}
@ -63,52 +71,12 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
IsProcessing = false;
}
await base.InitializeAsync();
}
public async Task ChangePageAsync(int page)
{
CurrentPage = page - 1;
if (CurrentPage > PageCount - 2)
{
try
{
var token = await _userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
IsProcessing = true;
GetProductsResponseDto dto = new GetProductsResponseDto();
if (Search.IsNullOrEmpty())
{
dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage,null,null, token);
}
else
{
dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search,null, token);
}
dto.Products.ForEach(d => PageDto.Add(d));
if (PageDto.Count % 20 == 0)
PageCount = CurrentPage + 2;
}
catch (ApiException ex)
{
var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
}
catch (Exception e)
{
_snackbar.Add(e.Message, Severity.Error);
}
finally
{
IsProcessing = false;
}
}
await GetEntitiesAsync();
}
public async Task AddProductClicked()
@ -116,7 +84,7 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, DisableBackdropClick = true };
var breakPoint = await _browserViewportService.GetCurrentBreakpointAsync();
if (breakPoint == Breakpoint.Xs)
maxWidth = new DialogOptions { FullScreen = true , CloseButton = true};
maxWidth = new DialogOptions { FullScreen = true, CloseButton = true };
var dialogResult = await _dialogService.ShowAsync<ProductActionDialogBox>("افزودن محصول جدید", maxWidth);
var result = await dialogResult.Result;
if (!result.Canceled && result.Data is bool and true)
@ -128,7 +96,7 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
public async Task AddFastProductClicked()
{
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, NoHeader = true, DisableBackdropClick = true , CloseButton = true };
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, NoHeader = true, DisableBackdropClick = true, CloseButton = true };
var breakPoint = await _browserViewportService.GetCurrentBreakpointAsync();
if (breakPoint == Breakpoint.Xs)
maxWidth = new DialogOptions { FullScreen = true, NoHeader = true, CloseButton = true };
@ -208,47 +176,6 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
await InitializeAsync();
Search = search;
}
public async Task SearchAsync()
{
try
{
if (Search.IsNullOrEmpty())
throw new AppException("دسته بندی برای جست جو وارد نشده است");
var token = await _userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
IsProcessing = true;
CurrentPage = 0;
PageCount = 1;
PageDto.Clear();
GetProductsResponseDto dto;
if (SelectedCategory != null)
dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search, SelectedCategory.Id, token);
else
dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search,null, token);
dto.Products.ForEach(d => PageDto.Add(d));
if (PageDto.Count == 20)
PageCount = 2;
}
catch (ApiException ex)
{
var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
}
catch (Exception e)
{
_snackbar.Add(e.Message, Severity.Error);
}
finally
{
IsProcessing = false;
}
}
private List<ProductCategorySDto> _productCategories = new List<ProductCategorySDto>();
@ -281,74 +208,13 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
public async Task ProductCategorySelected(ProductCategorySDto productCategory)
{
SelectedCategory = productCategory;
try
{
if (SelectedCategory == null)
{
return;
}
IsProcessing = true;
var token = await _userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
CurrentPage = 0;
PageCount = 1;
PageDto.Clear();
GetProductsResponseDto dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search, SelectedCategory.Id, token);
dto.Products.ForEach(d => PageDto.Add(d));
if (PageDto.Count == 20)
PageCount = 2;
}
catch (ApiException ex)
{
var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
}
catch (Exception e)
{
_snackbar.Add(e.Message, Severity.Error);
}
finally
{
IsProcessing = false;
}
await GetEntitiesAsync();
}
public async Task ClearProductCategorySearch()
{
SelectedCategory = null;
try
{
IsProcessing = true;
var token = await _userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
CurrentPage = 0;
PageCount = 1;
PageDto.Clear();
GetProductsResponseDto dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search, null, token);
dto.Products.ForEach(d => PageDto.Add(d));
if (PageDto.Count == 20)
PageCount = 2;
}
catch (ApiException ex)
{
var exe = await ex.GetContentAsAsync<ApiResult>();
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
}
catch (Exception e)
{
_snackbar.Add(e.Message, Severity.Error);
}
finally
{
IsProcessing = false;
}
await GetEntitiesAsync();
}
public async Task DisplayedChanged(ProductSDto product)
@ -370,4 +236,13 @@ public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductS
_snackbar.Add(e.Message, Severity.Error);
}
}
public async Task ProductEnableChanged(bool? arg)
{
if (arg == null)
return;
IsEnable = arg.Value;
CurrentPage = 0;
await GetEntitiesAsync();
}
}

View File

@ -9,10 +9,10 @@ public interface IProductRestApi
Task<GetProductResponseDto> ReadOne(Guid productId);
[Get("")]
Task<GetProductsResponseDto> ReadAll([Query] string productName, [Header("Authorization")] string authorization);
Task<GetProductsResponseDto> ReadAll([Query] string productName);
[Get("")]
Task<GetProductsResponseDto> ReadAll([Query] int page, [Query] string? productName, [Query] Guid? categoryId, [Header("Authorization")] string authorization);
Task<GetProductsResponseDto> ReadAll([Query] int page, [Query] string? productName, [Query] Guid? categoryId, [Query] bool? isActive);
[Get("")]
Task<GetProductsResponseDto> ReadAll([Query] string productName, [Query] Guid categoryId, [Header("Authorization")] string authorization);

View File

@ -8,11 +8,12 @@
"Microsoft.AspNetCore.Http.Connections": "Debug"
}
},
"WebSiteUrl": "https://vesmeh.com",
"AdminPanelBaseUrl": "https://admin.vesmeh.com",
"StorageBaseUrl": "https://storage.vesmeh.com/",
//"ApiUrl": "https://api.vesmeh.com/api"
"ApiUrl": "http://localhost:32770/api"
"WebSiteUrl": "https://bonsaigallery.shop",
"AdminPanelBaseUrl": "https://admin.bonsaigallery.shop",
"StorageBaseUrl": "https://storage.bonsaigallery.shop",
"ApiUrl": "https://api.bonsaigallery.shop/api",
"IsShop": true
//"ApiUrl": "http://localhost:32770/api"
//"WebSiteUrl": "https://hamyanedalat.com",
//"AdminPanelBaseUrl": "https://admin.hamyanedalat.com",

View File

@ -1045,6 +1045,9 @@ input:checked + .toggle-bg {
.top-0 {
top: 0px;
}
.\!z-\[9999\] {
z-index: 9999 !important;
}
.z-10 {
z-index: 10;
}

View File

@ -1113,6 +1113,10 @@ input:checked + .toggle-bg {
top: 0px;
}
.\!z-\[9999\] {
z-index: 9999 !important;
}
.z-10 {
z-index: 10;
}

View File

@ -43,7 +43,7 @@
</div>
</div>
<div dir="rtl" id="blazor-error-ui" class="!text-black">
<div dir="rtl" id="blazor-error-ui" class="!text-black !z-[9999]">
<b>مشکلی رخ داده است</b>
<a href="" class="reload">بارگزاری مجدد</a>
<a class="dismiss">بستن</a>