This commit is contained in:
2020-02-26 18:46:32 +00:00
parent a5b3444e4b
commit 1a36dad3e9
10 changed files with 70 additions and 73 deletions

View File

@@ -31,10 +31,11 @@ Client
- Each row contains a bunch of row objects
- Each column from the db is converted to an object and is formatted like this:
- {v:[field value],id:42[optional id value if openable]}, {v:[field value],id:42[optional id value if openable]}...etc
- df First column object is ALWAYS the Default "df" object and is not intended for display
- First column contains the same format as a normal column but doesn't display and is intended for the client to know what type and ID of object to open
- This is necessary in cases where they have made selections that preclude knowing what link to open, so if there is no links in the row this is the default for the entire row
- This also saves bandwidth as a list that has no other types can not bother setting the type or id for any other columns
- rid flag: (was df)
- A column with a flag of rid:true means it's the RowId column or IsRowId and must be visible to user at client
- rid is not required because some datalists won't need one to open a record or have a practical row id due to the nature of the data
- for example ones used for REPORTING
- COLUMNS the list comes back as an object with not only the actual columns but also a separate property listing the set of columns in order to be displayed
- Also their data type
@@ -52,10 +53,8 @@ Server
- SERVER SENDS LIST OF COLUMNS
- The server needs to tell the client which columns are coming back with the list and what types etc so the client can just adapt to any template setting
- column list has type of object behind each column if applicable and user has rights to open so client can make hyperlinks
- FIRST column in column list is always the DEFAULT column corresponding to the first "default" column in the data row
- cm value is always "df"
- dt value is always 0 (dt:0)
- AyaType is always the default type to open, if it's nothing there is nothing to open (not likely)
- RID flagged column in column list is always the default RowID column corresponding to the underlying object and ID in the datalist
- rid column must have an id and an object type to be valid rid column
- SERVER SENDS DATA
- Data in a standard format all grid lists json format, not based on set objects (I think I can do that, probably a hybrid object with JSON data)
- Each row has each column as a object comprising of:
@@ -64,7 +63,7 @@ Server
- To save bandwidth abbreviations are used in the column definitions:
- ColumnsJSON=@"""columns"":[ {""cm"":""Widget"",""dt"":""text"",""ay"":"+ AyaType.Widget.ToString()+ "}]";
- cm=column name locale key, dt=AyDataType, ay=AyaType to open on click of that column field (optional, not present if not openable)
- First column in each row is *ALWAYS* the DEFAULT column that corresponds to the df column specified in objectfields with it's sql attributes
- rid flagged column in each row is *ALWAYS* the rowID column specified in objectfields with it's sql attributes
- For example (wide list):
data:{
columns:{[ {cm:"lt_client_name",dt:text,ay:2},{cm:"lt_client_notes",dt:text},{cm:"lt_last_workorder",dt:number,ay:workorder}]}

View File

@@ -79,16 +79,12 @@ Response:
"next": "http://localhost:7575/api/v8/DataList/List?DataListKey=TestWidgetDataList&pageNo=3&pageSize=2",
"last": "http://localhost:7575/api/v8/DataList/List?DataListKey=TestWidgetDataList&pageNo=50&pageSize=2"
},
"columns": [
{
"cm": "df",
"dt": 0,
"ay": 2
},
"columns": [
{
"cm": "WidgetName",
"dt": 4,
"ay": 2
"ay": 2,
"rid":1
},
{
"cm": "WidgetSerial",
@@ -123,7 +119,7 @@ Response:
`Previous` or `next` properties will contain "null" instead of an url on boundaries where there is no record to link to.
`columns` collection is the list of columns returned in the same order as the individual data arrays for each object.
Note that the `df` column is the default column and contains the object type and id to open for that row which guarantees an openable object for the row regardless of which columns are templated to be returned.
Note that the column with the `rid` flag is the default row ID column and contains the object type and id to open for that row which guarantees an openable object for the row regardless of which columns are set to be returned.
### PUT RESPONSE

View File

@@ -19,7 +19,7 @@ namespace AyaNova.DataList
}
public string SQLFrom { get; set; }
public List<AyaDataListFieldDefinition> FieldDefinitions { get; set; }//NOTE: First field after df is used as the title above the narrow grid view so it should be the name of the item to be shown that is most identifiable
public List<AyaDataListFieldDefinition> FieldDefinitions { get; set; }
public AuthorizationRoles AllowedRoles { get; set; }
public AyaType DefaultListObjectType { get; set; }
@@ -50,8 +50,7 @@ namespace AyaNova.DataList
StringBuilder sb = new StringBuilder();
sb.Append("[");
//df First column is always the df column
sb.Append($"{{\"cm\":\"df\",\"dt\":0,\"ay\":{(int)DefaultListObjectType}}}");
foreach (string s in ListViewFieldKeys)
{
@@ -75,6 +74,11 @@ namespace AyaNova.DataList
//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))

View File

@@ -30,6 +30,10 @@ namespace AyaNova.DataList
//CLIENT Use only for display
public string EnumType { get; set; }
//SERVER / CLIENT - used to identify the column that represents the entire row ID and object
//MUST be present in all datalists and displayed at the client
public bool IsRowId { get; set; }
//CLIENT / SERVER - client display and to indicate what object to open , Server for formatting return object
public int AyaObjectType { get; set; }
@@ -41,6 +45,9 @@ namespace AyaNova.DataList
public string SqlValueColumnName { get; set; }
public AyaDataListFieldDefinition()
{
//most common defaults
@@ -48,6 +55,7 @@ namespace AyaNova.DataList
IsCustomField = false;
IsFilterable = true;
IsSortable = true;
IsRowId = false;
//Set openable object type to no type which is the default and means it's not a link to another object
AyaObjectType = (int)AyaType.NoType;

View File

@@ -72,7 +72,7 @@ namespace AyaNova.DataList
qTotalRecordsQuery = $"SELECT COUNT(*) {qFrom} {qWhere}".Replace(" ", " ");
//RETURN OBJECTS
int returnRowColumnCount = ListViewFieldList.Count();// + 1;//Templates don't have the DF column in them but we need it and it's in the query so plus one
int returnRowColumnCount = ListViewFieldList.Count();
List<List<AyaFieldData>> rows = new List<List<AyaFieldData>>();
long totalRecordCount = 0;
@@ -89,28 +89,11 @@ namespace AyaNova.DataList
{
List<AyaFieldData> row = new List<AyaFieldData>(returnRowColumnCount);
//PROCESS THE DF DEFAULT FIRST COLUMN
//first column is always the underlying id value of the default record to open for this row in the client ui
if (!dr.IsDBNull(0))
{
row.Add(new AyaFieldData() { v = dr.GetInt64(0) });
}
else
{
#if (DEBUG)
throw new System.ArgumentNullException($"DEV ERROR in DataListFetcher.cs: fetching df column for {DataListKey} df value is null, expecting long int record value");
#endif
}
//GetOrdinal by name is flakey in npgsql so just going by field definition and ordinal numerically
// int nCurrentColumnPointer = 1;//start at 1
// dr.GetOrdinal();
// dr.GetName();
//INSERT REMAINING FIELDS FROM TEMPLATE INTO THE RETURN ROWS LIST
foreach (string TemplateField in ListViewFieldList)
{
if (TemplateField == "df")
continue;
//get the AyaObjectFieldDefinition
AyaDataListFieldDefinition f = DataList.FieldDefinitions.FirstOrDefault(x => x.FieldKey == TemplateField);
if (f.IsCustomField)
@@ -150,15 +133,14 @@ dr.GetOrdinal("customfields");
{
AyaFieldData AyaField = new AyaFieldData();
AyaField.v = dr.GetValue(SelectBuild.map[f.GetSqlValueColumnName()]);
//nCurrentColumnPointer++;
if (f.SqlIdColumnName != null)//skip over df column id, it's not there
if (f.SqlIdColumnName != null)
{
var ordinal = SelectBuild.map[f.SqlIdColumnName];
if (!await dr.IsDBNullAsync(ordinal))
AyaField.i = dr.GetInt64(ordinal);
//nCurrentColumnPointer++;
}
row.Add(AyaField);
}

View File

@@ -60,9 +60,10 @@ namespace AyaNova.DataList
if (sb.Length == 0)
{
//no sort specified so default it
if (objectFieldsList[0].FieldKey == "df")
AyaDataListFieldDefinition rid = objectFieldsList.FirstOrDefault(x => x.IsRowId == true);
if (rid!=null)
{
return $"ORDER BY {objectFieldsList[0].SqlIdColumnName} DESC";
return $"ORDER BY {rid.SqlIdColumnName} DESC";
}
else
{

View File

@@ -25,22 +25,23 @@ namespace AyaNova.DataList
StringBuilder sb = new StringBuilder();
sb.Append("SELECT ");
//Default ID column for each row (always is aliased as df)
AyaDataListFieldDefinition def = objectFieldsList.FirstOrDefault(x => x.FieldKey == "df");
if (def == null)
{
throw new System.ArgumentNullException("DataListSqlSelectBuilder: objectFieldList is missing the df default field");
}
if (string.IsNullOrEmpty(def.SqlIdColumnName))
{
sb.Append("id");//default when no alternate column is specified
}
else
{
sb.Append(def.SqlIdColumnName);
}
//DEPRECATED
// //Default ID column for each row (always is aliased as df)
// AyaDataListFieldDefinition def = objectFieldsList.FirstOrDefault(x => x.FieldKey == "df");
// if (def == null)
// {
// throw new System.ArgumentNullException("DataListSqlSelectBuilder: objectFieldList is missing the df default field");
// }
// if (string.IsNullOrEmpty(def.SqlIdColumnName))
// {
// sb.Append("id");//default when no alternate column is specified
// }
// else
// {
// sb.Append(def.SqlIdColumnName);
// }
sb.Append(" AS df");
// sb.Append(" AS df");
//keep track of which custom fields columns were added already
//this ensures that if there is more than one set of custom fields like from two different objects in the list
@@ -49,13 +50,15 @@ namespace AyaNova.DataList
//map sql column name to ordinal name
Dictionary<string, int> map = new Dictionary<string, int>();
map.Add("df", 0);
//DEPRECATED map.Add("df", 0);
int nOrdinal = 0;
foreach (string ColumnName in listViewFieldList)
{
//skip the df column, it's already been processed above
if (ColumnName == "df")
continue;
// //skip the df column, it's already been processed above
// if (ColumnName == "df")
// continue;
AyaDataListFieldDefinition o = objectFieldsList.FirstOrDefault(x => x.FieldKey == ColumnName);
#if (DEBUG)
//Developers little helper
@@ -76,7 +79,7 @@ namespace AyaNova.DataList
{ //nope
sb.Append(", ");
sb.Append(CustomFieldSqlColumnName);
map.Add(CustomFieldSqlColumnName, ++nOrdinal);
map.Add(CustomFieldSqlColumnName, nOrdinal++);
}
//if it was already added then can just ignore it
// else
@@ -106,6 +109,7 @@ namespace AyaNova.DataList
map.Add(idColumnName, ++nOrdinal);
}
}
}
}

View File

@@ -42,7 +42,7 @@ namespace AyaNova.DataList
//NOTE: Due to the join, all the sql id and name fields that can conflict with the joined (in this case User) table need to be specified completely
FieldDefinitions = new List<AyaDataListFieldDefinition>();
FieldDefinitions.Add(new AyaDataListFieldDefinition { FieldKey = "df", AyaObjectType = (int)AyaType.User, SqlIdColumnName = "auser.id" });
//DPRECATED FieldDefinitions.Add(new AyaDataListFieldDefinition { FieldKey = "df", AyaObjectType = (int)AyaType.User, SqlIdColumnName = "auser.id" });
FieldDefinitions.Add(new AyaDataListFieldDefinition
{
LtKey = "User",
@@ -50,7 +50,8 @@ namespace AyaNova.DataList
AyaObjectType = (int)AyaType.User,
UiFieldDataType = (int)UiFieldDataType.Text,
SqlIdColumnName = "auser.id",
SqlValueColumnName = "auser.name"
SqlValueColumnName = "auser.name",
IsRowId=true
});
FieldDefinitions.Add(new AyaDataListFieldDefinition

View File

@@ -58,8 +58,8 @@ namespace AyaNova.DataList
//NOTE: Due to the join, all the sql id and name fields that can conflict with the joined (in this case User) table need to be specified completely
FieldDefinitions = new List<AyaDataListFieldDefinition>();
FieldDefinitions.Add(new AyaDataListFieldDefinition { FieldKey = "df", AyaObjectType = (int)AyaType.Widget, SqlIdColumnName = "awidget.id", IsFilterable = false, IsSortable = false, });
//NOTE: First field after df is used as the title above the narrow grid view so it should be the name of the item to be shown that is most identifiable
//DEPRECATED: FieldDefinitions.Add(new AyaDataListFieldDefinition { FieldKey = "df", AyaObjectType = (int)AyaType.Widget, SqlIdColumnName = "awidget.id", IsFilterable = false, IsSortable = false, });
FieldDefinitions.Add(new AyaDataListFieldDefinition
{
LtKey = "WidgetName",
@@ -67,7 +67,8 @@ namespace AyaNova.DataList
AyaObjectType = (int)AyaType.Widget,
UiFieldDataType = (int)UiFieldDataType.Text,
SqlIdColumnName = "awidget.id",
SqlValueColumnName = "awidget.name"
SqlValueColumnName = "awidget.name",
IsRowId = true
});
FieldDefinitions.Add(new AyaDataListFieldDefinition
{

View File

@@ -26,7 +26,7 @@ namespace AyaNova.DataList
dynamic cm = new JObject();
cm.fld = "widgetname";
dlistView.Add(cm);
cm = new JObject();
cm.fld = "username";
dlistView.Add(cm);
@@ -44,7 +44,7 @@ namespace AyaNova.DataList
//NOTE: First field after df is used as the title above the narrow grid view so it should be the name of the item to be shown that is most identifiable
FieldDefinitions = new List<AyaDataListFieldDefinition>();
FieldDefinitions.Add(new AyaDataListFieldDefinition { FieldKey = "df", AyaObjectType = (int)AyaType.Widget, SqlIdColumnName = "awidget.id" });
//DEPRECATED FieldDefinitions.Add(new AyaDataListFieldDefinition { FieldKey = "df", AyaObjectType = (int)AyaType.Widget, SqlIdColumnName = "awidget.id" });
FieldDefinitions.Add(new AyaDataListFieldDefinition
{
FieldKey = "widgetname",
@@ -52,7 +52,8 @@ namespace AyaNova.DataList
UiFieldDataType = (int)UiFieldDataType.Text,
AyaObjectType = (int)AyaType.Widget,
SqlIdColumnName = "awidget.id",
SqlValueColumnName = "awidget.name"
SqlValueColumnName = "awidget.name",
IsRowId = true
});
FieldDefinitions.Add(new AyaDataListFieldDefinition
{