Dynamic Reportların sütun genişlikleri ve Windows Emoji
This commit is contained in:
parent
9129bc17db
commit
0e1e83fc00
7 changed files with 413 additions and 161 deletions
|
|
@ -307,10 +307,17 @@ public class DynamicFormReport : XtraReport
|
||||||
if (TryGetFormattedValue(field, row, out var text))
|
if (TryGetFormattedValue(field, row, out var text))
|
||||||
{
|
{
|
||||||
label.Text = text;
|
label.Text = text;
|
||||||
|
label.Font = new DXFont(
|
||||||
|
DynamicReportFontHelper.GetFontFamilyForText(text),
|
||||||
|
DynamicReportFontHelper.DataFontSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
label.ExpressionBindings.Add(new ExpressionBinding("BeforePrint", "Text", $"[{field.BindingName}]"));
|
label.ExpressionBindings.Add(new ExpressionBinding("BeforePrint", "Text", $"[{field.BindingName}]"));
|
||||||
|
label.ExpressionBindings.Add(new ExpressionBinding(
|
||||||
|
"BeforePrint",
|
||||||
|
"Font.Name",
|
||||||
|
DynamicReportImageHelper.CreateFontFamilyExpression($"[{field.BindingName}]")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return label;
|
return label;
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,9 @@ public class DynamicGridReport : XtraReport
|
||||||
var visibleFields = DynamicReportGridStateHelper.GetVisibleFields(
|
var visibleFields = DynamicReportGridStateHelper.GetVisibleFields(
|
||||||
availableFields,
|
availableFields,
|
||||||
gridState?.CustomizationData);
|
gridState?.CustomizationData);
|
||||||
|
var stateWidths = DynamicReportGridStateHelper.GetColumnWidths(
|
||||||
|
gridState?.CustomizationData,
|
||||||
|
GetParameter(parameters, "columnWidths"));
|
||||||
|
|
||||||
if (visibleFields.Count == 0)
|
if (visibleFields.Count == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -174,12 +177,12 @@ public class DynamicGridReport : XtraReport
|
||||||
localizer);
|
localizer);
|
||||||
reportColumns = await ApplyImageCountsAsync(reportColumns, dynamicDataRepository, selectQuery, connectionString, imageBaseUrl);
|
reportColumns = await ApplyImageCountsAsync(reportColumns, dynamicDataRepository, selectQuery, connectionString, imageBaseUrl);
|
||||||
|
|
||||||
ConfigurePage(reportColumns, isSubReport);
|
ConfigurePage(reportColumns, localizer, stateWidths, isSubReport);
|
||||||
ConfigureDataSource(
|
ConfigureDataSource(
|
||||||
selectQuery,
|
selectQuery,
|
||||||
connectionString,
|
connectionString,
|
||||||
dataSourceType);
|
dataSourceType);
|
||||||
BuildLayout(listForm, reportColumns, groupColumns, localizer, imageBaseUrl, currentUser.UserName, criteriaText, isSubReport);
|
BuildLayout(listForm, reportColumns, groupColumns, localizer, imageBaseUrl, currentUser.UserName, criteriaText, isSubReport, stateWidths);
|
||||||
RequestParameters = false;
|
RequestParameters = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,12 +210,18 @@ public class DynamicGridReport : XtraReport
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CA1416
|
#pragma warning disable CA1416
|
||||||
private void ConfigurePage(IReadOnlyCollection<ReportColumn> visibleFields, bool isSubReport)
|
private void ConfigurePage(
|
||||||
|
IReadOnlyCollection<ReportColumn> visibleFields,
|
||||||
|
IStringLocalizer<PlatformResource> localizer,
|
||||||
|
IReadOnlyDictionary<string, float> stateWidths,
|
||||||
|
bool isSubReport)
|
||||||
{
|
{
|
||||||
Margins = CreateReportMargins(HorizontalMargin, HorizontalMargin, 35, 35);
|
Margins = CreateReportMargins(HorizontalMargin, HorizontalMargin, 35, 35);
|
||||||
PaperKind = DevExpress.Drawing.Printing.DXPaperKind.A4;
|
PaperKind = DevExpress.Drawing.Printing.DXPaperKind.A4;
|
||||||
var portraitContentWidth = A4PortraitWidth - Margins.Left - Margins.Right;
|
var portraitContentWidth = A4PortraitWidth - Margins.Left - Margins.Right;
|
||||||
var requestedContentWidth = visibleFields.Sum(x => x.IsImage ? GetImageColumnWidth(x) : GetPreferredColumnWidth(x.Field));
|
var requestedContentWidth = visibleFields.Sum(x => x.IsImage
|
||||||
|
? GetImageColumnWidth(x)
|
||||||
|
: DynamicReportGridStateHelper.GetPreferredColumnWidth(x.Field, localizer, stateWidths));
|
||||||
Landscape = !isSubReport &&
|
Landscape = !isSubReport &&
|
||||||
(visibleFields.Count >= LandscapeColumnThreshold || requestedContentWidth > portraitContentWidth);
|
(visibleFields.Count >= LandscapeColumnThreshold || requestedContentWidth > portraitContentWidth);
|
||||||
Font = DynamicReportFontHelper.CreateDataFont();
|
Font = DynamicReportFontHelper.CreateDataFont();
|
||||||
|
|
@ -294,7 +303,8 @@ public class DynamicGridReport : XtraReport
|
||||||
string imageBaseUrl,
|
string imageBaseUrl,
|
||||||
string currentUserName,
|
string currentUserName,
|
||||||
string criteriaText,
|
string criteriaText,
|
||||||
bool isSubReport)
|
bool isSubReport,
|
||||||
|
IReadOnlyDictionary<string, float> stateWidths)
|
||||||
{
|
{
|
||||||
Bands.Clear();
|
Bands.Clear();
|
||||||
|
|
||||||
|
|
@ -352,8 +362,7 @@ public class DynamicGridReport : XtraReport
|
||||||
|
|
||||||
var detailIndent = GetGroupDetailIndent(groupFields.Count, pageWidth);
|
var detailIndent = GetGroupDetailIndent(groupFields.Count, pageWidth);
|
||||||
var tableWidth = pageWidth - detailIndent;
|
var tableWidth = pageWidth - detailIndent;
|
||||||
var detailWidths = CalculateWidths(fields, tableWidth);
|
var detailWidths = DynamicReportGridStateHelper.CalculateWidths(fields, tableWidth, localizer, stateWidths);
|
||||||
var headerWidths = CreateIndentedHeaderWidths(detailWidths, detailIndent);
|
|
||||||
var headerTable = CreateTable(pageWidth, 28);
|
var headerTable = CreateTable(pageWidth, 28);
|
||||||
var headerRow = new XRTableRow { HeightF = 28 };
|
var headerRow = new XRTableRow { HeightF = 28 };
|
||||||
var detailTable = CreateTable(tableWidth, detailHeight, detailIndent);
|
var detailTable = CreateTable(tableWidth, detailHeight, detailIndent);
|
||||||
|
|
@ -362,10 +371,15 @@ public class DynamicGridReport : XtraReport
|
||||||
var footerTable = CreateTable(tableWidth, 24, detailIndent);
|
var footerTable = CreateTable(tableWidth, 24, detailIndent);
|
||||||
var footerRow = new XRTableRow { HeightF = 24 };
|
var footerRow = new XRTableRow { HeightF = 24 };
|
||||||
|
|
||||||
|
if (detailIndent > 0)
|
||||||
|
{
|
||||||
|
headerRow.Cells.Add(CreateIndentHeaderCell(detailIndent));
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < fields.Count; i++)
|
for (var i = 0; i < fields.Count; i++)
|
||||||
{
|
{
|
||||||
var field = fields[i];
|
var field = fields[i];
|
||||||
headerRow.Cells.Add(CreateHeaderCell(field, headerWidths[i], localizer));
|
headerRow.Cells.Add(CreateHeaderCell(field, detailWidths[i], localizer));
|
||||||
detailRow.Cells.Add(CreateDetailCell(field, detailWidths[i], imageBaseUrl, detailHeight));
|
detailRow.Cells.Add(CreateDetailCell(field, detailWidths[i], imageBaseUrl, detailHeight));
|
||||||
footerRow.Cells.Add(CreateFooterCell(field, detailWidths[i]));
|
footerRow.Cells.Add(CreateFooterCell(field, detailWidths[i]));
|
||||||
}
|
}
|
||||||
|
|
@ -457,19 +471,6 @@ public class DynamicGridReport : XtraReport
|
||||||
return Math.Min(groupCount * GroupIndentWidth, pageWidth * 0.25F);
|
return Math.Min(groupCount * GroupIndentWidth, pageWidth * 0.25F);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] CreateIndentedHeaderWidths(float[] detailWidths, float detailIndent)
|
|
||||||
{
|
|
||||||
if (detailWidths.Length == 0 || detailIndent <= 0)
|
|
||||||
{
|
|
||||||
return detailWidths;
|
|
||||||
}
|
|
||||||
|
|
||||||
var headerWidths = detailWidths.ToArray();
|
|
||||||
headerWidths[0] += detailIndent;
|
|
||||||
|
|
||||||
return headerWidths;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static XRTable CreateTable(float width, float height, float left = 0)
|
private static XRTable CreateTable(float width, float height, float left = 0)
|
||||||
{
|
{
|
||||||
return new XRTable
|
return new XRTable
|
||||||
|
|
@ -481,6 +482,17 @@ public class DynamicGridReport : XtraReport
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static XRTableCell CreateIndentHeaderCell(float width)
|
||||||
|
{
|
||||||
|
return new XRTableCell
|
||||||
|
{
|
||||||
|
WidthF = width,
|
||||||
|
Weight = width,
|
||||||
|
BackColor = System.Drawing.Color.FromArgb(238, 242, 247),
|
||||||
|
Padding = new PaddingInfo(0, 0, 0, 0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static XRTableCell CreateHeaderCell(
|
private static XRTableCell CreateHeaderCell(
|
||||||
ReportColumn column,
|
ReportColumn column,
|
||||||
float width,
|
float width,
|
||||||
|
|
@ -532,10 +544,15 @@ public class DynamicGridReport : XtraReport
|
||||||
Multiline = true,
|
Multiline = true,
|
||||||
CanGrow = true
|
CanGrow = true
|
||||||
};
|
};
|
||||||
|
var valueExpression = DynamicReportImageHelper.CreateFormatValueExpression($"[{column.BindingName}]", field, column.EditorType);
|
||||||
cell.ExpressionBindings.Add(new ExpressionBinding(
|
cell.ExpressionBindings.Add(new ExpressionBinding(
|
||||||
"BeforePrint",
|
"BeforePrint",
|
||||||
"Text",
|
"Text",
|
||||||
DynamicReportImageHelper.CreateFormatValueExpression($"[{column.BindingName}]", field, column.EditorType)));
|
valueExpression));
|
||||||
|
cell.ExpressionBindings.Add(new ExpressionBinding(
|
||||||
|
"BeforePrint",
|
||||||
|
"Font.Name",
|
||||||
|
DynamicReportImageHelper.CreateFontFamilyExpression(valueExpression)));
|
||||||
|
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
@ -614,66 +631,6 @@ public class DynamicGridReport : XtraReport
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] CalculateWidths(IReadOnlyList<ReportColumn> fields, float pageWidth)
|
|
||||||
{
|
|
||||||
var raw = fields.Select(x => x.IsImage ? GetImageColumnWidth(x) : GetPreferredColumnWidth(x.Field)).ToArray();
|
|
||||||
var total = raw.Sum();
|
|
||||||
if (total <= 0)
|
|
||||||
{
|
|
||||||
return fields.Select(_ => pageWidth / fields.Count).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return raw.Select(x => pageWidth * x / total).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float GetPreferredColumnWidth(ListFormField field)
|
|
||||||
{
|
|
||||||
if (field.Width > 0)
|
|
||||||
{
|
|
||||||
return Math.Max(field.Width.Value, 60);
|
|
||||||
}
|
|
||||||
|
|
||||||
var caption = string.IsNullOrWhiteSpace(field.CaptionName) ? field.FieldName : field.CaptionName;
|
|
||||||
var name = field.FieldName ?? string.Empty;
|
|
||||||
var text = $"{caption} {name}".ToLowerInvariant();
|
|
||||||
|
|
||||||
if (field.SourceDbType == DbType.Boolean)
|
|
||||||
{
|
|
||||||
return 75;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DynamicReportImageHelper.IsNumeric(field.SourceDbType))
|
|
||||||
{
|
|
||||||
return 70;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field.SourceDbType is DbType.Date or DbType.DateTime or DbType.DateTime2 or DbType.DateTimeOffset)
|
|
||||||
{
|
|
||||||
return 115;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.Contains("description") ||
|
|
||||||
text.Contains("explanation") ||
|
|
||||||
text.Contains("note") ||
|
|
||||||
text.Contains("comment") ||
|
|
||||||
text.Contains("address") ||
|
|
||||||
text.Contains("content") ||
|
|
||||||
text.Contains("html") ||
|
|
||||||
text.Contains("text"))
|
|
||||||
{
|
|
||||||
return 220;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.Contains("name") ||
|
|
||||||
text.Contains("title") ||
|
|
||||||
text.Contains("subject"))
|
|
||||||
{
|
|
||||||
return 160;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.Clamp((caption?.Length ?? 0) * 9F + 36F, 85F, 180F);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool HasAnySummary(IEnumerable<ReportColumn> fields)
|
private static bool HasAnySummary(IEnumerable<ReportColumn> fields)
|
||||||
{
|
{
|
||||||
return fields.Any(x => GetSummaryType(x.Field.TotalSummaryJson) != null);
|
return fields.Any(x => GetSummaryType(x.Field.TotalSummaryJson) != null);
|
||||||
|
|
@ -737,7 +694,10 @@ public class DynamicGridReport : XtraReport
|
||||||
bool IsImage,
|
bool IsImage,
|
||||||
bool IsHtml,
|
bool IsHtml,
|
||||||
string EditorType,
|
string EditorType,
|
||||||
int ImageCount = 1) : DynamicReportSqlBuilder.IReportLookupColumn;
|
int ImageCount = 1) : DynamicReportSqlBuilder.IReportLookupColumn, DynamicReportGridStateHelper.IReportColumnWidth
|
||||||
|
{
|
||||||
|
public float ImageWidth => GetImageColumnWidth(this);
|
||||||
|
}
|
||||||
|
|
||||||
private static SummaryFunc? GetSummaryType(string totalSummaryJson)
|
private static SummaryFunc? GetSummaryType(string totalSummaryJson)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ internal static class DynamicReportFontHelper
|
||||||
public const float DataFontSize = 8.5F;
|
public const float DataFontSize = 8.5F;
|
||||||
|
|
||||||
private const string WindowsFontFamily = "Arial";
|
private const string WindowsFontFamily = "Arial";
|
||||||
|
private const string WindowsEmojiFontFamily = "Segoe UI Emoji";
|
||||||
private const string LinuxFontFamily = "Liberation Sans";
|
private const string LinuxFontFamily = "Liberation Sans";
|
||||||
|
|
||||||
public static DXFont CreateHeaderFont(DXFontStyle style = DXFontStyle.Bold) =>
|
public static DXFont CreateHeaderFont(DXFontStyle style = DXFontStyle.Bold) =>
|
||||||
|
|
@ -19,10 +20,48 @@ internal static class DynamicReportFontHelper
|
||||||
|
|
||||||
public static DXFont CreateValueFont(float size, DXFontStyle style = DXFontStyle.Regular)
|
public static DXFont CreateValueFont(float size, DXFontStyle style = DXFontStyle.Regular)
|
||||||
{
|
{
|
||||||
var fontFamily = OperatingSystem.IsLinux()
|
return new DXFont(GetDefaultFontFamily(), size, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetFontFamilyForText(string text)
|
||||||
|
{
|
||||||
|
return OperatingSystem.IsWindows() && ContainsEmojiOrSymbol(text)
|
||||||
|
? WindowsEmojiFontFamily
|
||||||
|
: GetDefaultFontFamily();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ContainsEmojiOrSymbol(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(text))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < text.Length; i++)
|
||||||
|
{
|
||||||
|
int codePoint;
|
||||||
|
if (char.IsHighSurrogate(text[i]) && i + 1 < text.Length && char.IsLowSurrogate(text[i + 1]))
|
||||||
|
{
|
||||||
|
codePoint = char.ConvertToUtf32(text, i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
codePoint = text[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codePoint is >= 0x1F000 and <= 0x1FAFF ||
|
||||||
|
codePoint is >= 0x2600 and <= 0x27BF)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetDefaultFontFamily() =>
|
||||||
|
OperatingSystem.IsLinux()
|
||||||
? LinuxFontFamily
|
? LinuxFontFamily
|
||||||
: WindowsFontFamily;
|
: WindowsFontFamily;
|
||||||
|
|
||||||
return new DXFont(fontFamily, size, style);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,25 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
using Sozsoft.Platform;
|
using Sozsoft.Platform;
|
||||||
using Sozsoft.Platform.Entities;
|
using Sozsoft.Platform.Entities;
|
||||||
using Sozsoft.Platform.ListForms;
|
using Sozsoft.Platform.ListForms;
|
||||||
|
using Sozsoft.Platform.Localization;
|
||||||
|
|
||||||
namespace Sozsoft.Reports.PredefinedReports;
|
namespace Sozsoft.Reports.PredefinedReports;
|
||||||
|
|
||||||
internal static class DynamicReportGridStateHelper
|
internal static class DynamicReportGridStateHelper
|
||||||
{
|
{
|
||||||
|
public interface IReportColumnWidth
|
||||||
|
{
|
||||||
|
ListFormField Field { get; }
|
||||||
|
bool IsImage { get; }
|
||||||
|
float ImageWidth { get; }
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetFilterName(ListForm listForm, string prefix) =>
|
public static string GetFilterName(ListForm listForm, string prefix) =>
|
||||||
$"{prefix}-{GetStateStorageKey(listForm)}";
|
$"{prefix}-{GetStateStorageKey(listForm)}";
|
||||||
|
|
||||||
|
|
@ -79,6 +89,74 @@ internal static class DynamicReportGridStateHelper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, float> GetColumnWidths(string gridStateJson, string columnWidthsJson = null)
|
||||||
|
{
|
||||||
|
var widths = TryGetColumnStates(gridStateJson, out var statesByField)
|
||||||
|
? statesByField
|
||||||
|
.Where(x => x.Value.Width.HasValue && x.Value.Width.Value > 0)
|
||||||
|
.ToDictionary(x => x.Key, x => x.Value.Width.Value, StringComparer.OrdinalIgnoreCase)
|
||||||
|
: new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
foreach (var item in ParseColumnWidths(columnWidthsJson))
|
||||||
|
{
|
||||||
|
widths[item.Key] = item.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return widths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float[] CalculateWidths<TColumn>(
|
||||||
|
IReadOnlyList<TColumn> columns,
|
||||||
|
float pageWidth,
|
||||||
|
IStringLocalizer<PlatformResource> localizer,
|
||||||
|
IReadOnlyDictionary<string, float> stateWidths = null)
|
||||||
|
where TColumn : IReportColumnWidth
|
||||||
|
{
|
||||||
|
if (columns.Count == 0)
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var ideal = columns
|
||||||
|
.Select(column => column.IsImage
|
||||||
|
? column.ImageWidth
|
||||||
|
: GetPreferredColumnWidth(column.Field, localizer, stateWidths))
|
||||||
|
.ToArray();
|
||||||
|
var total = ideal.Sum();
|
||||||
|
if (total <= 0)
|
||||||
|
{
|
||||||
|
return columns.Select(_ => pageWidth / columns.Count).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ideal.Select(width => pageWidth * width / total).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float GetPreferredColumnWidth(
|
||||||
|
ListFormField field,
|
||||||
|
IStringLocalizer<PlatformResource> localizer = null,
|
||||||
|
IReadOnlyDictionary<string, float> stateWidths = null)
|
||||||
|
{
|
||||||
|
var caption = localizer == null
|
||||||
|
? (string.IsNullOrWhiteSpace(field.CaptionName) ? field.FieldName : field.CaptionName)
|
||||||
|
: DynamicReportImageHelper.GetLocalizedFieldCaption(field, localizer);
|
||||||
|
var name = field.FieldName ?? string.Empty;
|
||||||
|
var calculatedWidth = CalculateTextColumnWidth(field, caption, name);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(field.FieldName) &&
|
||||||
|
stateWidths?.TryGetValue(field.FieldName, out var stateWidth) == true &&
|
||||||
|
stateWidth > 0)
|
||||||
|
{
|
||||||
|
return Math.Max(stateWidth, 40F);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.Width > 0)
|
||||||
|
{
|
||||||
|
return Math.Max(field.Width.Value, 40F);
|
||||||
|
}
|
||||||
|
|
||||||
|
return calculatedWidth;
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetStateStorageKey(ListForm listForm)
|
private static string GetStateStorageKey(ListForm listForm)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(listForm.StateStoringJson))
|
if (!string.IsNullOrWhiteSpace(listForm.StateStoringJson))
|
||||||
|
|
@ -151,10 +229,14 @@ internal static class DynamicReportGridStateHelper
|
||||||
groupIndexProperty.TryGetInt32(out var groupValue)
|
groupIndexProperty.TryGetInt32(out var groupValue)
|
||||||
? groupValue
|
? groupValue
|
||||||
: (int?)null;
|
: (int?)null;
|
||||||
|
var width = TryGetProperty(column, "width", out var widthProperty) &&
|
||||||
|
TryGetFloat(widthProperty, out var widthValue)
|
||||||
|
? widthValue
|
||||||
|
: (float?)null;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(fieldName))
|
if (!string.IsNullOrWhiteSpace(fieldName))
|
||||||
{
|
{
|
||||||
states.Add(new GridColumnState(fieldName, visible, visibleIndex, groupIndex));
|
states.Add(new GridColumnState(fieldName, visible, visibleIndex, groupIndex, width));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TryGetProperty(column, "columns", out var childColumns) &&
|
if (TryGetProperty(column, "columns", out var childColumns) &&
|
||||||
|
|
@ -182,6 +264,114 @@ internal static class DynamicReportGridStateHelper
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool TryGetFloat(JsonElement element, out float value)
|
||||||
|
{
|
||||||
|
if (element.ValueKind == JsonValueKind.Number && element.TryGetSingle(out value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.ValueKind == JsonValueKind.String &&
|
||||||
|
float.TryParse(element.GetString(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float CalculateTextColumnWidth(ListFormField field, string caption, string name)
|
||||||
|
{
|
||||||
|
if (field.SourceDbType == DbType.Boolean)
|
||||||
|
{
|
||||||
|
return Math.Max(75F, MeasureTextWidth(caption, 7.2F, 30F, 68F, 100F));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DynamicReportImageHelper.IsNumeric(field.SourceDbType))
|
||||||
|
{
|
||||||
|
return Math.Max(70F, MeasureTextWidth(caption, 7.2F, 30F, 68F, 120F));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.SourceDbType is DbType.Date or DbType.DateTime or DbType.DateTime2 or DbType.DateTimeOffset)
|
||||||
|
{
|
||||||
|
return Math.Max(115F, MeasureTextWidth(caption, 7.2F, 30F, 90F, 145F));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Max(
|
||||||
|
MeasureTextWidth(caption, 7.2F, 30F, 85F, 220F),
|
||||||
|
MeasureTextWidth(name, 5.6F, 28F, 85F, 180F));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float MeasureTextWidth(
|
||||||
|
string value,
|
||||||
|
float characterWidth,
|
||||||
|
float padding,
|
||||||
|
float minimum,
|
||||||
|
float maximum)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Clamp(value.Trim().Length * characterWidth + padding, minimum, maximum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, float> ParseColumnWidths(string columnWidthsJson)
|
||||||
|
{
|
||||||
|
var widths = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
if (string.IsNullOrWhiteSpace(columnWidthsJson))
|
||||||
|
{
|
||||||
|
return widths;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var document = JsonDocument.Parse(columnWidthsJson);
|
||||||
|
if (document.RootElement.ValueKind == JsonValueKind.Object)
|
||||||
|
{
|
||||||
|
foreach (var property in document.RootElement.EnumerateObject())
|
||||||
|
{
|
||||||
|
if (TryGetFloat(property.Value, out var width) && width > 0)
|
||||||
|
{
|
||||||
|
widths[property.Name] = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (document.RootElement.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
AddColumnWidths(document.RootElement, widths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (JsonException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return widths;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddColumnWidths(JsonElement columns, IDictionary<string, float> widths)
|
||||||
|
{
|
||||||
|
foreach (var column in columns.EnumerateArray())
|
||||||
|
{
|
||||||
|
var fieldName = GetColumnFieldName(column);
|
||||||
|
if (!string.IsNullOrWhiteSpace(fieldName) &&
|
||||||
|
TryGetProperty(column, "width", out var widthProperty) &&
|
||||||
|
TryGetFloat(widthProperty, out var width) &&
|
||||||
|
width > 0)
|
||||||
|
{
|
||||||
|
widths[fieldName] = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryGetProperty(column, "columns", out var childColumns) &&
|
||||||
|
childColumns.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
AddColumnWidths(childColumns, widths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static List<ListFormField> GetGroupFieldsFromParameter(
|
private static List<ListFormField> GetGroupFieldsFromParameter(
|
||||||
IReadOnlyList<ListFormField> availableFields,
|
IReadOnlyList<ListFormField> availableFields,
|
||||||
string groupParameter)
|
string groupParameter)
|
||||||
|
|
@ -249,5 +439,5 @@ internal static class DynamicReportGridStateHelper
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed record GridColumnState(string FieldName, bool Visible, int VisibleIndex, int? GroupIndex);
|
private sealed record GridColumnState(string FieldName, bool Visible, int VisibleIndex, int? GroupIndex, float? Width);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ internal static class DynamicReportImageHelper
|
||||||
private const string ImageUrlFunctionName = "SozReportImageUrl";
|
private const string ImageUrlFunctionName = "SozReportImageUrl";
|
||||||
private const string ImageSourceFunctionName = "SozReportImageSource";
|
private const string ImageSourceFunctionName = "SozReportImageSource";
|
||||||
private const string FormatValueFunctionName = "SozReportFormatValue";
|
private const string FormatValueFunctionName = "SozReportFormatValue";
|
||||||
|
private const string FontFamilyFunctionName = "SozReportFontFamily";
|
||||||
private static readonly Regex ReportPagingRegex = new(
|
private static readonly Regex ReportPagingRegex = new(
|
||||||
@"\s+OFFSET\s+\d+\s+ROWS(?:\s+FETCH\s+NEXT\s+\d+\s+ROWS\s+ONLY)?\s*$",
|
@"\s+OFFSET\s+\d+\s+ROWS(?:\s+FETCH\s+NEXT\s+\d+\s+ROWS\s+ONLY)?\s*$",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||||
|
|
@ -55,6 +56,7 @@ internal static class DynamicReportImageHelper
|
||||||
RegisterImageFunction(new ReportImageUrlFunction());
|
RegisterImageFunction(new ReportImageUrlFunction());
|
||||||
RegisterImageFunction(new ReportImageSourceFunction());
|
RegisterImageFunction(new ReportImageSourceFunction());
|
||||||
RegisterImageFunction(new ReportFormatValueFunction());
|
RegisterImageFunction(new ReportFormatValueFunction());
|
||||||
|
RegisterImageFunction(new ReportFontFamilyFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, SelectField> CreateSelectFieldMap(IEnumerable<SelectField> selectFields)
|
public static Dictionary<string, SelectField> CreateSelectFieldMap(IEnumerable<SelectField> selectFields)
|
||||||
|
|
@ -487,13 +489,13 @@ internal static class DynamicReportImageHelper
|
||||||
{
|
{
|
||||||
WidthF = width,
|
WidthF = width,
|
||||||
Weight = width,
|
Weight = width,
|
||||||
Padding = new PaddingInfo(3, 3, 3, 3),
|
Padding = new PaddingInfo(0, 0, 0, 0),
|
||||||
CanGrow = false
|
CanGrow = false
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var i = 0; i < safeImageCount; i++)
|
for (var i = 0; i < safeImageCount; i++)
|
||||||
{
|
{
|
||||||
var pictureBox = CreatePictureBox(i, width, DefaultGridImageHeight - 6, safeImageCount);
|
var pictureBox = CreatePictureBox(i, width, DefaultGridImageHeight, safeImageCount);
|
||||||
pictureBox.Visible = true;
|
pictureBox.Visible = true;
|
||||||
pictureBox.ExpressionBindings.Add(new ExpressionBinding(
|
pictureBox.ExpressionBindings.Add(new ExpressionBinding(
|
||||||
"BeforePrint",
|
"BeforePrint",
|
||||||
|
|
@ -602,6 +604,11 @@ internal static class DynamicReportImageHelper
|
||||||
return $"{FormatValueFunctionName}({valueExpression}, '{field.SourceDbType}', '{EscapeExpressionString(GetEffectiveFormat(field))}', '{EscapeExpressionString(editorType)}')";
|
return $"{FormatValueFunctionName}({valueExpression}, '{field.SourceDbType}', '{EscapeExpressionString(GetEffectiveFormat(field))}', '{EscapeExpressionString(editorType)}')";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string CreateFontFamilyExpression(string valueExpression)
|
||||||
|
{
|
||||||
|
return $"{FontFamilyFunctionName}({valueExpression})";
|
||||||
|
}
|
||||||
|
|
||||||
public static string FormatReportDate(DateTime value)
|
public static string FormatReportDate(DateTime value)
|
||||||
{
|
{
|
||||||
var culture = CultureInfo.CurrentCulture;
|
var culture = CultureInfo.CurrentCulture;
|
||||||
|
|
@ -2006,4 +2013,34 @@ internal static class DynamicReportImageHelper
|
||||||
: DbType.String;
|
: DbType.String;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed class ReportFontFamilyFunction : ICustomFunctionOperatorBrowsable
|
||||||
|
{
|
||||||
|
public string Name => FontFamilyFunctionName;
|
||||||
|
public int MinOperandCount => 1;
|
||||||
|
public int MaxOperandCount => 1;
|
||||||
|
public FunctionCategory Category => FunctionCategory.Text;
|
||||||
|
public string Description => "Returns a report font family with emoji fallback.";
|
||||||
|
|
||||||
|
public object Evaluate(params object[] operands)
|
||||||
|
{
|
||||||
|
var text = Convert.ToString(operands.ElementAtOrDefault(0), CultureInfo.CurrentCulture);
|
||||||
|
return DynamicReportFontHelper.GetFontFamilyForText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ResultType(params Type[] operands)
|
||||||
|
{
|
||||||
|
return typeof(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsValidOperandCount(int count)
|
||||||
|
{
|
||||||
|
return count == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsValidOperandType(int operandIndex, int operandCount, Type type)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,9 @@ public class DynamicTreeReport : XtraReport
|
||||||
var visibleFields = DynamicReportGridStateHelper.GetVisibleFields(
|
var visibleFields = DynamicReportGridStateHelper.GetVisibleFields(
|
||||||
availableFields,
|
availableFields,
|
||||||
gridState?.CustomizationData);
|
gridState?.CustomizationData);
|
||||||
|
var stateWidths = DynamicReportGridStateHelper.GetColumnWidths(
|
||||||
|
gridState?.CustomizationData,
|
||||||
|
GetParameter(parameters, "columnWidths"));
|
||||||
|
|
||||||
if (visibleFields.Count == 0)
|
if (visibleFields.Count == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -169,19 +172,24 @@ public class DynamicTreeReport : XtraReport
|
||||||
var orderedRows = OrderTreeRows(sourceRows, treeOptions).ToList();
|
var orderedRows = OrderTreeRows(sourceRows, treeOptions).ToList();
|
||||||
reportColumns = ApplyImageCounts(reportColumns, orderedRows, imageBaseUrl);
|
reportColumns = ApplyImageCounts(reportColumns, orderedRows, imageBaseUrl);
|
||||||
|
|
||||||
ConfigurePage(reportColumns);
|
ConfigurePage(reportColumns, localizer, stateWidths);
|
||||||
ConfigureDataSource(orderedRows, reportColumns);
|
ConfigureDataSource(orderedRows, reportColumns);
|
||||||
BuildLayout(listForm, reportColumns, localizer, imageBaseUrl, currentUser.UserName, criteriaText, isSubReport);
|
BuildLayout(listForm, reportColumns, localizer, imageBaseUrl, currentUser.UserName, criteriaText, isSubReport, stateWidths);
|
||||||
RequestParameters = false;
|
RequestParameters = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CA1416
|
#pragma warning disable CA1416
|
||||||
private void ConfigurePage(IReadOnlyCollection<ReportColumn> visibleFields)
|
private void ConfigurePage(
|
||||||
|
IReadOnlyCollection<ReportColumn> visibleFields,
|
||||||
|
IStringLocalizer<PlatformResource> localizer,
|
||||||
|
IReadOnlyDictionary<string, float> stateWidths)
|
||||||
{
|
{
|
||||||
Margins = CreateReportMargins(HorizontalMargin, HorizontalMargin, 35, 35);
|
Margins = CreateReportMargins(HorizontalMargin, HorizontalMargin, 35, 35);
|
||||||
PaperKind = DevExpress.Drawing.Printing.DXPaperKind.A4;
|
PaperKind = DevExpress.Drawing.Printing.DXPaperKind.A4;
|
||||||
var portraitContentWidth = A4PortraitWidth - Margins.Left - Margins.Right;
|
var portraitContentWidth = A4PortraitWidth - Margins.Left - Margins.Right;
|
||||||
var requestedContentWidth = visibleFields.Sum(x => x.IsImage ? GetImageColumnWidth(x) : GetPreferredColumnWidth(x.Field));
|
var requestedContentWidth = visibleFields.Sum(x => x.IsImage
|
||||||
|
? GetImageColumnWidth(x)
|
||||||
|
: DynamicReportGridStateHelper.GetPreferredColumnWidth(x.Field, localizer, stateWidths));
|
||||||
Landscape = visibleFields.Count >= LandscapeColumnThreshold || requestedContentWidth > portraitContentWidth;
|
Landscape = visibleFields.Count >= LandscapeColumnThreshold || requestedContentWidth > portraitContentWidth;
|
||||||
Font = DynamicReportFontHelper.CreateDataFont();
|
Font = DynamicReportFontHelper.CreateDataFont();
|
||||||
}
|
}
|
||||||
|
|
@ -423,7 +431,8 @@ public class DynamicTreeReport : XtraReport
|
||||||
string imageBaseUrl,
|
string imageBaseUrl,
|
||||||
string currentUserName,
|
string currentUserName,
|
||||||
string criteriaText,
|
string criteriaText,
|
||||||
bool isSubReport)
|
bool isSubReport,
|
||||||
|
IReadOnlyDictionary<string, float> stateWidths)
|
||||||
{
|
{
|
||||||
Bands.Clear();
|
Bands.Clear();
|
||||||
|
|
||||||
|
|
@ -466,7 +475,7 @@ public class DynamicTreeReport : XtraReport
|
||||||
TextAlignment = TextAlignment.MiddleRight
|
TextAlignment = TextAlignment.MiddleRight
|
||||||
});
|
});
|
||||||
|
|
||||||
var widths = CalculateWidths(fields, pageWidth);
|
var widths = DynamicReportGridStateHelper.CalculateWidths(fields, pageWidth, localizer, stateWidths);
|
||||||
var headerTable = CreateTable(pageWidth, 28);
|
var headerTable = CreateTable(pageWidth, 28);
|
||||||
var headerRow = new XRTableRow { HeightF = 28 };
|
var headerRow = new XRTableRow { HeightF = 28 };
|
||||||
var detailTable = CreateTable(pageWidth, detailHeight);
|
var detailTable = CreateTable(pageWidth, detailHeight);
|
||||||
|
|
@ -560,12 +569,17 @@ public class DynamicTreeReport : XtraReport
|
||||||
};
|
};
|
||||||
|
|
||||||
var valueExpression = DynamicReportImageHelper.CreateFormatValueExpression($"[{column.BindingName}]", column.Field, column.EditorType);
|
var valueExpression = DynamicReportImageHelper.CreateFormatValueExpression($"[{column.BindingName}]", column.Field, column.EditorType);
|
||||||
|
var textExpression = isTreeColumn
|
||||||
|
? $"Concat([{TreePrefixColumn}], {valueExpression})"
|
||||||
|
: valueExpression;
|
||||||
cell.ExpressionBindings.Add(new ExpressionBinding(
|
cell.ExpressionBindings.Add(new ExpressionBinding(
|
||||||
"BeforePrint",
|
"BeforePrint",
|
||||||
"Text",
|
"Text",
|
||||||
isTreeColumn
|
textExpression));
|
||||||
? $"Concat([{TreePrefixColumn}], {valueExpression})"
|
cell.ExpressionBindings.Add(new ExpressionBinding(
|
||||||
: valueExpression));
|
"BeforePrint",
|
||||||
|
"Font.Name",
|
||||||
|
DynamicReportImageHelper.CreateFontFamilyExpression(textExpression)));
|
||||||
|
|
||||||
if (isTreeColumn)
|
if (isTreeColumn)
|
||||||
{
|
{
|
||||||
|
|
@ -635,66 +649,6 @@ public class DynamicTreeReport : XtraReport
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] CalculateWidths(IReadOnlyList<ReportColumn> fields, float pageWidth)
|
|
||||||
{
|
|
||||||
var raw = fields.Select(x => x.IsImage ? GetImageColumnWidth(x) : GetPreferredColumnWidth(x.Field)).ToArray();
|
|
||||||
var total = raw.Sum();
|
|
||||||
if (total <= 0)
|
|
||||||
{
|
|
||||||
return fields.Select(_ => pageWidth / fields.Count).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return raw.Select(x => pageWidth * x / total).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float GetPreferredColumnWidth(ListFormField field)
|
|
||||||
{
|
|
||||||
if (field.Width > 0)
|
|
||||||
{
|
|
||||||
return Math.Max(field.Width.Value, 60);
|
|
||||||
}
|
|
||||||
|
|
||||||
var caption = string.IsNullOrWhiteSpace(field.CaptionName) ? field.FieldName : field.CaptionName;
|
|
||||||
var name = field.FieldName ?? string.Empty;
|
|
||||||
var text = $"{caption} {name}".ToLowerInvariant();
|
|
||||||
|
|
||||||
if (field.SourceDbType == DbType.Boolean)
|
|
||||||
{
|
|
||||||
return 75;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DynamicReportImageHelper.IsNumeric(field.SourceDbType))
|
|
||||||
{
|
|
||||||
return 70;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field.SourceDbType is DbType.Date or DbType.DateTime or DbType.DateTime2 or DbType.DateTimeOffset)
|
|
||||||
{
|
|
||||||
return 115;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.Contains("description") ||
|
|
||||||
text.Contains("explanation") ||
|
|
||||||
text.Contains("note") ||
|
|
||||||
text.Contains("comment") ||
|
|
||||||
text.Contains("address") ||
|
|
||||||
text.Contains("content") ||
|
|
||||||
text.Contains("html") ||
|
|
||||||
text.Contains("text"))
|
|
||||||
{
|
|
||||||
return 220;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.Contains("name") ||
|
|
||||||
text.Contains("title") ||
|
|
||||||
text.Contains("subject"))
|
|
||||||
{
|
|
||||||
return 160;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.Clamp((caption?.Length ?? 0) * 9F + 36F, 85F, 180F);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool HasAnySummary(IEnumerable<ReportColumn> fields)
|
private static bool HasAnySummary(IEnumerable<ReportColumn> fields)
|
||||||
{
|
{
|
||||||
return fields.Any(x => GetSummaryType(x.Field.TotalSummaryJson) != null);
|
return fields.Any(x => GetSummaryType(x.Field.TotalSummaryJson) != null);
|
||||||
|
|
@ -778,7 +732,10 @@ public class DynamicTreeReport : XtraReport
|
||||||
bool IsImage,
|
bool IsImage,
|
||||||
bool IsHtml,
|
bool IsHtml,
|
||||||
string EditorType,
|
string EditorType,
|
||||||
int ImageCount = 1) : DynamicReportSqlBuilder.IReportLookupColumn;
|
int ImageCount = 1) : DynamicReportSqlBuilder.IReportLookupColumn, DynamicReportGridStateHelper.IReportColumnWidth
|
||||||
|
{
|
||||||
|
public float ImageWidth => GetImageColumnWidth(this);
|
||||||
|
}
|
||||||
|
|
||||||
private static SummaryFunc? GetSummaryType(string totalSummaryJson)
|
private static SummaryFunc? GetSummaryType(string totalSummaryJson)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,63 @@ const getReportSort = (grid: GridInstance) => {
|
||||||
.join(MULTIVALUE_DELIMITER)
|
.join(MULTIVALUE_DELIMITER)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getReportColumnWidths = (grid: GridInstance) => {
|
||||||
|
const getVisibleColumns = (grid as any).getVisibleColumns
|
||||||
|
if (typeof getVisibleColumns !== 'function') {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const stateColumnWidths: Record<string, number> = {}
|
||||||
|
const addStateColumnWidths = (columns: any[] | undefined) => {
|
||||||
|
columns?.forEach((column) => {
|
||||||
|
const fieldName = column?.dataField || column?.name
|
||||||
|
const width = Number(column?.width)
|
||||||
|
if (fieldName && Number.isFinite(width) && width > 0) {
|
||||||
|
stateColumnWidths[fieldName] = width
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(column?.columns)) {
|
||||||
|
addStateColumnWidths(column.columns)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsState(grid)) {
|
||||||
|
const state = grid.state()
|
||||||
|
if (Array.isArray(state?.columns)) {
|
||||||
|
addStateColumnWidths(state.columns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const visibleColumns = getVisibleColumns.call(grid) as any[]
|
||||||
|
const widths = visibleColumns.reduce((result: Record<string, number>, column: any) => {
|
||||||
|
const fieldName = column?.dataField || column?.name
|
||||||
|
if (!fieldName || column?.type === 'buttons') {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
const stateWidth = stateColumnWidths[fieldName]
|
||||||
|
const columnWidth = Number(column?.width)
|
||||||
|
const visibleWidth = Number(column?.visibleWidth)
|
||||||
|
const width =
|
||||||
|
Number.isFinite(stateWidth) && stateWidth > 0
|
||||||
|
? stateWidth
|
||||||
|
: Number.isFinite(columnWidth) && columnWidth > 0
|
||||||
|
? columnWidth
|
||||||
|
: Number.isFinite(visibleWidth) && visibleWidth > 0
|
||||||
|
? visibleWidth
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
if (width) {
|
||||||
|
result[fieldName] = Math.round(width)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}, {})
|
||||||
|
|
||||||
|
return Object.keys(widths).length ? widths : undefined
|
||||||
|
}
|
||||||
|
|
||||||
const createDynamicListReportUrl = (
|
const createDynamicListReportUrl = (
|
||||||
grid: GridInstance | undefined,
|
grid: GridInstance | undefined,
|
||||||
listFormCode: string,
|
listFormCode: string,
|
||||||
|
|
@ -222,6 +279,7 @@ const createDynamicListReportUrl = (
|
||||||
const searchParams = new URLSearchParams()
|
const searchParams = new URLSearchParams()
|
||||||
const filter = getReportFilter(grid)
|
const filter = getReportFilter(grid)
|
||||||
const sort = getReportSort(grid)
|
const sort = getReportSort(grid)
|
||||||
|
const columnWidths = getReportColumnWidths(grid)
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
searchParams.set('filter', JSON.stringify(filter))
|
searchParams.set('filter', JSON.stringify(filter))
|
||||||
|
|
@ -231,6 +289,10 @@ const createDynamicListReportUrl = (
|
||||||
searchParams.set('sort', sort)
|
searchParams.set('sort', sort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (columnWidths) {
|
||||||
|
searchParams.set('columnWidths', JSON.stringify(columnWidths))
|
||||||
|
}
|
||||||
|
|
||||||
const queryString = createReportQueryString(searchParams)
|
const queryString = createReportQueryString(searchParams)
|
||||||
return queryString ? `${reportUrl}?${queryString}` : reportUrl
|
return queryString ? `${reportUrl}?${queryString}` : reportUrl
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue