Refactor MgGridInfoPanel for theme, UX, and PDF perf
- Refactored MgGridInfoPanel for DevExpress theme compatibility and improved usability; streamlined HTML/CSS, added OnDataItemChanged event, and enhanced empty state handling. - Updated CSS to use theme variables, improved responsive grid and table styling, and enhanced integration with DevExpress components. - GridShippingDocumentInfoPanel now uses OnDataItemChanged to load a random PDF per row selection; table layout and totals improved. - Optimized pdfViewer.js to cache rendered PDFs, skip redundant renders, and improve logging and error handling. - Added empty helper classes for future extensibility. - Minor: MainLayout now uses RefreshMainLayout for UI refresh after auto-login.
This commit is contained in:
parent
ed99db3238
commit
3c5b737207
|
|
@ -4,7 +4,7 @@
|
|||
@using System.IO
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<MgGridInfoPanel>
|
||||
<MgGridInfoPanel OnDataItemChanged="OnDataItemChangedAsync">
|
||||
@* <HeaderTemplate Context="dataItem">
|
||||
<div class="dxbl-grid-header-panel px-3 py-2 border-bottom d-flex align-items-center">
|
||||
<span class="me-2">??</span>
|
||||
|
|
@ -24,33 +24,43 @@
|
|||
<AfterColumnsTemplate Context="dataItem">
|
||||
@if (dataItem is ShippingDocument doc)
|
||||
{
|
||||
<table class="table table-bordered table-striped">
|
||||
<table class="table table-bordered table-striped" style="margin-top: 35px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="white-space: nowrap;">Termék neve</th>
|
||||
<th style="white-space: nowrap;">Név a dokumentumon</th>
|
||||
<th style="white-space: nowrap;">Raklapok</th>
|
||||
<th style="white-space: nowrap;">Mennyiség</th>
|
||||
<th style="white-space: nowrap;">Net.súly</th>
|
||||
<th style="white-space: nowrap;">Brt.súly</th>
|
||||
<th>Név a dokumentumon</th>
|
||||
<th style ="padding-left: 10px;">Termék neve</th>
|
||||
<th style="text-align: right; padding-left: 10px;">Rakl.</th>
|
||||
<th style="text-align: right; padding-left: 10px;">Menny.</th>
|
||||
<th style="text-align: right; padding-left: 10px;">Net.súly</th>
|
||||
<th style="text-align: right; padding-left: 10px;">Br.súly</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var shippingItem in doc.ShippingItems)
|
||||
{
|
||||
<tr>
|
||||
<td style="white-space: nowrap;">@shippingItem.ProductName</td>
|
||||
<td style="white-space: nowrap;">@shippingItem.NameOnDocument</td>
|
||||
<td style="white-space: nowrap;">@shippingItem.QuantityOnDocument</td>
|
||||
<td style="white-space: nowrap;">@shippingItem.NetWeightOnDocument</td>
|
||||
<td style="white-space: nowrap;">@shippingItem.GrossWeightOnDocument</td>
|
||||
<td style="white-space: nowrap;">@shippingItem.PalletsOnDocument</td>
|
||||
<td>@shippingItem.NameOnDocument</td>
|
||||
<td style="padding-left: 10px;">@shippingItem.ProductName</td>
|
||||
<td style="text-align: right; padding-left: 10px;">@shippingItem.PalletsOnDocument</td>
|
||||
<td style="text-align: right; padding-left: 10px;">@shippingItem.QuantityOnDocument</td>
|
||||
<td style="text-align: right; padding-left: 10px;">@shippingItem.NetWeightOnDocument</td>
|
||||
<td style="text-align: right; padding-left: 10px;">@shippingItem.GrossWeightOnDocument</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr style="font-weight: bold;">
|
||||
<td>TOTAL:</td>
|
||||
<td style="padding-left: 10px;"></td>
|
||||
<td style="text-align: right; padding-left: 10px;">@doc.ShippingItems.Sum(x => x.PalletsOnDocument)</td>
|
||||
<td style="text-align: right; padding-left: 10px;">@doc.ShippingItems.Sum(x => x.QuantityOnDocument)</td>
|
||||
<td style="text-align: right; padding-left: 10px;">@double.Round(doc.ShippingItems.Sum(x => x.NetWeightOnDocument), 1)</td>
|
||||
<td style="text-align: right; padding-left: 10px;">@double.Round(doc.ShippingItems.Sum(x => x.GrossWeightOnDocument), 1)</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div id="pdfContainer" style="width: 100%; height: 800px; overflow-y: auto;">
|
||||
<div id="pdfContainer" style="width: 100%; height: 800px; overflow-y: auto; margin-top: 30px;">
|
||||
</div>
|
||||
}
|
||||
</AfterColumnsTemplate>
|
||||
|
|
@ -65,19 +75,18 @@
|
|||
|
||||
@code
|
||||
{
|
||||
private readonly string[] _pdfFiles = new[]
|
||||
{
|
||||
private readonly string[] _pdfFiles =
|
||||
[
|
||||
"1_Albaran_AH25007715.pdf",
|
||||
"2_BANK FRA.pdf",
|
||||
"3_BP-30M35_20251113_163816.pdf"
|
||||
};
|
||||
];
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
private async Task OnDataItemChangedAsync(object? dataItem)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var pdfUrls = _pdfFiles.Select(f => $"_content/FruitBankHybrid.Shared/uploads/{f}").ToArray();
|
||||
await JS.InvokeVoidAsync("pdfViewer.renderPdfs", "pdfContainer", pdfUrls);
|
||||
}
|
||||
// Véletlenszerű PDF kiválasztása minden sor váltáskor
|
||||
var randomPdf = _pdfFiles[Random.Shared.Next(_pdfFiles.Length)];
|
||||
var pdfUrls = new[] { $"_content/FruitBankHybrid.Shared/uploads/{randomPdf}" };
|
||||
await JS.InvokeVoidAsync("pdfViewer.renderPdfs", "pdfContainer", pdfUrls);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ public partial class MainLayout : LayoutComponentBase
|
|||
}
|
||||
else if (LoggedInModel.IsLoggedIn)
|
||||
{
|
||||
StateHasChanged(); // Refresh UI after successful auto-login
|
||||
RefreshMainLayout();
|
||||
//StateHasChanged(); // Refresh UI after successful auto-login
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ window.pdfViewer = {
|
|||
_currentContainerId: null,
|
||||
_currentPdfUrls: null,
|
||||
_renderTimeout: null,
|
||||
_lastRenderedUrls: null, // Track what was last rendered
|
||||
|
||||
renderPdfs: async function (containerId, pdfUrls) {
|
||||
// Wait for container to be available
|
||||
|
|
@ -19,14 +20,24 @@ window.pdfViewer = {
|
|||
return;
|
||||
}
|
||||
|
||||
// Check if URLs changed - if same, skip render (use cache)
|
||||
const urlsKey = JSON.stringify(pdfUrls);
|
||||
if (this._lastRenderedUrls === urlsKey && this._currentContainerId === containerId) {
|
||||
console.log('[PDF] Same URLs, skipping render (cached)');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[PDF] New URLs detected, rendering:', pdfUrls);
|
||||
|
||||
// Store for resize handling
|
||||
this._currentContainerId = containerId;
|
||||
this._currentPdfUrls = pdfUrls;
|
||||
this._lastRenderedUrls = urlsKey;
|
||||
|
||||
// Setup resize observer
|
||||
this._setupResizeObserver(container);
|
||||
|
||||
// Initial render
|
||||
// Render
|
||||
await this._doRender(container, pdfUrls);
|
||||
},
|
||||
|
||||
|
|
@ -74,17 +85,19 @@ window.pdfViewer = {
|
|||
return;
|
||||
}
|
||||
|
||||
console.log('Rendering PDFs at width:', containerWidth);
|
||||
console.log('[PDF] Rendering at width:', containerWidth, 'URLs:', pdfUrls);
|
||||
|
||||
for (const url of pdfUrls) {
|
||||
try {
|
||||
// Use cached PDF if available
|
||||
// Use cached PDF document if available (PDF.js document cache)
|
||||
let pdf = this._pdfCache.get(url);
|
||||
if (!pdf) {
|
||||
console.log('Loading PDF:', url);
|
||||
console.log('[PDF] Loading new PDF:', url);
|
||||
const loadingTask = pdfjsLib.getDocument(url);
|
||||
pdf = await loadingTask.promise;
|
||||
this._pdfCache.set(url, pdf);
|
||||
} else {
|
||||
console.log('[PDF] Using cached PDF:', url);
|
||||
}
|
||||
|
||||
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
||||
|
|
@ -111,7 +124,7 @@ window.pdfViewer = {
|
|||
}).promise;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error rendering PDF:', url, error);
|
||||
console.error('[PDF] Error rendering:', url, error);
|
||||
const errorDiv = document.createElement('div');
|
||||
errorDiv.textContent = 'Hiba a PDF betöltésekor: ' + url + ' - ' + error.message;
|
||||
errorDiv.style.color = 'red';
|
||||
|
|
@ -129,6 +142,13 @@ window.pdfViewer = {
|
|||
if (this._renderTimeout) {
|
||||
clearTimeout(this._renderTimeout);
|
||||
}
|
||||
// Keep PDF cache for performance, only clear on full dispose
|
||||
this._pdfCache.clear();
|
||||
this._lastRenderedUrls = null;
|
||||
},
|
||||
|
||||
// Clear only the render cache (not PDF documents)
|
||||
clearRenderCache: function() {
|
||||
this._lastRenderedUrls = null;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue