DynamicForm Url değişiklikleri ve Rapor Aç

This commit is contained in:
Sedat Öztürk 2026-06-17 00:19:14 +03:00
parent fdf48c04ee
commit 1997a8aacb
13 changed files with 313 additions and 93 deletions

View file

@ -1398,6 +1398,18 @@
"en": "Menu Management",
"tr": "Menü Yönetimi"
},
{
"resourceName": "Platform",
"key": "App.Reports.List",
"en": "List Report",
"tr": "Liste Raporu"
},
{
"resourceName": "Platform",
"key": "App.Reports.Form",
"en": "Form Report",
"tr": "Form Raporu"
},
{
"resourceName": "Platform",
"key": "App.Reports",

View file

@ -1584,7 +1584,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
Text ="App.Platform.View",
UrlTarget="_blank",
AuthName = listFormName,
Url=$"/admin/reports/DynamicReport/view?id=@Id",
Url=$"/admin/reports/DynamicReport/view/@Id",
IsVisible = true,
VisibleExpression = "((e)=> e.row.data.CategoryId === 'Raporlar')"
},
@ -1593,7 +1593,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
Text ="App.Platform.Design",
UrlTarget="_blank",
AuthName = listFormName + ".Update",
Url=$"/admin/reports/DynamicReport/design?id=@Id",
Url=$"/admin/reports/DynamicReport/design/@Id",
IsVisible = true,
VisibleExpression = "((e)=> e.row.data.CategoryId === 'Raporlar')"
},
@ -1602,7 +1602,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
Text ="App.Platform.View",
UrlTarget="_blank",
AuthName = listFormName,
Url=$"/admin/reports/DynamicGrid/view?listFormCode=@Name",
Url=$"/admin/reports/DynamicGrid/view/@Name",
IsVisible = true,
VisibleExpression = "((e)=> e.row.data.CategoryId === 'Listeler')"
},
@ -1611,7 +1611,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
Text ="App.Platform.View",
UrlTarget="_blank",
AuthName = listFormName,
Url=$"/admin/reports/DynamicGrid/view?listFormCode=@Name&id=@Id",
Url=$"/admin/reports/DynamicGrid/view/@Id/@Name",
IsVisible = true,
VisibleExpression = "((e)=> e.row.data.CategoryId === 'Formlar')"
},

View file

@ -418,7 +418,7 @@
},
{
"key": "admin.devexpressDynamicReportView",
"path": "/admin/reports/:id/view",
"path": "/admin/reports/:report/view/:id?/:listFormCode?",
"componentType": "normal",
"componentPath": "@/views/report/DevexpressReportViewer",
"routeType": "protected",
@ -426,7 +426,7 @@
},
{
"key": "admin.devexpressDynamicReportDesigner",
"path": "/admin/reports/:id/design",
"path": "/admin/reports/:report/design/:id?/:listFormCode?",
"componentType": "normal",
"componentPath": "@/views/report/DevexpressReportDesigner",
"routeType": "protected",

View file

@ -1383,21 +1383,21 @@
"name": "Standard Taahhütname",
"description": "Standard Taahhütname",
"categoryName": "Raporlar",
"htmlContent": "<h1>Taahhütname</h1><p>http://localhost:3000/admin/reports/DynamicReport/view?id=ede12de7-0e94-4b84-a953-6c359606478b</p>",
"htmlContent": "<h1>Taahhütname</h1><p>http://localhost:3000/admin/reports/DynamicReport/view/ede12de7-0e94-4b84-a953-6c359606478b</p>",
"status": "active"
},
{
"name": "App.Languages.LanguageText",
"description": "Liste Raporları",
"categoryName": "Listeler",
"htmlContent": "<h1>Liste Raporları.</h1><p>http://localhost:3000/admin/reports/DynamicGridReport/view?listFormCode=App.Languages.LanguageText&filter=[%22CultureName%22,%22=%22,%22en%22]</p>",
"htmlContent": "<h1>Liste Raporları.</h1><p>http://localhost:3000/admin/reports/DynamicGridReport/view/App.Languages.LanguageText?filter=[%22CultureName%22,%22=%22,%22en%22]</p>",
"status": "active"
},
{
"name": "App.Languages.Language",
"description": "Form Raporları",
"categoryName": "Formlar",
"htmlContent": "<h1>Liste Raporları.</h1><p>http://localhost:3000/admin/reports/DynamicFormReport/view?listFormCode=App.Languages.Language&id=e2c8a2e0-af22-f7bb-5d88-3a21e3079997</p>",
"htmlContent": "<h1>Liste Raporları.</h1><p>http://localhost:3000/admin/reports/DynamicFormReport/view/e2c8a2e0-af22-f7bb-5d88-3a21e3079997/App.Languages.Language</p>",
"status": "active"
}
],

