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:
2026-05-23 09:32:57 -04:00
parent 64a9c1531b
commit 05935b110a
3 changed files with 40 additions and 4 deletions
@@ -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 &mdash; @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()">
&#128438; Print Label &#128438; Print Label
@@ -122,6 +129,7 @@
&#8592; Back to Item &#8592; 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>