Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
4cb195e
paginate substation images
nbeatty-gpa May 11, 2026
aa5fb0d
reset to first page on sort
nbeatty-gpa May 19, 2026
72b13f3
reset to first page on sort
nbeatty-gpa May 19, 2026
7db50cf
reset to first page on sort
nbeatty-gpa May 19, 2026
2917ceb
reset to first page on sort
nbeatty-gpa May 19, 2026
013f26e
reset to first page on sort
nbeatty-gpa May 19, 2026
4207bb6
fix styling for paging
nbeatty-gpa May 22, 2026
e9983c8
paginate value list group item
nbeatty-gpa May 26, 2026
e30a42e
page asset ConnectedChannels endpoint
nbeatty-gpa May 27, 2026
2422277
page Asset Channels table
nbeatty-gpa May 27, 2026
8453e9c
paginate tables tab of external db
nbeatty-gpa May 28, 2026
1e4d8d9
Fix error filtering users by additional fields
nbeatty-gpa Jun 5, 2026
78bf4a3
Refactor byUser page from slices to local state with Generic Controller
nbeatty-gpa Jun 5, 2026
98d2aed
clean up byUser
nbeatty-gpa Jun 5, 2026
9c0834f
move ByUserGroup from GenericSlice to GenericController
nbeatty-gpa Jun 5, 2026
e28a75c
paginate GroupUsers
nbeatty-gpa Jun 8, 2026
1abcbb0
paginate ExternalDBTableFields
nbeatty-gpa Jun 8, 2026
9e4ea03
paginate byAssetGroup
nbeatty-gpa Jun 9, 2026
b0e51df
paginate assetGroupSubGroups
nbeatty-gpa Jun 9, 2026
534a01c
paginate assetGroupsAssets
nbeatty-gpa Jun 9, 2026
ccbc3cb
paginate assetGroupMeters
nbeatty-gpa Jun 9, 2026
7fc845f
paginate assetSubstations
nbeatty-gpa Jun 9, 2026
c9928a3
paginate assetMeters
nbeatty-gpa Jun 9, 2026
d8a6a19
paginate assetConnections
nbeatty-gpa Jun 9, 2026
a9bb8c9
paginate customerMeter
nbeatty-gpa Jun 9, 2026
284296d
paginate customerAsset
nbeatty-gpa Jun 9, 2026
16efba6
paginate MeterTrendChannel
nbeatty-gpa Jun 9, 2026
3510b5b
remove accidental comment
nbeatty-gpa Jun 9, 2026
f972665
paginate meterChannelScaling table
nbeatty-gpa Jun 9, 2026
adebab9
paginate meterEventChannels
nbeatty-gpa Jun 10, 2026
c31c0ba
Paginate remoteXDA assets
nbeatty-gpa Jun 10, 2026
79cd2c6
Paginate remoteXDA meters
nbeatty-gpa Jun 10, 2026
b901aeb
simplify settings sort
nbeatty-gpa Jun 10, 2026
c7a91f3
clean up user and userGroup
nbeatty-gpa Jun 10, 2026
4366021
fix generic controller typing
nbeatty-gpa Jun 10, 2026
2333778
fix dependency array
nbeatty-gpa Jun 10, 2026
e8af806
use stricter typing in EventChannelSlice
nbeatty-gpa Jun 10, 2026
1b62794
changes to store typing
nbeatty-gpa Jun 10, 2026
c72b93a
cleanup import
nbeatty-gpa Jun 10, 2026
5cce880
fix typing
nbeatty-gpa Jun 10, 2026
141d177
refresh on changed
nbeatty-gpa Jun 10, 2026
667f8d7
fix broken Additional Field selector in ExternalDBTable
nbeatty-gpa Jun 11, 2026
a8a1a84
fix decimal page
nbeatty-gpa Jun 15, 2026
053dcaf
fix grammar mistakes in ExternalDBUpdate
nbeatty-gpa Jun 15, 2026
162c498
do not error out completely on uncompleted search
nbeatty-gpa Jun 15, 2026
cfaf3e3
fix utf-A typo
nbeatty-gpa Jun 19, 2026
88063d6
remove companySlice from merged store
nbeatty-gpa Jun 19, 2026
084f8d6
abort correct handle
nbeatty-gpa Jun 19, 2026
dd889d5
return empty PagedResults if no images found for substation
nbeatty-gpa Jun 19, 2026
e7344ba
include 'loading' status during paged search
nbeatty-gpa Jun 19, 2026
6ae84e4
filter customer assets on customer ID
nbeatty-gpa Jun 19, 2026
1db3547
add filters to value list
nbeatty-gpa Jun 19, 2026
f209485
fix effect cleanup logic
nbeatty-gpa Jun 22, 2026
c9e499c
check OrderBy values
nbeatty-gpa Jun 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,14 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Transactions;
using System.Reflection;
using System.Web.Http;
using GSF.Data;
using GSF.Data.Model;
using GSF.Web.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using openXDA.Model;
using SystemCenter.Model;