View file

@ -28,6 +28,7 @@ public class DynamicFormReport : XtraReport
private const string QueryName = "DynamicForm";
private const int HorizontalMargin = 35;
private const float RowHeight = 24;
private static readonly System.Drawing.Color FieldBorderColor = System.Drawing.Color.FromArgb(226, 232, 240);
private static IServiceProvider _serviceProvider;
public static void SetServiceProvider(IServiceProvider serviceProvider)
@ -107,6 +108,7 @@ public class DynamicFormReport : XtraReport
reportFields,
defaultValueHelper);
selectQuery = ApplyQueryParameters(selectQuery, selectQueryManager.SelectQueryParameters);
selectQuery = StripReportPaging(selectQuery);
var row = GetFirstRow(dynamicDataRepository.QueryAsync(selectQuery, connectionString).GetAwaiter().GetResult());
@ -118,12 +120,23 @@ public class DynamicFormReport : XtraReport
private void ConfigurePage()
{
Margins = new System.Drawing.Printing.Margins(HorizontalMargin, HorizontalMargin, 35, 35);
Margins = CreateReportMargins(HorizontalMargin, HorizontalMargin, 35, 35);
PaperKind = DevExpress.Drawing.Printing.DXPaperKind.A4;
Landscape = false;
Font = new DXFont("Arial", 8.25F);
}
#pragma warning disable CA1416
private static System.Drawing.Printing.Margins CreateReportMargins(
int left,
int right,
int top,
int bottom)
{
return new System.Drawing.Printing.Margins(left, right, top, bottom);
}
#pragma warning restore CA1416
private void ConfigureDataSource(string selectQuery, string connectionString, DataSourceTypeEnum dataSourceType)
{
var dataSource = new SqlDataSource(new CustomStringConnectionParameters(ToDevExpressConnectionString(connectionString, dataSourceType)));
@ -195,7 +208,7 @@ public class DynamicFormReport : XtraReport
var rowHeight = GetFieldRowHeight(field);
var labelWidth = pageWidth * 0.28F;
detail.Controls.Add(CreateCaptionLabel(field, localizer, 0, y, labelWidth, rowHeight));
detail.Controls.Add(CreateValueLabel(field, labelWidth, y, pageWidth - labelWidth, rowHeight));
detail.Controls.Add(CreateValueLabel(field, row, labelWidth, y, pageWidth - labelWidth, rowHeight));
y += rowHeight + 3;
}
@ -230,48 +243,75 @@ public class DynamicFormReport : XtraReport
Font = new DXFont("Arial", 8F, DXFontStyle.Bold),
BackColor = System.Drawing.Color.FromArgb(248, 250, 252),
Borders = BorderSide.All,
BorderWidth = 0.5F,
BorderColor = FieldBorderColor,
BorderWidth = 0.25F,
Padding = new PaddingInfo(5, 5, 2, 2),
TextAlignment = TextAlignment.MiddleLeft,
Multiline = true
};
}
private static XRLabel CreateValueLabel(FormReportField field, float x, float y, float width, float height)
private static XRLabel CreateValueLabel(
FormReportField field,
IDictionary<string, object> row,
float x,
float y,
float width,
float height)
{
var label = new XRLabel
{
BoundsF = new System.Drawing.RectangleF(x, y, width, height),
Font = new DXFont("Arial", 8F),
Borders = BorderSide.All,
BorderWidth = 0.5F,
BorderColor = FieldBorderColor,
BorderWidth = 0.25F,
Padding = new PaddingInfo(5, 5, 2, 2),
TextAlignment = ToTextAlignment(field.Field.Alignment, field.Field.SourceDbType),
Multiline = true,
CanGrow = true
};
label.ExpressionBindings.Add(new ExpressionBinding("BeforePrint", "Text", $"[{field.BindingName}]"));
if (IsBooleanEditor(field) || field.StaticLookupValues?.Count > 0)
if (TryGetFormattedValue(field, row, out var text))
{
label.BeforePrint += (_, _) =>
{
var value = Convert.ToString(label.Text, CultureInfo.InvariantCulture);
if (IsBooleanEditor(field) && TryFormatBoolean(value, out var booleanText))
{
label.Text = booleanText;
}
else if (value != null && field.StaticLookupValues?.TryGetValue(value, out var displayText) == true)
{
label.Text = displayText;
}
};
label.Text = text;
}
else
{
label.ExpressionBindings.Add(new ExpressionBinding("BeforePrint", "Text", $"[{field.BindingName}]"));
}
return label;
}
private static bool TryGetFormattedValue(
FormReportField field,
IDictionary<string, object> row,
out string text)
{
text = null;
if (row == null || !TryGetRowValue(row, field.BindingName, out var rawValue))
{
return false;
}
var value = Convert.ToString(rawValue, CultureInfo.InvariantCulture);
if (IsBooleanEditor(field) && TryFormatBoolean(value, out var booleanText))
{
text = booleanText;
return true;
}
if (value != null && field.StaticLookupValues?.TryGetValue(value, out var displayText) == true)
{
text = displayText;
return true;
}
text = value ?? string.Empty;
return true;
}
private static float CalculateDetailHeight(
IReadOnlyList<FormReportField> fields,
ListForm listForm,
@ -546,6 +586,20 @@ public class DynamicFormReport : XtraReport
return sql;
}
private static string StripReportPaging(string sql)
{
if (string.IsNullOrWhiteSpace(sql))
{
return sql;
}
return Regex.Replace(
sql,
@"\s+ORDER\s+BY[\s\S]*?(?:\s+OFFSET\s+\d+\s+ROWS(?:\s+FETCH\s+NEXT\s+\d+\s+ROWS\s+ONLY)?)?\s*$",
string.Empty,
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}
private static string ToSqlLiteral(object value)
{
if (value == null || value == DBNull.Value)
@ -741,7 +795,7 @@ public class DynamicFormReport : XtraReport
var query = lookupQuery.Trim().TrimEnd(';');
return Regex.Replace(
query,
@"\s+ORDER\s+BY\s+[\s\S]*$",
@"(?<![A-Za-z0-9_])ORDER\s+BY\b[\s\S]*$",
string.Empty,
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}

View file

@ -28,6 +28,7 @@ public class DynamicGridReport : XtraReport
private const int A4PortraitWidth = 827;
private const int HorizontalMargin = 35;
private const int LandscapeColumnThreshold = 5;
private static readonly System.Drawing.Color TableBorderColor = System.Drawing.Color.FromArgb(226, 232, 240);
private static IServiceProvider _serviceProvider;
public static void SetServiceProvider(IServiceProvider serviceProvider)
@ -126,19 +127,21 @@ public class DynamicGridReport : XtraReport
listForm,
reportColumns,
defaultValueHelper);
selectQuery = StripReportPaging(ApplyQueryParameters(selectQuery, selectQueryManager.SelectQueryParameters));
ConfigurePage(reportColumns);
ConfigureDataSource(
ApplyQueryParameters(selectQuery, selectQueryManager.SelectQueryParameters),
selectQuery,
connectionString,
dataSourceType);
BuildLayout(listForm, reportColumns, localizer);
RequestParameters = false;
}
#pragma warning disable CA1416
private void ConfigurePage(IReadOnlyCollection<ReportColumn> visibleFields)
{
Margins = new System.Drawing.Printing.Margins(HorizontalMargin, HorizontalMargin, 35, 35);
Margins = CreateReportMargins(HorizontalMargin, HorizontalMargin, 35, 35);
PaperKind = DevExpress.Drawing.Printing.DXPaperKind.A4;
var portraitContentWidth = A4PortraitWidth - Margins.Left - Margins.Right;
var requestedContentWidth = visibleFields.Sum(x => Math.Max(x.Field.Width ?? 90, 60));
@ -146,6 +149,16 @@ public class DynamicGridReport : XtraReport
Font = new DXFont("Arial", 8.25F);
}
private static System.Drawing.Printing.Margins CreateReportMargins(
int left,
int right,
int top,
int bottom)
{
return new System.Drawing.Printing.Margins(left, right, top, bottom);
}
#pragma warning restore CA1416
private void ConfigureDataSource(string selectQuery, string connectionString, DataSourceTypeEnum dataSourceType)
{
var dataSource = new SqlDataSource(new CustomStringConnectionParameters(ToDevExpressConnectionString(connectionString, dataSourceType)));
@ -195,6 +208,20 @@ public class DynamicGridReport : XtraReport
return sql;
}
private static string StripReportPaging(string sql)
{
if (string.IsNullOrWhiteSpace(sql))
{
return sql;
}
return Regex.Replace(
sql,
@"\s+ORDER\s+BY[\s\S]*?(?:\s+OFFSET\s+\d+\s+ROWS(?:\s+FETCH\s+NEXT\s+\d+\s+ROWS\s+ONLY)?)?\s*$",
string.Empty,
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}
private static string ToSqlLiteral(object value)
{
if (value == null || value == DBNull.Value)
@ -293,7 +320,8 @@ public class DynamicGridReport : XtraReport
{
BoundsF = new System.Drawing.RectangleF(0, 0, width, height),
Borders = BorderSide.All,
BorderWidth = 0.5F
BorderColor = TableBorderColor,
BorderWidth = 0.25F
};
}
@ -353,17 +381,6 @@ public class DynamicGridReport : XtraReport
CanGrow = false
};
cell.ExpressionBindings.Add(new ExpressionBinding("BeforePrint", "Text", $"[{column.BindingName}]"));
if (column.StaticLookupValues?.Count > 0)
{
cell.BeforePrint += (_, _) =>
{
var value = Convert.ToString(cell.Text, CultureInfo.InvariantCulture);
if (value != null && column.StaticLookupValues.TryGetValue(value, out var displayText))
{
cell.Text = displayText;
}
};
}
return cell;
}
@ -455,11 +472,12 @@ public class DynamicGridReport : XtraReport
if (lookup.DataSourceType == UiLookupDataSourceTypeEnum.StaticData)
{
var staticLookupValues = GetStaticLookupValues(lookup, defaultValueHelper);
return new ReportColumn(
field,
bindingName,
staticLookupValues?.Count > 0 ? GetLookupBindingName(field) : bindingName,
lookup,
GetStaticLookupValues(lookup, defaultValueHelper));
staticLookupValues);
}
return new ReportColumn(field, bindingName, null, null);
@ -570,11 +588,15 @@ public class DynamicGridReport : XtraReport
IReadOnlyList<ReportColumn> reportColumns,
DefaultValueHelper defaultValueHelper)
{
var lookupColumns = reportColumns
var queryLookupColumns = reportColumns
.Where(x => x.Lookup != null && IsReportQueryableLookup(x.Lookup))
.ToList();
var staticLookupColumns = reportColumns
.Where(x => x.StaticLookupValues?.Count > 0)
.ToList();
if (lookupColumns.Count == 0 || string.IsNullOrWhiteSpace(selectQuery))
if ((queryLookupColumns.Count == 0 && staticLookupColumns.Count == 0) ||
string.IsNullOrWhiteSpace(selectQuery))
{
return selectQuery;
}
@ -585,7 +607,12 @@ public class DynamicGridReport : XtraReport
var selectParts = new List<string>();
var joinParts = new List<string>();
foreach (var column in lookupColumns)
foreach (var column in staticLookupColumns)
{
selectParts.Add(CreateStaticLookupSelectPart(column, tableAlias));
}
foreach (var column in queryLookupColumns)
{
var lookup = column.Lookup;
var alias = GetLookupAlias(column.Field);
@ -612,6 +639,10 @@ public class DynamicGridReport : XtraReport
{
joinInsertIndex = FindClauseIndex(selectQuery, " ORDER BY ");
}
if (joinParts.Count == 0)
{
return selectQuery;
}
if (joinInsertIndex < 0)
{
return selectQuery + " " + string.Join(' ', joinParts);
@ -620,6 +651,15 @@ public class DynamicGridReport : XtraReport
return selectQuery.Insert(joinInsertIndex, " " + string.Join(' ', joinParts));
}
private static string CreateStaticLookupSelectPart(ReportColumn column, string tableAlias)
{
var sourceField = $"{QuoteSqlIdentifier(tableAlias)}.{QuoteSqlIdentifier(column.Field.FieldName)}";
var cases = column.StaticLookupValues
.Select(item => $"WHEN {ToSqlLiteral(item.Key)} THEN {ToSqlLiteral(item.Value)}");
return $"CASE {sourceField} {string.Join(" ", cases)} ELSE CAST({sourceField} AS VARCHAR(4000)) END AS {QuoteSqlIdentifier(column.BindingName)}";
}
private static int FindClauseIndex(string sql, string clause)
{
return sql.IndexOf(clause, StringComparison.OrdinalIgnoreCase);
@ -630,7 +670,7 @@ public class DynamicGridReport : XtraReport
var query = lookupQuery.Trim().TrimEnd(';');
return Regex.Replace(
query,
@"\s+ORDER\s+BY\s+[\s\S]*$",
@"(?<![A-Za-z0-9_])ORDER\s+BY\b[\s\S]*$",
string.Empty,
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}

View file

@ -69,7 +69,7 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
// Implement your own logic to prohibit URLs that contain spaces or other specific characters.
// Return **true** if no validation is required.
// Query string encoded gelse bile sadece rapor adını kontrol et.
// Query string veya path parametreleri gelse bile sadece rapor adını kontrol et.
var (reportName, _) = ParseReportUrl(url);
return Path.GetFileName(reportName) == reportName;
}
@ -172,9 +172,10 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
return ms.ToArray();
}
}
catch (Exception)
catch (Exception ex)
{
throw new FaultException(new FaultReason("Could not get report data."), new FaultCode("Server"), "GetData");
var message = ex.GetBaseException().Message;
throw new FaultException(new FaultReason($"Could not get report data. {message}"), new FaultCode("Server"), "GetData");
}
throw new FaultException(new FaultReason(string.Format("Could not find report '{0}'.", url)), new FaultCode("Server"), "GetData");
}
@ -182,31 +183,67 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
private static (string ReportName, Dictionary<string, string> Parameters) ParseReportUrl(string url)
{
var decodedUrl = DecodeRepeatedly(url);
var reportName = decodedUrl;
var parameters = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var queryIndex = decodedUrl.IndexOf('?');
if (queryIndex < 0)
var reportPath = queryIndex < 0 ? decodedUrl : decodedUrl[..queryIndex];
if (queryIndex >= 0)
{
return (reportName, parameters);
}
var queryString = decodedUrl[(queryIndex + 1)..];
var paramPairs = queryString.Split('&', StringSplitOptions.RemoveEmptyEntries);
reportName = decodedUrl[..queryIndex];
var queryString = decodedUrl[(queryIndex + 1)..];
var paramPairs = queryString.Split('&', StringSplitOptions.RemoveEmptyEntries);
foreach (var pair in paramPairs)
{
var keyValue = pair.Split('=', 2);
if (keyValue.Length == 2 && !string.IsNullOrWhiteSpace(keyValue[0]))
foreach (var pair in paramPairs)
{
parameters[keyValue[0]] = keyValue[1];
var keyValue = pair.Split('=', 2);
if (keyValue.Length == 2 && !string.IsNullOrWhiteSpace(keyValue[0]))
{
parameters[keyValue[0]] = keyValue[1];
}
}
}
var pathParts = reportPath
.Split('/', StringSplitOptions.RemoveEmptyEntries)
.Select(Uri.UnescapeDataString)
.ToArray();
if (pathParts.Length == 0)
{
return (reportPath, parameters);
}
var reportName = pathParts[0];
if (pathParts.Length >= 3 && IsReportActionSegment(pathParts[1]))
{
AddPathParameters(reportName, pathParts.Skip(2).ToArray(), parameters);
}
return (reportName, parameters);
}
private static void AddPathParameters(string reportName, string[] pathParameters, Dictionary<string, string> parameters)
{
if (pathParameters.Length == 0)
{
return;
}
if (IsDynamicGridReport(reportName) || IsDynamicFormReport(reportName))
{
if (pathParameters.Length == 1)
{
parameters.TryAdd("listFormCode", pathParameters[0]);
return;
}
parameters.TryAdd("id", pathParameters[0]);
parameters.TryAdd("listFormCode", pathParameters[1]);
return;
}
parameters.TryAdd("id", pathParameters[0]);
}
private static bool IsDynamicGridReport(string reportName)
{
return string.Equals(reportName, "DynamicGrid", StringComparison.OrdinalIgnoreCase) ||
@ -219,6 +256,12 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
string.Equals(reportName, Sozsoft.Reports.PredefinedReports.DynamicFormReport.ReportName, StringComparison.OrdinalIgnoreCase);
}
private static bool IsReportActionSegment(string value)
{
return string.Equals(value, "view", StringComparison.OrdinalIgnoreCase) ||
string.Equals(value, "design", StringComparison.OrdinalIgnoreCase);
}
private static bool HasParameter(Dictionary<string, string> parameters, string name)
{
return parameters.TryGetValue(name, out var value) && !string.IsNullOrWhiteSpace(value);

View file

@ -50,8 +50,8 @@ export const ROUTES_ENUM = {
dynamicServicesEdit: '/admin/developerkit/dynamic-services/edit/:id',
},
reports: {
view: '/admin/reports/:id/view',
design: '/admin/reports/:id/design',
view: '/admin/reports/:report/view/:id?/:listFormCode?',
design: '/admin/reports/:report/design/:id?/:listFormCode?',
},
},
admin: {

View file

@ -11,6 +11,7 @@ import {
FaEye,
FaSave,
FaCog,
FaFileAlt,
} from 'react-icons/fa'
import { useNavigate } from 'react-router-dom'
import { GridColumnData } from '../list/GridColumnData'
@ -80,6 +81,13 @@ const FormButtons = (props: {
layout,
})
const openDynamicGridReport = () => {
if (!id) return
const reportUrl = `/admin/reports/DynamicGrid/view/${encodeURIComponent(id)}/${encodeURIComponent(listFormCode)}`
window.open(reportUrl, isPwaMode ? '_self' : '_blank')
}
const handleDelete = async (e: any) => {
//auth check
e.preventDefault()
@ -279,7 +287,17 @@ const FormButtons = (props: {
{...(permissions.c || permissions.u ? {} : { disabled: true })}
></Button>
)}
{checkPermission(gridDto?.gridOptions.permissionDto.c) && !isSubForm && (
{id && !isSubForm && (
<Button
size="sm"
variant="default"
className="dx-button dx-button-mode-contained dx-button-normal"
icon={<FaFileAlt />}
title={translate('::App.Reports.Form')}
onClick={openDynamicGridReport}
></Button>
)}
{checkPermission(gridDto?.gridOptions.permissionDto.u) && !isSubForm && (
<Button
size="sm"
variant="default"

View file

@ -251,11 +251,20 @@ const useFilters = ({
}
const menus = []
const openDynamicGridReport = () => {
const reportUrl = `/admin/reports/DynamicGrid/view/${encodeURIComponent(listFormCode)}`
window.open(reportUrl, isPwaMode ? '_self' : '_blank')
}
// #region Save/Reset grid state and Filters
if (grdOpt.filterRowDto?.allowUserUiFilterSave || grdOpt.stateStoringDto?.enabled) {
//Kullanicinin filtre islemi yapmasina izin verilmis ise filtreleme menu elemanlarini ekle
if (grdOpt?.filterRowDto?.allowUserUiFilterSave) {
menus.push({
text: translate('::App.Reports.List'),
id: 'openDynamicGridReport',
icon: 'doc',
})
menus.push({
text: translate('::ListForms.ListForm.SaveFilter'),
id: 'saveActiveFilter',
@ -410,6 +419,8 @@ const useFilters = ({
setIsImportModalOpen(true)
} else if (itemData.id === 'permissionGrantedUsers') {
setIsPermissionUsersModalOpen(true)
} else if (itemData.id === 'openDynamicGridReport') {
openDynamicGridReport()
}
},
// filtre menüsündeki elemanlar

View file

@ -2,9 +2,10 @@ import React, { lazy, Suspense, useEffect } from 'react'
import { Container } from '@/components/shared'
import { Helmet } from 'react-helmet'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { useParams } from 'react-router-dom'
import { useLocation, useParams } from 'react-router-dom'
import { RequestOptions } from 'devexpress-reporting-react/dx-report-designer'
import { APP_NAME } from '@/constants/app.constant'
import { createReportUrl } from './reportRouteParams'
const ReportDesigner = lazy(() =>
import('devexpress-reporting-react/dx-report-designer')
@ -30,13 +31,19 @@ const loadDesignerCss = () => {
const DevexpressReportDesigner: React.FC = () => {
const { translate } = useLocalization()
const { id } = useParams<{ id: string }>()
const { report, id, listFormCode } = useParams<{
report: string
id: string
listFormCode: string
}>()
const location = useLocation()
const reportUrlWithParams = createReportUrl({ report, id, listFormCode }, location.search, 'design')
useEffect(() => {
loadDesignerCss()
}, [])
if (!id) return null
if (!reportUrlWithParams) return null
return (
<Container>
@ -47,7 +54,7 @@ const DevexpressReportDesigner: React.FC = () => {
/>
<Suspense fallback={<div>Rapor tasarımcısı yükleniyor...</div>}>
<ReportDesigner reportUrl={id}>
<ReportDesigner reportUrl={reportUrlWithParams}>
<RequestOptions
host={`${import.meta.env.VITE_API_URL}/`}
getDesignerModelAction="DXXRD/GetDesignerModel"

View file

@ -10,6 +10,7 @@ import { ajaxSetup } from '@devexpress/analytics-core/analytics-utils-native'
import { APP_NAME } from '@/constants/app.constant'
import { MODE_DARK } from '@/constants/theme.constant'
import { useStoreState } from '@/store'
import { createReportUrl } from './reportRouteParams'
const VIEWER_THEME_LINK_ID = 'devexpress-report-viewer-theme'
const VIEWER_DARK_OVERRIDES_ID = 'devexpress-report-viewer-dark-overrides'
@ -84,17 +85,16 @@ const loadViewerCss = (isDarkMode: boolean) => {
const DevexpressReportViewer: React.FC = () => {
const { translate } = useLocalization()
const { id, listFormCode, recordId } = useParams<{
id: string
const { report, listFormCode, id } = useParams<{
report: string
listFormCode: string
recordId: string
id: string
}>()
const location = useLocation()
const token = useStoreState((state) => state.auth.session.token)
const themeMode = useStoreState((state) => state.theme.mode)
const [isRequestAuthReady, setIsRequestAuthReady] = useState(false)
const isDarkMode = themeMode === MODE_DARK
const formRecordId = recordId ?? (listFormCode ? id : undefined)
useEffect(() => {
loadViewerCss(isDarkMode)
@ -121,22 +121,8 @@ const DevexpressReportViewer: React.FC = () => {
}, [token])
const reportUrlWithParams = useMemo(() => {
const searchParams = new URLSearchParams(location.search)
if (listFormCode) {
searchParams.set('listFormCode', listFormCode)
if (formRecordId) {
searchParams.set('id', formRecordId)
return `DynamicFormReport?${searchParams.toString()}`
}
return `DynamicListFormReport?${searchParams.toString()}`
}
if (!id) return ''
return location.search ? `${id}${location.search}` : id
}, [id, listFormCode, formRecordId, location.search])
return createReportUrl({ report, id, listFormCode }, location.search)
}, [report, id, listFormCode, location.search])
if (!reportUrlWithParams) return null

View file

@ -0,0 +1,49 @@
export type ReportRouteParams = {
report?: string
id?: string
listFormCode?: string
}
const isDynamicGridReport = (report?: string) =>
report === 'DynamicGrid' || report === 'DynamicGridReport'
export const normalizeReportRouteParams = ({
report,
id,
listFormCode,
}: ReportRouteParams) => {
if (isDynamicGridReport(report) && id && !listFormCode) {
return {
report,
id: undefined,
listFormCode: id,
}
}
return {
report,
id,
listFormCode,
}
}
export const createReportUrl = (
params: ReportRouteParams,
search: string,
action = 'view',
) => {
const { report, id, listFormCode } = normalizeReportRouteParams(params)
if (!report) return ''
const searchParams = new URLSearchParams(search)
searchParams.delete('id')
searchParams.delete('listFormCode')
const pathSegments = [report, action]
if (id) pathSegments.push(id)
if (listFormCode) pathSegments.push(listFormCode)
const path = pathSegments.map((segment) => encodeURIComponent(segment)).join('/')
const queryString = searchParams.toString()
return queryString ? `${path}?${queryString}` : path
}