using System.Collections.Generic; using System.Linq; using System.Text; using AyaNova.Biz; using Newtonsoft.Json.Linq; using Microsoft.EntityFrameworkCore; namespace AyaNova.DataList { /// /// DataList object base class /// internal abstract class AyaDataList : IAyaDataList { public AyaDataList() { } public string SQLFrom { get; set; } public List FieldDefinitions { get; set; } public AuthorizationRoles AllowedRoles { get; set; } public AyaType DefaultListObjectType { get; set; } public string DefaultListView { get; set; } //return array of field keys in list view public List GetFieldListFromListView(JArray listViewArray) { // [{key:"COLUMN UNIQUE KEY ID",sort:"-" or "+",filter:{any:true/false,items:[{FILTER OBJECT SEE BELOW}]} }, {key:"second column unique key"},{...etc...}] List ret = new List(); for (int i = 0; i < listViewArray.Count; i++) { var cm = listViewArray[i]; ret.Add(cm["fld"].Value()); } return ret; } public Newtonsoft.Json.Linq.JArray GenerateListColumnsJSONFromListView(JArray listViewArray) { var ListViewFieldKeys = GetFieldListFromListView(listViewArray); var CustomFieldDefinitions = GetCustomFieldDefinitionsForList(); //Generate JSON fragment to return with column definitions StringBuilder sb = new StringBuilder(); sb.Append("["); bool FirstColumnAdded = false; foreach (string s in ListViewFieldKeys) { AyaDataListFieldDefinition o = FieldDefinitions.FirstOrDefault(x => x.FieldKey == s); #if (DEBUG) //Developers little helper if (o == null) { throw new System.ArgumentNullException($"DEV ERROR in AyaDataList::GenerateListColumnsJSONFromListView - field {s} specified in ListView 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 AyObjectType? (linkable / openable) if (o.AyaObjectType != 0) sb.Append($",\"ay\":{(int)o.AyaObjectType}"); //Row ID column? if (o.IsRowId) { sb.Append($",\"rid\":1"); } //Has a Enumtype? if (!string.IsNullOrEmpty(o.EnumType)) sb.Append($",\"et\":\"{AyaNova.Util.StringUtil.TrimTypeName(o.EnumType)}\""); 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 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 ret = new Dictionary(); List typesProcessed = new List(); //custom fields handling foreach (AyaDataListFieldDefinition d in this.FieldDefinitions) { if (d.IsCustomField) { //this relies on the convention I'm using of AyaType name as the first part of all custom fields lT keys, e.g. //WidgetCustom1 -> Widget var ayatypename = d.TKey.Split("Custom")[0]; if (!typesProcessed.Contains(ayatypename)) { //make sure we do each type only once typesProcessed.Add(ayatypename); //fetch it and set it using (var ct = AyaNova.Util.ServiceProviderProvider.DBContext) { var fc = ct.FormCustom.AsNoTracking().SingleOrDefault(x => x.FormKey == ayatypename); #if (DEBUG) if (fc == null) { throw new System.ArgumentNullException($"AyaDataList:GetCustomFieldDefinitionsForList, Custom field object type {ayatypename} has no FormCustom defined"); } #endif //production handling of missing formcustom 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(), t["type"].Value()); } } } } } } /*{[ { "fld": "Notes", "required": true }, { "fld": "WidgetCustom1", "required": false, "type": 1 }, { "fld": "WidgetCustom2", "required": true, "type": 4 }, { "fld": "WidgetCustom3", "required": false, "type": 5 }, { "fld": "WidgetCustom4", "required": false, "type": 6 }, { "fld": "WidgetCustom5", "required": false, "type": 8 }, { "fld": "WidgetCustom6", "required": false, "type": 2 }, { "fld": "WidgetCustom7", "required": false, "type": 3 } ]}*/ return ret; } }//eoc }//eons