PredifinedReports için tasarım ve düzenleme
This commit is contained in:
parent
d8763d6dee
commit
566a0ae0e5
11 changed files with 450 additions and 96 deletions
|
|
@ -20,6 +20,7 @@ using Sozsoft.Platform.Enums;
|
||||||
using Sozsoft.Platform.ListForms;
|
using Sozsoft.Platform.ListForms;
|
||||||
using Sozsoft.Platform.Localization;
|
using Sozsoft.Platform.Localization;
|
||||||
using Sozsoft.Platform.Queries;
|
using Sozsoft.Platform.Queries;
|
||||||
|
using Volo.Abp.Users;
|
||||||
|
|
||||||
namespace Sozsoft.Reports.PredefinedReports;
|
namespace Sozsoft.Reports.PredefinedReports;
|
||||||
|
|
||||||
|
|
@ -76,6 +77,7 @@ public class DynamicFormReport : XtraReport
|
||||||
var defaultValueHelper = scope.ServiceProvider.GetRequiredService<DefaultValueHelper>();
|
var defaultValueHelper = scope.ServiceProvider.GetRequiredService<DefaultValueHelper>();
|
||||||
var localizer = scope.ServiceProvider.GetRequiredService<IStringLocalizer<PlatformResource>>();
|
var localizer = scope.ServiceProvider.GetRequiredService<IStringLocalizer<PlatformResource>>();
|
||||||
var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
||||||
|
var currentUser = scope.ServiceProvider.GetRequiredService<ICurrentUser>();
|
||||||
|
|
||||||
if (!await authManager.CanAccess(listFormCode))
|
if (!await authManager.CanAccess(listFormCode))
|
||||||
{
|
{
|
||||||
|
|
@ -117,7 +119,7 @@ public class DynamicFormReport : XtraReport
|
||||||
|
|
||||||
ConfigurePage();
|
ConfigurePage();
|
||||||
ConfigureDataSource(selectQuery, connectionString, dataSourceType);
|
ConfigureDataSource(selectQuery, connectionString, dataSourceType);
|
||||||
await BuildLayoutAsync(listForm, reportFields, row, localizer, DynamicReportImageHelper.GetImageBaseUrl(configuration));
|
await BuildLayoutAsync(listForm, reportFields, row, localizer, DynamicReportImageHelper.GetImageBaseUrl(configuration), currentUser.UserName);
|
||||||
RequestParameters = false;
|
RequestParameters = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +157,8 @@ public class DynamicFormReport : XtraReport
|
||||||
IReadOnlyList<FormReportField> fields,
|
IReadOnlyList<FormReportField> fields,
|
||||||
IDictionary<string, object> row,
|
IDictionary<string, object> row,
|
||||||
IStringLocalizer<PlatformResource> localizer,
|
IStringLocalizer<PlatformResource> localizer,
|
||||||
string imageBaseUrl)
|
string imageBaseUrl,
|
||||||
|
string currentUserName)
|
||||||
{
|
{
|
||||||
Bands.Clear();
|
Bands.Clear();
|
||||||
var formGroups = GetFormGroups(listForm, fields).ToList();
|
var formGroups = GetFormGroups(listForm, fields).ToList();
|
||||||
|
|
@ -176,19 +179,15 @@ public class DynamicFormReport : XtraReport
|
||||||
Font = new DXFont("Arial", 14F, DXFontStyle.Bold),
|
Font = new DXFont("Arial", 14F, DXFontStyle.Bold),
|
||||||
TextAlignment = TextAlignment.MiddleLeft
|
TextAlignment = TextAlignment.MiddleLeft
|
||||||
});
|
});
|
||||||
|
DynamicReportImageHelper.AddGeneratedAtToHeader(reportHeader.Controls, pageWidth);
|
||||||
|
|
||||||
|
DynamicReportImageHelper.AddFooterTopLine(bottomMargin.Controls, pageWidth);
|
||||||
|
DynamicReportImageHelper.AddCurrentUserNameToFooter(bottomMargin.Controls, currentUserName, pageWidth);
|
||||||
|
|
||||||
bottomMargin.Controls.Add(new XRPageInfo
|
|
||||||
{
|
|
||||||
PageInfo = PageInfo.DateTime,
|
|
||||||
TextFormatString = "{0:dd.MM.yyyy HH:mm}",
|
|
||||||
BoundsF = new System.Drawing.RectangleF(0, 0, pageWidth / 2, 18),
|
|
||||||
Font = new DXFont("Arial", 7.5F),
|
|
||||||
TextAlignment = TextAlignment.MiddleLeft
|
|
||||||
});
|
|
||||||
bottomMargin.Controls.Add(new XRPageInfo
|
bottomMargin.Controls.Add(new XRPageInfo
|
||||||
{
|
{
|
||||||
TextFormatString = "Sayfa {0} / {1}",
|
TextFormatString = "Sayfa {0} / {1}",
|
||||||
BoundsF = new System.Drawing.RectangleF(pageWidth / 2, 0, pageWidth / 2, 18),
|
BoundsF = new System.Drawing.RectangleF(pageWidth / 2, 8, pageWidth / 2, 18),
|
||||||
Font = new DXFont("Arial", 8F),
|
Font = new DXFont("Arial", 8F),
|
||||||
TextAlignment = TextAlignment.MiddleRight
|
TextAlignment = TextAlignment.MiddleRight
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ using Sozsoft.Platform.Enums;
|
||||||
using Sozsoft.Platform.ListForms;
|
using Sozsoft.Platform.ListForms;
|
||||||
using Sozsoft.Platform.Localization;
|
using Sozsoft.Platform.Localization;
|
||||||
using Sozsoft.Platform.Queries;
|
using Sozsoft.Platform.Queries;
|
||||||
|
using Volo.Abp.Users;
|
||||||
|
|
||||||
namespace Sozsoft.Reports.PredefinedReports;
|
namespace Sozsoft.Reports.PredefinedReports;
|
||||||
|
|
||||||
|
|
@ -69,6 +70,7 @@ public class DynamicGridReport : XtraReport
|
||||||
var defaultValueHelper = scope.ServiceProvider.GetRequiredService<DefaultValueHelper>();
|
var defaultValueHelper = scope.ServiceProvider.GetRequiredService<DefaultValueHelper>();
|
||||||
var localizer = scope.ServiceProvider.GetRequiredService<IStringLocalizer<PlatformResource>>();
|
var localizer = scope.ServiceProvider.GetRequiredService<IStringLocalizer<PlatformResource>>();
|
||||||
var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
||||||
|
var currentUser = scope.ServiceProvider.GetRequiredService<ICurrentUser>();
|
||||||
|
|
||||||
if (!await authManager.CanAccess(listFormCode))
|
if (!await authManager.CanAccess(listFormCode))
|
||||||
{
|
{
|
||||||
|
|
@ -142,6 +144,11 @@ public class DynamicGridReport : XtraReport
|
||||||
defaultValueHelper,
|
defaultValueHelper,
|
||||||
dataSourceType);
|
dataSourceType);
|
||||||
var imageBaseUrl = DynamicReportImageHelper.GetImageBaseUrl(configuration);
|
var imageBaseUrl = DynamicReportImageHelper.GetImageBaseUrl(configuration);
|
||||||
|
var criteriaText = DynamicReportImageHelper.BuildReportCriteriaText(
|
||||||
|
queryParams.Filter,
|
||||||
|
queryParams.Sort,
|
||||||
|
fields,
|
||||||
|
localizer);
|
||||||
reportColumns = await ApplyImageCountsAsync(reportColumns, dynamicDataRepository, selectQuery, connectionString, imageBaseUrl);
|
reportColumns = await ApplyImageCountsAsync(reportColumns, dynamicDataRepository, selectQuery, connectionString, imageBaseUrl);
|
||||||
|
|
||||||
ConfigurePage(reportColumns);
|
ConfigurePage(reportColumns);
|
||||||
|
|
@ -149,7 +156,7 @@ public class DynamicGridReport : XtraReport
|
||||||
selectQuery,
|
selectQuery,
|
||||||
connectionString,
|
connectionString,
|
||||||
dataSourceType);
|
dataSourceType);
|
||||||
BuildLayout(listForm, reportColumns, localizer, imageBaseUrl);
|
BuildLayout(listForm, reportColumns, localizer, imageBaseUrl, currentUser.UserName, criteriaText);
|
||||||
RequestParameters = false;
|
RequestParameters = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,13 +243,15 @@ public class DynamicGridReport : XtraReport
|
||||||
ListForm listForm,
|
ListForm listForm,
|
||||||
IReadOnlyList<ReportColumn> fields,
|
IReadOnlyList<ReportColumn> fields,
|
||||||
IStringLocalizer<PlatformResource> localizer,
|
IStringLocalizer<PlatformResource> localizer,
|
||||||
string imageBaseUrl)
|
string imageBaseUrl,
|
||||||
|
string currentUserName,
|
||||||
|
string criteriaText)
|
||||||
{
|
{
|
||||||
Bands.Clear();
|
Bands.Clear();
|
||||||
|
|
||||||
var topMargin = new TopMarginBand { HeightF = Margins.Top };
|
var topMargin = new TopMarginBand { HeightF = Margins.Top };
|
||||||
var bottomMargin = new BottomMarginBand { HeightF = 32 };
|
var bottomMargin = new BottomMarginBand { HeightF = 32 };
|
||||||
var reportHeader = new ReportHeaderBand { HeightF = 32 };
|
var reportHeader = new ReportHeaderBand { HeightF = string.IsNullOrWhiteSpace(criteriaText) ? 32 : 50 };
|
||||||
var pageHeader = new PageHeaderBand { HeightF = 28 };
|
var pageHeader = new PageHeaderBand { HeightF = 28 };
|
||||||
var detailHeight = fields.Any(x => x.IsImage)
|
var detailHeight = fields.Any(x => x.IsImage)
|
||||||
? DynamicReportImageHelper.GetGridImageHeight()
|
? DynamicReportImageHelper.GetGridImageHeight()
|
||||||
|
|
@ -262,21 +271,16 @@ public class DynamicGridReport : XtraReport
|
||||||
Font = new DXFont("Arial", 14F, DXFontStyle.Bold),
|
Font = new DXFont("Arial", 14F, DXFontStyle.Bold),
|
||||||
TextAlignment = TextAlignment.MiddleLeft
|
TextAlignment = TextAlignment.MiddleLeft
|
||||||
});
|
});
|
||||||
|
DynamicReportImageHelper.AddGeneratedAtToHeader(reportHeader.Controls, pageWidth);
|
||||||
|
DynamicReportImageHelper.AddReportCriteriaToHeader(reportHeader.Controls, criteriaText, pageWidth);
|
||||||
|
|
||||||
var generatedAt = new XRPageInfo
|
DynamicReportImageHelper.AddFooterTopLine(bottomMargin.Controls, pageWidth);
|
||||||
{
|
DynamicReportImageHelper.AddCurrentUserNameToFooter(bottomMargin.Controls, currentUserName, pageWidth);
|
||||||
PageInfo = PageInfo.DateTime,
|
|
||||||
TextFormatString = "{0:dd.MM.yyyy HH:mm}",
|
|
||||||
BoundsF = new System.Drawing.RectangleF(0, 0, pageWidth / 2, 18),
|
|
||||||
Font = new DXFont("Arial", 7.5F),
|
|
||||||
TextAlignment = TextAlignment.MiddleLeft
|
|
||||||
};
|
|
||||||
bottomMargin.Controls.Add(generatedAt);
|
|
||||||
|
|
||||||
var pageInfo = new XRPageInfo
|
var pageInfo = new XRPageInfo
|
||||||
{
|
{
|
||||||
TextFormatString = "Sayfa {0} / {1}",
|
TextFormatString = "Sayfa {0} / {1}",
|
||||||
BoundsF = new System.Drawing.RectangleF(pageWidth / 2, 0, pageWidth / 2, 18),
|
BoundsF = new System.Drawing.RectangleF(pageWidth / 2, 8, pageWidth / 2, 18),
|
||||||
Font = new DXFont("Arial", 8F),
|
Font = new DXFont("Arial", 8F),
|
||||||
TextAlignment = TextAlignment.MiddleRight
|
TextAlignment = TextAlignment.MiddleRight
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using DevExpress.XtraReports.UI;
|
||||||
using Sozsoft.Languages.Entities;
|
using Sozsoft.Languages.Entities;
|
||||||
using Sozsoft.Platform.EntityFrameworkCore;
|
using Sozsoft.Platform.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Volo.Abp.Users;
|
||||||
|
|
||||||
namespace Sozsoft.Reports.PredefinedReports;
|
namespace Sozsoft.Reports.PredefinedReports;
|
||||||
|
|
||||||
|
|
@ -35,11 +36,47 @@ public partial class DynamicReport : XtraReport
|
||||||
|
|
||||||
// Language verilerini yükle
|
// Language verilerini yükle
|
||||||
LoadLanguageParameters();
|
LoadLanguageParameters();
|
||||||
|
AddHeaderGeneratedAt();
|
||||||
|
AddFooterCurrentUserName();
|
||||||
|
AddFooterLine();
|
||||||
|
|
||||||
pageInfo1.TextFormatString = "{0:d}";
|
pageInfo1.Visible = false;
|
||||||
xrRichText1.BeforePrint += XrRichText1_BeforePrint;
|
xrRichText1.BeforePrint += XrRichText1_BeforePrint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddFooterLine()
|
||||||
|
{
|
||||||
|
var pageWidth = PageWidth - Margins.Left - Margins.Right;
|
||||||
|
DynamicReportImageHelper.AddFooterTopLine(BottomMargin.Controls, pageWidth);
|
||||||
|
pageInfo1.TopF = 8;
|
||||||
|
pageInfo2.TopF = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddHeaderGeneratedAt()
|
||||||
|
{
|
||||||
|
var pageWidth = PageWidth - Margins.Left - Margins.Right;
|
||||||
|
DynamicReportImageHelper.AddGeneratedAtToHeader(ReportHeader.Controls, pageWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddFooterCurrentUserName()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_serviceProvider == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var scope = _serviceProvider.CreateScope();
|
||||||
|
var currentUser = scope.ServiceProvider.GetRequiredService<ICurrentUser>();
|
||||||
|
var pageWidth = PageWidth - Margins.Left - Margins.Right;
|
||||||
|
DynamicReportImageHelper.AddCurrentUserNameToFooter(BottomMargin.Controls, currentUser.UserName, pageWidth);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void LoadLanguageParameters()
|
private void LoadLanguageParameters()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ internal static class DynamicReportImageHelper
|
||||||
private const string ImageSourceFunctionName = "SozReportImageSource";
|
private const string ImageSourceFunctionName = "SozReportImageSource";
|
||||||
private const string FormatValueFunctionName = "SozReportFormatValue";
|
private const string FormatValueFunctionName = "SozReportFormatValue";
|
||||||
private static readonly Regex ReportPagingRegex = new(
|
private static readonly Regex ReportPagingRegex = new(
|
||||||
@"\s+ORDER\s+BY[\s\S]*?(?:\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);
|
||||||
private static readonly HttpClient HttpClient = new(new HttpClientHandler
|
private static readonly HttpClient HttpClient = new(new HttpClientHandler
|
||||||
{
|
{
|
||||||
|
|
@ -271,6 +271,94 @@ internal static class DynamicReportImageHelper
|
||||||
return Localize(localizer, caption, field.FieldName);
|
return Localize(localizer, caption, field.FieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AddGeneratedAtToHeader(XRControlCollection controls, float pageWidth)
|
||||||
|
{
|
||||||
|
var width = Math.Min(260F, pageWidth * 0.4F);
|
||||||
|
controls.Add(new XRPageInfo
|
||||||
|
{
|
||||||
|
PageInfo = PageInfo.DateTime,
|
||||||
|
TextFormatString = "{0:dd.MM.yyyy HH:mm}",
|
||||||
|
BoundsF = new System.Drawing.RectangleF(pageWidth - width, 0, width, 18),
|
||||||
|
Font = new DevExpress.Drawing.DXFont("Arial", 8F),
|
||||||
|
TextAlignment = TextAlignment.MiddleRight,
|
||||||
|
CanGrow = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddCurrentUserNameToFooter(XRControlCollection controls, string userName, float pageWidth)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(userName))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.Add(new XRLabel
|
||||||
|
{
|
||||||
|
Text = userName,
|
||||||
|
BoundsF = new System.Drawing.RectangleF(0, 8, pageWidth / 2, 18),
|
||||||
|
Font = new DevExpress.Drawing.DXFont("Arial", 7.5F),
|
||||||
|
TextAlignment = TextAlignment.MiddleLeft,
|
||||||
|
CanGrow = false,
|
||||||
|
Multiline = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddReportCriteriaToHeader(
|
||||||
|
XRControlCollection controls,
|
||||||
|
string criteriaText,
|
||||||
|
float pageWidth)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(criteriaText))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.Add(new XRLabel
|
||||||
|
{
|
||||||
|
Text = criteriaText,
|
||||||
|
BoundsF = new System.Drawing.RectangleF(0, 28, pageWidth, 18),
|
||||||
|
Font = new DevExpress.Drawing.DXFont("Arial", 7.5F),
|
||||||
|
ForeColor = System.Drawing.Color.FromArgb(100, 116, 139),
|
||||||
|
TextAlignment = TextAlignment.MiddleLeft,
|
||||||
|
CanGrow = true,
|
||||||
|
Multiline = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddFooterTopLine(XRControlCollection controls, float pageWidth)
|
||||||
|
{
|
||||||
|
controls.Add(new XRLine
|
||||||
|
{
|
||||||
|
BoundsF = new System.Drawing.RectangleF(0, 0, pageWidth, 2),
|
||||||
|
ForeColor = System.Drawing.Color.FromArgb(203, 213, 225),
|
||||||
|
LineWidth = 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string BuildReportCriteriaText(
|
||||||
|
string filter,
|
||||||
|
string sort,
|
||||||
|
IEnumerable<ListFormField> fields,
|
||||||
|
IStringLocalizer<PlatformResource> localizer)
|
||||||
|
{
|
||||||
|
var parts = new List<string>();
|
||||||
|
var fieldCaptions = CreateFieldCaptionMap(fields, localizer);
|
||||||
|
var filterText = FormatFilterText(filter, fieldCaptions);
|
||||||
|
var sortText = FormatSortText(sort, fieldCaptions);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(filterText))
|
||||||
|
{
|
||||||
|
parts.Add("Filtre: " + filterText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(sortText))
|
||||||
|
{
|
||||||
|
parts.Add("Sıralama: " + sortText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Join(" | ", parts);
|
||||||
|
}
|
||||||
|
|
||||||
public static string Localize(IStringLocalizer<PlatformResource> localizer, string key, string fallback)
|
public static string Localize(IStringLocalizer<PlatformResource> localizer, string key, string fallback)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(key))
|
if (string.IsNullOrWhiteSpace(key))
|
||||||
|
|
@ -485,7 +573,7 @@ internal static class DynamicReportImageHelper
|
||||||
string editorType,
|
string editorType,
|
||||||
out string text)
|
out string text)
|
||||||
{
|
{
|
||||||
return TryFormatReportValue(value, field.SourceDbType, field.Format, editorType, out text);
|
return TryFormatReportValue(value, field.SourceDbType, GetEffectiveFormat(field), editorType, out text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string CreateFormatValueExpression(
|
public static string CreateFormatValueExpression(
|
||||||
|
|
@ -493,7 +581,7 @@ internal static class DynamicReportImageHelper
|
||||||
ListFormField field,
|
ListFormField field,
|
||||||
string editorType)
|
string editorType)
|
||||||
{
|
{
|
||||||
return $"{FormatValueFunctionName}({valueExpression}, '{field.SourceDbType}', '{EscapeExpressionString(field.Format)}', '{EscapeExpressionString(editorType)}')";
|
return $"{FormatValueFunctionName}({valueExpression}, '{field.SourceDbType}', '{EscapeExpressionString(GetEffectiveFormat(field))}', '{EscapeExpressionString(editorType)}')";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FormatReportDate(DateTime value)
|
public static string FormatReportDate(DateTime value)
|
||||||
|
|
@ -627,6 +715,190 @@ internal static class DynamicReportImageHelper
|
||||||
: value ? "Yes" : "No";
|
: value ? "Yes" : "No";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, string> CreateFieldCaptionMap(
|
||||||
|
IEnumerable<ListFormField> fields,
|
||||||
|
IStringLocalizer<PlatformResource> localizer)
|
||||||
|
{
|
||||||
|
return (fields ?? [])
|
||||||
|
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName))
|
||||||
|
.GroupBy(x => x.FieldName, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToDictionary(
|
||||||
|
x => x.Key,
|
||||||
|
x => GetLocalizedFieldCaption(x.First(), localizer),
|
||||||
|
StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatSortText(string sort, IReadOnlyDictionary<string, string> fieldCaptions)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(sort))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = sort
|
||||||
|
.Split(PlatformConsts.MultiValueDelimiter, StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(item =>
|
||||||
|
{
|
||||||
|
var parts = item.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (parts.Length == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fieldName = parts[0].Trim('"');
|
||||||
|
var direction = parts.Length > 1 ? parts[1] : "asc";
|
||||||
|
var directionText = string.Equals(direction, "desc", StringComparison.OrdinalIgnoreCase)
|
||||||
|
? "azalan"
|
||||||
|
: "artan";
|
||||||
|
|
||||||
|
return $"{GetFieldCaption(fieldName, fieldCaptions)} {directionText}";
|
||||||
|
})
|
||||||
|
.Where(x => !string.IsNullOrWhiteSpace(x));
|
||||||
|
|
||||||
|
return string.Join(", ", items);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatFilterText(string filter, IReadOnlyDictionary<string, string> fieldCaptions)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(filter))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var document = JsonDocument.Parse(filter);
|
||||||
|
return FormatFilterElement(document.RootElement, fieldCaptions);
|
||||||
|
}
|
||||||
|
catch (JsonException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatFilterElement(JsonElement element, IReadOnlyDictionary<string, string> fieldCaptions)
|
||||||
|
{
|
||||||
|
if (element.ValueKind != JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
return FormatJsonValue(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = element.EnumerateArray().ToList();
|
||||||
|
if (items.Count == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items.Count >= 3 &&
|
||||||
|
items[0].ValueKind == JsonValueKind.String &&
|
||||||
|
items[1].ValueKind == JsonValueKind.String)
|
||||||
|
{
|
||||||
|
return FormatFilterCondition(items[0].GetString(), items[1].GetString(), items[2], fieldCaptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items.Count == 2 &&
|
||||||
|
items[0].ValueKind == JsonValueKind.String &&
|
||||||
|
items[0].GetString() == "!")
|
||||||
|
{
|
||||||
|
var text = FormatFilterElement(items[1], fieldCaptions);
|
||||||
|
return string.IsNullOrWhiteSpace(text) ? null : "değil (" + text + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
var parts = new List<string>();
|
||||||
|
for (var i = 0; i < items.Count; i++)
|
||||||
|
{
|
||||||
|
if (items[i].ValueKind == JsonValueKind.String &&
|
||||||
|
IsFilterConnector(items[i].GetString()))
|
||||||
|
{
|
||||||
|
parts.Add(FormatFilterConnector(items[i].GetString()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var text = FormatFilterElement(items[i], fieldCaptions);
|
||||||
|
if (!string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
parts.Add(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Join(" ", parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatFilterCondition(
|
||||||
|
string fieldName,
|
||||||
|
string operation,
|
||||||
|
JsonElement value,
|
||||||
|
IReadOnlyDictionary<string, string> fieldCaptions)
|
||||||
|
{
|
||||||
|
var caption = GetFieldCaption(fieldName, fieldCaptions);
|
||||||
|
var op = FormatFilterOperation(operation);
|
||||||
|
var formattedValue = FormatJsonValue(value);
|
||||||
|
|
||||||
|
return string.IsNullOrWhiteSpace(formattedValue)
|
||||||
|
? $"{caption} {op}"
|
||||||
|
: $"{caption} {op} {formattedValue}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatFilterOperation(string operation)
|
||||||
|
{
|
||||||
|
return operation?.ToLowerInvariant() switch
|
||||||
|
{
|
||||||
|
"=" => "=",
|
||||||
|
"<>" => "eşit değil",
|
||||||
|
">" => ">",
|
||||||
|
">=" => ">=",
|
||||||
|
"<" => "<",
|
||||||
|
"<=" => "<=",
|
||||||
|
"contains" => "içerir",
|
||||||
|
"notcontains" => "içermez",
|
||||||
|
"startswith" => "ile başlar",
|
||||||
|
"endswith" => "ile biter",
|
||||||
|
"between" => "arasında",
|
||||||
|
"anyof" => "şunlardan biri",
|
||||||
|
"noneof" => "şunlardan hiçbiri",
|
||||||
|
"isblank" => "boş",
|
||||||
|
"isnotblank" => "boş değil",
|
||||||
|
_ => operation
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatJsonValue(JsonElement value)
|
||||||
|
{
|
||||||
|
return value.ValueKind switch
|
||||||
|
{
|
||||||
|
JsonValueKind.String => value.GetString(),
|
||||||
|
JsonValueKind.Number => value.GetRawText(),
|
||||||
|
JsonValueKind.True => "Evet",
|
||||||
|
JsonValueKind.False => "Hayır",
|
||||||
|
JsonValueKind.Null => string.Empty,
|
||||||
|
JsonValueKind.Array => string.Join(", ", value.EnumerateArray().Select(FormatJsonValue)),
|
||||||
|
_ => value.ToString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFieldCaption(string fieldName, IReadOnlyDictionary<string, string> fieldCaptions)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(fieldName))
|
||||||
|
{
|
||||||
|
return fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fieldCaptions.TryGetValue(fieldName, out var caption)
|
||||||
|
? caption
|
||||||
|
: fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsFilterConnector(string value)
|
||||||
|
{
|
||||||
|
return string.Equals(value, "and", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(value, "or", StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatFilterConnector(string value)
|
||||||
|
{
|
||||||
|
return string.Equals(value, "or", StringComparison.OrdinalIgnoreCase) ? "veya" : "ve";
|
||||||
|
}
|
||||||
|
|
||||||
private static bool IsBooleanField(string editorType, DbType dbType)
|
private static bool IsBooleanField(string editorType, DbType dbType)
|
||||||
{
|
{
|
||||||
return editorType is PlatformConsts.EditorTypes.dxCheckBox or PlatformConsts.EditorTypes.dxSwitch ||
|
return editorType is PlatformConsts.EditorTypes.dxCheckBox or PlatformConsts.EditorTypes.dxSwitch ||
|
||||||
|
|
@ -635,12 +907,70 @@ internal static class DynamicReportImageHelper
|
||||||
|
|
||||||
private static string GetCustomFormat(string format)
|
private static string GetCustomFormat(string format)
|
||||||
{
|
{
|
||||||
return string.IsNullOrWhiteSpace(format) ? null : format;
|
if (string.IsNullOrWhiteSpace(format))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var customFormat = TryGetFormatOption(format, "displayFormat") ??
|
||||||
|
TryGetFormatOption(format, "format") ??
|
||||||
|
format.Trim();
|
||||||
|
|
||||||
|
return NormalizeDateTimeFormat(customFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetEffectiveFormat(ListFormField field)
|
||||||
|
{
|
||||||
|
return TryGetFormatOption(field?.EditorOptions, "displayFormat") ??
|
||||||
|
TryGetFormatOption(field?.EditorOptions, "format") ??
|
||||||
|
field?.Format;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string TryGetFormatOption(string json, string propertyName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(json))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var document = JsonDocument.Parse(json);
|
||||||
|
if (document.RootElement.ValueKind != JsonValueKind.Object ||
|
||||||
|
!TryGetLookupProperty(document.RootElement, propertyName, out var value))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.ValueKind == JsonValueKind.String ? value.GetString() : null;
|
||||||
|
}
|
||||||
|
catch (JsonException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeDateTimeFormat(string format)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(format))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return format.Trim() switch
|
||||||
|
{
|
||||||
|
PlatformConsts.GridColumnOptions.ColumnValueFormatShortDate => "d",
|
||||||
|
PlatformConsts.GridColumnOptions.ColumnValueFormatShortTime => "t",
|
||||||
|
PlatformConsts.GridColumnOptions.ColumnValueFormatLongTime => "T",
|
||||||
|
PlatformConsts.GridColumnOptions.ColumnValueFormatShortDateShortTime => "g",
|
||||||
|
PlatformConsts.GridColumnOptions.ColumnValueFormatLongDateLongTime => "G",
|
||||||
|
_ => format.Trim()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsDateField(DbType dbType)
|
private static bool IsDateField(DbType dbType)
|
||||||
{
|
{
|
||||||
return dbType is DbType.Date or DbType.DateTime or DbType.DateTime2 or DbType.DateTimeOffset;
|
return dbType is DbType.Date or DbType.DateTime or DbType.DateTime2 or DbType.DateTimeOffset or DbType.Time;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool TryConvertToDateTime(object value, out DateTime date)
|
private static bool TryConvertToDateTime(object value, out DateTime date)
|
||||||
|
|
@ -653,6 +983,9 @@ internal static class DynamicReportImageHelper
|
||||||
case DateTimeOffset dateTimeOffset:
|
case DateTimeOffset dateTimeOffset:
|
||||||
date = dateTimeOffset.LocalDateTime;
|
date = dateTimeOffset.LocalDateTime;
|
||||||
return true;
|
return true;
|
||||||
|
case TimeSpan timeSpan:
|
||||||
|
date = DateTime.Today.Add(timeSpan);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var text = Convert.ToString(value, CultureInfo.InvariantCulture);
|
var text = Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,14 @@ internal static class DynamicReportSqlBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
var sourceAlias = QuoteSqlIdentifier(SourceAlias);
|
var sourceAlias = QuoteSqlIdentifier(SourceAlias);
|
||||||
return $"SELECT {sourceAlias}.*, {string.Join(", ", lookupSelectParts)} FROM ({NormalizeSql(selectQuery)}) AS {sourceAlias}";
|
var normalizedSql = NormalizeSql(selectQuery);
|
||||||
|
var orderBy = ExtractOrderBy(normalizedSql);
|
||||||
|
if (!string.IsNullOrWhiteSpace(orderBy))
|
||||||
|
{
|
||||||
|
normalizedSql = OrderByRegex.Replace(normalizedSql, string.Empty).Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"SELECT {sourceAlias}.*, {string.Join(", ", lookupSelectParts)} FROM ({normalizedSql}) AS {sourceAlias}{orderBy}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateLookupSelectPart(
|
private static string CreateLookupSelectPart(
|
||||||
|
|
@ -139,6 +146,12 @@ internal static class DynamicReportSqlBuilder
|
||||||
return sql.Trim().TrimEnd(';');
|
return sql.Trim().TrimEnd(';');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string ExtractOrderBy(string sql)
|
||||||
|
{
|
||||||
|
var match = OrderByRegex.Match(sql);
|
||||||
|
return match.Success ? " " + match.Value.Trim() : string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
private static string QuoteSqlIdentifier(string identifier)
|
private static string QuoteSqlIdentifier(string identifier)
|
||||||
{
|
{
|
||||||
return $"\"{identifier.Replace("\"", "\"\"")}\"";
|
return $"\"{identifier.Replace("\"", "\"\"")}\"";
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ using Sozsoft.Platform.Enums;
|
||||||
using Sozsoft.Platform.ListForms;
|
using Sozsoft.Platform.ListForms;
|
||||||
using Sozsoft.Platform.Localization;
|
using Sozsoft.Platform.Localization;
|
||||||
using Sozsoft.Platform.Queries;
|
using Sozsoft.Platform.Queries;
|
||||||
|
using Volo.Abp.Users;
|
||||||
|
|
||||||
namespace Sozsoft.Reports.PredefinedReports;
|
namespace Sozsoft.Reports.PredefinedReports;
|
||||||
|
|
||||||
|
|
@ -73,6 +74,7 @@ public class DynamicTreeReport : XtraReport
|
||||||
var defaultValueHelper = scope.ServiceProvider.GetRequiredService<DefaultValueHelper>();
|
var defaultValueHelper = scope.ServiceProvider.GetRequiredService<DefaultValueHelper>();
|
||||||
var localizer = scope.ServiceProvider.GetRequiredService<IStringLocalizer<PlatformResource>>();
|
var localizer = scope.ServiceProvider.GetRequiredService<IStringLocalizer<PlatformResource>>();
|
||||||
var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
||||||
|
var currentUser = scope.ServiceProvider.GetRequiredService<ICurrentUser>();
|
||||||
|
|
||||||
if (!await authManager.CanAccess(listFormCode))
|
if (!await authManager.CanAccess(listFormCode))
|
||||||
{
|
{
|
||||||
|
|
@ -153,13 +155,18 @@ public class DynamicTreeReport : XtraReport
|
||||||
dataSourceType);
|
dataSourceType);
|
||||||
|
|
||||||
var imageBaseUrl = DynamicReportImageHelper.GetImageBaseUrl(configuration);
|
var imageBaseUrl = DynamicReportImageHelper.GetImageBaseUrl(configuration);
|
||||||
|
var criteriaText = DynamicReportImageHelper.BuildReportCriteriaText(
|
||||||
|
queryParams.Filter,
|
||||||
|
queryParams.Sort,
|
||||||
|
fields,
|
||||||
|
localizer);
|
||||||
var sourceRows = await ReadRowsAsync(dynamicDataRepository, selectQuery, connectionString);
|
var sourceRows = await ReadRowsAsync(dynamicDataRepository, selectQuery, connectionString);
|
||||||
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);
|
||||||
ConfigureDataSource(orderedRows, reportColumns);
|
ConfigureDataSource(orderedRows, reportColumns);
|
||||||
BuildLayout(listForm, reportColumns, localizer, imageBaseUrl);
|
BuildLayout(listForm, reportColumns, localizer, imageBaseUrl, currentUser.UserName, criteriaText);
|
||||||
RequestParameters = false;
|
RequestParameters = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -408,13 +415,15 @@ public class DynamicTreeReport : XtraReport
|
||||||
ListForm listForm,
|
ListForm listForm,
|
||||||
IReadOnlyList<ReportColumn> fields,
|
IReadOnlyList<ReportColumn> fields,
|
||||||
IStringLocalizer<PlatformResource> localizer,
|
IStringLocalizer<PlatformResource> localizer,
|
||||||
string imageBaseUrl)
|
string imageBaseUrl,
|
||||||
|
string currentUserName,
|
||||||
|
string criteriaText)
|
||||||
{
|
{
|
||||||
Bands.Clear();
|
Bands.Clear();
|
||||||
|
|
||||||
var topMargin = new TopMarginBand { HeightF = Margins.Top };
|
var topMargin = new TopMarginBand { HeightF = Margins.Top };
|
||||||
var bottomMargin = new BottomMarginBand { HeightF = 32 };
|
var bottomMargin = new BottomMarginBand { HeightF = 32 };
|
||||||
var reportHeader = new ReportHeaderBand { HeightF = 32 };
|
var reportHeader = new ReportHeaderBand { HeightF = string.IsNullOrWhiteSpace(criteriaText) ? 32 : 50 };
|
||||||
var pageHeader = new PageHeaderBand { HeightF = 28 };
|
var pageHeader = new PageHeaderBand { HeightF = 28 };
|
||||||
var detailHeight = fields.Any(x => x.IsImage)
|
var detailHeight = fields.Any(x => x.IsImage)
|
||||||
? DynamicReportImageHelper.GetGridImageHeight()
|
? DynamicReportImageHelper.GetGridImageHeight()
|
||||||
|
|
@ -434,20 +443,16 @@ public class DynamicTreeReport : XtraReport
|
||||||
Font = new DXFont("Arial", 14F, DXFontStyle.Bold),
|
Font = new DXFont("Arial", 14F, DXFontStyle.Bold),
|
||||||
TextAlignment = TextAlignment.MiddleLeft
|
TextAlignment = TextAlignment.MiddleLeft
|
||||||
});
|
});
|
||||||
|
DynamicReportImageHelper.AddGeneratedAtToHeader(reportHeader.Controls, pageWidth);
|
||||||
|
DynamicReportImageHelper.AddReportCriteriaToHeader(reportHeader.Controls, criteriaText, pageWidth);
|
||||||
|
|
||||||
bottomMargin.Controls.Add(new XRPageInfo
|
DynamicReportImageHelper.AddFooterTopLine(bottomMargin.Controls, pageWidth);
|
||||||
{
|
DynamicReportImageHelper.AddCurrentUserNameToFooter(bottomMargin.Controls, currentUserName, pageWidth);
|
||||||
PageInfo = PageInfo.DateTime,
|
|
||||||
TextFormatString = "{0:dd.MM.yyyy HH:mm}",
|
|
||||||
BoundsF = new System.Drawing.RectangleF(0, 0, pageWidth / 2, 18),
|
|
||||||
Font = new DXFont("Arial", 7.5F),
|
|
||||||
TextAlignment = TextAlignment.MiddleLeft
|
|
||||||
});
|
|
||||||
|
|
||||||
bottomMargin.Controls.Add(new XRPageInfo
|
bottomMargin.Controls.Add(new XRPageInfo
|
||||||
{
|
{
|
||||||
TextFormatString = "Sayfa {0} / {1}",
|
TextFormatString = "Sayfa {0} / {1}",
|
||||||
BoundsF = new System.Drawing.RectangleF(pageWidth / 2, 0, pageWidth / 2, 18),
|
BoundsF = new System.Drawing.RectangleF(pageWidth / 2, 8, pageWidth / 2, 18),
|
||||||
Font = new DXFont("Arial", 8F),
|
Font = new DXFont("Arial", 8F),
|
||||||
TextAlignment = TextAlignment.MiddleRight
|
TextAlignment = TextAlignment.MiddleRight
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
||||||
var keyValue = pair.Split('=', 2);
|
var keyValue = pair.Split('=', 2);
|
||||||
if (keyValue.Length == 2 && !string.IsNullOrWhiteSpace(keyValue[0]))
|
if (keyValue.Length == 2 && !string.IsNullOrWhiteSpace(keyValue[0]))
|
||||||
{
|
{
|
||||||
parameters[keyValue[0]] = keyValue[1];
|
parameters[DecodeQueryComponent(keyValue[0])] = DecodeQueryComponent(keyValue[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -375,6 +375,11 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
||||||
return decoded;
|
return decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string DecodeQueryComponent(string value)
|
||||||
|
{
|
||||||
|
return DecodeRepeatedly(value ?? string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
public override Dictionary<string, string> GetUrls()
|
public override Dictionary<string, string> GetUrls()
|
||||||
{
|
{
|
||||||
// Returns a dictionary that contains the report names (URLs) and display names.
|
// Returns a dictionary that contains the report names (URLs) and display names.
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||||
import { GanttRef } from 'devextreme-react/cjs/gantt'
|
import { GanttRef } from 'devextreme-react/cjs/gantt'
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
import { MULTIVALUE_DELIMITER } from '@/constants/app.constant'
|
import { MULTIVALUE_DELIMITER } from '@/constants/app.constant'
|
||||||
|
import { createReportQueryString } from '../report/reportRouteParams'
|
||||||
|
|
||||||
export interface ISelectBoxData {
|
export interface ISelectBoxData {
|
||||||
value?: string
|
value?: string
|
||||||
|
|
@ -208,7 +209,7 @@ const createDynamicListReportUrl = (
|
||||||
searchParams.set('sort', sort)
|
searchParams.set('sort', sort)
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryString = searchParams.toString()
|
const queryString = createReportQueryString(searchParams)
|
||||||
return queryString ? `${reportUrl}?${queryString}` : reportUrl
|
return queryString ? `${reportUrl}?${queryString}` : reportUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,30 +58,6 @@ const loadViewerCss = (isDarkMode: boolean) => {
|
||||||
if (themeLink.href !== themeHref) {
|
if (themeLink.href !== themeHref) {
|
||||||
themeLink.href = themeHref
|
themeLink.href = themeHref
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!document.getElementById(VIEWER_DARK_OVERRIDES_ID)) {
|
|
||||||
const style = document.createElement('style')
|
|
||||||
style.id = VIEWER_DARK_OVERRIDES_ID
|
|
||||||
style.textContent = `
|
|
||||||
.report-viewer-shell {
|
|
||||||
min-height: calc(100vh - 4rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-viewer-shell-dark {
|
|
||||||
background: #111827;
|
|
||||||
color: #e5e7eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-viewer-shell-dark .dxrd-preview,
|
|
||||||
.report-viewer-shell-dark .dxrd-preview-wrapper,
|
|
||||||
.report-viewer-shell-dark .dxrd-toolbar-wrapper,
|
|
||||||
.report-viewer-shell-dark .dxrd-right-panel,
|
|
||||||
.report-viewer-shell-dark .dxrd-search-wrapper {
|
|
||||||
background-color: #111827;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
document.head.appendChild(style)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DevexpressReportDesigner: React.FC = () => {
|
const DevexpressReportDesigner: React.FC = () => {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { ZoomAutoBy } from 'devexpress-reporting/viewer/constants'
|
||||||
import { APP_NAME } from '@/constants/app.constant'
|
import { APP_NAME } from '@/constants/app.constant'
|
||||||
import { MODE_DARK } from '@/constants/theme.constant'
|
import { MODE_DARK } from '@/constants/theme.constant'
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
import { createReportUrl } from './reportRouteParams'
|
import { createReportQueryString, createReportUrl } from './reportRouteParams'
|
||||||
|
|
||||||
const VIEWER_THEME_LINK_ID = 'devexpress-report-viewer-theme'
|
const VIEWER_THEME_LINK_ID = 'devexpress-report-viewer-theme'
|
||||||
const VIEWER_DARK_OVERRIDES_ID = 'devexpress-report-viewer-dark-overrides'
|
const VIEWER_DARK_OVERRIDES_ID = 'devexpress-report-viewer-dark-overrides'
|
||||||
|
|
@ -60,30 +60,6 @@ const loadViewerCss = (isDarkMode: boolean) => {
|
||||||
if (themeLink.href !== themeHref) {
|
if (themeLink.href !== themeHref) {
|
||||||
themeLink.href = themeHref
|
themeLink.href = themeHref
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!document.getElementById(VIEWER_DARK_OVERRIDES_ID)) {
|
|
||||||
const style = document.createElement('style')
|
|
||||||
style.id = VIEWER_DARK_OVERRIDES_ID
|
|
||||||
style.textContent = `
|
|
||||||
.report-viewer-shell {
|
|
||||||
min-height: calc(100vh - 4rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-viewer-shell-dark {
|
|
||||||
background: #111827;
|
|
||||||
color: #e5e7eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-viewer-shell-dark .dxrd-preview,
|
|
||||||
.report-viewer-shell-dark .dxrd-preview-wrapper,
|
|
||||||
.report-viewer-shell-dark .dxrd-toolbar-wrapper,
|
|
||||||
.report-viewer-shell-dark .dxrd-right-panel,
|
|
||||||
.report-viewer-shell-dark .dxrd-search-wrapper {
|
|
||||||
background-color: #111827;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
document.head.appendChild(style)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DevexpressReportViewer: React.FC = () => {
|
const DevexpressReportViewer: React.FC = () => {
|
||||||
|
|
@ -177,7 +153,7 @@ const DevexpressReportViewer: React.FC = () => {
|
||||||
searchParams.set('cultureName', reportCultureName)
|
searchParams.set('cultureName', reportCultureName)
|
||||||
}
|
}
|
||||||
|
|
||||||
const search = searchParams.toString()
|
const search = createReportQueryString(searchParams)
|
||||||
return createReportUrl({ report, id, listFormCode }, search ? `?${search}` : '')
|
return createReportUrl({ report, id, listFormCode }, search ? `?${search}` : '')
|
||||||
}, [report, id, listFormCode, location.search, reportCultureName])
|
}, [report, id, listFormCode, location.search, reportCultureName])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ export const normalizeReportRouteParams = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const createReportQueryString = (searchParams: URLSearchParams) =>
|
||||||
|
Array.from(searchParams.entries())
|
||||||
|
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||||
|
.join('&')
|
||||||
|
|
||||||
export const createReportUrl = (
|
export const createReportUrl = (
|
||||||
params: ReportRouteParams,
|
params: ReportRouteParams,
|
||||||
search: string,
|
search: string,
|
||||||
|
|
@ -47,6 +52,6 @@ export const createReportUrl = (
|
||||||
if (listFormCode) pathSegments.push(listFormCode)
|
if (listFormCode) pathSegments.push(listFormCode)
|
||||||
|
|
||||||
const path = pathSegments.map((segment) => encodeURIComponent(segment)).join('/')
|
const path = pathSegments.map((segment) => encodeURIComponent(segment)).join('/')
|
||||||
const queryString = searchParams.toString()
|
const queryString = createReportQueryString(searchParams)
|
||||||
return queryString ? `${path}?${queryString}` : path
|
return queryString ? `${path}?${queryString}` : path
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue