diff --git a/CutList.Web/Components/Pages/Materials/Index.razor b/CutList.Web/Components/Pages/Materials/Index.razor
index 95396d1..099a2f0 100644
--- a/CutList.Web/Components/Pages/Materials/Index.razor
+++ b/CutList.Web/Components/Pages/Materials/Index.razor
@@ -33,36 +33,47 @@ else if (materials.Count == 0)
}
else
{
-
-
-
- | Shape |
- Type |
- Grade |
- Size |
- Actions |
-
-
-
- @foreach (var material in pagedMaterials)
- {
-
- | @material.Shape.GetDisplayName() |
- @material.Type |
- @material.Grade |
- @material.Size |
-
-
- Edit
-
-
- |
-
- }
-
-
+
-
+ @if (filteredMaterials.Count == 0)
+ {
+
+ No materials match your filters.
+
+ }
+ else
+ {
+
+
+
+ | Shape |
+ Type |
+ Grade |
+ Size |
+ Actions |
+
+
+
+ @foreach (var material in pagedMaterials)
+ {
+
+ | @material.Shape.GetDisplayName() |
+ @material.Type |
+ @material.Grade |
+ @material.Size |
+
+
+
+
+
+ |
+
+ }
+
+
+
+
+ }
}
pagedMaterials => materials.Skip((currentPage - 1) * pageSize).Take(pageSize);
+ private List filteredMaterials => materials.Where(m =>
+ {
+ if (filterState.Shape.HasValue && m.Shape != filterState.Shape.Value)
+ return false;
+ if (filterState.Type.HasValue && m.Type != filterState.Type.Value)
+ return false;
+ if (!string.IsNullOrEmpty(filterState.Grade) && m.Grade != filterState.Grade)
+ return false;
+ if (!string.IsNullOrWhiteSpace(filterState.SearchText))
+ {
+ var search = filterState.SearchText.Trim();
+ if (!Contains(m.Size, search)
+ && !Contains(m.Grade, search)
+ && !Contains(m.Description, search)
+ && !Contains(m.Shape.GetDisplayName(), search))
+ return false;
+ }
+ return true;
+ }).ToList();
+
+ private IEnumerable availableGrades => materials
+ .Select(m => m.Grade)
+ .Where(g => !string.IsNullOrEmpty(g))
+ .Distinct()
+ .OrderBy(g => g)!;
+
+ private IEnumerable pagedMaterials => filteredMaterials
+ .Skip((currentPage - 1) * pageSize)
+ .Take(pageSize);
protected override async Task OnInitializedAsync()
{
@@ -99,6 +139,12 @@ else
}
}
+ private void OnFilterChanged(MaterialFilterState state)
+ {
+ filterState = state;
+ currentPage = 1;
+ }
+
private void ConfirmDelete(Material material)
{
materialToDelete = material;
@@ -113,11 +159,14 @@ else
await MaterialService.DeleteAsync(materialToDelete.Id);
materials = await MaterialService.GetAllAsync();
- var totalPages = (int)Math.Ceiling((double)materials.Count / pageSize);
+ var totalPages = (int)Math.Ceiling((double)filteredMaterials.Count / pageSize);
if (currentPage > totalPages && totalPages > 0)
currentPage = totalPages;
}
}
private void OnPageChanged(int page) => currentPage = page;
+
+ private static bool Contains(string? value, string search) =>
+ value != null && value.Contains(search, StringComparison.OrdinalIgnoreCase);
}
diff --git a/CutList.Web/Components/Pages/Stock/Index.razor b/CutList.Web/Components/Pages/Stock/Index.razor
index 3584324..b92647c 100644
--- a/CutList.Web/Components/Pages/Stock/Index.razor
+++ b/CutList.Web/Components/Pages/Stock/Index.razor
@@ -28,49 +28,60 @@ else if (stockItems.Count == 0)
}
else
{
-
-
-
- | Shape |
- Type |
- Grade |
- Size |
- Length |
- On Hand |
- Actions |
-
-
-
- @foreach (var item in pagedItems)
- {
-
- | @item.Material.Shape.GetDisplayName() |
- @item.Material.Type |
- @item.Material.Grade |
- @item.Material.Size |
- @ArchUnits.FormatFromInches((double)item.LengthInches) |
-
- @if (item.QuantityOnHand > 0)
- {
- @item.QuantityOnHand
- }
- else
- {
- 0
- }
- |
-
-
- Edit
-
-
- |
-
- }
-
-
+
-
+ @if (filteredItems.Count == 0)
+ {
+
+ No stock items match your filters.
+
+ }
+ else
+ {
+
+
+
+ | Shape |
+ Type |
+ Grade |
+ Size |
+ Length |
+ On Hand |
+ Actions |
+
+
+
+ @foreach (var item in pagedItems)
+ {
+
+ | @item.Material.Shape.GetDisplayName() |
+ @item.Material.Type |
+ @item.Material.Grade |
+ @item.Material.Size |
+ @ArchUnits.FormatFromInches((double)item.LengthInches) |
+
+ @if (item.QuantityOnHand > 0)
+ {
+ @item.QuantityOnHand
+ }
+ else
+ {
+ 0
+ }
+ |
+
+
+
+
+
+ |
+
+ }
+
+
+
+
+ }
}
pagedItems => stockItems.Skip((currentPage - 1) * pageSize).Take(pageSize);
+ private List filteredItems => stockItems.Where(s =>
+ {
+ var m = s.Material;
+ if (filterState.Shape.HasValue && m.Shape != filterState.Shape.Value)
+ return false;
+ if (filterState.Type.HasValue && m.Type != filterState.Type.Value)
+ return false;
+ if (!string.IsNullOrEmpty(filterState.Grade) && m.Grade != filterState.Grade)
+ return false;
+ if (!string.IsNullOrWhiteSpace(filterState.SearchText))
+ {
+ var search = filterState.SearchText.Trim();
+ if (!Contains(m.Size, search)
+ && !Contains(m.Grade, search)
+ && !Contains(m.Description, search)
+ && !Contains(m.Shape.GetDisplayName(), search)
+ && !Contains(s.Name, search)
+ && !Contains(s.Notes, search))
+ return false;
+ }
+ return true;
+ }).ToList();
+
+ private IEnumerable availableGrades => stockItems
+ .Select(s => s.Material.Grade)
+ .Where(g => !string.IsNullOrEmpty(g))
+ .Distinct()
+ .OrderBy(g => g)!;
+
+ private IEnumerable pagedItems => filteredItems
+ .Skip((currentPage - 1) * pageSize)
+ .Take(pageSize);
protected override async Task OnInitializedAsync()
{
@@ -96,6 +139,12 @@ else
loading = false;
}
+ private void OnFilterChanged(MaterialFilterState state)
+ {
+ filterState = state;
+ currentPage = 1;
+ }
+
private void ConfirmDelete(StockItem item)
{
itemToDelete = item;
@@ -110,11 +159,14 @@ else
await StockItemService.DeleteAsync(itemToDelete.Id);
stockItems = await StockItemService.GetAllAsync();
- var totalPages = (int)Math.Ceiling((double)stockItems.Count / pageSize);
+ var totalPages = (int)Math.Ceiling((double)filteredItems.Count / pageSize);
if (currentPage > totalPages && totalPages > 0)
currentPage = totalPages;
}
}
private void OnPageChanged(int page) => currentPage = page;
+
+ private static bool Contains(string? value, string search) =>
+ value != null && value.Contains(search, StringComparison.OrdinalIgnoreCase);
}