Open QR Label in modal instead of a new browser tab
Adds an embed mode to the Label view (hides standalone nav controls) and an iframe-based modal on Inventory Details. The modal footer Print button calls contentWindow.print() so the print dialog opens without spawning a new window. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1623,11 +1623,12 @@ public class InventoryController : Controller
|
|||||||
/// Renders a print-optimised label for the inventory item containing the QR code,
|
/// Renders a print-optimised label for the inventory item containing the QR code,
|
||||||
/// item name, SKU, and colour. Designed to be printed directly from the browser.
|
/// item name, SKU, and colour. Designed to be printed directly from the browser.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<IActionResult> Label(int? id)
|
public async Task<IActionResult> Label(int? id, bool embed = false)
|
||||||
{
|
{
|
||||||
if (id == null) return NotFound();
|
if (id == null) return NotFound();
|
||||||
var item = await _unitOfWork.InventoryItems.GetByIdAsync(id.Value);
|
var item = await _unitOfWork.InventoryItems.GetByIdAsync(id.Value);
|
||||||
if (item == null) return NotFound();
|
if (item == null) return NotFound();
|
||||||
|
ViewBag.IsEmbed = embed;
|
||||||
return View(_mapper.Map<InventoryItemDto>(item));
|
return View(_mapper.Map<InventoryItemDto>(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -457,9 +457,9 @@
|
|||||||
<button type="button" class="btn btn-outline-success" data-bs-toggle="modal" data-bs-target="#stockAdjustmentModal">
|
<button type="button" class="btn btn-outline-success" data-bs-toggle="modal" data-bs-target="#stockAdjustmentModal">
|
||||||
<i class="bi bi-plus-slash-minus me-2"></i>Stock Adjustment
|
<i class="bi bi-plus-slash-minus me-2"></i>Stock Adjustment
|
||||||
</button>
|
</button>
|
||||||
<a asp-action="Label" asp-route-id="@Model.Id" target="_blank" class="btn btn-outline-secondary">
|
<button type="button" class="btn btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#qrLabelModal">
|
||||||
<i class="bi bi-qr-code me-2"></i>Print QR Label
|
<i class="bi bi-qr-code me-2"></i>Print QR Label
|
||||||
</a>
|
</button>
|
||||||
<a asp-action="Ledger" asp-route-inventoryItemId="@Model.Id" class="btn btn-outline-secondary">
|
<a asp-action="Ledger" asp-route-inventoryItemId="@Model.Id" class="btn btn-outline-secondary">
|
||||||
<i class="bi bi-journal-text me-2"></i>View Activity History
|
<i class="bi bi-journal-text me-2"></i>View Activity History
|
||||||
</a>
|
</a>
|
||||||
@@ -644,6 +644,33 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@* QR Label Modal *@
|
||||||
|
<div class="modal fade" id="qrLabelModal" tabindex="-1" aria-labelledby="qrLabelModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header py-2">
|
||||||
|
<h6 class="modal-title" id="qrLabelModalLabel">
|
||||||
|
<i class="bi bi-qr-code me-2"></i>QR Label — @Model.Name
|
||||||
|
</h6>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body p-0 d-flex justify-content-center" style="background:#f0f0f0;min-height:360px;">
|
||||||
|
<iframe id="qrLabelFrame"
|
||||||
|
src="@Url.Action("Label", new { id = Model.Id, embed = true })"
|
||||||
|
style="width:100%;height:400px;border:none;"
|
||||||
|
title="QR Label Preview"></iframe>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer py-2">
|
||||||
|
<button type="button" class="btn btn-primary btn-sm"
|
||||||
|
onclick="document.getElementById('qrLabelFrame').contentWindow.print()">
|
||||||
|
<i class="bi bi-printer me-2"></i>Print Label
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary btn-sm" data-bs-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
<script>
|
<script>
|
||||||
/* ── Stock Adjustment Modal ───────────────────────────────── */
|
/* ── Stock Adjustment Modal ───────────────────────────────── */
|
||||||
|
|||||||
@@ -22,6 +22,11 @@
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.embedded {
|
||||||
|
padding-top: 24px;
|
||||||
|
min-height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.screen-controls {
|
.screen-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
@@ -112,8 +117,10 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="@((bool)(ViewBag.IsEmbed ?? false) ? "embedded" : "")">
|
||||||
|
|
||||||
|
@if (!(bool)(ViewBag.IsEmbed ?? false))
|
||||||
|
{
|
||||||
<div class="screen-controls">
|
<div class="screen-controls">
|
||||||
<button class="btn btn-primary" onclick="window.print()">
|
<button class="btn btn-primary" onclick="window.print()">
|
||||||
🖶 Print Label
|
🖶 Print Label
|
||||||
@@ -122,6 +129,7 @@
|
|||||||
← Back to Item
|
← Back to Item
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<div class="label-card">
|
<div class="label-card">
|
||||||
<div class="label-logo">Powder Coating Logix</div>
|
<div class="label-logo">Powder Coating Logix</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user