Skip to content

Commit 064679a

Browse files
committed
Model Pagination
1 parent 61dfc9b commit 064679a

File tree

3 files changed

+226
-3
lines changed

3 files changed

+226
-3
lines changed

src/BlackDigital.Report.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<PropertyGroup>
44
<TargetFrameworks>net8.0;net7.0;net6.0;net5.0</TargetFrameworks>
55
<Nullable>enable</Nullable>
6-
<AssemblyVersion>0.5.1</AssemblyVersion>
7-
<FileVersion>0.5.1</FileVersion>
6+
<AssemblyVersion>0.6.0</AssemblyVersion>
7+
<FileVersion>0.6.0</FileVersion>
88
<PackageReadmeFile>README.md</PackageReadmeFile>
99
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
1010
<Version>$(VersionPrefix)0.5.1</Version>
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Threading.Tasks;
6+
7+
namespace BlackDigital.Report.Sources
8+
{
9+
public class ModelPaginationReportSource<T> : ReportSource
10+
where T : class
11+
{
12+
#region "Constructors"
13+
14+
public ModelPaginationReportSource()
15+
{
16+
Take = 5000;
17+
Skip = 0;
18+
19+
Properties = typeof(T).GetProperties();
20+
}
21+
22+
public ModelPaginationReportSource(GetDataPaginationFunc getDataPagination)
23+
: this()
24+
{
25+
GetDataPagination = getDataPagination;
26+
}
27+
28+
public ModelPaginationReportSource(GetDataPaginationFunc getDataPagination, ProgressAction progress)
29+
: this(getDataPagination)
30+
{
31+
Progress = progress;
32+
}
33+
34+
#endregion "Constructors"
35+
36+
#region "Delegates"
37+
38+
public delegate Task<IEnumerable<T>> GetDataPaginationFunc(int skip, int take);
39+
40+
public delegate Task ProgressAction(double progress);
41+
42+
#endregion "Delegates"
43+
44+
#region "Properties"
45+
46+
private uint _rowCount = 0;
47+
48+
public override uint RowCount => _rowCount;
49+
50+
private uint _columnCount = 0;
51+
public override uint ColumnCount => _columnCount;
52+
53+
public int Take { get; set; }
54+
55+
public int Skip { get; set; }
56+
57+
public int? TotalItens { get; set; }
58+
59+
private List<List<object>>? _data = null;
60+
61+
private int _rowPosition = -1;
62+
private int _columnPosition = -1;
63+
private double _progress = 0.0;
64+
65+
66+
protected IEnumerable<PropertyInfo>? Properties;
67+
68+
public GetDataPaginationFunc? GetDataPagination { get; set; }
69+
70+
public ProgressAction? Progress { get; set; }
71+
72+
#endregion "Properties"
73+
74+
#region "ReportSource"
75+
76+
public override bool IsSourceType(Type type, object? value)
77+
{
78+
return value is GetDataPaginationFunc;
79+
}
80+
81+
public override void Load(object data)
82+
{
83+
if (data == null)
84+
throw new NullReferenceException("Data cannot be null");
85+
86+
if (!IsSourceType(data.GetType(), data))
87+
throw new Exception("Invalid data type");
88+
89+
GetDataPagination = (GetDataPaginationFunc)data;
90+
}
91+
92+
private async Task<bool> LoadDataAsync()
93+
{
94+
if (GetDataPagination == null)
95+
throw new NullReferenceException("GetDataPagination cannot be null");
96+
97+
if (_data != null)
98+
{
99+
if (_data.Count < Take)
100+
return false;
101+
102+
GC.SuppressFinalize(_data);
103+
_data = null;
104+
GC.Collect();
105+
}
106+
107+
108+
var data = await GetDataPagination(Skip, Take);
109+
Skip += Take;
110+
111+
if (data == null || !data.Any())
112+
{
113+
_data = null;
114+
return false;
115+
}
116+
117+
_data = new List<List<object>>();
118+
var properties = ReportHelper.GetPropertiesAndAttributes<T>();
119+
120+
foreach (var row in data)
121+
{
122+
var dataRow = new List<object>();
123+
124+
foreach (var property in properties)
125+
{
126+
dataRow.Add(property.Item1?.GetValue(row) ?? string.Empty);
127+
}
128+
129+
_data.Add(dataRow);
130+
}
131+
132+
_rowPosition = 0;
133+
134+
return true;
135+
}
136+
137+
public override async Task<bool> NextRowAsync()
138+
{
139+
_rowPosition++;
140+
141+
if (_data == null || _rowPosition >= _data.Count())
142+
{
143+
var hasData = await LoadDataAsync();
144+
145+
if (!hasData)
146+
return false;
147+
}
148+
149+
if (Progress != null
150+
&& TotalItens != null
151+
&& TotalItens > 0)
152+
{
153+
double percent = (double)_rowCount / (double)TotalItens.Value * 100;
154+
percent = Math.Round(percent, 2);
155+
156+
if ((percent - _progress) > 1)
157+
{
158+
_progress = percent;
159+
await Progress(percent);
160+
}
161+
}
162+
163+
_rowCount++;
164+
_columnPosition = -1;
165+
166+
return true;
167+
}
168+
169+
public override Task<bool> NextColumnAsync()
170+
{
171+
if (_data == null || _rowPosition < 0)
172+
throw new Exception("ReportSource is not loaded");
173+
174+
_columnPosition++;
175+
176+
if (_columnPosition >= (Properties?.Count() ?? 0))
177+
return Task.FromResult(false);
178+
179+
int columnSize = _columnPosition + 1;
180+
181+
if (columnSize > _columnCount)
182+
_columnCount = (uint)columnSize;
183+
184+
return Task.FromResult(true);
185+
}
186+
187+
public override Task<object?> GetValueAsync()
188+
{
189+
if (_data == null)
190+
throw new Exception("ReportSource is not loaded");
191+
192+
if (_rowPosition < 0 || _columnPosition < 0)
193+
throw new Exception("ReportSource is not loaded");
194+
195+
if (_rowPosition >= _data.Count())
196+
throw new Exception("Row position is out of range");
197+
198+
if (_columnPosition >= (Properties?.Count() ?? 0))
199+
throw new Exception("Column position is out of range");
200+
201+
var row = _data.ElementAt(_rowPosition);
202+
var value = row?.ElementAt(_columnPosition) ?? null;
203+
204+
return Task.FromResult(value);
205+
}
206+
207+
public override Task ResetAsync()
208+
{
209+
_data = null;
210+
_rowPosition = -1;
211+
_columnPosition = -1;
212+
_rowCount = 0;
213+
_columnCount = 0;
214+
Skip = 0;
215+
216+
return Task.CompletedTask;
217+
}
218+
219+
#endregion "ReportSource"
220+
}
221+
}

src/Spreadsheet/SpreadsheetConfiguration.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ private void CreateBaseValues()
8383

8484
public ICreaterCellValue GetCreaterCellValue(Type type)
8585
{
86-
if (CreaterValues.ContainsKey(type))
86+
if (CreaterValues != null
87+
&& type != null
88+
&& CreaterValues.ContainsKey(type))
8789
return CreaterValues[type];
8890

8991
return new StringCreaterCellValue(this);

0 commit comments

Comments
 (0)