namespace SystemCenter.Controllers.OpenXDA
{
Expand Down Expand Up @@ -105,6 +104,78 @@ GROUP BY
return Unauthorized();
}

[HttpPost, Route("{assetGroupID:int}/Assets/{page:int}")]
public IHttpActionResult GetAssetsPaged([FromBody] PostData postData, [FromUri] int assetGroupID, [FromUri] int page)
{

if (!GetAuthCheck())
return Unauthorized();

int recordsPerPage = Take ?? 50;

PagedResults results = new PagedResults();
results.RecordsPerPage = recordsPerPage;

string orderBy = "ID";

if (typeof(Asset).GetProperties().Select(prop => prop.Name).Contains(postData.OrderBy) || postData.OrderBy == "AssetType")
{
orderBy = postData.OrderBy;
}

using (AdoDataConnection connection = new AdoDataConnection(Connection))
{
string sql = $@"SELECT
DISTINCT
Asset.ID,
AssetAssetGroup.AssetGroupID,
Asset.AssetKey,
Asset.AssetName,
Asset.VoltageKV,
AssetType.Name as AssetType,
COUNT(DISTINCT Meter.ID) as Meters,
COUNT(DISTINCT Location.ID) as Locations
FROM
Asset Join
AssetType ON Asset.AssetTypeID = AssetType.ID LEFT JOIN
MeterAsset ON MeterAsset.AssetID = Asset.ID LEFT JOIN
Meter ON MeterAsset.MeterID = Meter.ID LEFT JOIN
AssetLocation ON AssetLocation.AssetID = Asset.ID LEFT JOIN
Location ON AssetLocation.LocationID = Location.ID LEFT JOIN
AssetAssetGroup ON Asset.ID = AssetAssetGroup.AssetID
GROUP BY
Asset.ID,
Asset.AssetKey,
Asset.AssetName,
Asset.VoltageKV,
AssetType.Name,
AssetAssetGroup.AssetGroupID
HAVING AssetAssetGroup.AssetGroupID = {{0}}
ORDER BY {orderBy} {(postData.Ascending ? "ASC" : "DESC")}
";
Comment thread
nbeatty-gpa marked this conversation as resolved.

DataTable records = connection.RetrieveData(sql, assetGroupID);

int totalRecords = records.Rows.Count;

DataRow[] rows = records.AsEnumerable()
.Skip((page) * recordsPerPage)
.Take(recordsPerPage)
.ToArray();

DataTable pagedTable = records.Clone();

foreach (DataRow row in rows)
pagedTable.ImportRow(row);

results.TotalRecords = totalRecords;
results.NumberOfPages = (totalRecords + recordsPerPage - 1) / recordsPerPage;
results.Data = JsonConvert.SerializeObject(pagedTable);
}

return Ok(results);
}

[HttpPost, Route("{assetGroupID:int}/AddAssets")]
public IHttpActionResult AddAssets(int assetGroupID, [FromBody] IEnumerable<int> assets)
{
Expand Down Expand Up @@ -205,6 +276,73 @@ GROUP BY
return Unauthorized();
}

