This commit is contained in:
210
server/DataList/DataListProcessingBase.cs
Normal file
210
server/DataList/DataListProcessingBase.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Sockeye.Models;
|
||||
using Sockeye.Biz;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Sockeye.DataList
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// DataList object base class
|
||||
/// </summary>
|
||||
internal abstract class DataListProcessingBase : IDataListProcessing
|
||||
{
|
||||
//CoreBizObject add here
|
||||
//well, not here exactly but add a new DATALIST class if it will be displayed as a list anywhere in the UI or reported on
|
||||
public DataListProcessingBase()
|
||||
{
|
||||
/*
|
||||
NOTE: all sql identifiers need to be explicitly identified as understood by postgres
|
||||
|
||||
DefaultColumns = new List<string>() { "XXX", "XXXX", "XXXX", "XXXX", "XXXX", "XXX", "XXXX", "XXXX", "XXXX", "XXXX" };
|
||||
DefaultSortBy = new Dictionary<string, string>() { { "XXXX", "+" }, { "XXXX", "-" } };
|
||||
*/
|
||||
}
|
||||
|
||||
public string SQLFrom { get; set; }
|
||||
public List<DataListFieldDefinition> FieldDefinitions { get; set; }
|
||||
public AuthorizationRoles AllowedRoles { get; set; }
|
||||
public SockType DefaultListAType { get; set; }
|
||||
//public long CurrentUserId { get; set; }
|
||||
//public long CurrentUserTranslationId { get; set; }
|
||||
public List<string> DefaultColumns { get; set; }
|
||||
public Dictionary<string, string> DefaultSortBy { get; set; }
|
||||
|
||||
//set defaults if not provided in listOptions
|
||||
public void SetListOptionDefaultsIfNecessary(Models.DataListProcessingBase listOptions)
|
||||
{
|
||||
//columns, filter and sortby could all be null
|
||||
if (listOptions.Filter == null)
|
||||
listOptions.Filter = new List<DataListFilterOption>();
|
||||
|
||||
if (listOptions.SortBy == null)
|
||||
listOptions.SortBy = new Dictionary<string, string>();
|
||||
|
||||
//Check Columns
|
||||
if (listOptions is DataListTableProcessingOptions)
|
||||
{
|
||||
var dlto = ((DataListTableProcessingOptions)listOptions);
|
||||
if (dlto.Columns == null)
|
||||
dlto.Columns = new List<string>();
|
||||
//if this doesn't work then just ditch this method in favor of local code, it's not really saving much
|
||||
if (dlto.Columns.Count == 0)
|
||||
dlto.Columns = DefaultColumns;
|
||||
}
|
||||
|
||||
//Check SortBy
|
||||
if (listOptions.SortBy.Count == 0)
|
||||
listOptions.SortBy = DefaultSortBy;
|
||||
|
||||
//Check filter
|
||||
if (listOptions.Filter == null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Newtonsoft.Json.Linq.JArray GenerateReturnListColumns(List<string> columns)
|
||||
{
|
||||
var CustomFieldDefinitions = GetCustomFieldDefinitionsForList();
|
||||
|
||||
//Generate JSON fragment to return with column definitions
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append("[");
|
||||
|
||||
bool FirstColumnAdded = false;
|
||||
|
||||
foreach (string s in columns)
|
||||
{
|
||||
DataListFieldDefinition o = FieldDefinitions.FirstOrDefault(z => z.FieldKey == s);
|
||||
#if (DEBUG)
|
||||
//Developers little helper
|
||||
if (o == null)
|
||||
{
|
||||
throw new System.ArgumentNullException($"DEV ERROR in AyaDataList::GenerateReturnListColumns - field {s} specified in columns was NOT found in ObjectFields list");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (o != null)
|
||||
{//Here is where we can vet the field name, if it doesn't exist. For production we'll just ignore those ones
|
||||
|
||||
if (FirstColumnAdded)
|
||||
sb.Append(",");
|
||||
sb.Append("{");
|
||||
//Build required part of column definition
|
||||
if (!o.IsCustomField)
|
||||
sb.Append($"\"cm\":\"{o.TKey}\",\"dt\":{(int)o.UiFieldDataType}");
|
||||
else
|
||||
{
|
||||
//insert specific type for this custom field
|
||||
if (CustomFieldDefinitions.ContainsKey(o.TKey))
|
||||
{
|
||||
var customFieldType = CustomFieldDefinitions[o.TKey];
|
||||
sb.Append($"\"cm\":\"{o.TKey}\",\"dt\":{customFieldType}");
|
||||
}
|
||||
else
|
||||
{
|
||||
//this is normal as there may not be a definition for a Custom field but it's been requested so just treat it like text
|
||||
sb.Append($"\"cm\":\"{o.TKey}\",\"dt\":{(int)UiFieldDataType.Text}");
|
||||
}
|
||||
}
|
||||
|
||||
//Has a AyAType? (linkable / openable)
|
||||
if (o.SockType != 0)
|
||||
sb.Append($",\"sock\":{(int)o.SockType}");
|
||||
|
||||
//Row ID column?
|
||||
if (o.IsRowId)
|
||||
{
|
||||
sb.Append($",\"rid\":1");
|
||||
}
|
||||
|
||||
//Has a Enumtype?
|
||||
if (!string.IsNullOrEmpty(o.EnumType))
|
||||
sb.Append($",\"et\":\"{Sockeye.Util.StringUtil.TrimTypeName(o.EnumType)}\"");
|
||||
|
||||
|
||||
//field key needed for sorting etc
|
||||
sb.Append($",\"fk\":\"{o.FieldKey}\"");
|
||||
|
||||
//Not Sortable?
|
||||
if (!o.IsSortable)
|
||||
sb.Append($",\"ns\":1");
|
||||
|
||||
//Not Filterable?
|
||||
if (!o.IsFilterable)
|
||||
sb.Append($",\"nf\":1");
|
||||
|
||||
//translate required?
|
||||
if (o.Translate)
|
||||
sb.Append($",\"tra\":1");
|
||||
|
||||
|
||||
sb.Append("}");
|
||||
FirstColumnAdded = true;
|
||||
|
||||
}
|
||||
}
|
||||
sb.Append("]");
|
||||
|
||||
return JArray.Parse(sb.ToString());
|
||||
}
|
||||
|
||||
|
||||
//Find and return a dictionary of all custom fields definitions for all types in list
|
||||
//used to build the column array and define specific type defined for custom fields so client datatable
|
||||
//knows how to format it
|
||||
private Dictionary<string, int> GetCustomFieldDefinitionsForList()
|
||||
{
|
||||
//all keys and types can go in the same list since they are unique to each type of list
|
||||
//i.e. both users and widget custom fields can be in the same list
|
||||
Dictionary<string, int> ret = new Dictionary<string, int>();
|
||||
List<string> typesProcessed = new List<string>();
|
||||
//custom fields handling
|
||||
foreach (DataListFieldDefinition d in this.FieldDefinitions)
|
||||
{
|
||||
if (d.IsCustomField)
|
||||
{
|
||||
//this relies on the convention I'm using of SockType name as the first part of all custom fields lT keys, e.g.
|
||||
//WidgetCustom1 -> Widget
|
||||
var aysockTypename = d.TKey.Split("Custom")[0];
|
||||
if (!typesProcessed.Contains(aysockTypename))
|
||||
{
|
||||
//make sure we do each type only once
|
||||
typesProcessed.Add(aysockTypename);
|
||||
//fetch it and set it
|
||||
using (var ct = Sockeye.Util.ServiceProviderProvider.DBContext)
|
||||
{
|
||||
var fc = ct.FormCustom.AsNoTracking().SingleOrDefault(z => z.FormKey == aysockTypename);
|
||||
//normal condition
|
||||
if (fc == null)
|
||||
continue;
|
||||
|
||||
//iterate the fields and add each custom one with a type to the return dictionary
|
||||
var flds = JArray.Parse(fc.Template);
|
||||
foreach (JToken t in flds)
|
||||
{
|
||||
if (t["type"] != null)
|
||||
{
|
||||
ret.Add(t["fld"].Value<string>(), t["type"].Value<int>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}//eoc
|
||||
|
||||
}//eons
|
||||
Reference in New Issue
Block a user