Raporlama, Chart, Pivot hataları düzeltildi.
This commit is contained in:
parent
39e4e448d7
commit
16036ce7f9
14 changed files with 295 additions and 46 deletions
|
|
@ -1231,8 +1231,6 @@ public class PlatformDbContext :
|
|||
|
||||
b.Property(x => x.SubmissionTime).IsRequired();
|
||||
|
||||
b.HasIndex(x => new { x.SurveyId, x.UserId }).IsUnique().HasFilter("[IsDeleted] = 0");
|
||||
|
||||
b.HasOne(x => x.Survey)
|
||||
.WithMany(x => x.SurveyResponses)
|
||||
.HasForeignKey(x => x.SurveyId)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
|
|||
namespace Sozsoft.Platform.Migrations
|
||||
{
|
||||
[DbContext(typeof(PlatformDbContext))]
|
||||
[Migration("20260619185755_Initial")]
|
||||
[Migration("20260622213308_Initial")]
|
||||
partial class Initial
|
||||
{
|
||||
/// <inheritdoc />
|
||||
|
|
@ -5470,9 +5470,7 @@ namespace Sozsoft.Platform.Migrations
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SurveyId", "UserId")
|
||||
.IsUnique()
|
||||
.HasFilter("[IsDeleted] = 0");
|
||||
b.HasIndex("SurveyId");
|
||||
|
||||
b.ToTable("Adm_T_SurveyResponse", (string)null);
|
||||
});
|
||||
|
|
@ -3808,11 +3808,9 @@ namespace Sozsoft.Platform.Migrations
|
|||
column: "QuestionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Adm_T_SurveyResponse_SurveyId_UserId",
|
||||
name: "IX_Adm_T_SurveyResponse_SurveyId",
|
||||
table: "Adm_T_SurveyResponse",
|
||||
columns: new[] { "SurveyId", "UserId" },
|
||||
unique: true,
|
||||
filter: "[IsDeleted] = 0");
|
||||
column: "SurveyId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Adm_T_Videoroom_TenantId_BranchId_Name",
|
||||
|
|
@ -5467,9 +5467,7 @@ namespace Sozsoft.Platform.Migrations
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SurveyId", "UserId")
|
||||
.IsUnique()
|
||||
.HasFilter("[IsDeleted] = 0");
|
||||
b.HasIndex("SurveyId");
|
||||
|
||||
b.ToTable("Adm_T_SurveyResponse", (string)null);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class DynamicFormReport : XtraReport
|
|||
{
|
||||
public const string ReportName = nameof(DynamicFormReport);
|
||||
private const string QueryName = "DynamicForm";
|
||||
private const int HorizontalMargin = 35;
|
||||
private const int HorizontalMargin = 50;
|
||||
private const float RowHeight = 24;
|
||||
private const float ColumnGap = 10;
|
||||
private static readonly System.Drawing.Color FieldBorderColor = System.Drawing.Color.FromArgb(226, 232, 240);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public class DynamicGridReport : XtraReport
|
|||
public const string ReportName = nameof(DynamicGridReport);
|
||||
private const string QueryName = "DynamicGrid";
|
||||
private const int A4PortraitWidth = 827;
|
||||
private const int HorizontalMargin = 35;
|
||||
private const int HorizontalMargin = 50;
|
||||
private const int LandscapeColumnThreshold = 5;
|
||||
private static readonly System.Drawing.Color TableBorderColor = System.Drawing.Color.FromArgb(226, 232, 240);
|
||||
private static IServiceProvider _serviceProvider;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace Sozsoft.Reports.PredefinedReports
|
|||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DynamicReport));
|
||||
this.TopMargin = new DevExpress.XtraReports.UI.TopMarginBand();
|
||||
this.BottomMargin = new DevExpress.XtraReports.UI.BottomMarginBand();
|
||||
this.pageInfo1 = new DevExpress.XtraReports.UI.XRPageInfo();
|
||||
this.currentUserNameLabel = new DevExpress.XtraReports.UI.XRLabel();
|
||||
this.pageInfo2 = new DevExpress.XtraReports.UI.XRPageInfo();
|
||||
this.ReportHeader = new DevExpress.XtraReports.UI.ReportHeaderBand();
|
||||
this.label1 = new DevExpress.XtraReports.UI.XRLabel();
|
||||
|
|
@ -55,6 +55,10 @@ namespace Sozsoft.Reports.PredefinedReports
|
|||
this.PageInfo = new DevExpress.XtraReports.UI.XRControlStyle();
|
||||
((System.ComponentModel.ISupportInitialize)(this.xrRichText1)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
|
||||
//
|
||||
// ReportHeader
|
||||
//
|
||||
this.ReportHeader.HeightF = 35F;
|
||||
//
|
||||
// TopMargin
|
||||
//
|
||||
|
|
@ -63,17 +67,16 @@ namespace Sozsoft.Reports.PredefinedReports
|
|||
// BottomMargin
|
||||
//
|
||||
this.BottomMargin.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
|
||||
this.pageInfo1,
|
||||
this.currentUserNameLabel,
|
||||
this.pageInfo2});
|
||||
this.BottomMargin.Name = "BottomMargin";
|
||||
//
|
||||
// pageInfo1
|
||||
// currentUserNameLabel
|
||||
//
|
||||
this.pageInfo1.LocationFloat = new DevExpress.Utils.PointFloat(0F, 0F);
|
||||
this.pageInfo1.Name = "pageInfo1";
|
||||
this.pageInfo1.PageInfo = DevExpress.XtraPrinting.PageInfo.DateTime;
|
||||
this.pageInfo1.SizeF = new System.Drawing.SizeF(325F, 23F);
|
||||
this.pageInfo1.StyleName = "PageInfo";
|
||||
this.currentUserNameLabel.LocationFloat = new DevExpress.Utils.PointFloat(0F, 0F);
|
||||
this.currentUserNameLabel.Name = "currentUserNameLabel";
|
||||
this.currentUserNameLabel.SizeF = new System.Drawing.SizeF(325F, 23F);
|
||||
this.currentUserNameLabel.StyleName = "PageInfo";
|
||||
//
|
||||
// pageInfo2
|
||||
//
|
||||
|
|
@ -196,7 +199,7 @@ namespace Sozsoft.Reports.PredefinedReports
|
|||
|
||||
private DevExpress.XtraReports.UI.TopMarginBand TopMargin;
|
||||
private DevExpress.XtraReports.UI.BottomMarginBand BottomMargin;
|
||||
private DevExpress.XtraReports.UI.XRPageInfo pageInfo1;
|
||||
private DevExpress.XtraReports.UI.XRLabel currentUserNameLabel;
|
||||
private DevExpress.XtraReports.UI.XRPageInfo pageInfo2;
|
||||
private DevExpress.XtraReports.UI.ReportHeaderBand ReportHeader;
|
||||
private DevExpress.XtraReports.UI.XRLabel label1;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using DevExpress.Drawing;
|
||||
using DevExpress.XtraPrinting;
|
||||
using DevExpress.XtraReports.UI;
|
||||
using Sozsoft.Languages.Entities;
|
||||
using Sozsoft.Platform.EntityFrameworkCore;
|
||||
|
|
@ -12,6 +14,9 @@ namespace Sozsoft.Reports.PredefinedReports;
|
|||
|
||||
public partial class DynamicReport : XtraReport
|
||||
{
|
||||
private const int HorizontalMargin = 50;
|
||||
private const int VerticalMargin = 35;
|
||||
|
||||
private Dictionary<string, string> _parameters;
|
||||
private static IServiceProvider _serviceProvider;
|
||||
|
||||
|
|
@ -27,10 +32,7 @@ public partial class DynamicReport : XtraReport
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
// A4 kağıt ayarları
|
||||
this.PageHeight = 1169;
|
||||
this.PageWidth = 827;
|
||||
this.Landscape = false;
|
||||
ConfigurePage();
|
||||
|
||||
_parameters = new Dictionary<string, string>();
|
||||
|
||||
|
|
@ -40,15 +42,39 @@ public partial class DynamicReport : XtraReport
|
|||
AddFooterCurrentUserName();
|
||||
AddFooterLine();
|
||||
|
||||
pageInfo1.Visible = false;
|
||||
xrRichText1.BeforePrint += XrRichText1_BeforePrint;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
private void ConfigurePage()
|
||||
{
|
||||
PaperKind = DevExpress.Drawing.Printing.DXPaperKind.A4;
|
||||
Landscape = false;
|
||||
Margins = new System.Drawing.Printing.Margins(
|
||||
HorizontalMargin,
|
||||
HorizontalMargin,
|
||||
VerticalMargin,
|
||||
VerticalMargin);
|
||||
Font = new DXFont("Arial", 8.25F);
|
||||
|
||||
TopMargin.HeightF = Margins.Top;
|
||||
BottomMargin.HeightF = Margins.Bottom;
|
||||
|
||||
var pageWidth = PageWidth - Margins.Left - Margins.Right;
|
||||
xrRichText1.WidthF = pageWidth;
|
||||
currentUserNameLabel.LocationFloat = new DevExpress.Utils.PointFloat(0, 8);
|
||||
currentUserNameLabel.SizeF = new System.Drawing.SizeF(pageWidth / 2, 18);
|
||||
currentUserNameLabel.TextAlignment = TextAlignment.MiddleLeft;
|
||||
pageInfo2.LocationFloat = new DevExpress.Utils.PointFloat(pageWidth / 2, 8);
|
||||
pageInfo2.SizeF = new System.Drawing.SizeF(pageWidth / 2, 18);
|
||||
pageInfo2.TextAlignment = TextAlignment.MiddleRight;
|
||||
}
|
||||
#pragma warning restore CA1416
|
||||
|
||||
private void AddFooterLine()
|
||||
{
|
||||
var pageWidth = PageWidth - Margins.Left - Margins.Right;
|
||||
DynamicReportImageHelper.AddFooterTopLine(BottomMargin.Controls, pageWidth);
|
||||
pageInfo1.TopF = 8;
|
||||
pageInfo2.TopF = 8;
|
||||
}
|
||||
|
||||
|
|
@ -69,8 +95,7 @@ public partial class DynamicReport : XtraReport
|
|||
|
||||
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);
|
||||
currentUserNameLabel.Text = currentUser.UserName ?? string.Empty;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public class DynamicTreeReport : XtraReport
|
|||
{
|
||||
public const string ReportName = nameof(DynamicTreeReport);
|
||||
private const int A4PortraitWidth = 827;
|
||||
private const int HorizontalMargin = 35;
|
||||
private const int HorizontalMargin = 50;
|
||||
private const int LandscapeColumnThreshold = 5;
|
||||
private const string TreeLevelColumn = "__TreeLevel";
|
||||
private const string TreeHasChildrenColumn = "__TreeHasChildren";
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ using System.Linq;
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using DevExpress.XtraPrinting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Volo.Abp.Users;
|
||||
|
||||
namespace Sozsoft.Platform.ReportServices;
|
||||
|
||||
|
|
@ -48,11 +51,11 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
|||
this.reportDirectory = reportDirectory;
|
||||
}
|
||||
|
||||
private bool IsWithinReportsFolder(string url, string folder)
|
||||
private static bool IsSafeReportFileName(string reportName)
|
||||
{
|
||||
var rootDirectory = new DirectoryInfo(folder);
|
||||
var fileInfo = new FileInfo(Path.Combine(folder, url));
|
||||
return fileInfo.Directory.FullName.ToLower().StartsWith(rootDirectory.FullName.ToLower());
|
||||
return !string.IsNullOrWhiteSpace(reportName) &&
|
||||
Path.GetFileName(reportName) == reportName &&
|
||||
reportName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0;
|
||||
}
|
||||
|
||||
public override bool CanSetData(string url)
|
||||
|
|
@ -72,8 +75,8 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
|||
// Return **true** if no validation is required.
|
||||
|
||||
// Query string veya path parametreleri gelse bile sadece rapor adını kontrol et.
|
||||
var (reportName, _) = ParseReportUrl(url);
|
||||
return Path.GetFileName(reportName) == reportName;
|
||||
var reportName = GetStorageReportName(url);
|
||||
return IsSafeReportFileName(reportName);
|
||||
}
|
||||
|
||||
public override byte[] GetData(string url)
|
||||
|
|
@ -181,7 +184,13 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
|||
return SaveReportLayout(report);
|
||||
}
|
||||
|
||||
var reportData = TryGetStoredReportData(reportName, parameters);
|
||||
var storedReportName = GetStoredReportName(reportName, parameters);
|
||||
var isDynamicReport = IsDynamicReport(reportName);
|
||||
var reportData = TryGetStoredReportData(storedReportName, parameters, isDynamicReport);
|
||||
if (reportData == null && !string.Equals(storedReportName, reportName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
reportData = TryGetStoredReportData(reportName, parameters, isDynamicReport);
|
||||
}
|
||||
if (reportData != null)
|
||||
{
|
||||
return reportData;
|
||||
|
|
@ -195,7 +204,10 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
|||
throw new FaultException(new FaultReason(string.Format("Could not find report '{0}'.", url)), new FaultCode("Server"), "GetData");
|
||||
}
|
||||
|
||||
private byte[] TryGetStoredReportData(string reportName, Dictionary<string, string> parameters)
|
||||
private byte[] TryGetStoredReportData(
|
||||
string reportName,
|
||||
Dictionary<string, string> parameters,
|
||||
bool isDynamicReport)
|
||||
{
|
||||
var report = TryLoadStoredReport(reportName);
|
||||
if (report == null)
|
||||
|
|
@ -204,9 +216,52 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
|||
}
|
||||
|
||||
ApplyReportParameters(report, parameters);
|
||||
if (isDynamicReport)
|
||||
{
|
||||
ApplyDynamicReportFooter(report);
|
||||
}
|
||||
return SaveReportLayout(report);
|
||||
}
|
||||
|
||||
private void ApplyDynamicReportFooter(XtraReport report)
|
||||
{
|
||||
var bottomMargin = report.Bands.OfType<BottomMarginBand>().FirstOrDefault();
|
||||
if (bottomMargin == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pageWidth = report.PageWidth - report.Margins.Left - report.Margins.Right;
|
||||
var legacyDateTime = bottomMargin.Controls
|
||||
.OfType<XRPageInfo>()
|
||||
.FirstOrDefault(control =>
|
||||
string.Equals(control.Name, "pageInfo1", StringComparison.OrdinalIgnoreCase) &&
|
||||
control.PageInfo == PageInfo.DateTime);
|
||||
if (legacyDateTime != null)
|
||||
{
|
||||
legacyDateTime.Visible = false;
|
||||
}
|
||||
|
||||
var userNameLabel = bottomMargin.Controls
|
||||
.OfType<XRLabel>()
|
||||
.FirstOrDefault(control =>
|
||||
string.Equals(control.Name, "currentUserNameLabel", StringComparison.OrdinalIgnoreCase));
|
||||
if (userNameLabel == null)
|
||||
{
|
||||
userNameLabel = new XRLabel { Name = "currentUserNameLabel" };
|
||||
bottomMargin.Controls.Add(userNameLabel);
|
||||
}
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var currentUser = scope.ServiceProvider.GetService<ICurrentUser>();
|
||||
userNameLabel.Text = currentUser?.Name ?? currentUser?.UserName ?? string.Empty;
|
||||
userNameLabel.BoundsF = new System.Drawing.RectangleF(0, 8, pageWidth / 2, 18);
|
||||
userNameLabel.Font = new DevExpress.Drawing.DXFont("Arial", 7.5F);
|
||||
userNameLabel.TextAlignment = TextAlignment.MiddleLeft;
|
||||
userNameLabel.CanGrow = false;
|
||||
userNameLabel.Multiline = false;
|
||||
}
|
||||
|
||||
private XtraReport TryLoadStoredReport(string reportName)
|
||||
{
|
||||
if (Directory.EnumerateFiles(reportDirectory).Select(Path.GetFileNameWithoutExtension).Contains(reportName))
|
||||
|
|
@ -329,6 +384,20 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
|||
parameters.TryAdd("id", pathParameters[0]);
|
||||
}
|
||||
|
||||
private static string GetStorageReportName(string url)
|
||||
{
|
||||
var (reportName, parameters) = ParseReportUrl(url);
|
||||
return GetStoredReportName(reportName, parameters);
|
||||
}
|
||||
|
||||
private static string GetStoredReportName(string reportName, Dictionary<string, string> parameters)
|
||||
{
|
||||
return string.Equals(reportName, nameof(Sozsoft.Reports.PredefinedReports.DynamicReport), StringComparison.OrdinalIgnoreCase) &&
|
||||
HasParameter(parameters, "id")
|
||||
? parameters["id"]
|
||||
: reportName;
|
||||
}
|
||||
|
||||
private static bool IsDynamicGridReport(string reportName)
|
||||
{
|
||||
return string.Equals(reportName, "DynamicGrid", StringComparison.OrdinalIgnoreCase) ||
|
||||
|
|
@ -347,6 +416,14 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
|||
string.Equals(reportName, Sozsoft.Reports.PredefinedReports.DynamicFormReport.ReportName, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static bool IsDynamicReport(string reportName)
|
||||
{
|
||||
return string.Equals(
|
||||
reportName,
|
||||
nameof(Sozsoft.Reports.PredefinedReports.DynamicReport),
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static bool IsReportActionSegment(string value)
|
||||
{
|
||||
return string.Equals(value, "view", StringComparison.OrdinalIgnoreCase) ||
|
||||
|
|
@ -403,9 +480,12 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
|
|||
{
|
||||
// Saves the specified report to the report storage with the specified name
|
||||
// (saves existing reports only).
|
||||
if (!IsWithinReportsFolder(url, reportDirectory))
|
||||
var reportName = GetStorageReportName(url);
|
||||
if (!IsSafeReportFileName(reportName))
|
||||
throw new FaultException(new FaultReason("Invalid report name."), new FaultCode("Server"), "GetData");
|
||||
report.SaveLayoutToXml(Path.Combine(reportDirectory, url + FileExtension));
|
||||
|
||||
Directory.CreateDirectory(reportDirectory);
|
||||
report.SaveLayoutToXml(Path.Combine(reportDirectory, reportName + FileExtension));
|
||||
}
|
||||
|
||||
public override string SetNewData(XtraReport report, string defaultUrl)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import {
|
|||
} from '@/services/admin/list-form.service'
|
||||
import { layoutTypes } from '../admin/listForm/edit/types'
|
||||
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
|
||||
import { useListFormColumns } from './useListFormColumns'
|
||||
import { GridColumnData } from './GridColumnData'
|
||||
import Toolbar, { Item } from 'devextreme-react/toolbar'
|
||||
|
||||
interface ChartProps extends CommonProps, Meta {
|
||||
|
|
@ -39,6 +41,8 @@ interface ChartProps extends CommonProps, Meta {
|
|||
refreshGridDto?: () => Promise<void>
|
||||
}
|
||||
|
||||
type LookupDisplayValues = Record<string, Map<string, string>>
|
||||
|
||||
const Chart = (props: ChartProps) => {
|
||||
// State UserId güncellemesi için
|
||||
const { userName } = useStoreState((s) => s.auth.user)
|
||||
|
|
@ -51,6 +55,12 @@ const Chart = (props: ChartProps) => {
|
|||
const [searchParams] = useSearchParams()
|
||||
const [chartOptions, setChartOptions] = useState<any>()
|
||||
const { createSelectDataSource } = useListFormCustomDataSource({} as any)
|
||||
const { loadLookupDisplayValues } = useListFormColumns({
|
||||
gridDto,
|
||||
listFormCode,
|
||||
isSubForm,
|
||||
})
|
||||
const [lookupDisplayValues, setLookupDisplayValues] = useState<LookupDisplayValues>({})
|
||||
|
||||
const params = useParams()
|
||||
const _listFormCode = props?.listFormCode ?? params?.listFormCode ?? ''
|
||||
|
|
@ -94,6 +104,34 @@ const Chart = (props: ChartProps) => {
|
|||
|
||||
const [allSeries, setAllSeries] = useState<ChartSeriesDto[]>([])
|
||||
|
||||
const lookupColumns = useMemo<GridColumnData[]>(
|
||||
() =>
|
||||
gridDto?.columnFormats
|
||||
.filter((column) => column.fieldName)
|
||||
.map((column) => ({ dataField: column.fieldName, colData: column })) ?? [],
|
||||
[gridDto?.columnFormats],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
let isActive = true
|
||||
|
||||
const loadValues = async () => {
|
||||
try {
|
||||
const values = await loadLookupDisplayValues(lookupColumns)
|
||||
if (isActive) {
|
||||
setLookupDisplayValues(values)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Chart lookup load error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
loadValues()
|
||||
return () => {
|
||||
isActive = false
|
||||
}
|
||||
}, [lookupColumns, loadLookupDisplayValues])
|
||||
|
||||
useEffect(() => {
|
||||
if (gridDto) {
|
||||
const initialSeries = gridDto.gridOptions.seriesDto.map((s, index) => ({ ...s, index }))
|
||||
|
|
@ -134,6 +172,10 @@ const Chart = (props: ChartProps) => {
|
|||
layoutTypes.chart,
|
||||
)
|
||||
|
||||
const argumentLookupValues = currentSeries
|
||||
.map((series) => (series.argumentField ? lookupDisplayValues[series.argumentField] : undefined))
|
||||
.find((values) => values?.size)
|
||||
|
||||
return {
|
||||
dataSource: dataSource,
|
||||
|
||||
|
|
@ -165,7 +207,20 @@ const Chart = (props: ChartProps) => {
|
|||
animation: gridDto.gridOptions.animationDto,
|
||||
export: gridDto.gridOptions.exportDto,
|
||||
crosshair: gridDto.gridOptions.crosshairDto,
|
||||
argumentAxis: gridDto.gridOptions.argumentAxisDto,
|
||||
argumentAxis: {
|
||||
...gridDto.gridOptions.argumentAxisDto,
|
||||
label: {
|
||||
...gridDto.gridOptions.argumentAxisDto?.label,
|
||||
...(argumentLookupValues
|
||||
? {
|
||||
customizeText: (argument: any) => {
|
||||
const value = argument.value ?? argument.valueText
|
||||
return argumentLookupValues.get(String(value)) ?? argument.valueText ?? String(value ?? '')
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
},
|
||||
valueAxis: gridDto.gridOptions.valueAxisDto,
|
||||
tooltip: gridDto.gridOptions.tooltipDto || {
|
||||
enabled: true,
|
||||
|
|
@ -194,6 +249,7 @@ const Chart = (props: ChartProps) => {
|
|||
listFormCode,
|
||||
urlSearchParams,
|
||||
openDrawer,
|
||||
lookupDisplayValues,
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ interface PivotProps {
|
|||
|
||||
const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' // kullanici tanimli gridState ile islem gormus gridin paneline ait renk
|
||||
|
||||
type LookupDisplayValues = Record<string, Map<string, string>>
|
||||
|
||||
const Pivot = (props: PivotProps) => {
|
||||
const { listFormCode, searchParams, isSubForm, level, gridDto } = props
|
||||
const { translate } = useLocalization()
|
||||
|
|
@ -68,6 +70,7 @@ const Pivot = (props: PivotProps) => {
|
|||
|
||||
const [gridDataSource, setGridDataSource] = useState<CustomStore<any, any>>()
|
||||
const [columnData, setColumnData] = useState<GridColumnData[]>()
|
||||
const [lookupDisplayValues, setLookupDisplayValues] = useState<LookupDisplayValues>({})
|
||||
const [showChart, setShowChart] = useState(false)
|
||||
|
||||
// StateStoring için storageKey'i memoize et
|
||||
|
|
@ -82,7 +85,7 @@ const Pivot = (props: PivotProps) => {
|
|||
})
|
||||
|
||||
const { createSelectDataSource } = useListFormCustomDataSource({ gridRef })
|
||||
const { getBandedColumns } = useListFormColumns({
|
||||
const { getBandedColumns, loadLookupDisplayValues } = useListFormColumns({
|
||||
gridDto,
|
||||
listFormCode,
|
||||
isSubForm,
|
||||
|
|
@ -355,6 +358,30 @@ const Pivot = (props: PivotProps) => {
|
|||
}
|
||||
}, [memoizedColumns])
|
||||
|
||||
// PivotGrid, DataGrid'deki lookup ayarını doğrudan desteklemez. Lookup değerlerini
|
||||
// yükleyip sadece görünen metni dönüştürüyoruz; gruplama/filtreleme gerçek value ile devam eder.
|
||||
useEffect(() => {
|
||||
let isActive = true
|
||||
|
||||
const loadValues = async () => {
|
||||
if (!columnData) return
|
||||
|
||||
try {
|
||||
const values = await loadLookupDisplayValues(columnData)
|
||||
if (isActive) {
|
||||
setLookupDisplayValues(values)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Pivot lookup load error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
loadValues()
|
||||
return () => {
|
||||
isActive = false
|
||||
}
|
||||
}, [columnData, loadLookupDisplayValues])
|
||||
|
||||
useEffect(() => {
|
||||
if (memoizedDataSource) {
|
||||
setGridDataSource(memoizedDataSource)
|
||||
|
|
@ -384,6 +411,7 @@ const Pivot = (props: PivotProps) => {
|
|||
|
||||
// Default fields'i hazırla
|
||||
const defaultFields: any = columnData?.map((b) => {
|
||||
const lookupValues = b.dataField ? lookupDisplayValues[b.dataField] : undefined
|
||||
return {
|
||||
dataField: b.dataField,
|
||||
caption: b.caption,
|
||||
|
|
@ -397,6 +425,14 @@ const Pivot = (props: PivotProps) => {
|
|||
wordWrapEnabled: b.colData?.pivotSettingsDto.wordWrapEnabled,
|
||||
visible: true,
|
||||
width: b.width,
|
||||
...(lookupValues
|
||||
? {
|
||||
customizeText: (cellInfo: any) => {
|
||||
const value = cellInfo.value ?? cellInfo.valueText
|
||||
return lookupValues.get(String(value)) ?? cellInfo.valueText ?? String(value ?? '')
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
} as Field
|
||||
})
|
||||
|
||||
|
|
@ -408,7 +444,7 @@ const Pivot = (props: PivotProps) => {
|
|||
}
|
||||
|
||||
instance.option('dataSource', dataSource)
|
||||
}, [columnData, gridDataSource, gridDto])
|
||||
}, [columnData, gridDataSource, gridDto, lookupDisplayValues])
|
||||
|
||||
// Component mount olduğunda state'i bir kez yükle
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -435,6 +435,50 @@ const useListFormColumns = ({
|
|||
[listFormCode],
|
||||
)
|
||||
|
||||
const loadLookupDisplayValues = useCallback(
|
||||
async (columns: GridColumnData[]) => {
|
||||
const entries = await Promise.all(
|
||||
columns
|
||||
.filter(
|
||||
(column) =>
|
||||
column.dataField &&
|
||||
column.colData?.lookupDto?.dataSourceType &&
|
||||
!column.colData.lookupDto.cascadeParentFields,
|
||||
)
|
||||
.map(async (column) => {
|
||||
const lookup = column.colData!.lookupDto
|
||||
const source = lookupDataSource({}, column.colData, listFormCode)
|
||||
const store =
|
||||
source instanceof CustomStore
|
||||
? source
|
||||
: (source as { store?: CustomStore<any, any> } | undefined)?.store
|
||||
const items = ((await store?.load?.()) ?? []) as Record<string, any>[]
|
||||
const values = new Map<string, string>()
|
||||
|
||||
items.forEach((item: Record<string, any>) => {
|
||||
const getValue = (expression?: string) => {
|
||||
const key = Object.keys(item).find(
|
||||
(itemKey) => itemKey.toLowerCase() === expression?.toLowerCase(),
|
||||
)
|
||||
return key ? item[key] : undefined
|
||||
}
|
||||
const value = getValue(lookup.valueExpr)
|
||||
const text = getValue(lookup.displayExpr)
|
||||
|
||||
if (value !== undefined && value !== null && text !== undefined && text !== null) {
|
||||
values.set(String(value), String(text))
|
||||
}
|
||||
})
|
||||
|
||||
return [column.dataField!, values] as const
|
||||
}),
|
||||
)
|
||||
|
||||
return Object.fromEntries(entries) as Record<string, Map<string, string>>
|
||||
},
|
||||
[listFormCode, lookupDataSource],
|
||||
)
|
||||
|
||||
const createLookupStaticDataSource = (
|
||||
load: () => any,
|
||||
filter: any = null,
|
||||
|
|
@ -1036,6 +1080,7 @@ const useListFormColumns = ({
|
|||
|
||||
return {
|
||||
getBandedColumns,
|
||||
loadLookupDisplayValues,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ const ReportDesigner = lazy(() =>
|
|||
|
||||
const VIEWER_THEME_LINK_ID = 'devexpress-report-viewer-theme'
|
||||
const VIEWER_DARK_OVERRIDES_ID = 'devexpress-report-viewer-dark-overrides'
|
||||
const REPORT_DESIGNER_CSS_ID = 'devexpress-report-designer-css'
|
||||
|
||||
const getViewerClassName = (isDarkMode: boolean) =>
|
||||
[
|
||||
|
|
@ -58,6 +59,17 @@ const loadViewerCss = (isDarkMode: boolean) => {
|
|||
if (themeLink.href !== themeHref) {
|
||||
themeLink.href = themeHref
|
||||
}
|
||||
|
||||
if (!document.getElementById(REPORT_DESIGNER_CSS_ID)) {
|
||||
const designerLink = document.createElement('link')
|
||||
designerLink.id = REPORT_DESIGNER_CSS_ID
|
||||
designerLink.rel = 'stylesheet'
|
||||
designerLink.href = new URL(
|
||||
'devexpress-reporting/dist/css/dx-reportdesigner.css',
|
||||
import.meta.url,
|
||||
).href
|
||||
document.head.appendChild(designerLink)
|
||||
}
|
||||
}
|
||||
|
||||
const DevexpressReportDesigner: React.FC = () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue