feat: unify add/edit stock UI into a single modal on Job Edit page
Replaces the three separate surfaces (bulk import modal, inline custom-length form, inline edit forms) with one "Add Stock" button and modal that handles both add and edit, for both inventory-sourced and custom-length stock.
This commit is contained in:
@@ -229,17 +229,40 @@ else
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@* Import Stock Modal *@
|
@* Add/Edit Stock Modal *@
|
||||||
@if (showImportModal)
|
@if (showStockModal)
|
||||||
{
|
{
|
||||||
<div class="modal fade show d-block" tabindex="-1" style="background-color: rgba(0,0,0,0.5);">
|
<div class="modal fade show d-block" tabindex="-1" style="background-color: rgba(0,0,0,0.5);">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">Import Stock from Inventory</h5>
|
<h5 class="modal-title">@(editingStock == null ? "Add Stock" : "Edit Stock")</h5>
|
||||||
<button type="button" class="btn-close" @onclick="CloseImportModal"></button>
|
<button type="button" class="btn-close" @onclick="CloseStockModal"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
@if (editingStock == null)
|
||||||
|
{
|
||||||
|
<ul class="nav nav-tabs mb-3" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link @(stockModalTab == StockModalTab.Inventory ? "active" : "")"
|
||||||
|
type="button" disabled="@(job.Parts.Count == 0)"
|
||||||
|
title="@(job.Parts.Count == 0 ? "Add parts first to match against inventory" : "")"
|
||||||
|
@onclick="() => stockModalTab = StockModalTab.Inventory">
|
||||||
|
From Inventory
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link @(stockModalTab == StockModalTab.Custom ? "active" : "")"
|
||||||
|
type="button"
|
||||||
|
@onclick="() => stockModalTab = StockModalTab.Custom">
|
||||||
|
Custom Length
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (stockModalTab == StockModalTab.Inventory && editingStock == null)
|
||||||
|
{
|
||||||
@if (loadingImport)
|
@if (loadingImport)
|
||||||
{
|
{
|
||||||
<div class="text-center py-4">
|
<div class="text-center py-4">
|
||||||
@@ -307,9 +330,109 @@ else
|
|||||||
{
|
{
|
||||||
<div class="alert alert-danger mt-3 mb-0">@importErrorMessage</div>
|
<div class="alert alert-danger mt-3 mb-0">@importErrorMessage</div>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (stockModalTab == StockModalTab.Inventory && editingStock != null)
|
||||||
|
{
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Shape</label>
|
||||||
|
<select class="form-select" @bind="stockSelectedShape" @bind:after="OnStockShapeChanged">
|
||||||
|
<option value="">-- Select --</option>
|
||||||
|
@foreach (var shape in DistinctShapes)
|
||||||
|
{
|
||||||
|
<option value="@shape">@shape.GetDisplayName()</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Size</label>
|
||||||
|
<select class="form-select" @bind="stockSelectedMaterialId" @bind:after="OnStockMaterialChanged"
|
||||||
|
disabled="@(!stockSelectedShape.HasValue)">
|
||||||
|
<option value="0">-- Select --</option>
|
||||||
|
@foreach (var material in materials.Where(m => stockSelectedShape.HasValue && m.Shape == stockSelectedShape.Value).OrderBy(m => m.SortOrder).ThenBy(m => m.Size))
|
||||||
|
{
|
||||||
|
<option value="@material.Id">@material.Size</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Stock Length</label>
|
||||||
|
<select class="form-select" @bind="newStock.StockItemId" disabled="@(stockSelectedMaterialId == 0)">
|
||||||
|
<option value="">-- Select --</option>
|
||||||
|
@foreach (var stock in availableStockItems)
|
||||||
|
{
|
||||||
|
<option value="@stock.Id">@ArchUnits.FormatFromInches((double)stock.LengthInches)</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Qty to Use</label>
|
||||||
|
<input type="number" class="form-control" @bind="newStock.Quantity" min="-1" />
|
||||||
|
<small class="text-muted">-1 = unlimited</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-3 mt-1">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Priority</label>
|
||||||
|
<input type="number" class="form-control" @bind="newStock.Priority" min="1" />
|
||||||
|
<small class="text-muted">Lower = used first</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (!string.IsNullOrEmpty(stockErrorMessage))
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger mt-3 mb-0">@stockErrorMessage</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Shape</label>
|
||||||
|
<select class="form-select" @bind="stockSelectedShape" @bind:after="OnStockShapeChanged">
|
||||||
|
<option value="">-- Select --</option>
|
||||||
|
@foreach (var shape in DistinctShapes)
|
||||||
|
{
|
||||||
|
<option value="@shape">@shape.GetDisplayName()</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Size</label>
|
||||||
|
<select class="form-select" @bind="newStock.MaterialId" disabled="@(!stockSelectedShape.HasValue)">
|
||||||
|
<option value="0">-- Select --</option>
|
||||||
|
@foreach (var material in materials.Where(m => stockSelectedShape.HasValue && m.Shape == stockSelectedShape.Value).OrderBy(m => m.SortOrder).ThenBy(m => m.Size))
|
||||||
|
{
|
||||||
|
<option value="@material.Id">@material.Size</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Length</label>
|
||||||
|
<LengthInput @bind-Value="newStock.LengthInches" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Quantity</label>
|
||||||
|
<input type="number" class="form-control" @bind="newStock.Quantity" min="-1" />
|
||||||
|
<small class="text-muted">Use -1 for unlimited</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-3 mt-1">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Priority</label>
|
||||||
|
<input type="number" class="form-control" @bind="newStock.Priority" min="1" />
|
||||||
|
<small class="text-muted">Lower = used first</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (!string.IsNullOrEmpty(stockErrorMessage))
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger mt-3 mb-0">@stockErrorMessage</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-outline-secondary" @onclick="CloseImportModal">Cancel</button>
|
<button type="button" class="btn btn-outline-secondary" @onclick="CloseStockModal">Cancel</button>
|
||||||
|
@if (stockModalTab == StockModalTab.Inventory && editingStock == null)
|
||||||
|
{
|
||||||
@if (importCandidates.Count > 0)
|
@if (importCandidates.Count > 0)
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick="ImportSelectedStockAsync"
|
<button type="button" class="btn btn-primary" @onclick="ImportSelectedStockAsync"
|
||||||
@@ -317,6 +440,17 @@ else
|
|||||||
Import @importCandidates.Count(c => c.Selected) Item@(importCandidates.Count(c => c.Selected) != 1 ? "s" : "")
|
Import @importCandidates.Count(c => c.Selected) Item@(importCandidates.Count(c => c.Selected) != 1 ? "s" : "")
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (stockModalTab == StockModalTab.Inventory && editingStock != null)
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-primary" @onclick="SaveStockFromInventoryAsync">Save Changes</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-primary" @onclick="SaveCustomStockAsync">
|
||||||
|
@(editingStock == null ? "Add Stock" : "Save Changes")
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -350,18 +484,16 @@ else
|
|||||||
private int partSelectedMaterialId;
|
private int partSelectedMaterialId;
|
||||||
private List<PartRow> partRows = new();
|
private List<PartRow> partRows = new();
|
||||||
|
|
||||||
// Stock form
|
// Stock modal (unified add/edit, both inventory-sourced and custom-length)
|
||||||
private bool showStockForm;
|
private enum StockModalTab { Inventory, Custom }
|
||||||
private bool showCustomStockForm;
|
private bool showStockModal;
|
||||||
|
private StockModalTab stockModalTab = StockModalTab.Inventory;
|
||||||
private JobStock newStock = new();
|
private JobStock newStock = new();
|
||||||
private JobStock? editingStock;
|
private JobStock? editingStock;
|
||||||
private string? stockErrorMessage;
|
private string? stockErrorMessage;
|
||||||
private MaterialShape? stockSelectedShape;
|
private MaterialShape? stockSelectedShape;
|
||||||
private int stockSelectedMaterialId;
|
private int stockSelectedMaterialId;
|
||||||
private List<StockItem> availableStockItems = new();
|
private List<StockItem> availableStockItems = new();
|
||||||
|
|
||||||
// Import modal
|
|
||||||
private bool showImportModal;
|
|
||||||
private bool loadingImport;
|
private bool loadingImport;
|
||||||
private List<ImportStockCandidate> importCandidates = new();
|
private List<ImportStockCandidate> importCandidates = new();
|
||||||
private string? importErrorMessage;
|
private string? importErrorMessage;
|
||||||
@@ -741,25 +873,10 @@ else
|
|||||||
<h5 class="mb-0">Stock for This Job</h5>
|
<h5 class="mb-0">Stock for This Job</h5>
|
||||||
@if (!job.IsLocked)
|
@if (!job.IsLocked)
|
||||||
{
|
{
|
||||||
<div class="d-flex gap-2">
|
<button class="btn btn-primary" @onclick="ShowAddStockModal">Add Stock</button>
|
||||||
<button class="btn btn-success" @onclick="ShowImportModal" disabled="@(job.Parts.Count == 0)"
|
|
||||||
title="@(job.Parts.Count == 0 ? "Add parts first to match against inventory" : "Find and import stock matching your parts")">
|
|
||||||
Import from Inventory
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-primary" @onclick="ShowAddCustomStock">Add Custom Length</button>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@if (showStockForm)
|
|
||||||
{
|
|
||||||
@RenderStockFromInventoryForm()
|
|
||||||
}
|
|
||||||
else if (showCustomStockForm)
|
|
||||||
{
|
|
||||||
@RenderCustomStockForm()
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (job.Stock.Count == 0)
|
@if (job.Stock.Count == 0)
|
||||||
{
|
{
|
||||||
<div class="text-center py-4 text-muted">
|
<div class="text-center py-4 text-muted">
|
||||||
@@ -776,122 +893,6 @@ else
|
|||||||
</div>
|
</div>
|
||||||
};
|
};
|
||||||
|
|
||||||
private RenderFragment RenderStockFromInventoryForm() => __builder =>
|
|
||||||
{
|
|
||||||
<div class="border rounded p-3 mb-3 bg-light">
|
|
||||||
<h6>@(editingStock == null ? "Add Stock from Inventory" : "Edit Stock Selection")</h6>
|
|
||||||
<div class="row g-3">
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Shape</label>
|
|
||||||
<select class="form-select" @bind="stockSelectedShape" @bind:after="OnStockShapeChanged">
|
|
||||||
<option value="">-- Select --</option>
|
|
||||||
@foreach (var shape in DistinctShapes)
|
|
||||||
{
|
|
||||||
<option value="@shape">@shape.GetDisplayName()</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Size</label>
|
|
||||||
<select class="form-select" @bind="stockSelectedMaterialId" @bind:after="OnStockMaterialChanged"
|
|
||||||
disabled="@(!stockSelectedShape.HasValue)">
|
|
||||||
<option value="0">-- Select --</option>
|
|
||||||
@foreach (var material in materials.Where(m => stockSelectedShape.HasValue && m.Shape == stockSelectedShape.Value).OrderBy(m => m.SortOrder).ThenBy(m => m.Size))
|
|
||||||
{
|
|
||||||
<option value="@material.Id">@material.Size</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Stock Length</label>
|
|
||||||
<select class="form-select" @bind="newStock.StockItemId" disabled="@(stockSelectedMaterialId == 0)">
|
|
||||||
<option value="">-- Select --</option>
|
|
||||||
@foreach (var stock in availableStockItems)
|
|
||||||
{
|
|
||||||
<option value="@stock.Id">@ArchUnits.FormatFromInches((double)stock.LengthInches)</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Qty to Use</label>
|
|
||||||
<input type="number" class="form-control" @bind="newStock.Quantity" min="-1" />
|
|
||||||
<small class="text-muted">-1 = unlimited</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row g-3 mt-1">
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Priority</label>
|
|
||||||
<input type="number" class="form-control" @bind="newStock.Priority" min="1" />
|
|
||||||
<small class="text-muted">Lower = used first</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@if (!string.IsNullOrEmpty(stockErrorMessage))
|
|
||||||
{
|
|
||||||
<div class="alert alert-danger mt-3 mb-0">@stockErrorMessage</div>
|
|
||||||
}
|
|
||||||
<div class="mt-3 d-flex gap-2">
|
|
||||||
<button class="btn btn-primary" @onclick="SaveStockFromInventoryAsync">
|
|
||||||
@(editingStock == null ? "Add Stock" : "Save Changes")
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-outline-secondary" @onclick="CancelStockForm">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
|
|
||||||
private RenderFragment RenderCustomStockForm() => __builder =>
|
|
||||||
{
|
|
||||||
<div class="border rounded p-3 mb-3 bg-light">
|
|
||||||
<h6>@(editingStock == null ? "Add Custom Stock Length" : "Edit Custom Stock")</h6>
|
|
||||||
<div class="row g-3">
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Shape</label>
|
|
||||||
<select class="form-select" @bind="stockSelectedShape" @bind:after="OnStockShapeChanged">
|
|
||||||
<option value="">-- Select --</option>
|
|
||||||
@foreach (var shape in DistinctShapes)
|
|
||||||
{
|
|
||||||
<option value="@shape">@shape.GetDisplayName()</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Size</label>
|
|
||||||
<select class="form-select" @bind="newStock.MaterialId" disabled="@(!stockSelectedShape.HasValue)">
|
|
||||||
<option value="0">-- Select --</option>
|
|
||||||
@foreach (var material in materials.Where(m => stockSelectedShape.HasValue && m.Shape == stockSelectedShape.Value).OrderBy(m => m.SortOrder).ThenBy(m => m.Size))
|
|
||||||
{
|
|
||||||
<option value="@material.Id">@material.Size</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Length</label>
|
|
||||||
<LengthInput @bind-Value="newStock.LengthInches" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Quantity</label>
|
|
||||||
<input type="number" class="form-control" @bind="newStock.Quantity" min="-1" />
|
|
||||||
<small class="text-muted">Use -1 for unlimited</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row g-3 mt-1">
|
|
||||||
<div class="col-md-3">
|
|
||||||
<label class="form-label">Priority</label>
|
|
||||||
<input type="number" class="form-control" @bind="newStock.Priority" min="1" />
|
|
||||||
<small class="text-muted">Lower = used first</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@if (!string.IsNullOrEmpty(stockErrorMessage))
|
|
||||||
{
|
|
||||||
<div class="alert alert-danger mt-3 mb-0">@stockErrorMessage</div>
|
|
||||||
}
|
|
||||||
<div class="mt-3 d-flex gap-2">
|
|
||||||
<button class="btn btn-primary" @onclick="SaveCustomStockAsync">
|
|
||||||
@(editingStock == null ? "Add Stock" : "Save Changes")
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-outline-secondary" @onclick="CancelStockForm">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
|
|
||||||
private RenderFragment RenderStockTable() => __builder =>
|
private RenderFragment RenderStockTable() => __builder =>
|
||||||
{
|
{
|
||||||
@@ -1227,21 +1228,32 @@ else
|
|||||||
await JS.InvokeVoidAsync("printWithTitle", filename);
|
await JS.InvokeVoidAsync("printWithTitle", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowAddCustomStock()
|
private async Task ShowAddStockModal()
|
||||||
{
|
{
|
||||||
editingStock = null;
|
editingStock = null;
|
||||||
newStock = new JobStock { JobId = Id!.Value, Quantity = -1, Priority = 10, IsCustomLength = true };
|
newStock = new JobStock { JobId = Id!.Value, Quantity = -1, Priority = 10 };
|
||||||
stockSelectedShape = null;
|
stockSelectedShape = null;
|
||||||
showStockForm = false;
|
stockSelectedMaterialId = 0;
|
||||||
showCustomStockForm = true;
|
availableStockItems.Clear();
|
||||||
stockErrorMessage = null;
|
stockErrorMessage = null;
|
||||||
|
importErrorMessage = null;
|
||||||
|
importCandidates.Clear();
|
||||||
|
stockModalTab = job.Parts.Count > 0 ? StockModalTab.Inventory : StockModalTab.Custom;
|
||||||
|
showStockModal = true;
|
||||||
|
|
||||||
|
if (job.Parts.Count > 0)
|
||||||
|
{
|
||||||
|
await LoadImportCandidatesAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CancelStockForm()
|
private void CloseStockModal()
|
||||||
{
|
{
|
||||||
showStockForm = false;
|
showStockModal = false;
|
||||||
showCustomStockForm = false;
|
|
||||||
editingStock = null;
|
editingStock = null;
|
||||||
|
importCandidates.Clear();
|
||||||
|
stockErrorMessage = null;
|
||||||
|
importErrorMessage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnStockShapeChanged()
|
private async Task OnStockShapeChanged()
|
||||||
@@ -1284,16 +1296,11 @@ else
|
|||||||
stockSelectedShape = stock.Material?.Shape;
|
stockSelectedShape = stock.Material?.Shape;
|
||||||
stockSelectedMaterialId = stock.MaterialId;
|
stockSelectedMaterialId = stock.MaterialId;
|
||||||
stockErrorMessage = null;
|
stockErrorMessage = null;
|
||||||
|
stockModalTab = stock.IsCustomLength ? StockModalTab.Custom : StockModalTab.Inventory;
|
||||||
|
showStockModal = true;
|
||||||
|
|
||||||
if (stock.IsCustomLength)
|
if (!stock.IsCustomLength)
|
||||||
{
|
{
|
||||||
showStockForm = false;
|
|
||||||
showCustomStockForm = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
showStockForm = true;
|
|
||||||
showCustomStockForm = false;
|
|
||||||
_ = OnStockMaterialChanged();
|
_ = OnStockMaterialChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1347,7 +1354,7 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
job = (await JobService.GetByIdAsync(Id!.Value))!;
|
job = (await JobService.GetByIdAsync(Id!.Value))!;
|
||||||
showStockForm = false;
|
showStockModal = false;
|
||||||
editingStock = null;
|
editingStock = null;
|
||||||
packResult = null;
|
packResult = null;
|
||||||
summary = null;
|
summary = null;
|
||||||
@@ -1394,7 +1401,7 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
job = (await JobService.GetByIdAsync(Id!.Value))!;
|
job = (await JobService.GetByIdAsync(Id!.Value))!;
|
||||||
showCustomStockForm = false;
|
showStockModal = false;
|
||||||
editingStock = null;
|
editingStock = null;
|
||||||
packResult = null;
|
packResult = null;
|
||||||
summary = null;
|
summary = null;
|
||||||
@@ -1408,13 +1415,12 @@ else
|
|||||||
summary = null;
|
summary = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import modal methods
|
// Loads inventory stock candidates for the modal's "From Inventory" tab
|
||||||
private async Task ShowImportModal()
|
private async Task LoadImportCandidatesAsync()
|
||||||
{
|
{
|
||||||
importErrorMessage = null;
|
importErrorMessage = null;
|
||||||
importCandidates.Clear();
|
importCandidates.Clear();
|
||||||
loadingImport = true;
|
loadingImport = true;
|
||||||
showImportModal = true;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1449,13 +1455,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseImportModal()
|
|
||||||
{
|
|
||||||
showImportModal = false;
|
|
||||||
importCandidates.Clear();
|
|
||||||
importErrorMessage = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ToggleAllImportCandidates(bool selected)
|
private void ToggleAllImportCandidates(bool selected)
|
||||||
{
|
{
|
||||||
foreach (var c in importCandidates)
|
foreach (var c in importCandidates)
|
||||||
@@ -1490,7 +1489,7 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
job = (await JobService.GetByIdAsync(Id!.Value))!;
|
job = (await JobService.GetByIdAsync(Id!.Value))!;
|
||||||
showImportModal = false;
|
showStockModal = false;
|
||||||
importCandidates.Clear();
|
importCandidates.Clear();
|
||||||
packResult = null;
|
packResult = null;
|
||||||
summary = null;
|
summary = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user