[HttpPost, Route("{assetGroupID:int}/Meters/{page:int}")]
public IHttpActionResult GetMetersPaged([FromBody] PostData postData, [FromUri] int assetGroupID, [FromUri] int page)
{
if (!GetAuthCheck())
return Unauthorized();

int recordsPerPage = Take ?? 50;

PagedResults results = new PagedResults();
results.RecordsPerPage = recordsPerPage;

string orderBy = "ID";

if (typeof(Meter).GetProperties().Select(prop => prop.Name).Contains(postData.OrderBy))
orderBy = postData.OrderBy;

using (AdoDataConnection connection = new AdoDataConnection(Connection))
{
string sql = $@"SELECT DISTINCT
Meter.ID,
MeterAssetGroup.AssetGroupID,
Meter.AssetKey,
Meter.Name,
Meter.Make,
Meter.Model,
Location.Name as Location,
COUNT(DISTINCT MeterAsset.AssetID) as MappedAssets
FROM
Meter LEFT JOIN
Location ON Meter.LocationID = Location.ID LEFT JOIN
MeterAsset ON Meter.ID = MeterAsset.MeterID LEFT JOIN
Asset ON MeterAsset.AssetID = Asset.ID LEFT JOIN
MeterAssetGroup ON Meter.ID = MeterAssetGroup.MeterID
GROUP BY
Meter.ID,
Meter.AssetKey,
Meter.Name,
Meter.Make,
Meter.Model,
Location.Name,
MeterAssetGroup.AssetGroupID
HAVING MeterAssetGroup.AssetGroupID = {{0}}
ORDER BY {orderBy} {(postData.Ascending ? "ASC" : "DESC")}
";
Comment thread
nbeatty-gpa marked this conversation as resolved.

DataTable records = connection.RetrieveData(sql, assetGroupID);

int totalRecords = records.Rows.Count;

DataRow[] rows = records.AsEnumerable()
.Skip((page) * recordsPerPage)
.Take(recordsPerPage)
.ToArray();

DataTable pagedTable = records.Clone();

foreach (DataRow row in rows)
pagedTable.ImportRow(row);

results.TotalRecords = totalRecords;
results.NumberOfPages = (totalRecords + recordsPerPage - 1) / recordsPerPage;
results.Data = JsonConvert.SerializeObject(pagedTable);
}

return Ok(results);
}

[HttpPost, Route("{assetGroupID:int}/AddMeters")]
public IHttpActionResult AddMeters(int assetGroupID, [FromBody] IEnumerable<int> meters)
{
Expand Down Expand Up @@ -293,7 +431,6 @@ public IHttpActionResult GetSubGroups(int assetGroupID)
try
{
IEnumerable<AssetGroupView> records = new TableOperations<AssetGroupView>(connection).QueryRecordsWhere("ID in (SELECT ChildAssetGroupID FROM AssetGroupAssetGroupView WHERE ParentAssetGroupID = {0})", assetGroupID);

return Ok(records);
}
catch (Exception ex)
Expand All @@ -306,6 +443,33 @@ public IHttpActionResult GetSubGroups(int assetGroupID)
return Unauthorized();
}

[HttpPost, Route("{assetGroupID:int}/AssetGroups/{page:int}")]
public IHttpActionResult GetSubGroupsPaged([FromBody] PostData postData, [FromUri] int assetGroupID, [FromUri] int page)
{
if (!GetAuthCheck())
return Unauthorized();

int recordsPerPage = Take ?? 50;

PagedResults results = new PagedResults();
results.RecordsPerPage = recordsPerPage;

using (AdoDataConnection connection = new AdoDataConnection(Connection))
{
IEnumerable<AssetGroupView> records = new TableOperations<AssetGroupView>(connection).QueryRecordsWhere("ID in (SELECT ChildAssetGroupID FROM AssetGroupAssetGroupView WHERE ParentAssetGroupID = {0})", assetGroupID);
if (postData.Ascending)
records = records.OrderBy(record => record.GetType().GetProperty(postData.OrderBy).GetValue(record) ?? record.ID);
else
records = records.OrderByDescending(record => record.GetType().GetProperty(postData.OrderBy).GetValue(record) ?? record.ID);

results.TotalRecords = records.Count();
results.NumberOfPages = (records.Count() + recordsPerPage - 1) / recordsPerPage;
results.Data = JsonConvert.SerializeObject(records.Skip(page * recordsPerPage).Take(recordsPerPage));
}

return Ok(results);
}

[HttpPost, Route("{assetGroupID:int}/AddAssetGroups")]
public IHttpActionResult AddSubgroups(int assetGroupID, [FromBody] IEnumerable<int> subGroups)
{
Expand Down
Loading