diff --git a/devdocs/specs/core-display-format-template-system.txt b/devdocs/specs/core-display-format-template-system.txt index 1bd3211d..bbf69921 100644 --- a/devdocs/specs/core-display-format-template-system.txt +++ b/devdocs/specs/core-display-format-template-system.txt @@ -60,4 +60,14 @@ Back AND front end - REPORTS (FUTURE) Should send the customized templated display name field to the reports as well as all the regular including name fields - This is because users will likely want that for many reports - Kind of a calculated field - - Default templates come with Raven, user can customize further \ No newline at end of file + - Default templates come with Raven, user can customize further + +MOCK TEMPLATE +{ + columns:[ + + ], + mini:[ + + ] +} \ No newline at end of file diff --git a/devdocs/todo.txt b/devdocs/todo.txt index fd517868..67c56e1f 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -20,6 +20,15 @@ REALLY MAKING MORE PROGRESS WHEN CLIENT DEV DRIVES BACKEND DEV, STICK TO THAT!! ----------------------- GRID LISTS TODO NOW: + + - FormAvailableFields rename to ObjectFields + - It was previously used for only custom forms, but it also needs to exist for creating list templates + - Some list templates don't have exact corresponding biz object as they are compound or made up so need for all lists as well + - Need filterable property added so can control what can be filtered + - Need sortable property so can control what can be sorted + - This will now drive both form customization and list filters and possibly other shit in future + - Remove FilterOptions in list objects and use this instead + - Return JSON and internally work with JSON so the list can return dynamic object - https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/ - https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#fast-built-in-json-support diff --git a/server/AyaNova/Controllers/FormCustomController.cs b/server/AyaNova/Controllers/FormCustomController.cs index 19755ae1..a351c050 100644 --- a/server/AyaNova/Controllers/FormCustomController.cs +++ b/server/AyaNova/Controllers/FormCustomController.cs @@ -117,9 +117,9 @@ namespace AyaNova.Api.Controllers if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); - if (FormAvailableFields.IsValidFormKey(formkey)) + if (ObjectFields.IsValidObjectKey(formkey)) { - return Ok(ApiOkResponse.Response(FormAvailableFields.FormFields(formkey), true)); + return Ok(ApiOkResponse.Response(ObjectFields.FormFields(formkey), true)); } else { @@ -173,7 +173,7 @@ namespace AyaNova.Api.Controllers if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); - return Ok(ApiOkResponse.Response(FormAvailableFields.AvailableFormKeys, true)); + return Ok(ApiOkResponse.Response(ObjectFields.AvailableObjectKeys, true)); } diff --git a/server/AyaNova/biz/CustomFieldsValidator.cs b/server/AyaNova/biz/CustomFieldsValidator.cs index 443b41b0..e1ddcc3b 100644 --- a/server/AyaNova/biz/CustomFieldsValidator.cs +++ b/server/AyaNova/biz/CustomFieldsValidator.cs @@ -16,7 +16,7 @@ namespace AyaNova.Biz return; var FormTemplate = JArray.Parse(formCustom.Template); - var ThisFormCustomFieldsList = FormAvailableFields.FormFields(formCustom.FormKey).Where(x => x.Custom == true).Select(x => x.Key).ToList(); + var ThisFormCustomFieldsList = ObjectFields.FormFields(formCustom.FormKey).Where(x => x.Custom == true).Select(x => x.Key).ToList(); //If the customFields string is empty then only validation is if any of the fields are required to be filled in if (!hasCustomData) @@ -52,7 +52,7 @@ namespace AyaNova.Biz { //Translate the LT field key to the actual customFieldData field key - var InternalCustomFieldName = FormAvailableFields.TranslateLTCustomFieldToInternalCustomFieldName(iFldKey); + var InternalCustomFieldName = ObjectFields.TranslateLTCustomFieldToInternalCustomFieldName(iFldKey); //Check if it's set to required var isRequired = CustomFieldIsSetToRequired(FormTemplate, iFldKey); diff --git a/server/AyaNova/biz/FormAvailableFields.cs b/server/AyaNova/biz/FormAvailableFields.cs deleted file mode 100644 index 8149f366..00000000 --- a/server/AyaNova/biz/FormAvailableFields.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.Collections.Generic; - -namespace AyaNova.Biz -{ - //************************************************ - // This contains all the fields that are on customizable forms - //in addition it serves as a source for valid form keys in AvailableFormKeys - // - public static class FormAvailableFields - { - - public const string WIDGET_FORM_KEY = "widget"; - public const string USER_FORM_KEY = "user"; - - - public static List AvailableFormKeys - { - get - { - List l = new List{ - WIDGET_FORM_KEY, USER_FORM_KEY - }; - return l; - } - } - - public static bool IsValidFormKey(string key) - { - return AvailableFormKeys.Contains(key); - } - - public static List FormFields(string key) - { -/* -***************************** WARNING: Be careful here, if a standard field is hideable and also it's DB SCHEMA is set to NON NULLABLE then the CLIENT end needs to set a default -***************************** Otherwise the hidden field can't be set and the object can't be saved EVER -*/ - List l = new List(); - switch (key) - { - case WIDGET_FORM_KEY: - l.Add(new FormField("WidgetName", "Name", false, false));//is not shared localized text key and not hideable as it is in the validation rules for widget - l.Add(new FormField("WidgetSerial", "Serial"));//not in validation rules BUT, is HIDEABLE and is set to NOT NULLABLE in the schema so this field MUST MUST have a default value in client - l.Add(new FormField("WidgetDollarAmount", "DollarAmount")); - l.Add(new FormField("WidgetCount", "Count")); - l.Add(new FormField("WidgetRoles", "Roles"));//not required but must be a valid default - l.Add(new FormField("WidgetStartDate", "StartDate"));//have rule for date precedence but can both be empty so allowing to hide is ok - l.Add(new FormField("WidgetEndDate", "EndDate")); - l.Add(new FormField("WidgetNotes", "Notes")); - l.Add(new FormField("Active", "Active", true, false));//active is not hideable / required - l.Add(new FormField("Tags", "Tags", true)); - l.Add(new FormField("WidgetCustom1", false, true, true)); - l.Add(new FormField("WidgetCustom2", false, true, true)); - l.Add(new FormField("WidgetCustom3", false, true, true)); - l.Add(new FormField("WidgetCustom4", false, true, true)); - l.Add(new FormField("WidgetCustom5", false, true, true)); - l.Add(new FormField("WidgetCustom6", false, true, true)); - l.Add(new FormField("WidgetCustom7", false, true, true)); - l.Add(new FormField("WidgetCustom8", false, true, true)); - l.Add(new FormField("WidgetCustom9", false, true, true)); - l.Add(new FormField("WidgetCustom10", false, true, true)); - l.Add(new FormField("WidgetCustom11", false, true, true)); - l.Add(new FormField("WidgetCustom12", false, true, true)); - l.Add(new FormField("WidgetCustom13", false, true, true)); - l.Add(new FormField("WidgetCustom14", false, true, true)); - l.Add(new FormField("WidgetCustom15", false, true, true)); - l.Add(new FormField("WidgetCustom16", false, true, true)); - break; - - case USER_FORM_KEY: - l.Add(new FormField("Name", true, false));//is not shared localized text key and not hideable as it is in the validation rules for widget - l.Add(new FormField("EmployeeNumber")); - l.Add(new FormField("Roles", false, false)); - l.Add(new FormField("UserNotes", "Notes")); - l.Add(new FormField("UserType", false, false)); - l.Add(new FormField("Active", true, false)); - l.Add(new FormField("Tags", true, false)); - l.Add(new FormField("UserCustom1", false, true, true)); - l.Add(new FormField("UserCustom2", false, true, true)); - l.Add(new FormField("UserCustom3", false, true, true)); - l.Add(new FormField("UserCustom4", false, true, true)); - l.Add(new FormField("UserCustom5", false, true, true)); - l.Add(new FormField("UserCustom6", false, true, true)); - l.Add(new FormField("UserCustom7", false, true, true)); - l.Add(new FormField("UserCustom8", false, true, true)); - l.Add(new FormField("UserCustom9", false, true, true)); - l.Add(new FormField("UserCustom10", false, true, true)); - l.Add(new FormField("UserCustom11", false, true, true)); - l.Add(new FormField("UserCustom12", false, true, true)); - l.Add(new FormField("UserCustom13", false, true, true)); - l.Add(new FormField("UserCustom14", false, true, true)); - l.Add(new FormField("UserCustom15", false, true, true)); - l.Add(new FormField("UserCustom16", false, true, true)); - break; - - - - default: - throw new System.ArgumentOutOfRangeException($"FormAvailableFields: {key} is not a valid form key"); - } - return l; - } - - - public static string TranslateLTCustomFieldToInternalCustomFieldName(string lTCustomFieldName) - { - var i = System.Convert.ToInt32(System.Text.RegularExpressions.Regex.Replace( - lTCustomFieldName, // Our input - "[^0-9]", // Select everything that is not in the range of 0-9 - "" // Replace that with an empty string. - )); - - return $"c{i}"; - } - - - - }//eoc FormAvailableFields - - public class FormField - { - public string Key { get; set; } - public string PropertyName { get; set; } - //NOTE: Not hideable fields don't require a PropertyName value because they are already required and will be validated - public bool Hideable { get; set; } - public bool SharedLTKey { get; set; } - public bool Custom { get; set; } - - - public FormField(string key, string propertyName, bool sharedLTKey = false, bool hideable = true, bool custom = false) - { - Key = key; - Hideable = hideable; - Custom = custom; - SharedLTKey = sharedLTKey; - PropertyName = propertyName;//Only if hideable do they require this as non-hideable ones are automatically validated anyway and this is only required for validation - } - - public FormField(string key, bool sharedLTKey = false, bool hideable = true, bool custom = false) - { - Key = key; - Hideable = hideable; - Custom = custom; - SharedLTKey = sharedLTKey; - PropertyName = null; - - } - } - - -}//ens diff --git a/server/AyaNova/biz/FormCustomBiz.cs b/server/AyaNova/biz/FormCustomBiz.cs index c91adf6a..a2ed3e20 100644 --- a/server/AyaNova/biz/FormCustomBiz.cs +++ b/server/AyaNova/biz/FormCustomBiz.cs @@ -96,7 +96,7 @@ namespace AyaNova.Biz } //If it doesn't exist, vet the form key name is ok by checking with this list - if (!FormAvailableFields.AvailableFormKeys.Contains(formKey)) + if (!ObjectFields.AvailableObjectKeys.Contains(formKey)) { //Nope, whatever it is, it's not valid return null; @@ -165,7 +165,7 @@ namespace AyaNova.Biz AddError(ApiErrorCode.VALIDATION_REQUIRED, "FormKey"); else { - if (!FormAvailableFields.IsValidFormKey(inObj.FormKey)) + if (!ObjectFields.IsValidObjectKey(inObj.FormKey)) { AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "FormKey"); } @@ -192,7 +192,7 @@ namespace AyaNova.Biz if ((!PropertyHasErrors("FormKey") && !string.IsNullOrWhiteSpace(inObj.Template))) { var ValidCustomFieldTypes = CustomFieldType.ValidCustomFieldTypes; - var ValidFormFields = FormAvailableFields.FormFields(inObj.FormKey); + var ValidFormFields = ObjectFields.FormFields(inObj.FormKey); try { //Parse the json, expecting something like this: @@ -206,7 +206,7 @@ namespace AyaNova.Biz for (int i = 0; i < v.Count; i++) { - FormField MasterFormField = null; + ObjectField MasterFormField = null; var formFieldItem = v[i]; if (formFieldItem["fld"] == null) diff --git a/server/AyaNova/biz/ObjectFields.cs b/server/AyaNova/biz/ObjectFields.cs new file mode 100644 index 00000000..8115b0be --- /dev/null +++ b/server/AyaNova/biz/ObjectFields.cs @@ -0,0 +1,159 @@ +using System.Collections.Generic; + +namespace AyaNova.Biz +{ + //************************************************ + // This contains all the fields that are: + // Customizable on forms + // In grid list templates + //In addition it serves as a source for valid form keys in AvailableFormKeys + // + public static class ObjectFields + { + + public const string WIDGET_FORM_KEY = "widget"; + public const string USER_FORM_KEY = "user"; + + + public static List AvailableObjectKeys + { + get + { + List l = new List{ + WIDGET_FORM_KEY, USER_FORM_KEY + }; + return l; + } + } + + public static bool IsValidObjectKey(string key) + { + return AvailableObjectKeys.Contains(key); + } + + public static List FormFields(string key) + { + /* + ***************************** WARNING: Be careful here, if a standard field is hideable and also it's DB SCHEMA is set to NON NULLABLE then the CLIENT end needs to set a default + ***************************** Otherwise the hidden field can't be set and the object can't be saved EVER + */ + List l = new List(); + switch (key) + { + case WIDGET_FORM_KEY: + l.Add(new ObjectField("WidgetName", "Name", false, false));//is not shared localized text key and not hideable as it is in the validation rules for widget + l.Add(new ObjectField("WidgetSerial", "Serial"));//not in validation rules BUT, is HIDEABLE and is set to NOT NULLABLE in the schema so this field MUST MUST have a default value in client + l.Add(new ObjectField("WidgetDollarAmount", "DollarAmount")); + l.Add(new ObjectField("WidgetCount", "Count")); + l.Add(new ObjectField("WidgetRoles", "Roles"));//not required but must be a valid default + l.Add(new ObjectField("WidgetStartDate", "StartDate"));//have rule for date precedence but can both be empty so allowing to hide is ok + l.Add(new ObjectField("WidgetEndDate", "EndDate")); + l.Add(new ObjectField("WidgetNotes", "Notes")); + l.Add(new ObjectField("Active", "Active", true, false));//active is not hideable / required + l.Add(new ObjectField("Tags", "Tags", true)); + l.Add(new ObjectField("WidgetCustom1", false, true, true)); + l.Add(new ObjectField("WidgetCustom2", false, true, true)); + l.Add(new ObjectField("WidgetCustom3", false, true, true)); + l.Add(new ObjectField("WidgetCustom4", false, true, true)); + l.Add(new ObjectField("WidgetCustom5", false, true, true)); + l.Add(new ObjectField("WidgetCustom6", false, true, true)); + l.Add(new ObjectField("WidgetCustom7", false, true, true)); + l.Add(new ObjectField("WidgetCustom8", false, true, true)); + l.Add(new ObjectField("WidgetCustom9", false, true, true)); + l.Add(new ObjectField("WidgetCustom10", false, true, true)); + l.Add(new ObjectField("WidgetCustom11", false, true, true)); + l.Add(new ObjectField("WidgetCustom12", false, true, true)); + l.Add(new ObjectField("WidgetCustom13", false, true, true)); + l.Add(new ObjectField("WidgetCustom14", false, true, true)); + l.Add(new ObjectField("WidgetCustom15", false, true, true)); + l.Add(new ObjectField("WidgetCustom16", false, true, true)); + break; + + case USER_FORM_KEY: + l.Add(new ObjectField("Name", true, false));//is not shared localized text key and not hideable as it is in the validation rules for widget + l.Add(new ObjectField("EmployeeNumber")); + l.Add(new ObjectField("Roles", false, false)); + l.Add(new ObjectField("UserNotes", "Notes")); + l.Add(new ObjectField("UserType", false, false)); + l.Add(new ObjectField("Active", true, false)); + l.Add(new ObjectField("Tags", true, false)); + l.Add(new ObjectField("UserCustom1", false, true, true)); + l.Add(new ObjectField("UserCustom2", false, true, true)); + l.Add(new ObjectField("UserCustom3", false, true, true)); + l.Add(new ObjectField("UserCustom4", false, true, true)); + l.Add(new ObjectField("UserCustom5", false, true, true)); + l.Add(new ObjectField("UserCustom6", false, true, true)); + l.Add(new ObjectField("UserCustom7", false, true, true)); + l.Add(new ObjectField("UserCustom8", false, true, true)); + l.Add(new ObjectField("UserCustom9", false, true, true)); + l.Add(new ObjectField("UserCustom10", false, true, true)); + l.Add(new ObjectField("UserCustom11", false, true, true)); + l.Add(new ObjectField("UserCustom12", false, true, true)); + l.Add(new ObjectField("UserCustom13", false, true, true)); + l.Add(new ObjectField("UserCustom14", false, true, true)); + l.Add(new ObjectField("UserCustom15", false, true, true)); + l.Add(new ObjectField("UserCustom16", false, true, true)); + break; + + + + default: + throw new System.ArgumentOutOfRangeException($"FormAvailableFields: {key} is not a valid form key"); + } + return l; + } + + + public static string TranslateLTCustomFieldToInternalCustomFieldName(string lTCustomFieldName) + { + var i = System.Convert.ToInt32(System.Text.RegularExpressions.Regex.Replace( + lTCustomFieldName, // Our input + "[^0-9]", // Select everything that is not in the range of 0-9 + "" // Replace that with an empty string. + )); + + return $"c{i}"; + } + + + + }//eoc FormAvailableFields + + public class ObjectField + { + public string Key { get; set; } + public string PropertyName { get; set; } + //NOTE: Not hideable fields don't require a PropertyName value because they are already required and will be validated + public bool Hideable { get; set; } + public bool SharedLTKey { get; set; } + public bool Custom { get; set; } + public bool Filterable { get; set; } + public bool Sortable { get; set; } + public bool MiniAvailable { get; set; } + public string DataType { get; set; } + + + public ObjectField() { } + + public ObjectField(string key, string propertyName, bool sharedLTKey = false, bool hideable = true, bool custom = false) + { + Key = key; + Hideable = hideable; + Custom = custom; + SharedLTKey = sharedLTKey; + PropertyName = propertyName;//Only if hideable do they require this as non-hideable ones are automatically validated anyway and this is only required for validation + } + + public ObjectField(string key, bool sharedLTKey = false, bool hideable = true, bool custom = false) + { + Key = key; + Hideable = hideable; + Custom = custom; + SharedLTKey = sharedLTKey; + PropertyName = null; + + } + } + + +}//ens diff --git a/server/AyaNova/biz/RequiredFieldsValidator.cs b/server/AyaNova/biz/RequiredFieldsValidator.cs index 1d8636eb..e81e9b65 100644 --- a/server/AyaNova/biz/RequiredFieldsValidator.cs +++ b/server/AyaNova/biz/RequiredFieldsValidator.cs @@ -18,7 +18,7 @@ namespace AyaNova.Biz //var OuterJson=JObject.Parse(formCustom.Template); var FormTemplate = JArray.Parse(formCustom.Template); // var FormTemplate=(JArray)OuterJson["template"]; - var FormFields = FormAvailableFields.FormFields(formCustom.FormKey); + var FormFields = ObjectFields.FormFields(formCustom.FormKey); // var ThisFormNormalFieldsList = FormFields.Where(x => x.Custom == false).Select(x => x.Key).ToList(); foreach (JObject jo in FormTemplate) @@ -30,7 +30,7 @@ namespace AyaNova.Biz // - e.g.: {template:[{fld:"ltkeyfieldname",hide:"true/false",required:"true/false", type:"bool"},{fld:"ltkeyfieldname",hide:"true/false",required:"true/false", type:"text"]} //get the FormField object - FormField FF = FormFields.Where(x => x.Key == FldLtKey).Single(); + ObjectField FF = FormFields.Where(x => x.Key == FldLtKey).Single(); if (!string.IsNullOrWhiteSpace(FF.PropertyName)) { //Now get the actual property name from the available fields using the lt key diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index 71f054e7..af780f4a 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -531,7 +531,7 @@ namespace AyaNova.Biz AddError(ApiErrorCode.VALIDATION_LENGTH_EXCEEDED, "EmployeeNumber", "255 max"); //Any form customizations to validate? - var FormCustomization = ct.FormCustom.SingleOrDefault(x => x.FormKey == FormAvailableFields.USER_FORM_KEY); + var FormCustomization = ct.FormCustom.SingleOrDefault(x => x.FormKey == ObjectFields.USER_FORM_KEY); if (FormCustomization != null) { //Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required diff --git a/server/AyaNova/biz/WidgetBiz.cs b/server/AyaNova/biz/WidgetBiz.cs index a2750639..b9166b8e 100644 --- a/server/AyaNova/biz/WidgetBiz.cs +++ b/server/AyaNova/biz/WidgetBiz.cs @@ -338,7 +338,7 @@ namespace AyaNova.Biz //BUILD THE RETURN BASED ON TEMPLATE and MINI CONDITIONAL FORMAT - //TODO: Get template + //TODO: Get template (MOCKED FOR NOW UNTIL PROOF OF CONCEPT) //TODO: BUILD THE RETURN LIST OF FIELDS / TYPES AND ORDER FROM TEMPLATE AND MINI CONDITIONAL @@ -495,7 +495,7 @@ namespace AyaNova.Biz } //Any form customizations to validate? - var FormCustomization = ct.FormCustom.SingleOrDefault(x => x.FormKey == FormAvailableFields.WIDGET_FORM_KEY); + var FormCustomization = ct.FormCustom.SingleOrDefault(x => x.FormKey == ObjectFields.WIDGET_FORM_KEY); if (FormCustomization != null) { //Yeppers, do the validation, there are two, the custom fields and the regular fields that might be set to required