sozsoft-platform/api/src/Sozsoft.Platform.HttpApi.Host/PredefinedReports/DynamicReportGridStateHelper.cs
2026-06-29 17:44:30 +03:00

153 lines
5.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Sozsoft.Platform.Entities;
namespace Sozsoft.Reports.PredefinedReports;
internal static class DynamicReportGridStateHelper
{
public static string GetFilterName(ListForm listForm, string prefix) =>
$"{prefix}-{GetStateStorageKey(listForm)}";
public static List<ListFormField> GetVisibleFields(
IReadOnlyList<ListFormField> availableFields,
string gridStateJson)
{
if (!TryGetColumnStates(gridStateJson, out var statesByField))
{
return availableFields
.Where(x => x.Visible == true)
.ToList();
}
return availableFields
.Where(field => statesByField.TryGetValue(field.FieldName, out var state)
? state.Visible
: field.Visible == true)
.OrderBy(field => statesByField.TryGetValue(field.FieldName, out var state)
? state.VisibleIndex
: int.MaxValue)
.ToList();
}
private static string GetStateStorageKey(ListForm listForm)
{
if (!string.IsNullOrWhiteSpace(listForm.StateStoringJson))
{
try
{
using var document = JsonDocument.Parse(listForm.StateStoringJson);
if (TryGetProperty(document.RootElement, "storageKey", out var storageKey) &&
storageKey.ValueKind == JsonValueKind.String &&
!string.IsNullOrWhiteSpace(storageKey.GetString()))
{
return storageKey.GetString();
}
}
catch (JsonException)
{
// Fall back to the same default value used by GridOptionsDto.
}
}
return $"listFormGridStorage-{listForm.ListFormCode}";
}
private static bool TryGetColumnStates(
string gridStateJson,
out Dictionary<string, GridColumnState> statesByField)
{
statesByField = null;
if (string.IsNullOrWhiteSpace(gridStateJson))
{
return false;
}
try
{
using var document = JsonDocument.Parse(gridStateJson);
if (!TryGetProperty(document.RootElement, "columns", out var columns) ||
columns.ValueKind != JsonValueKind.Array)
{
return false;
}
var states = new List<GridColumnState>();
AddColumnStates(columns, true, states);
statesByField = states
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName))
.GroupBy(x => x.FieldName, StringComparer.OrdinalIgnoreCase)
.ToDictionary(x => x.Key, x => x.First(), StringComparer.OrdinalIgnoreCase);
return statesByField.Count > 0;
}
catch (JsonException)
{
return false;
}
}
private static void AddColumnStates(JsonElement columns, bool parentVisible, ICollection<GridColumnState> states)
{
foreach (var column in columns.EnumerateArray())
{
var visible = parentVisible &&
(!TryGetProperty(column, "visible", out var visibleProperty) ||
visibleProperty.ValueKind != JsonValueKind.False);
var fieldName = GetColumnFieldName(column);
var visibleIndex = TryGetProperty(column, "visibleIndex", out var visibleIndexProperty) &&
visibleIndexProperty.TryGetInt32(out var value)
? value
: states.Count;
if (!string.IsNullOrWhiteSpace(fieldName))
{
states.Add(new GridColumnState(fieldName, visible, visibleIndex));
}
if (TryGetProperty(column, "columns", out var childColumns) &&
childColumns.ValueKind == JsonValueKind.Array)
{
AddColumnStates(childColumns, visible, states);
}
}
}
private static string GetColumnFieldName(JsonElement column)
{
if (TryGetProperty(column, "dataField", out var dataField) &&
dataField.ValueKind == JsonValueKind.String)
{
return dataField.GetString();
}
if (TryGetProperty(column, "name", out var name) &&
name.ValueKind == JsonValueKind.String)
{
return name.GetString();
}
return null;
}
private static bool TryGetProperty(JsonElement element, string name, out JsonElement value)
{
if (element.ValueKind == JsonValueKind.Object)
{
foreach (var property in element.EnumerateObject())
{
if (string.Equals(property.Name, name, StringComparison.OrdinalIgnoreCase))
{
value = property.Value;
return true;
}
}
}
value = default;
return false;
}
private sealed record GridColumnState(string FieldName, bool Visible, int VisibleIndex);
}