diff --git a/SaxoniteCoreWebAdmin/Admin/Controllers/RegionController-Ajax.cs b/SaxoniteCoreWebAdmin/Admin/Controllers/RegionController-Ajax.cs index 5706a7a..f7bef73 100644 --- a/SaxoniteCoreWebAdmin/Admin/Controllers/RegionController-Ajax.cs +++ b/SaxoniteCoreWebAdmin/Admin/Controllers/RegionController-Ajax.cs @@ -167,21 +167,27 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); - // Identify item. - SysId regionId = model.RegionId.ToSysId(); - if (!SysId.IsValid(regionId)) - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); - - // Retrieve item. - SaxRegion region = ReferenceMgr.GetRegionById(regionId); - if (region == null) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposableItems = new DisposableCollection()) { - SaLogger.Warn(fn + " Failed to retrieve region for Id: '" + model.RegionId + "'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } - // Construct response. - PopulateRegionResponseData(region, responseData.region); + // Identify item. + SysId regionId = model.RegionId.ToSysId(); + if (!SysId.IsValid(regionId)) + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); + + // Retrieve item. + SaxRegion region = ReferenceMgr.GetRegionById(regionId); + disposableItems.Add(region); + if (region == null) + { + SaLogger.Warn(fn + " Failed to retrieve region for Id: '" + model.RegionId + "'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + } + + // Construct response. + PopulateRegionResponseData(region, responseData.region); + } // Complete response. responseData.Success = true; @@ -204,56 +210,65 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); - // Validate item properties. - model.ValidateRegionData(responseData); - if (responseData.HasControlErrors()) - return Json(responseData); - - // Retrieve existing item. - SysId regionId = model.RegionId.ToSysId(); - SaxRegion region = ReferenceMgr.GetRegionById(regionId); - if (region == null && SysId.IsValid(regionId)) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposableItems = new DisposableCollection()) { - SaLogger.Warn(fn + " Failed to retrieve region for Id: '" + model.RegionId + "'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } - // Create new item if required. - if (region == null) - region = ReferenceMgr.CreateRegion(); + // Validate item properties. + model.ValidateRegionData(responseData); + if (responseData.HasControlErrors()) + return Json(responseData); - // Populate item properties. - if (model.RegionTypeCode != null) - region.RegionType = model.RegionType; - if (model.RegionCountryIso2Code != null) - region.CountryIso2Code = model.RegionCountryIso2Code; - if (model.RegionName != null) - region.Name = model.RegionName; - if (model.RegionIdParent != null) - region.RegionIdParent = model.RegionIdParent.ToSysId(); - if (model.RegionStatusCode != null) - region.Status = model.RegionStatus; - - // Store item. - if (!SysId.IsValid(region.Id)) - { - if (!ReferenceMgr.InsertRegion(region, DbUpdateInfo)) + // Retrieve existing item. + SysId regionId = model.RegionId.ToSysId(); + SaxRegion region = ReferenceMgr.GetRegionById(regionId); + disposableItems.Add(region); + if (region == null && SysId.IsValid(regionId)) { - SaLogger.Warn(fn + " Failed to insert region: " + ReferenceMgr.ErrorStateMessage); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + ReferenceMgr.ErrorStateMessage)); + SaLogger.Warn(fn + " Failed to retrieve region for Id: '" + model.RegionId + "'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } - } - else - { - if (!ReferenceMgr.UpdateRegion(region, DbUpdateInfo)) - { - SaLogger.Warn(fn + " Failed to update region [Id:" + SysId.ToString(region.Id) + "]: " + ReferenceMgr.ErrorStateMessage); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + ReferenceMgr.ErrorStateMessage)); - } - } - // Construct response. - PopulateRegionResponseData(region, responseData.region); + // Create new item if required. + if (region == null) + { + region = ReferenceMgr.CreateRegion(); + disposableItems.Add(region); + } + + // Populate item properties. + if (model.RegionTypeCode != null) + region.RegionType = model.RegionType; + if (model.RegionCountryIso2Code != null) + region.CountryIso2Code = model.RegionCountryIso2Code; + if (model.RegionName != null) + region.Name = model.RegionName; + if (model.RegionIdParent != null) + region.RegionIdParent = model.RegionIdParent.ToSysId(); + if (model.RegionStatusCode != null) + region.Status = model.RegionStatus; + + // Store item. + if (!SysId.IsValid(region.Id)) + { + if (!ReferenceMgr.InsertRegion(region, DbUpdateInfo)) + { + SaLogger.Warn(fn + " Failed to insert region: " + ReferenceMgr.ErrorStateMessage); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + ReferenceMgr.ErrorStateMessage)); + } + } + else + { + if (!ReferenceMgr.UpdateRegion(region, DbUpdateInfo)) + { + SaLogger.Warn(fn + " Failed to update region [Id:" + SysId.ToString(region.Id) + "]: " + ReferenceMgr.ErrorStateMessage); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + ReferenceMgr.ErrorStateMessage)); + } + } + + // Construct response. + PopulateRegionResponseData(region, responseData.region); + } // Complete response. responseData.Success = true; diff --git a/SaxoniteCoreWebAdmin/Admin/Controllers/SportController-Ajax.cs b/SaxoniteCoreWebAdmin/Admin/Controllers/SportController-Ajax.cs index 63cdf52..2c2f4fd 100644 --- a/SaxoniteCoreWebAdmin/Admin/Controllers/SportController-Ajax.cs +++ b/SaxoniteCoreWebAdmin/Admin/Controllers/SportController-Ajax.cs @@ -22,24 +22,28 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers private class SportData_List : AjaxResponse_Data.ItemData_Base { public String Name { get; set; } + public String SportIdParent { get; set; } + public String SportNameParent { get; set; } public String SpecialityLabelCode { get; set; } public String SpecialityLabelDesc { get; set; } } private class SportData_Full : SportData_List { } - private void PopulateSportResponseData(SaxSport sport, SportData_List data) + private void PopulateSportResponseData(SaxSport sport, SaxSport parentSport, SportData_List data) { data.Id = SysId.ToString(sport.Id); + data.SportNameParent = parentSport?.Name ?? null; + data.SportIdParent = parentSport?.Id.ToString() ?? null; data.Name = sport.Name; data.SpecialityLabelCode = SportSpecialityLabelCodes.GetCodeForType(sport.SpecialityLabel); data.SpecialityLabelDesc = SportSpecialityLabelCodes.GetDescForType(sport.SpecialityLabel); data.StatusCode = sport.StatusCode; data.StatusDesc = sport.StatusDesc; } - private void PopulateSportResponseData(SaxSport sport, SportData_Full data) + private void PopulateSportResponseData(SaxSport sport, SaxSport parentSport, SportData_Full data) { - PopulateSportResponseData(sport, data as SportData_List); + PopulateSportResponseData(sport, parentSport, data as SportData_List); } //------------------------------------------------------------------- @@ -82,14 +86,15 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers // Item columns. ColumnDfn colId = ReferenceMgr.GetSportColumnDfn(SaxSport.Column.Id); + ColumnDfn colParentId = ReferenceMgr.GetSportColumnDfn(SaxSport.Column.SportIdParent); + ColumnDfn colParentName = ReferenceMgr.GetSportColumnDfn(SaxSport.Column.ParentSport_Name); ColumnDfn colName = ReferenceMgr.GetSportColumnDfn(SaxSport.Column.Name); ColumnDfn colSpecialityLabel = ReferenceMgr.GetSportColumnDfn(SaxSport.Column.SpecialityLabel); ColumnDfn colStatus = ReferenceMgr.GetSportColumnDfn(SaxSport.Column.Status); List columns = new List() { - colId, - colName, colSpecialityLabel, - colStatus + colId, colParentId, colParentName, + colName, colSpecialityLabel, colStatus }; // Sort order. @@ -105,6 +110,8 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers SportData_List sportData = new SportData_List() { Id = values.GetString(colId.DataName), + SportIdParent = values.GetString(colParentId.DataName), + SportNameParent = values.GetString(colParentName.DataName), Name = values.GetString(colName.DataName), SpecialityLabelCode = SportSpecialityLabelCodes.GetCodeForType(specialityLabel), SpecialityLabelDesc = SportSpecialityLabelCodes.GetDescForType(specialityLabel), @@ -146,21 +153,31 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); - // Identify item. - SysId sportId = model.SportId.ToSysId(); - if (!SysId.IsValid(sportId)) - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); - - // Retrieve item. - SaxSport sport = ReferenceMgr.GetSportById(sportId); - if (sport == null) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposableItems = new DisposableCollection()) { - SaLogger.Warn(fn + " Failed to retrieve sport for Id: '" + model.SportId + "'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } - // Construct response. - PopulateSportResponseData(sport, responseData.sport); + // Identify item. + SysId sportId = model.SportId.ToSysId(); + if (!SysId.IsValid(sportId)) + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); + + // Retrieve item. + SaxSport sport = ReferenceMgr.GetSportById(sportId); + disposableItems.Add(sport); + if (sport == null) + { + SaLogger.Warn(fn + " Failed to retrieve sport for Id: '" + model.SportId + "'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + } + + // Parent sport. + SaxSport parentSport = ReferenceMgr.GetSportById(sport.SportIdParent); + disposableItems.Add(parentSport); + + // Construct response. + PopulateSportResponseData(sport, parentSport, responseData.sport); + } // Complete response. responseData.Success = true; @@ -183,52 +200,67 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); - // Validate item properties. - model.ValidateSportData(responseData); - if (responseData.HasControlErrors()) - return Json(responseData); - - // Retrieve existing item. - SysId sportId = model.SportId.ToSysId(); - SaxSport sport = ReferenceMgr.GetSportById(sportId); - if (sport == null && SysId.IsValid(sportId)) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposableItems = new DisposableCollection()) { - SaLogger.Warn(fn + " Failed to retrieve sport for Id: '" + model.SportId + "'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } - // Create new item if required. - if (sport == null) - sport = ReferenceMgr.CreateSport(); + // Validate item properties. + model.ValidateSportData(responseData); + if (responseData.HasControlErrors()) + return Json(responseData); - // Populate item properties. - if (model.SportName != null) - sport.Name = model.SportName; - if (model.SportSpecialityLabelCode != null) - sport.SpecialityLabel = model.SportSpecialityLabel; - if (model.SportStatusCode != null) - sport.Status = model.SportStatus; - - // Store item. - if (!SysId.IsValid(sport.Id)) - { - if (!ReferenceMgr.InsertSport(sport, DbUpdateInfo)) + // Retrieve existing item. + SysId sportId = model.SportId.ToSysId(); + SaxSport sport = ReferenceMgr.GetSportById(sportId); + disposableItems.Add(sport); + if (sport == null && SysId.IsValid(sportId)) { - SaLogger.Warn(fn + " Failed to insert sport: " + ReferenceMgr.ErrorStateMessage); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + ReferenceMgr.ErrorStateMessage)); + SaLogger.Warn(fn + " Failed to retrieve sport for Id: '" + model.SportId + "'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } - } - else - { - if (!ReferenceMgr.UpdateSport(sport, DbUpdateInfo)) - { - SaLogger.Warn(fn + " Failed to update sport [Id:" + SysId.ToString(sport.Id) + "]: " + ReferenceMgr.ErrorStateMessage); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + ReferenceMgr.ErrorStateMessage)); - } - } - // Construct response. - PopulateSportResponseData(sport, responseData.sport); + // Create new item if required. + if (sport == null) + { + sport = ReferenceMgr.CreateSport(); + disposableItems.Add(sport); + } + + // Populate item properties. + if (model.SportIdParent != null) + sport.SportIdParent = model.SportIdParent.ToSysId(); + if (model.SportName != null) + sport.Name = model.SportName; + if (model.SportSpecialityLabelCode != null) + sport.SpecialityLabel = model.SportSpecialityLabel; + if (model.SportStatusCode != null) + sport.Status = model.SportStatus; + + // Store item. + if (!SysId.IsValid(sport.Id)) + { + if (!ReferenceMgr.InsertSport(sport, DbUpdateInfo)) + { + SaLogger.Warn(fn + " Failed to insert sport: " + ReferenceMgr.ErrorStateMessage); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + ReferenceMgr.ErrorStateMessage)); + } + } + else + { + if (!ReferenceMgr.UpdateSport(sport, DbUpdateInfo)) + { + SaLogger.Warn(fn + " Failed to update sport [Id:" + SysId.ToString(sport.Id) + "]: " + ReferenceMgr.ErrorStateMessage); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + ReferenceMgr.ErrorStateMessage)); + } + } + + // Parent sport. + SaxSport parentSport = ReferenceMgr.GetSportById(sport.SportIdParent); + disposableItems.Add(parentSport); + + // Construct response. + PopulateSportResponseData(sport, parentSport, responseData.sport); + } // Complete response. responseData.Success = true; diff --git a/SaxoniteCoreWebAdmin/Admin/Controllers/UsersOnlineController.cs b/SaxoniteCoreWebAdmin/Admin/Controllers/UsersOnlineController.cs index a204ff1..70d6657 100644 --- a/SaxoniteCoreWebAdmin/Admin/Controllers/UsersOnlineController.cs +++ b/SaxoniteCoreWebAdmin/Admin/Controllers/UsersOnlineController.cs @@ -34,7 +34,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers // Paging. Model_UsersOnline model = new Model_UsersOnline(Localiser); model.Paging.PageNo = 1; - model.Paging.PageLength = 24; + model.Paging.PageLength = 12; return View(model); } diff --git a/SaxoniteCoreWebAdmin/Admin/Models/Model_Organisation.cs b/SaxoniteCoreWebAdmin/Admin/Models/Model_Organisation.cs index 041f274..7337d5e 100644 --- a/SaxoniteCoreWebAdmin/Admin/Models/Model_Organisation.cs +++ b/SaxoniteCoreWebAdmin/Admin/Models/Model_Organisation.cs @@ -24,7 +24,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models public Model_Organisation(SaxLocaliser localiser) : base(localiser) { - AdditionalFiles_JS.Add("js/sax-organisation.js"); + AdditionalFiles_JS.Add("js/sax-org.js"); } //------------------------------------------------------------------- diff --git a/SaxoniteCoreWebAdmin/Admin/Models/Model_OrganisationMembers.cs b/SaxoniteCoreWebAdmin/Admin/Models/Model_OrganisationMembers.cs index 26cd850..6f3d369 100644 --- a/SaxoniteCoreWebAdmin/Admin/Models/Model_OrganisationMembers.cs +++ b/SaxoniteCoreWebAdmin/Admin/Models/Model_OrganisationMembers.cs @@ -24,7 +24,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models public Model_OrganisationMembers(SaxLocaliser localiser) : base(localiser) { - AdditionalFiles_JS.Add("js/sax-organisationMembers.js"); + AdditionalFiles_JS.Add("js/sax-org-mbr.js"); } //------------------------------------------------------------------- diff --git a/SaxoniteCoreWebAdmin/Admin/Models/Model_Region.cs b/SaxoniteCoreWebAdmin/Admin/Models/Model_Region.cs index 9b975ec..b15b1f5 100644 --- a/SaxoniteCoreWebAdmin/Admin/Models/Model_Region.cs +++ b/SaxoniteCoreWebAdmin/Admin/Models/Model_Region.cs @@ -23,7 +23,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models public Model_Region(SaxLocaliser localiser) : base(localiser) { - AdditionalFiles_JS.Add("js/sax-region.js"); + AdditionalFiles_JS.Add("js/sax-rgn.js"); } //------------------------------------------------------------------- diff --git a/SaxoniteCoreWebAdmin/Admin/Models/Model_Sport.cs b/SaxoniteCoreWebAdmin/Admin/Models/Model_Sport.cs index 50e9237..497c709 100644 --- a/SaxoniteCoreWebAdmin/Admin/Models/Model_Sport.cs +++ b/SaxoniteCoreWebAdmin/Admin/Models/Model_Sport.cs @@ -58,12 +58,13 @@ namespace Saxonite.Net.Core.Web.Admin.Models SysId sportIdParent = SportIdParent.ToSysId(); if (SportIdParent != null && SysId.IsValid(sportIdParent)) { + String controlName = "SportParent"; SaxSport sport = ReferenceMgr.GetSportById(SportIdParent.ToSysId()); disposableItems.Add(sport); if (sport == null) - responseData.SetControlError(nameof(SportIdParent), Localiser["msg.validation.invalid.value"]); + responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); else if (SysId.IsValid(sport.SportIdParent)) - responseData.SetControlError(nameof(SportIdParent), Localiser["msg.validation.invalid.value"]); + responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); } // Sport name. @@ -81,7 +82,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models SysId sportId = SportId.ToSysId(); if (SysId.IsValid(sportId)) prmSport.IdsExcluded.Add(sportId); - prmSport.NamePartial = SportName; + prmSport.NameFull = SportName; prmSport.StatusCat = SaxSport.StatusCat.Any; if (ReferenceMgr.GetSportCount(prmSport) > 0) responseData.SetControlError(nameof(SportName), Localiser["msg.validation.duplicate.value"]); diff --git a/SaxoniteCoreWebAdmin/Admin/Models/Model_User.cs b/SaxoniteCoreWebAdmin/Admin/Models/Model_User.cs index 064a16e..7e835c6 100644 --- a/SaxoniteCoreWebAdmin/Admin/Models/Model_User.cs +++ b/SaxoniteCoreWebAdmin/Admin/Models/Model_User.cs @@ -26,7 +26,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models public Model_User(SaxLocaliser localiser) : base(localiser) { - AdditionalFiles_JS.Add("js/sax-user.js"); + AdditionalFiles_JS.Add("js/sax-usr.js"); } //------------------------------------------------------------------- diff --git a/SaxoniteCoreWebAdmin/Views/Common/ResultsPaging.cshtml b/SaxoniteCoreWebAdmin/Views/Common/ResultsPaging.cshtml index 88e6589..d80aced 100644 --- a/SaxoniteCoreWebAdmin/Views/Common/ResultsPaging.cshtml +++ b/SaxoniteCoreWebAdmin/Views/Common/ResultsPaging.cshtml @@ -1,7 +1,7 @@ @model SaxModel_Admin @inject SaxLocaliser Localiser - + diff --git a/SaxoniteCoreWebAdmin/Views/Common/SelectCode.cshtml b/SaxoniteCoreWebAdmin/Views/Common/SelectCode.cshtml index 4455b49..bb17642 100644 --- a/SaxoniteCoreWebAdmin/Views/Common/SelectCode.cshtml +++ b/SaxoniteCoreWebAdmin/Views/Common/SelectCode.cshtml @@ -2,7 +2,7 @@ @inject SaxLocaliser Localiser - + diff --git a/SaxoniteCoreWebAdmin/Views/Common/SelectItem.cshtml b/SaxoniteCoreWebAdmin/Views/Common/SelectItem.cshtml index 9d3aa50..e17e99c 100644 --- a/SaxoniteCoreWebAdmin/Views/Common/SelectItem.cshtml +++ b/SaxoniteCoreWebAdmin/Views/Common/SelectItem.cshtml @@ -44,6 +44,6 @@ - + diff --git a/SaxoniteCoreWebAdmin/Views/Common/SelectOrganisation.cshtml b/SaxoniteCoreWebAdmin/Views/Common/SelectOrganisation.cshtml index 1e27ad3..38176a8 100644 --- a/SaxoniteCoreWebAdmin/Views/Common/SelectOrganisation.cshtml +++ b/SaxoniteCoreWebAdmin/Views/Common/SelectOrganisation.cshtml @@ -2,7 +2,7 @@ @inject SaxLocaliser Localiser - + diff --git a/SaxoniteCoreWebAdmin/Views/Organisation/Index.cshtml b/SaxoniteCoreWebAdmin/Views/Organisation/Index.cshtml index 0be0053..05e8aa4 100644 --- a/SaxoniteCoreWebAdmin/Views/Organisation/Index.cshtml +++ b/SaxoniteCoreWebAdmin/Views/Organisation/Index.cshtml @@ -8,6 +8,8 @@
@@ -21,74 +23,88 @@ @* Filter Panel *@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmOrganisationFilter", @class = "sax-form", @onSubmit = "return false;" })) { -
- @* Header - Page caption, paging controls, actions. *@ -
-
-
@Localiser["organisation.caption.organisations"]
-
-
- -
-
-
@(Localiser[
-
@(Localiser[
-
+
+ @* Header - Page caption, paging controls, actions. *@ +
+
+
@Localiser["organisation.caption.organisations"]
+
+
+
-
-
-
- @* Organisation filter - name etc. *@ -
-
@Localiser["label.search"]
-
- @Html.TextBoxFor(model => model.Filter.Organisation, new { @id = "", @class = "FilterOrganisation", @maxlength = "32" }) -
-
- @* Organisation Category *@ -
-
@Localiser["label.category"]
-
- @Html.DropDownListFor(model => model.Filter.OrganisationCategoryCode, Model.AdminOrganisationCategoriesForSelect, Localiser["label.any"], new { @id = "", @class = "FilterOrganisationCategory sax-select" }) -
-
- @* Organisation sport *@ -
-
@Localiser["label.sport"]
-
-
- @Html.HiddenFor(model => model.Filter.OrganisationSportId, new { @id = "", @class = "FilterOrganisationSportId" }) -
-
-
@(Localiser[
-
@(Localiser[
-
-
-
-
- @* Organisation region *@ -
-
@Localiser["label.region"]
-
-
- @Html.HiddenFor(model => model.Filter.OrganisationRegionId, new { @id = "", @class = "FilterOrganisationRegionId" }) -
-
-
@(Localiser[
-
@(Localiser[
-
-
-
-
- @* Organisation Status *@ -
-
@Localiser["label.status"]
-
- @Html.DropDownListFor(model => model.Filter.OrganisationStatusCategoryCode, Model.OrganisationFilterStatusCategoriesForSelect, new { @id = "", @class = "FilterOrganisationStatusCategory sax-select" }) +
+ @* Burger menu *@ +
+
+ @* Organisation filter - name etc. *@ +
+
@Localiser["label.search"]
+
+ @Html.TextBoxFor(model => model.Filter.Organisation, new { @id = "", @class = "FilterOrganisation", @maxlength = "32" }) +
+
+ @* Organisation Category *@ +
+
@Localiser["label.category"]
+
+ @Html.DropDownListFor(model => model.Filter.OrganisationCategoryCode, Model.AdminOrganisationCategoriesForSelect, Localiser["label.any"], new { @id = "", @class = "FilterOrganisationCategory sax-select" }) +
+
+ @* Organisation sport *@ +
+
@Localiser["label.sport"]
+
+
+ @Html.HiddenFor(model => model.Filter.OrganisationSportId, new { @id = "", @class = "FilterOrganisationSportId" }) +
+
+
@(Localiser[
+
@(Localiser[
+
+
+
+
+ @* Organisation region *@ +
+
@Localiser["label.region"]
+
+
+ @Html.HiddenFor(model => model.Filter.OrganisationRegionId, new { @id = "", @class = "FilterOrganisationRegionId" }) +
+
+
@(Localiser[
+
@(Localiser[
+
+
+
+
+ @* Organisation Status *@ +
+
@Localiser["label.status"]
+
+ @Html.DropDownListFor(model => model.Filter.OrganisationStatusCategoryCode, Model.OrganisationFilterStatusCategoriesForSelect, new { @id = "", @class = "FilterOrganisationStatusCategory sax-select" }) +
+
+
+ + @* Filter element templates *@ +
+ @* Burger dropdown item template - ul is ignored *@ +
    +
  • XXX
  • +
+
+ +
}
diff --git a/SaxoniteCoreWebAdmin/Views/Region/Index.cshtml b/SaxoniteCoreWebAdmin/Views/Region/Index.cshtml index 41cde25..0d871d3 100644 --- a/SaxoniteCoreWebAdmin/Views/Region/Index.cshtml +++ b/SaxoniteCoreWebAdmin/Views/Region/Index.cshtml @@ -5,7 +5,7 @@ ViewData["Title"] = "Regions"; } -
+
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmRegionFilter", @class = "sax-form", @onSubmit = "return false;" })) @@ -52,7 +52,7 @@
-
+
diff --git a/SaxoniteCoreWebAdmin/Views/Sport/Index.cshtml b/SaxoniteCoreWebAdmin/Views/Sport/Index.cshtml index 08d076b..0abdc02 100644 --- a/SaxoniteCoreWebAdmin/Views/Sport/Index.cshtml +++ b/SaxoniteCoreWebAdmin/Views/Sport/Index.cshtml @@ -13,12 +13,13 @@ sax.lbl.edit = '@(Localiser.GetJavascriptText("label.edit"))'; - @* Filter Form *@ - @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSportFilter", @class = "sax-form", @onSubmit = "return false;" })) - { + @* Filter Panel *@ +
+ + @* Filter Form *@ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSportFilter", @class = "sax-form", @onSubmit = "return false;" })) + { - @* Filter Panel *@ -
@* Header - Page caption, paging controls, actions. *@
@Localiser["sport.caption.sports"]
@@ -51,9 +52,8 @@
  • XXX
  • - -
    - } + } +
    @* Results Panel *@
    @@ -81,8 +81,8 @@
    -
    @Localiser["label.speciality"]: 
    -
    +
    @Localiser["label.speciality"]: 
    +
    @Localiser["label.parent"]: 
    @@ -101,6 +101,7 @@
    +
    diff --git a/SaxoniteCoreWebAdmin/Views/Sport/Panel-SportDialog.cshtml b/SaxoniteCoreWebAdmin/Views/Sport/Panel-SportDialog.cshtml index 5a50b66..95a7a2c 100644 --- a/SaxoniteCoreWebAdmin/Views/Sport/Panel-SportDialog.cshtml +++ b/SaxoniteCoreWebAdmin/Views/Sport/Panel-SportDialog.cshtml @@ -7,14 +7,20 @@ + +@* Sport Id form. *@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSportId", @class = "sax-form" })) { @Html.HiddenFor(model => model.SportId, new { @class = "SportId" }) } -
    -
    +@* Sport dialog *@ +
    +
    + + @* Sport form *@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSport", @class = "sax-form", @onSubmit = "return false;" })) { @Html.HiddenFor(model => model.SportId, new { @class = "SportId" }) @@ -36,6 +42,26 @@
    + @* Sport Parent *@ +
    +
    +
    +
    + +
    +
    +
    +
    + @Html.HiddenFor(model => model.SportIdParent, new { @id = "ifSportIdParent", @class = "SportIdParent" }) +
    +
    @(Localiser[
    +
    +
    +
    +
    +
    +
    + @* Sport Speciality Label *@
    diff --git a/SaxoniteCoreWebAdmin/Views/System/Database.cshtml b/SaxoniteCoreWebAdmin/Views/System/Database.cshtml index a3e35a9..d4f93b8 100644 --- a/SaxoniteCoreWebAdmin/Views/System/Database.cshtml +++ b/SaxoniteCoreWebAdmin/Views/System/Database.cshtml @@ -60,7 +60,9 @@ @@ -74,14 +76,14 @@ Properties: - +
    Columns: - +
    @@ -93,7 +95,7 @@
    Pos Name
    Indices: - +
    diff --git a/SaxoniteCoreWebAdmin/wwwroot/css/sax-base.css b/SaxoniteCoreWebAdmin/wwwroot/css/sax-base.css index c625286..437b161 100644 --- a/SaxoniteCoreWebAdmin/wwwroot/css/sax-base.css +++ b/SaxoniteCoreWebAdmin/wwwroot/css/sax-base.css @@ -102,6 +102,21 @@ table empty-cells: inherit; } +table.sax-striped +{ + border-spacing: 0 2px; +} + +table.sax-striped tr.sax-odd +{ + background-color:#fff; +} + +table.sax-striped tr.sax-even +{ + background-color:#f8f8f8; +} + th, td { vertical-align: top; diff --git a/SaxoniteCoreWebAdmin/wwwroot/css/sax-data.css b/SaxoniteCoreWebAdmin/wwwroot/css/sax-data.css index d30bc60..8383757 100644 --- a/SaxoniteCoreWebAdmin/wwwroot/css/sax-data.css +++ b/SaxoniteCoreWebAdmin/wwwroot/css/sax-data.css @@ -100,6 +100,105 @@ background-color: #c0c0c0; } +/* Panel header - Burger */ + +.sax-header ul.nav.sax-burger +{ + margin: 0; +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu +{ + padding: 4px 8px 4px 4px; + box-shadow: 0 0 8px 2px #80808080; +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item +{ + margin: 2px 4px 2px 0; + padding: 2px 4px 2px 30px; + background-repeat: no-repeat; + background-position: left center; +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-refresh +{ + background-image: url('../img/action/refresh24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-add +{ + background-image: url('../img/action/add24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-edit +{ + background-image: url('../img/action/edit24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-remove +{ + background-image: url('../img/action/delete24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-experience +{ + background-image: url('../img/action/trophy24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-user +{ + background-image: url('../img/action/user24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-users +{ + background-image: url('../img/action/users24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-mail +{ + background-image: url('../img/action/mail24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-process +{ + background-image: url('../img/action/process24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-close +{ + background-image: url('../img/action/prev24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-itemlock +{ + background-image: url('../img/action/lock24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item.sax-unlock +{ + background-image: url('../img/action/unlock24.png'); +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item:hover +{ + background-color: #f8f8f8; + box-shadow: none; +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item .sax-label +{ + margin: 0; + padding: 0 0 0 4px; +} + +.sax-header ul.nav.sax-burger ul.sax-dropdown-menu li.sax-action.sax-dropdown-item:hover .sax-label +{ + background-color: #f8f8f8; + box-shadow: 0 0 2px 1px #80808080; +} + /* Data Items panel */ .sax-panel-results diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-organisationMembers.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-org-mbr.js similarity index 100% rename from SaxoniteCoreWebAdmin/wwwroot/js/sax-organisationMembers.js rename to SaxoniteCoreWebAdmin/wwwroot/js/sax-org-mbr.js diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-organisation.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-org.js similarity index 88% rename from SaxoniteCoreWebAdmin/wwwroot/js/sax-organisation.js rename to SaxoniteCoreWebAdmin/wwwroot/js/sax-org.js index ef33f60..dbbee90 100644 --- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-organisation.js +++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-org.js @@ -10,7 +10,7 @@ sax.itemIdPrefix = 'Itm_'; //-------------------------------------------------------------- - sax.refreshResults = function (delay) + op.refreshResults = function (delay) { if (!op.awaitingRefreshResponse) { @@ -21,14 +21,6 @@ sax.doAjaxRequest(op.ajax.refreshResults, delay || 50); op.awaitingRefreshResponse = true; } - op.getItemTemplate = function () - { - return $('.sax-panel-item-template .sax-panel-item.Organisation', $pnl.results).clone(); - } - op.getDropdownItemTemplate = function () - { - return $('.sax-panel-item-template .sax-dropdown-menu.Organisation li.sax-dropdown-item', $pnl.results); - } op.doRefreshResults = function (response) { //sax.debug('doRefreshResults', response); @@ -36,12 +28,18 @@ sax.refreshControlValues(response.controlValues); var $msgs = $('.sax-panel-messages', $pnl.results).hide().empty(); var $items = $('.sax-panel-item-list', $pnl.results).hide().empty(); - sax.refreshPaging(response, '#frmOrganisationFilter', sax.refreshResults); + sax.refreshPaging(response, '#frmOrganisationFilter', op.refreshResults); if (!response.success) return; // Reference data - Statuses. if (response.defaultStatusCode) sax.data.defaultStatusCode = response.defaultStatusCode; if (response.statuses) sax.populateSelectCodeDesc('#cbOrganisationStatus', response.statuses); + // Menu. + var $bgr = $('.sax-burger', $pnl.filter).hide(); + var $mnu = $('ul.sax-dropdown-menu', $bgr).empty(); + $mnu.append(op.getFilterMenuOption(sax.lbl.refresh, function () { op.refreshResults(); }, 'sax-refresh')); + $mnu.append(op.getFilterMenuOption(sax.lbl.create, function () { op.createItem(); }, 'sax-add')); + $bgr.toggle(!!$('.sax-dropdown-item', $mnu).length); // Items. var items = response.organisations; if (!items.length) @@ -62,20 +60,46 @@ $('.OrganisationMemberCount', $item).on('click', function () { op.onClickMemberCount(item.id); }).find('.MemberCount').text(item.memberCount); $('.StatusDesc', $item).text(item.statusDesc).addClass('sax-status-' + item.statusCode.toLowerCase()); $('.sax-caption .sax-action').toggleClass('sax-action', !item.deleted); + let $mnu = $('ul.sax-dropdown-menu', $item).empty(); if (!item.deleted) { - let $mnu = $('ul.sax-dropdown-menu', $item); - $mnu.append(op.getDropdownItemTemplate().clone().find('div.sax-label').text(sax.lbl.edit).end().on('click', function () { op.updateItem(item, $item) })); + $mnu.append(op.getItemMenuOption(sax.lbl.edit, function () { op.updateItem(item, $item) }, 'sax-edit')); if (item.awaiting) - $mnu.append(op.getDropdownItemTemplate().clone().find('div.sax-label').text(sax.lbl.activate).end().on('click', function () { op.activateItem(item) })); + $mnu.append(op.getItemMenuOption(sax.lbl.activate, function () { op.activateItem(item) }, 'sax-unlock')); $('.sax-header .sax-action.sax-item-update', $item).off('click').on('click', function () { op.updateItem(item, $item) }); $item.off('dblclick').on('dblclick', function () { op.updateItem(item, $item) }); } - $('.sax-burger', $item).toggle(!!$('.sax-burger .sax-dropdown-menu .sax-dropdown-item', $item).length); + $('.sax-burger', $item).toggle(!!$('.sax-dropdown-item', $mnu).length); $('.sax-panel-messages', $pnl.results).hide().empty(); return $item; } + //-------------------------------------------------------------- + op.getFilterDropdownTemplate = function () + { + return $('.sax-panel-item-template .sax-dropdown-menu.OrganisationFilter li.sax-dropdown-item', $pnl.filter).clone(); + } + op.getItemTemplate = function () + { + return $('.sax-panel-item-template .sax-panel-item.Organisation', $pnl.results).clone(); + } + op.getItemDropdownTemplate = function () + { + return $('.sax-panel-item-template .sax-dropdown-menu.Organisation li.sax-dropdown-item', $pnl.results).clone(); + } + op.getFilterMenuOption = function (lbl, fn, cls) + { + return op.getMenuOption(op.getFilterDropdownTemplate(), lbl, fn, cls); + } + op.getItemMenuOption = function (lbl, fn, cls) + { + return op.getMenuOption(op.getItemDropdownTemplate(), lbl, fn, cls); + } + op.getMenuOption = function ($opt, lbl, fn, cls) + { + return $opt.find('div.sax-label').text(lbl).end().on('click', fn).addClass(cls); + } + //-------------------------------------------------------------- op.selectFilterSport = function () { @@ -92,12 +116,12 @@ let frm = $frm.filter; $('.FilterOrganisationSportId', frm).val(spt.id); $('.FilterOrganisationSportCaption', frm).val(spt.name); - sax.refreshResults(); + op.refreshResults(); } op.clearFilterSport = function () { $('.FilterOrganisationSportId,.FilterOrganisationSportCaption', $frm.filter).val(''); - sax.refreshResults(); + op.refreshResults(); } op.populateSports = function (nextFn) { @@ -151,12 +175,12 @@ let frm = $frm.filter; $('.FilterOrganisationRegionId', frm).val(rgn.id); $('.FilterOrganisationRegionCaption', frm).val(rgn.name); - sax.refreshResults(); + op.refreshResults(); } op.clearFilterRegion = function () { $('.FilterOrganisationRegionId,.FilterOrganisationRegionCaption', $frm.filter).val(''); - sax.refreshResults(); + op.refreshResults(); } op.populateRegions = function (nextFn) { @@ -252,10 +276,10 @@ var $item = $('#' + sax.itemIdPrefix + item.id); if (!$item.length) { - $item = $('.sax-panel-item-template .sax-panel-item.Organisation', $pnl.results).clone(); + $item = op.getItemTemplate(); $('.sax-panel-item-list', $pnl.results).prepend($item).show(); } - $item.replaceWith(op.populateItem(op.getItemTemplate(), item)); + op.populateItem($item, item); } //-------------------------------------------------------------- @@ -331,12 +355,9 @@ $pnl.filter = $('.sax-panel-filter', $pnl.orgs); $pnl.results = $('.sax-panel-results', $pnl.orgs); - $('.sax-action.sax-item-create', $pnl.filter).on('click', function () { op.createItem(); }); - $('.sax-action.sax-results-refresh', $pnl.filter).on('click', function () { sax.refreshResults(); }); - $frm.filter = $('#frmOrganisationFilter'); - $('.FilterOrganisation', $frm.filter).on('input', function () { sax.refreshResults(250); }); - $('.FilterOrganisationCategory,.FilterOrganisationStatusCategory', $frm.filter).on('change', function () { sax.refreshResults(50); }); + $('.FilterOrganisation', $frm.filter).on('input', function () { op.refreshResults(250); }); + $('.FilterOrganisationCategory,.FilterOrganisationStatusCategory', $frm.filter).on('change', function () { op.refreshResults(50); }); $frm.filter.on('dblclick', '.FilterOrganisationSportCaption', op.selectFilterSport).on('click', '.FilterSportSelect', op.selectFilterSport).on('click', '.FilterSportClear', op.clearFilterSport); $frm.filter.on('dblclick', '.FilterOrganisationRegionCaption', op.selectFilterRegion).on('click', '.FilterRegionSelect', op.selectFilterRegion).on('click', '.FilterRegionClear', op.clearFilterRegion); $frm.orgId = $('#frmOrganisationId'); @@ -355,7 +376,7 @@ opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); }; $dlg.activate = $('#dlgOrganisationActivation').dialog(opt); - setTimeout(sax.refreshResults, 250); + setTimeout(op.refreshResults, 250); }); }(window, window.document)); diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-resultsPaging.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-res-pag.js similarity index 100% rename from SaxoniteCoreWebAdmin/wwwroot/js/sax-resultsPaging.js rename to SaxoniteCoreWebAdmin/wwwroot/js/sax-res-pag.js diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-region.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-rgn.js similarity index 98% rename from SaxoniteCoreWebAdmin/wwwroot/js/sax-region.js rename to SaxoniteCoreWebAdmin/wwwroot/js/sax-rgn.js index 14ebdb2..a4c8ba4 100644 --- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-region.js +++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-rgn.js @@ -56,7 +56,7 @@ $('.RegionCountryIso2Code', $item).text(item.countryIso2Code); $('.RegionTypeDesc', $item).text(item.regionTypeDesc); $('.RegionParentName', $item).text(item.parentName); - $('.RegionStatusDesc', $item).text(item.statusDesc); + $('.RegionStatusDesc', $item).text(item.statusDesc).addClass('sax-status-' + item.statusCode.toLowerCase()); $('.sax-caption .sax-action, .sax-actions .sax-action.sax-item-update', $item).off('click').on('click', function () { sax.updateItem(item.id) }) $item.off('dblclick').on('dblclick', function () { sax.updateItem(item.id) }) $('.sax-panel-results .sax-panel-messages').hide().empty(); diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-selectCode.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-sel-cod.js similarity index 100% rename from SaxoniteCoreWebAdmin/wwwroot/js/sax-selectCode.js rename to SaxoniteCoreWebAdmin/wwwroot/js/sax-sel-cod.js diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-selectItem.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-sel-itm.js similarity index 100% rename from SaxoniteCoreWebAdmin/wwwroot/js/sax-selectItem.js rename to SaxoniteCoreWebAdmin/wwwroot/js/sax-sel-itm.js diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-selectOrganisation.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-sel-org.js similarity index 100% rename from SaxoniteCoreWebAdmin/wwwroot/js/sax-selectOrganisation.js rename to SaxoniteCoreWebAdmin/wwwroot/js/sax-sel-org.js diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-sport.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-sport.js index 68c4a7b..31f810f 100644 --- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-sport.js +++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-sport.js @@ -5,30 +5,33 @@ (function (win, doc, undef) { "use strict"; - let $pnl = sax.$pnl, $frm = sax.$frm, $dlg = sax.$dlg; + let sm = sax.sportMgt = { + $pnl: {}, $frm: {}, $dlg: {}, ajax: {}, data: {} + }; + let $pnl = sm.$pnl, $frm = sm.$frm, $dlg = sm.$dlg; sax.itemIdPrefix = 'Itm_'; //-------------------------------------------------------------- - sax.refreshResults = function (delay) + sm.refreshResults = function (delay) { - if (!sax.awaitingRefreshResponse) + if (!sm.awaitingRefreshResponse) { $('.sax-burger', $pnl.filter).hide(); var $items = $('.sax-panel-item-list', $pnl.results).fadeOut(200).empty(); var $msgs = $('.sax-panel-messages', $pnl.results).hide().empty().append($('
    ' + sax.msg.dataQuerying + '
    ')).fadeIn(200); } - sax.ajax.refreshResults = sax.ajax.refreshResults || { url: sax.url.base + 'Sport/Ajax/GetList', formId: 'frmSportFilter', callbackFn: sax.doRefreshResults }; + sax.ajax.refreshResults = sax.ajax.refreshResults || { url: sax.url.base + 'Sport/Ajax/GetList', formId: 'frmSportFilter', callbackFn: sm.doRefreshResults }; sax.doAjaxRequest(sax.ajax.refreshResults, delay || 50); - sax.awaitingRefreshResponse = true; + sm.awaitingRefreshResponse = true; } - sax.doRefreshResults = function (response) + sm.doRefreshResults = function (response) { //sax.debug('doRefreshResults', response); - delete sax.awaitingRefreshResponse; + delete sm.awaitingRefreshResponse; sax.refreshControlValues(response.controlValues); var $msgs = $('.sax-panel-messages', $pnl.results).hide().empty(); var $items = $('.sax-panel-item-list', $pnl.results).hide().empty(); - sax.refreshPaging(response, '#frmSportFilter', sax.refreshResults); + sax.refreshPaging(response, '#frmSportFilter', sm.refreshResults); if (!response.success) return; // Reference data - Statuses. if (response.defaultStatusCode) sax.data.defaultStatusCode = response.defaultStatusCode; @@ -37,32 +40,34 @@ // Menu. var $bgr = $('.sax-burger', $pnl.filter).hide(); var $mnu = $('ul.sax-dropdown-menu', $bgr).empty(); - $mnu.append(sax.getFilterMenuOption(sax.lbl.refresh, function () { sax.refreshResults(); })); - $mnu.append(sax.getFilterMenuOption(sax.lbl.create, function () { sax.createItem(); })); + $mnu.append(sm.getFilterMenuOption(sax.lbl.refresh, function () { sm.refreshResults(); }, 'sax-refresh')); + $mnu.append(sm.getFilterMenuOption(sax.lbl.create, function () { sm.createItem(); }, 'sax-add')); $bgr.toggle(!!$('.sax-dropdown-item', $mnu).length); // Items. var items = response.sports; if (!items.length) return $msgs.append($('
    ' + sax.msg.dataNoneFound + '
    ')).fadeIn(500); for (let itemIdx = 0; itemIdx < items.length; itemIdx++) - $items.append(sax.populateItem(sax.getItemTemplate(), items[itemIdx])); + $items.append(sm.populateItem(sm.getItemTemplate(), items[itemIdx])); $items.fadeIn(50); } - sax.populateItem = function ($item, item) + sm.populateItem = function ($item, item) { if (!item) return; $item.prop('id', sax.itemIdPrefix + item.id); $('.SportName', $item).text(item.name); + $('.SportNameParent', $item).text(item.sportNameParent); + $('.SportParent', $item).toggle(!!item.sportNameParent); $('.SportSpecialityLabel', $item).text(item.specialityLabelDesc); $('.SportSpeciality', $item).toggle(!!item.specialityLabelCode); - $('.StatusDesc', $item).text(item.statusDesc); + $('.StatusDesc', $item).text(item.statusDesc).addClass('sax-status-' + item.statusCode.toLowerCase()); $('.sax-caption .sax-action').toggleClass('sax-action', !item.deleted); - let $mnu = $('ul.sax-dropdown-menu', $item); + let $mnu = $('ul.sax-dropdown-menu', $item).empty(); if (!item.deleted) { - $mnu.append(sax.getItemMenuOption(sax.lbl.edit, function () { sax.updateItem(item) })); - $('.sax-header .sax-action.sax-item-update', $item).off('click').on('click', function () { sax.updateItem(item) }); - $item.off('dblclick').on('dblclick', function () { sax.updateItem(item) }); + $mnu.append(sm.getItemMenuOption(sax.lbl.edit, function () { sm.updateItem(item) }, 'sax-edit')); + $('.sax-header .sax-action.sax-item-update', $item).off('click').on('click', function () { sm.updateItem(item) }); + $item.off('dblclick').on('dblclick', function () { sm.updateItem(item) }); } $('.sax-burger', $item).toggle(!!$('.sax-dropdown-item', $mnu).length); $('.sax-panel-messages', $pnl.results).hide().empty(); @@ -70,50 +75,55 @@ } //-------------------------------------------------------------- - sax.getFilterDropdownTemplate = function () + sm.getFilterDropdownTemplate = function () { return $('.sax-panel-item-template .sax-dropdown-menu.SportFilter li.sax-dropdown-item', $pnl.filter).clone(); } - sax.getItemTemplate = function () + sm.getItemTemplate = function () { return $('.sax-panel-item-template .sax-panel-item.Sport', $pnl.results).clone(); } - sax.getItemDropdownTemplate = function () + sm.getItemDropdownTemplate = function () { return $('.sax-panel-item-template .sax-dropdown-menu.Sport li.sax-dropdown-item', $pnl.results).clone(); } - sax.getFilterMenuOption = function (lbl, fn) + sm.getFilterMenuOption = function (lbl, fn, cls) { - return sax.getMenuOption(sax.getFilterDropdownTemplate(), lbl, fn); + return sm.getMenuOption(sm.getFilterDropdownTemplate(), lbl, fn, cls); } - sax.getItemMenuOption = function (lbl, fn) + sm.getItemMenuOption = function (lbl, fn, cls) { - return sax.getMenuOption(sax.getItemDropdownTemplate(), lbl, fn); + return sm.getMenuOption(sm.getItemDropdownTemplate(), lbl, fn, cls); } - sax.getMenuOption = function ($opt, lbl, fn) + sm.getMenuOption = function ($opt, lbl, fn, cls) { - return $opt.find('div.sax-label').text(lbl).end().on('click', fn); + return $opt.find('div.sax-label').text(lbl).end().on('click', fn).addClass(cls); } //-------------------------------------------------------------- - sax.createItem = function () + sm.createItem = function () + { + sm.clearItem(); + $dlg.sport.dialog('option', 'title', sax.dlg.title.createSport); + sax.openDialog($dlg.sport, 600, 600); + } + sm.clearItem = function () { let frm = $frm.sport; $('.SportId,input[type="text"],textarea,select', frm).val(''); $('.SportStatus', frm).val(sax.data.defaultStatusCode); sax.clearControlErrors(); - $dlg.sport.dialog('option', 'title', sax.dlg.title.createSport); - sax.openDialog($dlg.sport, 600, 600); } //-------------------------------------------------------------- - sax.updateItem = function (item) + sm.updateItem = function (item) { + sm.clearItem(); $('.SportId', $frm.sportId).val(item.id); - sax.ajax.updateItem = sax.ajax.updateItem || { url: sax.url.base + 'Sport/Ajax/GetItem', formId: 'frmSportId', callbackFn: sax.onUpdateItem }; + sax.ajax.updateItem = sax.ajax.updateItem || { url: sax.url.base + 'Sport/Ajax/GetItem', formId: 'frmSportId', callbackFn: sm.onUpdateItem }; sax.doAjaxRequest(sax.ajax.updateItem, 50); } - sax.onUpdateItem = function (response) + sm.onUpdateItem = function (response) { //sax.debug('onUpdateItem', response); let frm = $frm.sport; @@ -121,6 +131,8 @@ if (!response.success) return; let item = response.sport; $('.SportId', frm).val(item.id); + $('.SportIdParent', frm).val(item.sportIdParent); + $('.SportNameParent', frm).val(item.sportNameParent); $('.SportName', frm).val(item.name); $('.SportSpecialityLabel', frm).val(item.specialityLabelCode); $('.SportStatus', frm).val(item.statusCode); @@ -130,12 +142,52 @@ } //-------------------------------------------------------------- - sax.storeItem = function () + sm.populateSports = function (nextFn) { - sax.ajax.storeItem = sax.ajax.storeItem || { url: sax.url.base + 'Sport/Ajax/StoreItem', formId: 'frmSport', callbackFn: sax.onStoreItem }; + let handleResponse = function (response) + { + if (response && response.success && response.sports) + sm.data.sports = response.sports; + if (nextFn) nextFn(); + } + sm.ajax.sports = sm.ajax.sports || { url: sax.url.base + 'Sport/Ajax/GetList', formId: 'frmNavigate', callbackFn: handleResponse }; + sax.doAjaxRequest(sm.ajax.sports, 50); + } + sm.selectParentSport = function () + { + if (!sm.data.sports) + sm.populateSports(sm.showSelectParentSport); + else sm.showSelectParentSport(); + } + sm.showSelectParentSport = function () + { + let sports = []; + for (const spt of sm.data.sports || []) + { + if (spt.sportIdParent * 1 || 'a' * 1 || spt.id == $('.SportId', $frm.org).val()) continue; + sports.push(spt); + } + sax.data.selectItem.fn.selectItem({ caption: sax.dlg.title.selectSport, items: sports, itemId: $('.SportIdParent', $frm.sport).val(), fnCallback: sm.onParentSportSelected }); + } + sm.onParentSportSelected = function (spt) + { + let frm = $frm.org; + $('.SportIdParent', frm).val(spt.id); + $('.SportNameParent', frm).val(spt.name); + sax.clearControlError($('.SportParent', frm)); + } + sm.clearParentSport = function () + { + $('.SportIdParent,.SportNameParent', $frm.org).val(''); + } + + //-------------------------------------------------------------- + sm.storeItem = function () + { + sax.ajax.storeItem = sax.ajax.storeItem || { url: sax.url.base + 'Sport/Ajax/StoreItem', formId: 'frmSport', callbackFn: sm.onStoreItem }; sax.doAjaxRequest(sax.ajax.storeItem, 50); } - sax.onStoreItem = function (response) + sm.onStoreItem = function (response) { //sax.debug('onStoreItem', response); sax.refreshControlValues(response.controlValues); @@ -146,32 +198,35 @@ var $item = $('#' + sax.itemIdPrefix + item.id); if (!$item.length) { - $item = sax.getItemTemplate(); + $item = sm.getItemTemplate(); $('.sax-panel-item-list', $pnl.results).prepend($item).show(); } - sax.populateItem($item, item) + sm.populateItem($item, item); + // Force repopulation of sprts. + delete sm.data.sports; } //-------------------------------------------------------------- $(function () { $pnl.sports = $('.sax-panel.Sports'); + $pnl.filter = $('.sax-panel-filter', $pnl.sports); + $frm.filter = $('#frmSportFilter', $pnl.filter); + $('.FilterSport', $frm.filter).on('input', function () { sm.refreshResults(250); }); $pnl.results = $('.sax-panel-results', $pnl.sports); - sax.$frm.filter = $('#frmSportFilter'); - $('.FilterSport', sax.$frm.filter).on('input', function () { sax.refreshResults(250); }); - sax.$frm.sportId = $('#frmSportId'); - sax.$frm.sport = $('#frmSport'); - $('.sax-input', sax.$frm.sport).on('input', function () { sax.clearControlError(this); }); - $('.sax-select', sax.$frm.sport).on('change', function () { sax.clearControlError(this); }); + $frm.sportId = $('#frmSportId'); + $frm.sport = $('#frmSport'); + $frm.sport.on('input', '.sax-input', function () { sax.clearControlError(this); }).on('change', '.sax-select', function () { sax.clearControlError(this); }); + $frm.sport.on('dblclick', '.SportNameParent', sm.selectParentSport).on('click', '#pbSelectParentSport', sm.selectParentSport).on('click', '.ParentSportClear', sm.clearParentSport); var opt = sax.dlgOpts(); - opt.buttons[sax.dlg.btn.ok] = function () { sax.storeItem(); }; + opt.buttons[sax.dlg.btn.ok] = function () { sm.storeItem(); }; opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); }; $dlg.sport = $('#dlgSport').dialog(opt); - setTimeout(sax.refreshResults, 250); + setTimeout(sm.refreshResults, 250); }); }(window, window.document)); diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-sys-db.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-sys-db.js index fe3ee68..461db63 100644 --- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-sys-db.js +++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-sys-db.js @@ -78,7 +78,7 @@ for (let prtIdx = 0; prtIdx < prts.length; prtIdx++) { let prt = prts[prtIdx]; - let $prt = sd.getTablePropertyTemplate(); + let $prt = sd.getTablePropertyTemplate().addClass('sax-' + (prtIdx % 2 ? 'even' : 'odd')); $('.Label', $prt).text(prt.label); $('.Value', $prt).text(prt.value); $prts.append($prt); @@ -90,7 +90,7 @@ for (let colIdx = 0; colIdx < cols.length; colIdx++) { let col = cols[colIdx]; - let $col = sd.getTableColumnTemplate(); + let $col = sd.getTableColumnTemplate().addClass('sax-' + (colIdx % 2 ? 'even' : 'odd')); $('.Pos', $col).text(col.pos); $('.Name', $col).text(col.name); $('.Format', $col).text(col.format); @@ -103,11 +103,11 @@ for (let idxIdx = 0; idxIdx < idxs.length; idxIdx++) { let idx = idxs[idxIdx]; - let $idx = sd.getTableIndexTemplate(); + let $idx = sd.getTableIndexTemplate().addClass('sax-' + (idxIdx % 2 ? 'even' : 'odd')); $('.Name', $idx).text(idx.name); for (const col of idx.columns) $('.Columns', $idx).append($('
    ').text(col.name)); - $('.Unique', $idx).text(idx.unique?'Yes':''); + $('.Unique', $idx).text(idx.unique ? 'Yes' : ''); $idxs.append($idx); } // Display table details. @@ -134,7 +134,7 @@ } sd.getTableRowTemplate = function (name) { - return $('.sax-panel-item-template .'+name, $dlg.table).clone(); + return $('.sax-panel-item-template .' + name, $dlg.table).clone(); } //-------------------------------------------------------------- diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr-onl.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr-onl.js index 5dcd182..6c39741 100644 --- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr-onl.js +++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr-onl.js @@ -41,7 +41,7 @@ // Menu. var $bgr = $('.sax-burger', $pnl.filter).hide(); var $mnu = $('ul.sax-dropdown-menu', $bgr).empty(); - $mnu.append(sax.getFilterMenuOption(sax.lbl.refresh, function () { sax.refreshResults(); })); + $mnu.append(sax.getFilterMenuOption(sax.lbl.refresh, function () { sax.refreshResults(); }, 'sax-refresh')); $bgr.toggle(!!$('.sax-dropdown-item', $mnu).length); // Items. var items = response.users; @@ -85,17 +85,17 @@ { return $('.sax-panel-item-template .sax-dropdown-menu.User li.sax-dropdown-item', $pnl.results).clone(); } - sax.getFilterMenuOption = function (lbl, fn) + sax.getFilterMenuOption = function (lbl, fn, cls) { - return sax.getMenuOption(sax.getFilterDropdownTemplate(), lbl, fn); + return sax.getMenuOption(sax.getFilterDropdownTemplate(), lbl, fn, cls); } - sax.getItemMenuOption = function (lbl, fn) + sax.getItemMenuOption = function (lbl, fn, cls) { - return sax.getMenuOption(sax.getItemDropdownTemplate(), lbl, fn); + return sax.getMenuOption(sax.getItemDropdownTemplate(), lbl, fn, cls); } - sax.getMenuOption = function ($opt, lbl, fn) + sax.getMenuOption = function ($opt, lbl, fn, cls) { - return $opt.find('div.sax-label').text(lbl).end().on('click', fn); + return $opt.find('div.sax-label').text(lbl).end().on('click', fn).addClass(cls); } //-------------------------------------------------------------- diff --git a/SaxoniteCoreWebAdmin/wwwroot/js/sax-user.js b/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr.js similarity index 97% rename from SaxoniteCoreWebAdmin/wwwroot/js/sax-user.js rename to SaxoniteCoreWebAdmin/wwwroot/js/sax-usr.js index bea6543..b8cb43b 100644 --- a/SaxoniteCoreWebAdmin/wwwroot/js/sax-user.js +++ b/SaxoniteCoreWebAdmin/wwwroot/js/sax-usr.js @@ -41,8 +41,8 @@ // Menu. var $bgr = $('.sax-burger', $pnl.filter).hide(); var $mnu = $('ul.sax-dropdown-menu', $bgr).empty(); - $mnu.append(sax.getFilterMenuOption(sax.lbl.refresh, function () { sax.refreshResults(); })); - $mnu.append(sax.getFilterMenuOption(sax.lbl.create, function () { sax.createItem(); })); + $mnu.append(sax.getFilterMenuOption(sax.lbl.refresh, function () { sax.refreshResults(); }, 'sax-refresh')); + $mnu.append(sax.getFilterMenuOption(sax.lbl.create, function () { sax.createItem(); }, 'sax-add')); $bgr.toggle(!!$('.sax-dropdown-item', $mnu).length); // Items. var items = response.users; @@ -72,10 +72,10 @@ let $mnu = $('ul.sax-dropdown-menu', $item); if (!item.deleted) { - $mnu.append(sax.getItemMenuOption(sax.lbl.edit, function () { sax.updateItem(item) })); + $mnu.append(sax.getItemMenuOption(sax.lbl.edit, function () { sax.updateItem(item) }, 'sax-edit')); $('.sax-header .sax-action.sax-item-update', $item).off('click').on('click', function () { sax.updateItem(item) }); $item.off('dblclick').on('dblclick', function () { sax.updateItem(item) }); - $mnu.append(sax.getItemMenuOption(sax.lbl.emails, function () { sax.userEmails(item) })); + $mnu.append(sax.getItemMenuOption(sax.lbl.emails, function () { sax.userEmails(item) }, 'sax-mail')); } $('.sax-burger', $item).toggle(!!$('.sax-dropdown-item', $mnu).length); $('.sax-panel-messages', $pnl.results).hide().empty(); @@ -95,17 +95,17 @@ { return $('.sax-panel-item-template .sax-dropdown-menu.User li.sax-dropdown-item', $pnl.results).clone(); } - sax.getFilterMenuOption = function (lbl, fn) + sax.getFilterMenuOption = function (lbl, fn, cls) { - return sax.getMenuOption(sax.getFilterDropdownTemplate(), lbl, fn); + return sax.getMenuOption(sax.getFilterDropdownTemplate(), lbl, fn, cls); } - sax.getItemMenuOption = function (lbl, fn) + sax.getItemMenuOption = function (lbl, fn, cls) { - return sax.getMenuOption(sax.getItemDropdownTemplate(), lbl, fn); + return sax.getMenuOption(sax.getItemDropdownTemplate(), lbl, fn, cls); } - sax.getMenuOption = function ($opt, lbl, fn) + sax.getMenuOption = function ($opt, lbl, fn, cls) { - return $opt.find('div.sax-label').text(lbl).end().on('click', fn); + return $opt.find('div.sax-label').text(lbl).end().on('click', fn).addClass(cls); } //-------------------------------------------------------------- diff --git a/SaxoniteCoreWebOnline/Online/Controllers/AccountController-Ajax-Sports.cs b/SaxoniteCoreWebOnline/Online/Controllers/AccountController-Ajax-Sports.cs index 8132e8d..908198e 100644 --- a/SaxoniteCoreWebOnline/Online/Controllers/AccountController-Ajax-Sports.cs +++ b/SaxoniteCoreWebOnline/Online/Controllers/AccountController-Ajax-Sports.cs @@ -41,7 +41,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers } private void PopulateProfileSportResponseData(Model_Account model, SaxUserSport userSport, SaxSport sport, ProfileSportResponseData_Item data) { - data.Id = SysId.ToString(userSport.Id); + data.Id = model.EncryptId(userSport.Id); data.SportId = model.GetEncryptedSportId(userSport.SportId); data.SportName = sport.Name; data.SportSpecialityLabel = model.GetSportSpecialityLabel(userSport.SportId); @@ -113,7 +113,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers SysId sportId = new SysId(values.GetLong(colSportId.DataName)); ProfileSportResponseData_List userSportData = new ProfileSportResponseData_List() { - Id = values.GetLong(colId.DataName).ToString(), + Id = model.EncryptId(new SysId(values.GetLong(colId.DataName))), SportId = model.GetEncryptedSportId(sportId), SportName = values.GetString(colSportName.DataName), SportSpecialityLabel = model.GetSportSpecialityLabel(sportId), @@ -158,30 +158,37 @@ namespace Saxonite.Net.Core.Web.Online.Controllers if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); - // Identify item. - SysId userSportId = model.ExtractSysId(model.UserSportId); - if (!SysId.IsValid(userSportId)) - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); - - // Retrieve item. - SaxUserSport userSport = AccountMgr.GetUserSportById(userSportId); - if (userSport == null) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposableItems = new DisposableCollection()) { - SaLogger.Warn(fn + " Failed to retrieve User Sport for Id: '" + model.UserSportId + "'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } - // Retrieve sport. - SaxSport sport = ReferenceMgr.GetSportById(userSport.SportId); - if (sport == null) - { - SaLogger.Warn(fn + " Failed to retrieve Sport for Id: '" + userSport.SportId + "'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } + // Identify item. + SysId userSportId = model.ExtractSysId(model.UserSportId); + if (!SysId.IsValid(userSportId)) + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); - // Construct response. - PopulateProfileSportResponseData(model, userSport, sport, responseData.Sport); - responseData.Success = true; + // Retrieve item. + SaxUserSport userSport = AccountMgr.GetUserSportById(userSportId); + disposableItems.Add(userSport); + if (userSport == null) + { + SaLogger.Warn(fn + " Failed to retrieve User Sport for Id: '" + model.UserSportId + "'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + } + + // Retrieve sport. + SaxSport sport = ReferenceMgr.GetSportById(userSport.SportId); + disposableItems.Add(sport); + if (sport == null) + { + SaLogger.Warn(fn + " Failed to retrieve Sport for Id: '" + userSport.SportId + "'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + } + + // Construct response. + PopulateProfileSportResponseData(model, userSport, sport, responseData.Sport); + responseData.Success = true; + } return Json(responseData); } @@ -201,108 +208,119 @@ namespace Saxonite.Net.Core.Web.Online.Controllers if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); - // Validate item properties. - model.ValidateProfileSportData(responseData); - if (responseData.HasControlErrors()) - return Json(responseData); + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposableItems = new DisposableCollection()) + { - // Validate Profile Sport Id against 'Exists' flag. - SysId userSportId = model.ExtractSysId(model.UserSportId); - bool profileSportExists = StringUtil.ToBool(model.ProfileSportExists); - if (profileSportExists && !SysId.IsValid(userSportId)) - { - SaLogger.Warn(fn + " Id not specified for existing Profile Sport."); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } - if (!profileSportExists && SysId.IsValid(userSportId)) - { - SaLogger.Warn(fn + " Id specified for new Profile Sport: '" + model.UserSportId + "'"); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } + // Validate item properties. + model.ValidateProfileSportData(responseData); + if (responseData.HasControlErrors()) + return Json(responseData); - // Retrieve the sport. - SysId sportId = model.ExtractSysId(model.ProfileSportId); - SaxSport sport = ReferenceMgr.GetSportById(sportId); - if (sport == null) - { - SaLogger.Warn(fn + " Failed to retrieve Sport for Id: " + sportId); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } - - // Retrieve existing item. - SaxUserSport userSport = AccountMgr.GetUserSportById(userSportId); - if (userSport == null && SysId.IsValid(userSportId)) - { - SaLogger.Warn(fn + " Failed to retrieve User Sport for Id: '" + model.UserSportId + "'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } - // Validate user sport properties. - if (userSport != null) - { - if (!userSport.SportId.Equals(sportId)) + // Validate Profile Sport Id against 'Exists' flag. + SysId userSportId = model.ExtractSysId(model.UserSportId); + bool profileSportExists = StringUtil.ToBool(model.ProfileSportExists); + if (profileSportExists && !SysId.IsValid(userSportId)) { - SaLogger.Warn(fn + " Inconsistent Sport Id specified for User Sport. Expected: " + userSport.SportId + ". Found: " + sportId); + SaLogger.Warn(fn + " Id not specified for existing Profile Sport."); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); + } + if (!profileSportExists && SysId.IsValid(userSportId)) + { + SaLogger.Warn(fn + " Id specified for new Profile Sport: '" + model.UserSportId + "'"); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } - } - // If sport doesn't exist for the user, it may have been previously deleted. - if (userSport == null) - { - SaxUserSport.Params prmUserSport = new SaxUserSport.Params(); - prmUserSport.UserAccountIdsIncluded.Add(UserAccountId); - prmUserSport.SportIdsIncluded.Add(sportId); - prmUserSport.StatusCat = SaxUserSport.StatusCat.Any; - userSport = AccountMgr.GetUserSport(prmUserSport); + // Retrieve the sport. + SysId sportId = model.ExtractSysId(model.ProfileSportId); + SaxSport sport = ReferenceMgr.GetSportById(sportId); + disposableItems.Add(sport); + if (sport == null) + { + SaLogger.Warn(fn + " Failed to retrieve Sport for Id: " + sportId); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); + } + + // Retrieve existing item. + SaxUserSport userSport = AccountMgr.GetUserSportById(userSportId); + disposableItems.Add(userSport); + if (userSport == null && SysId.IsValid(userSportId)) + { + SaLogger.Warn(fn + " Failed to retrieve User Sport for Id: '" + model.UserSportId + "'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + } + // Validate user sport properties. if (userSport != null) { - if (userSport.Status == SaStatus.Deleted) + if (!userSport.SportId.Equals(sportId)) { - SaLogger.Info(fn + " Resurrecting User Sport with status: " + userSport.StatusDesc + ". Id: " + SysId.ToString(userSport.Id)); - userSport.Status = SaxUserSport.DefaultStatus; + SaLogger.Warn(fn + " Inconsistent Sport Id specified for User Sport. Expected: " + userSport.SportId + ". Found: " + sportId); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); + } + } + + // If sport doesn't exist for the user, it may have been previously deleted. + if (userSport == null) + { + SaxUserSport.Params prmUserSport = new SaxUserSport.Params(); + prmUserSport.UserAccountIdsIncluded.Add(UserAccountId); + prmUserSport.SportIdsIncluded.Add(sportId); + prmUserSport.StatusCat = SaxUserSport.StatusCat.Any; + userSport = AccountMgr.GetUserSport(prmUserSport); + if (userSport != null) + { + disposableItems.Add(userSport); + if (userSport.Status == SaStatus.Deleted) + { + SaLogger.Info(fn + " Resurrecting User Sport with status: " + userSport.StatusDesc + ". Id: " + SysId.ToString(userSport.Id)); + userSport.Status = SaxUserSport.DefaultStatus; + } + else + { + responseData.SetControlError(nameof(model.ProfileSportId), Localiser["msg.validation.duplicate.value"]); + return Json(responseData); + } } else { - responseData.SetControlError(nameof(model.ProfileSportId), Localiser["msg.validation.duplicate.value"]); - return Json(responseData); + userSport = AccountMgr.CreateUserSport(UserAccountId, sportId); + disposableItems.Add(userSport); + } + } + + // Populate item properties. + if (model.ProfileSportAbout != null) + userSport.About = model.ProfileSportAbout; + if (model.ProfileSportParticipationCode != null) + userSport.Participation = model.ProfileSportParticipation; + if (model.ProfileSportOfficiatingCode != null) + userSport.Officiating = model.ProfileSportOfficiating; + + // Store item. + if (!SysId.IsValid(userSport.Id)) + { + if (!AccountMgr.InsertUserSport(userSport, DbUpdateInfo)) + { + SaLogger.Warn(fn + " Failed to insert user sport: " + AccountMgr.ErrorStateMessage); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"])); } } else - userSport = AccountMgr.CreateUserSport(UserAccountId, sportId); - } - - // Populate item properties. - if (model.ProfileSportAbout != null) - userSport.About = model.ProfileSportAbout; - if (model.ProfileSportParticipationCode != null) - userSport.Participation = model.ProfileSportParticipation; - if (model.ProfileSportOfficiatingCode != null) - userSport.Officiating = model.ProfileSportOfficiating; - - // Store item. - if (!SysId.IsValid(userSport.Id)) - { - if (!AccountMgr.InsertUserSport(userSport, DbUpdateInfo)) { - SaLogger.Warn(fn + " Failed to insert user sport: " + AccountMgr.ErrorStateMessage); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"])); + if (!AccountMgr.UpdateUserSport(userSport, DbUpdateInfo)) + { + SaLogger.Warn(fn + " Failed to update user sport [Id:" + SysId.ToString(userSport.Id) + "]: " + AccountMgr.ErrorStateMessage); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"])); + } } - } - else - { - if (!AccountMgr.UpdateUserSport(userSport, DbUpdateInfo)) - { - SaLogger.Warn(fn + " Failed to update user sport [Id:" + SysId.ToString(userSport.Id) + "]: " + AccountMgr.ErrorStateMessage); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"])); - } - } - // Refresh list of profile sports for Activity Index. - RefreshSessionProfileSports(); + // Refresh list of profile sports for Activity Index. + RefreshSessionProfileSports(); - // Construct response. - PopulateProfileSportResponseData(model, userSport, sport, responseData.Sport); - responseData.Success = true; + // Construct response. + PopulateProfileSportResponseData(model, userSport, sport, responseData.Sport); + responseData.Success = true; + } return Json(responseData); } diff --git a/SaxoniteCoreWebOnline/Online/Controllers/AccountController-Ajax-UserSportExperience.cs b/SaxoniteCoreWebOnline/Online/Controllers/AccountController-Ajax-UserSportExperience.cs index ac76037..2aff3da 100644 --- a/SaxoniteCoreWebOnline/Online/Controllers/AccountController-Ajax-UserSportExperience.cs +++ b/SaxoniteCoreWebOnline/Online/Controllers/AccountController-Ajax-UserSportExperience.cs @@ -29,9 +29,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers { //------------------------------------------------------------------- // Common response data. - private class SportExperienceResponseData_List + private class SportExperienceResponseData_List : AjaxResponse_Data.ItemData_Base { - public String Id { get; set; } public String UserSportId { get; set; } public String Period { get; set; } public String PeriodFrom { get; set; } diff --git a/SaxoniteCoreWebOnline/Online/Controllers/ActivityController-Ajax.cs b/SaxoniteCoreWebOnline/Online/Controllers/ActivityController-Ajax.cs index 3dc12ae..a6487cc 100644 --- a/SaxoniteCoreWebOnline/Online/Controllers/ActivityController-Ajax.cs +++ b/SaxoniteCoreWebOnline/Online/Controllers/ActivityController-Ajax.cs @@ -182,8 +182,18 @@ namespace Saxonite.Net.Core.Web.Online.Controllers indexContext.EffectiveTo = DateTime.Today; // Sport and region combinations. + List sportIds = new List(); foreach (SysId sportId in sessionData.Profile.Sports.Select(item => item.SportId)) { + if (sportIds.Contains(sportId)) continue; + sportIds.AddId(sportId); + // Include child sports. + sportIds.AddIds(model.GetChildSports_Active(sportId).Select(item => item.Id)); + model.GetSportCaption(sportId); + } + foreach (SysId sportId in sportIds) + { + // Regions. if (SysId.IsValid(sessionData.User.RegionIdProvince)) indexContext.SportRegionIdsIncluded.Add(new SaxActivityIndex.SportRegionIds(sportId, sessionData.User.RegionIdProvince)); else if (SysId.IsValid(sessionData.User.RegionIdCountry)) diff --git a/SaxoniteCoreWebOnline/Online/Controllers/ArticleController-Ajax.cs b/SaxoniteCoreWebOnline/Online/Controllers/ArticleController-Ajax.cs index f553d18..3d8246c 100644 --- a/SaxoniteCoreWebOnline/Online/Controllers/ArticleController-Ajax.cs +++ b/SaxoniteCoreWebOnline/Online/Controllers/ArticleController-Ajax.cs @@ -53,6 +53,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers private class ArticleData_List : AjaxResponse_Data.ItemData_Base { public String OrganisationId { get; set; } + public String OrganisationName { get; set; } public String Headline { get; set; } public String Summary { get; set; } public String RegionCaptionPrimary { get; set; } @@ -69,7 +70,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers public String PublishedOn_Calendar { get; set; } public ArticleContentData Content { get; } = new ArticleContentData(); } - private void PopulateArticleResponseData(Model_Article model, SaxArticle article, ArticleData_List data) + private void PopulateArticleResponseData(Model_Article model, SaxArticle article, SaxOrganisation organisation, ArticleData_List data) { data.Id = model.EncryptId(article.Id); data.OrganisationId = SysId.ToString(article.OrganisationId); @@ -82,9 +83,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers data.StatusCode = article.StatusCode; data.StatusDesc = article.StatusDesc; } - private void PopulateArticleResponseData(Model_Article model, SaxArticle article, ArticleData_Full data) + private void PopulateArticleResponseData(Model_Article model, SaxArticle article, SaxOrganisation organisation, ArticleData_Full data) { - PopulateArticleResponseData(model, article, data as ArticleData_List); + PopulateArticleResponseData(model, article, organisation, data as ArticleData_List); data.RegionIdPrimary = model.GetEncryptedRegionId(article.RegionIdPrimary); data.SportIdPrimary = model.GetEncryptedSportId(article.SportIdPrimary); data.Published = DateUtil.IsValid(article.PublishedAt) ? true : (bool?)null; @@ -207,6 +208,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers prmArticle.UserAccountIdsAuthorIncluded.Add(sessionData.User.UserAccountId); if (SysId.IsValid(organisationIdFilter)) prmArticle.OrganisationIdsIncluded.Add(organisationIdFilter); + else + prmArticle.ExcludeOrganisationArticles = true; prmArticle.ArticleFilter = model.Filter.Article; prmArticle.StatusCat = SaxArticle.StatusCat.NotDeleted; model.Paging.ItemTotal = (ulong)ActivityMgr.GetArticleCount(prmArticle); @@ -215,6 +218,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers // Item columns. ColumnDfn colId = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Id); ColumnDfn colOrganisationId = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.OrganisationId); + ColumnDfn colOrganisationName = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Organisation_Name); ColumnDfn colHeadline = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Headline); ColumnDfn colSummary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.Summary); ColumnDfn colRegionIdPrimary = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.RegionIdPrimary); @@ -224,7 +228,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers ColumnDfn colCreatedOn = ActivityMgr.GetArticleColumnDfn(SaxArticle.Column.CreateOn_Date); List columns = new List() { - colId, colOrganisationId, colHeadline, colSummary, + colId, colOrganisationId, colOrganisationName, colHeadline, colSummary, colRegionIdPrimary, colSportIdPrimary, colPublishedOn, colStatus, colCreatedOn }; @@ -243,6 +247,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers { Id = model.EncryptId(new SysId(values.GetLong(colId.DataName))), OrganisationId = model.EncryptId(new SysId(values.GetLong(colOrganisationId.DataName))), + OrganisationName = values.GetString(colOrganisationName.DataName), Headline = values.GetString(colHeadline.DataName), Summary = values.GetString(colSummary.DataName), RegionCaptionPrimary = model.GetRegionCaption(values.GetString(colRegionIdPrimary.DataName).ToSysId()), @@ -315,6 +320,10 @@ namespace Saxonite.Net.Core.Web.Online.Controllers return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } + // Organisation. + SaxOrganisation organisation = AccountMgr.GetOrganisationById(article.OrganisationId); + disposableItems.Add(organisation); + // Delete upload images. SaxItemImage.Params prmItemImage = new SaxItemImage.Params(); prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.Article, articleId)); @@ -330,7 +339,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers } // Construct response. - PopulateArticleResponseData(model, article, responseData.Article); + PopulateArticleResponseData(model, article, organisation, responseData.Article); } responseData.Success = true; return Json(responseData); @@ -484,188 +493,202 @@ namespace Saxonite.Net.Core.Web.Online.Controllers SaxSessionData_Online sessionData = SessionData_Online; RefreshModel(model); - // Validate item properties. - model.ValidateArticleData(responseData); - if (responseData.HasControlErrors()) - return Json(responseData); - - // Validate User & Organisation. - SysId userAccountId = UserAccountId; - SysId organisationId = model.ExtractSysId(model.ArticleOrganisationId); - if (SysId.IsValid(organisationId)) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposableItems = new DisposableCollection()) { - // Organisation specified - User must have Article Admin role. - if (!AccountMgr.UserHasAnyOrganisationRole(userAccountId, organisationId, new[] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ArticleAdmin })) + + // Validate item properties. + model.ValidateArticleData(responseData); + if (responseData.HasControlErrors()) + return Json(responseData); + + // Validate User & Organisation. + SysId userAccountId = UserAccountId; + SysId organisationId = model.ExtractSysId(model.ArticleOrganisationId); + if (SysId.IsValid(organisationId)) { - SaLogger.Warn(fn + " User does not have Article Admin role for organisation." + GetLogSuffix()); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } - } - else - { - // Organisation not specified - User must be a Journalist. - if (!UserIsJournalist) - { - SaLogger.Warn(fn + " User is not a Journalist for non-organisation article." + GetLogSuffix()); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } - } - - // Validate item Id against 'Exists' flag. - SysId articleId = model.ExtractSysId(model.ArticleId); - bool articleExists = StringUtil.ToBool(model.ArticleExists); - if (articleExists && !SysId.IsValid(articleId)) - { - SaLogger.Warn(fn + " Id not specified for existing Article."); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } - if (!articleExists && SysId.IsValid(articleId)) - { - SaLogger.Warn(fn + " Id specified for new Article: '" + model.ArticleId + "'"); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } - - // Retrieve existing item. - SaxArticle article = ActivityMgr.GetArticleById(articleId); - if (article == null && SysId.IsValid(articleId)) - { - SaLogger.Warn(fn + " Failed to retrieve article for Id: '" + model.ArticleId + "'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } - if (article != null) - { - // Validate existing article. - if (SysId.ToLong(article.UserAccountIdAuthor) != SysId.ToLong(userAccountId)) - { - SaLogger.Warn(fn + " Inconsistent Article Author." + GetLogSuffix()); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } - if (SysId.ToLong(article.OrganisationId) != SysId.ToLong(organisationId)) - { - SaLogger.Warn(fn + " Inconsistent Article Organisation." + GetLogSuffix()); - return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); - } - } - - // Create new item if required. - if (article == null) - article = ActivityMgr.CreateArticle(sessionData.User.UserAccountId, organisationId); - - // Populate item properties. - if (model.ArticleRegionId != null) - article.RegionIdPrimary = model.ExtractSysId(model.ArticleRegionId); - if (model.ArticleSportId != null) - article.SportIdPrimary = model.ExtractSysId(model.ArticleSportId); - if (model.ArticleHeadline != null) - article.Headline = model.ArticleHeadline; - if (model.ArticleSummary != null) - article.Summary = model.ArticleSummary; - if (!model.ArticlePublished.ToBool()) - { - if (model.ArticlePublish) - article.PublishedAt = model.GetArticlePublishOn(); - else - article.PublishedAt = DateTime.MinValue; - } - if (model.ArticleStatusCode != null) - article.Status = model.ArticleStatus; - - // Retrieve all article images - before new article is created as uploaded images are assigned to user first. - SaxItemImage.Params prmItemImage = new SaxItemImage.Params(); - if (SysId.IsValid(article.Id)) - prmItemImage.ItemIdsIncluded.Add(article.GetItemId()); - else - prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.UserAccount, sessionData.User.UserAccountId)); - prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.Article); - prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload); - prmItemImage.StatusCat = SaxItemImage.StatusCat.NotDeleted; - List itemImages = ItemDataMgr.GetItemImageList(prmItemImage); - - // If Article doesn't yet exist, create it now so that images can be assigned. - bool articleCreated = false; - if (!SysId.IsValid(article.Id)) - { - if (!ActivityMgr.InsertArticle(article, DbUpdateInfo)) - { - SaLogger.Warn(fn + " Failed to insert article: " + ActivityMgr.ErrorStateMessage); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"])); - } - articleCreated = true; - } - - // Content. - if (model.ArticleContentSegmentBodies != null) - { - SaxArticle.ContentData articleContent = new SaxArticle.ContentData(); - for (int segmentIdx = 0; segmentIdx < model.ArticleContentSegmentBodies.Count; segmentIdx++) - { - String segmentBody = model.ArticleContentSegmentBodies[segmentIdx]; - String segmentItemImageId = model.ArticleContentSegmentItemImageIds.Count > segmentIdx ? model.ArticleContentSegmentItemImageIds[segmentIdx] : ""; - String segmentImageIdx = model.ArticleContentSegmentImageIdxs.Count > segmentIdx ? model.ArticleContentSegmentImageIdxs[segmentIdx] : ""; - if (!StringUtil.IsEmpty(segmentBody)) + // Organisation specified - User must have Article Admin role. + if (!AccountMgr.UserHasAnyOrganisationRole(userAccountId, organisationId, new[] { Sax.OrganisationRole.Admin, Sax.OrganisationRole.ArticleAdmin })) { - // HTML Body segment. - var segment = articleContent.AddSegment(); - segment.Body.Html = segmentBody; + SaLogger.Warn(fn + " User does not have Article Admin role for organisation." + GetLogSuffix()); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } - else if (!StringUtil.IsEmpty(segmentItemImageId) || !StringUtil.IsEmpty(segmentImageIdx)) + } + else + { + // Organisation not specified - User must be a Journalist. + if (!UserIsJournalist) { - SysId itemImageId = model.ExtractSysId(segmentItemImageId); - int imageIdx = StringUtil.ToInt(segmentImageIdx); + SaLogger.Warn(fn + " User is not a Journalist for non-organisation article." + GetLogSuffix()); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); + } + } - // Check for new image first. - SaxItemImage itemImage = itemImages.GetItemImageBySessionImage(sessionData.SessionIdx, imageIdx); - if (itemImage == null) - itemImage = itemImages.GetItemImageById(itemImageId); - if (itemImage != null) + // Validate item Id against 'Exists' flag. + SysId articleId = model.ExtractSysId(model.ArticleId); + bool articleExists = StringUtil.ToBool(model.ArticleExists); + if (articleExists && !SysId.IsValid(articleId)) + { + SaLogger.Warn(fn + " Id not specified for existing Article."); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); + } + if (!articleExists && SysId.IsValid(articleId)) + { + SaLogger.Warn(fn + " Id specified for new Article: '" + model.ArticleId + "'"); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); + } + + // Retrieve existing item. + SaxArticle article = ActivityMgr.GetArticleById(articleId); + disposableItems.Add(article); + if (article == null && SysId.IsValid(articleId)) + { + SaLogger.Warn(fn + " Failed to retrieve article for Id: '" + model.ArticleId + "'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + } + if (article != null) + { + // Validate existing article. + if (SysId.ToLong(article.UserAccountIdAuthor) != SysId.ToLong(userAccountId)) + { + SaLogger.Warn(fn + " Inconsistent Article Author." + GetLogSuffix()); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); + } + if (SysId.ToLong(article.OrganisationId) != SysId.ToLong(organisationId)) + { + SaLogger.Warn(fn + " Inconsistent Article Organisation." + GetLogSuffix()); + return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); + } + } + + // Organisation. + SaxOrganisation organisation = AccountMgr.GetOrganisationById(article.OrganisationId); + disposableItems.Add(organisation); + + // Create new item if required. + if (article == null) + { + article = ActivityMgr.CreateArticle(sessionData.User.UserAccountId, organisationId); + disposableItems.Add(article); + } + + // Populate item properties. + if (model.ArticleRegionId != null) + article.RegionIdPrimary = model.ExtractSysId(model.ArticleRegionId); + if (model.ArticleSportId != null) + article.SportIdPrimary = model.ExtractSysId(model.ArticleSportId); + if (model.ArticleHeadline != null) + article.Headline = model.ArticleHeadline; + if (model.ArticleSummary != null) + article.Summary = model.ArticleSummary; + if (!model.ArticlePublished.ToBool()) + { + if (model.ArticlePublish) + article.PublishedAt = model.GetArticlePublishOn(); + else + article.PublishedAt = DateTime.MinValue; + } + if (model.ArticleStatusCode != null) + article.Status = model.ArticleStatus; + + // Retrieve all article images - before new article is created as uploaded images are assigned to user first. + SaxItemImage.Params prmItemImage = new SaxItemImage.Params(); + if (SysId.IsValid(article.Id)) + prmItemImage.ItemIdsIncluded.Add(article.GetItemId()); + else + prmItemImage.ItemIdsIncluded.Add(new ItemId((short)Sax.DataItemType.UserAccount, sessionData.User.UserAccountId)); + prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.Article); + prmItemImage.ImageTypesIncluded.Add(Sax.ImageType.ArticleUpload); + prmItemImage.StatusCat = SaxItemImage.StatusCat.NotDeleted; + List itemImages = ItemDataMgr.GetItemImageList(prmItemImage); + disposableItems.AddRange(itemImages); + + // If Article doesn't yet exist, create it now so that images can be assigned. + bool articleCreated = false; + if (!SysId.IsValid(article.Id)) + { + if (!ActivityMgr.InsertArticle(article, DbUpdateInfo)) + { + SaLogger.Warn(fn + " Failed to insert article: " + ActivityMgr.ErrorStateMessage); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"])); + } + articleCreated = true; + } + + // Content. + if (model.ArticleContentSegmentBodies != null) + { + SaxArticle.ContentData articleContent = new SaxArticle.ContentData(); + for (int segmentIdx = 0; segmentIdx < model.ArticleContentSegmentBodies.Count; segmentIdx++) + { + String segmentBody = model.ArticleContentSegmentBodies[segmentIdx]; + String segmentItemImageId = model.ArticleContentSegmentItemImageIds.Count > segmentIdx ? model.ArticleContentSegmentItemImageIds[segmentIdx] : ""; + String segmentImageIdx = model.ArticleContentSegmentImageIdxs.Count > segmentIdx ? model.ArticleContentSegmentImageIdxs[segmentIdx] : ""; + if (!StringUtil.IsEmpty(segmentBody)) { - // Ensure that the image is correctly identified for the Article. - itemImage.ItemId = article.GetItemId(); - itemImage.ImageType = Sax.ImageType.Article; - itemImage.SessionUid = 0; - itemImage.ImageUid = 0; - itemImage.Status = SaxItemImage.DefaultStatus; - if (ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo)) + // HTML Body segment. + var segment = articleContent.AddSegment(); + segment.Body.Html = segmentBody; + } + else if (!StringUtil.IsEmpty(segmentItemImageId) || !StringUtil.IsEmpty(segmentImageIdx)) + { + SysId itemImageId = model.ExtractSysId(segmentItemImageId); + int imageIdx = StringUtil.ToInt(segmentImageIdx); + + // Check for new image first. + SaxItemImage itemImage = itemImages.GetItemImageBySessionImage(sessionData.SessionIdx, imageIdx); + if (itemImage == null) + itemImage = itemImages.GetItemImageById(itemImageId); + if (itemImage != null) { - // Assign the image segment to the article. - var segment = articleContent.AddSegment(); - segment.Image.ItemImageId = itemImage.Id; - // Remove the image from the list as it's now been handled. - itemImages.Remove(itemImage); + // Ensure that the image is correctly identified for the Article. + itemImage.ItemId = article.GetItemId(); + itemImage.ImageType = Sax.ImageType.Article; + itemImage.SessionUid = 0; + itemImage.ImageUid = 0; + itemImage.Status = SaxItemImage.DefaultStatus; + if (ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo)) + { + // Assign the image segment to the article. + var segment = articleContent.AddSegment(); + segment.Image.ItemImageId = itemImage.Id; + // Remove the image from the list as it's now been handled. + itemImages.Remove(itemImage); + } + else + SaLogger.Warn(fn + " Failed to update article image: " + ItemDataMgr.ErrorStateMessage); } else - SaLogger.Warn(fn + " Failed to update article image: " + ItemDataMgr.ErrorStateMessage); + SaLogger.Warn(fn + " Failed to identify article image. ItemImageId: " + itemImageId.ToInt() + ". SessionIdx: " + sessionData.SessionIdx + ". ImageIdx: " + imageIdx + "."); } - else - SaLogger.Warn(fn + " Failed to identify article image. ItemImageId: " + itemImageId.ToInt() + ". SessionIdx: " + sessionData.SessionIdx + ". ImageIdx: " + imageIdx + "."); } + article.BodyData = SaxArticle.GetContentData(articleContent); } - article.BodyData = SaxArticle.GetContentData(articleContent); + + // Update the Article. + if (!ActivityMgr.UpdateArticle(article, DbUpdateInfo)) + { + SaLogger.Warn(fn + " Failed to update article [Id:" + SysId.ToString(article.Id) + "]: " + ActivityMgr.ErrorStateMessage); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"])); + } + SaLogger.Info(fn + " Article " + (articleCreated ? "created" : "updated") + ". Id: " + article.Id.ToString() + ". User: " + SessionData.User.EmailAddress, true); + + // Store Article Activity Index data. + ActivityConsole.StoreActivityIndex(article, DbUpdateInfo); + + // Delete remaining images as they are no longer required. + foreach (SaxItemImage itemImage in itemImages) + { + itemImage.SessionUid = 0; + itemImage.ImageUid = 0; + itemImage.Status = SaStatus.Deleted; + ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo); + } + + // Construct response. + PopulateArticleResponseData(model, article, organisation, responseData.Article); + responseData.Success = true; } - - // Update the Article. - if (!ActivityMgr.UpdateArticle(article, DbUpdateInfo)) - { - SaLogger.Warn(fn + " Failed to update article [Id:" + SysId.ToString(article.Id) + "]: " + ActivityMgr.ErrorStateMessage); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"])); - } - SaLogger.Info(fn + " Article " + (articleCreated ? "created" : "updated") + ". Id: " + article.Id.ToString() + ". User: " + SessionData.User.EmailAddress, true); - - // Store Article Activity Index data. - ActivityConsole.StoreActivityIndex(article, DbUpdateInfo); - - // Delete remaining images as they are no longer required. - foreach (SaxItemImage itemImage in itemImages) - { - itemImage.SessionUid = 0; - itemImage.ImageUid = 0; - itemImage.Status = SaStatus.Deleted; - ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo); - } - - // Construct response. - PopulateArticleResponseData(model, article, responseData.Article); - responseData.Success = true; return Json(responseData); } diff --git a/SaxoniteCoreWebOnline/Online/Controllers/OrganisationController.cs b/SaxoniteCoreWebOnline/Online/Controllers/OrganisationController.cs index e1a1f2f..d14c756 100644 --- a/SaxoniteCoreWebOnline/Online/Controllers/OrganisationController.cs +++ b/SaxoniteCoreWebOnline/Online/Controllers/OrganisationController.cs @@ -129,73 +129,52 @@ namespace Saxonite.Net.Core.Web.Online.Controllers } private OrganisationData GetOrganisationForFilter(SysId filterOrganisationId, String filterOrganisationCaption, Sax.OrganisationRole organisationRole) { - // Check that user is associated with organisations. - SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params(); - prmUserOrganisation.UserAccountIdsIncluded.Add(UserAccountId); - prmUserOrganisation.OrganisationStatusCat = SaxOrganisation.StatusCat.ActiveOnly; - prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly; - if (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) < 1) - return null; + OrganisationData organisationData = null; // Roles (any) required for organisation list. - List requiredRoles = new List() { Sax.OrganisationRole.Admin }; + List requiredRoles = new List() { Sax.OrganisationRole.Admin }; if (organisationRole > 0) requiredRoles.Add(organisationRole); - // Retrieve specified organisation. - OrganisationData organisationData = null; + // Filter to identify suitable organisations that user is a member of and has the appropriate rights. + SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params(); + prmUserOrganisation.UserAccountIdsIncluded.Add(UserAccountId); + prmUserOrganisation.OrganisationStatusCat = SaxOrganisation.StatusCat.ActiveOnly; + prmUserOrganisation.OrganisationMembersOnly = true; + prmUserOrganisation.OrganisationRolesAny.AddRange(requiredRoles); + prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly; + + // Restrict to specified Organisation. if (SysId.IsValid(filterOrganisationId)) { - organisationData = new OrganisationData(filterOrganisationId) { Caption = filterOrganisationCaption }; - using (SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationData.Id)) - { - // Validate organisation. - if (organisation != null && organisation.IsStatusActive && AccountMgr.UserHasAnyOrganisationRole(UserAccountId, organisation.Id, requiredRoles)) - organisationData.Caption = organisation.Name; - else - organisationData = null; - } + // Verify that the specified organisation is valid for the filter conditions. + prmUserOrganisation.OrganisationIdsIncluded.Add(filterOrganisationId); + if (AccountMgr.GetUserOrganisationCount(prmUserOrganisation) < 1) + // Specified organisation is not valid - remove restriction. + prmUserOrganisation.OrganisationIdsIncluded.Clear(); } - if (organisationData == null) + // Pick the first valid Organisation. + ColumnDfn colOrganisationId = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationId); + ColumnDfn colOrganisationName = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Organisation_Name); + prmUserOrganisation.SortColumns.Add(colOrganisationName); + prmUserOrganisation.ResultsPaging.PageLength = 1; + prmUserOrganisation.ResultsPaging.PageNo = 1; + using (DbResultSet resultSet = AccountMgr.ExecuteUserOrganisationQuery(new List() { colOrganisationId, colOrganisationName }, prmUserOrganisation)) { - // Pick the first valid Organisation that the user is a member of. - ColumnDfn colOrganisationId = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationId); - ColumnDfn colOrganisationName = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Organisation_Name); - prmUserOrganisation = new SaxUserOrganisation.Params(); - prmUserOrganisation.UserAccountIdsIncluded.Add(UserAccountId); - if (organisationData != null && SysId.IsValid(organisationData.Id)) - prmUserOrganisation.OrganisationIdsIncluded.Add(organisationData.Id); - prmUserOrganisation.OrganisationStatusCat = SaxOrganisation.StatusCat.ActiveOnly; - prmUserOrganisation.OrganisationMembersOnly = true; - prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.ActiveOnly; - prmUserOrganisation.SortColumns.Add(colOrganisationName); - prmUserOrganisation.ResultsPaging.PageLength = 1; - prmUserOrganisation.ResultsPaging.PageNo = 1; - using (DbResultSet resultSet = AccountMgr.ExecuteUserOrganisationQuery(new List() { colOrganisationId, colOrganisationName }, prmUserOrganisation)) + if (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) { - while (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) + NamedValue.Map values = resultSet.GetRecordValues(); + SysId organisationId = new SysId(values.GetLong(colOrganisationId.DataName)); + if (SysId.IsValid(organisationId)) { - NamedValue.Map values = resultSet.GetRecordValues(); - SysId organisationId = new SysId(values.GetLong(colOrganisationId.DataName)); - if (SysId.IsValid(organisationId)) + organisationData = new OrganisationData(organisationId) { - organisationData = new OrganisationData(organisationId); - organisationData.Caption = values.GetString(colOrganisationName.DataName); - break; - } + Caption = values.GetString(colOrganisationName.DataName) + }; } } } - if (SysId.IsValid(organisationData.Id) && StringUtil.IsEmpty(organisationData.Caption)) - { - // Organisation has been identified but no caption available as yet. - using (SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationData.Id)) - { - if (organisation != null) - organisationData.Caption = organisation.Name; - } - } return organisationData; } diff --git a/SaxoniteCoreWebOnline/Online/Models/SaxModel_Online.cs b/SaxoniteCoreWebOnline/Online/Models/SaxModel_Online.cs index 37a9e30..aff697b 100644 --- a/SaxoniteCoreWebOnline/Online/Models/SaxModel_Online.cs +++ b/SaxoniteCoreWebOnline/Online/Models/SaxModel_Online.cs @@ -166,6 +166,8 @@ namespace Saxonite.Net.Core.Web.Online.Models } public SysId DecryptId(String encryptedId) { + if (StringUtil.IsEmpty(encryptedId)) + return new SysId(); if (StringUtil.IsNumeric(encryptedId)) return encryptedId.ToSysId(); NameValueCollection idObfuscationParams = SaxController_Base.DecryptParameters(encryptedId, Base64IV_IdObfuscation, Base64Key_IdObfuscation); @@ -230,6 +232,7 @@ namespace Saxonite.Net.Core.Web.Online.Models { /// Encrypted Id public String Id { get; set; } + public String SportIdParent { get; set; } public String Name { get; set; } public String StatusCode { get; set; } public String StatusDesc { get; set; } @@ -242,6 +245,7 @@ namespace Saxonite.Net.Core.Web.Online.Models SportData sportData = new SportData() { Id = GetEncryptedSportId(sport.Id), + SportIdParent = SysId.IsValid(sport.SportIdParent) ? GetEncryptedSportId(sport.SportIdParent) : null, Name = GetSportCaption(sport), StatusCode = sport.StatusCode, StatusDesc = Localiser.GetStatusCaption(sport.Status) @@ -250,6 +254,14 @@ namespace Saxonite.Net.Core.Web.Online.Models } return sports; } + public List GetChildSports_Active(SysId sportIdParent) + { + List sports = new List(); + if (!SysId.IsValid(sportIdParent)) return sports; + List activeSports = DataCacheConsole.GetActiveSports(); + sports.AddRange(activeSports.FindAll(item => sportIdParent.Equals(item.SportIdParent))); + return sports; + } public String GetEncryptedSportId(SysId sportId) { return DataCacheConsole.GetEncryptedSportId(sportId, EncryptId(sportId)); diff --git a/SaxoniteCoreWebOnline/Views/Article/Index.cshtml b/SaxoniteCoreWebOnline/Views/Article/Index.cshtml index d25a08c..6868eb1 100644 --- a/SaxoniteCoreWebOnline/Views/Article/Index.cshtml +++ b/SaxoniteCoreWebOnline/Views/Article/Index.cshtml @@ -78,6 +78,7 @@
    +
    @* Burger menu *@
    Name Unique
    ActivityIndex
    5 - EffectiveOn - DateTime - - 93 - smalldatetime - false - 16 - 16 - 0 - NoNulls - false - - - - dbo - ActivityIndex
    - 6 UserAccountIdOwner Int @@ -111,7 +94,7 @@ dbo ActivityIndex
    - 7 + 6 OrganisationIdOwner Int @@ -125,6 +108,23 @@ true
    + + dbo + ActivityIndex
    + 7 + EffectiveOn + DateTime + + 93 + smalldatetime + false + 16 + 16 + 0 + NoNulls + false + +
    dbo ActivityIndex
    @@ -300,14 +300,14 @@ dbo ActivityIndex
    - PK_ActivityIndex_1 + PK_ActivityIndex 1 true false false false 1 - 18 + 22 false @@ -762,7 +762,7 @@ false false 3 - 19 + 20 false @@ -2979,7 +2979,7 @@ false false 1 - 2 + 3 false @@ -4062,7 +4062,7 @@ false false 1 - 14 + 17 false @@ -4395,6 +4395,23 @@ dbo UserAccount
    17 + JournalistData + VarChar + + -9 + nvarchar + false + 0 + 0 + 0 + Nullable + true + +
    + + dbo + UserAccount
    + 18 PasswordToken VarChar @@ -4411,7 +4428,7 @@ dbo UserAccount
    - 18 + 19 PasswordHashed VarChar @@ -4428,7 +4445,7 @@ dbo UserAccount
    - 19 + 20 PasswordHistory VarChar @@ -4445,7 +4462,7 @@ dbo UserAccount
    - 20 + 21 PasswordChangedAt DateTime @@ -4462,7 +4479,7 @@ dbo UserAccount
    - 21 + 22 LastLoginAt DateTime @@ -4479,7 +4496,7 @@ dbo UserAccount
    - 22 + 23 LastInvalidLoginAt DateTime @@ -4496,7 +4513,7 @@ dbo UserAccount
    - 23 + 24 InvalidLoginCount SmallInt @@ -4513,7 +4530,7 @@ dbo UserAccount
    - 24 + 25 Notes VarChar @@ -4530,7 +4547,7 @@ dbo UserAccount
    - 25 + 26 Flags SmallInt @@ -4547,7 +4564,7 @@ dbo UserAccount
    - 26 + 27 Status VarChar @@ -4564,7 +4581,7 @@ dbo UserAccount
    - 27 + 28 CreateOn DateTime @@ -4581,7 +4598,7 @@ dbo UserAccount
    - 28 + 29 CreateBy Int @@ -4598,7 +4615,7 @@ dbo UserAccount
    - 29 + 30 CreateHost VarChar @@ -4615,7 +4632,7 @@ dbo UserAccount
    - 30 + 31 UpdateOn DateTime @@ -4632,7 +4649,7 @@ dbo UserAccount
    - 31 + 32 UpdateBy Int @@ -4649,7 +4666,7 @@ dbo UserAccount
    - 32 + 33 UpdateHost VarChar @@ -5138,7 +5155,7 @@ false false 1 - 24 + 32 false @@ -6385,7 +6402,7 @@ false false 1 - 14 + 15 false