v1.0.5.3
Activity index, Db schema validation.
This commit is contained in:
@@ -7,7 +7,7 @@ namespace Saxonite.Net.Core.UnitTests.Data.Population
|
||||
{
|
||||
//=======================================================================
|
||||
[TestClass]
|
||||
class SaxoniteRegionPopulation_Tester
|
||||
public class SaxoniteRegionPopulation_Tester
|
||||
{
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ namespace Saxonite.Net.Core.UnitTests.Web.Admin.App
|
||||
{
|
||||
//=======================================================================
|
||||
[TestClass]
|
||||
public class SaxSessionData_Tester
|
||||
public class SaxSessionData_Admin_Tester
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
@@ -23,7 +23,7 @@ namespace Saxonite.Net.Core.UnitTests.Web.Admin.App
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[TestMethod]
|
||||
public void Test_SmmSessionData_Serialization()
|
||||
public void Test_SmmSessionData_Admin_Serialization()
|
||||
{
|
||||
// User account.
|
||||
SaxAccountMgr accountMgr = Internals.AccountMgr;
|
||||
+59
-23
@@ -15,7 +15,7 @@ namespace Saxonite.Net.Core.UnitTests.Web.Online.App
|
||||
{
|
||||
//=======================================================================
|
||||
[TestClass]
|
||||
public class SaxSessionData_Tester
|
||||
public class SaxSessionData_Online_Tester
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
@@ -24,7 +24,7 @@ namespace Saxonite.Net.Core.UnitTests.Web.Online.App
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[TestMethod]
|
||||
public void Test_SmmSessionData_Serialization()
|
||||
public void Test_SmmSessionData_Online_Serialization()
|
||||
{
|
||||
// User account.
|
||||
SaxAccountMgr accountMgr = Internals.AccountMgr;
|
||||
@@ -35,20 +35,38 @@ namespace Saxonite.Net.Core.UnitTests.Web.Online.App
|
||||
userAccount.EmailAddress = "john.smith@acme.co.uk";
|
||||
userAccount.FirstName = "John";
|
||||
userAccount.LastName = "Smith";
|
||||
userAccount.RegionIdCountry = new SysId(SacsRandomHelper.GetInt32(Int32.MaxValue));
|
||||
userAccount.RegionIdProvince = new SysId(SacsRandomHelper.GetInt32(Int32.MaxValue));
|
||||
|
||||
// User Roles.
|
||||
List<SaxUserRole> userRoles = new List<SaxUserRole>();
|
||||
SaxUserRole userRole = accountMgr.CreateUserRole(userAccount.Id, Sax.UserRole.Journalist);
|
||||
userRoles.Add(userRole);
|
||||
|
||||
// User Sports.
|
||||
SaxSessionData_Online.UserProfileData.SportData sport1 = new SaxSessionData_Online.UserProfileData.SportData(new SysId(SacsRandomHelper.GetInt32(Int32.MaxValue)), Sarand.Net.Standard.Base.Core.SaStatus.Active);
|
||||
SaxSessionData_Online.UserProfileData.SportData sport2 = new SaxSessionData_Online.UserProfileData.SportData(new SysId(SacsRandomHelper.GetInt32(Int32.MaxValue)), Sarand.Net.Standard.Base.Core.SaStatus.Active);
|
||||
SaxSessionData_Online.UserProfileData.SportData sport3 = new SaxSessionData_Online.UserProfileData.SportData(new SysId(SacsRandomHelper.GetInt32(Int32.MaxValue)), Sarand.Net.Standard.Base.Core.SaStatus.Inactive);
|
||||
List<SaxSessionData_Online.UserProfileData.SportData> sports = new List<SaxSessionData_Online.UserProfileData.SportData>()
|
||||
{
|
||||
sport1, sport2, sport3
|
||||
};
|
||||
|
||||
// Create user session and verify user id.
|
||||
SaxSessionData_Online sessionData = new SaxSessionData_Online(App.SessionContext, userAccount, userRoles);
|
||||
Assert.AreEqual(SysId.ToInt(sessionData.User.UserAccountId), SysId.ToInt(sessionData.User.UserAccountId));
|
||||
Assert.AreEqual(userAccount.FirstName, sessionData.User.FirstName);
|
||||
Assert.AreEqual(userAccount.LastName, sessionData.User.LastName);
|
||||
Assert.AreEqual(userAccount.RegionIdCountry, sessionData.User.RegionIdCountry);
|
||||
Assert.AreEqual(userAccount.RegionIdProvince, sessionData.User.RegionIdProvince);
|
||||
Assert.IsTrue(sessionData.ValidUserSession);
|
||||
Assert.AreNotEqual("", sessionData.User.DisplayName);
|
||||
|
||||
// Profile sports.
|
||||
foreach (SaxSessionData_Online.UserProfileData.SportData sport in sports)
|
||||
sessionData.Profile.AddSport(sport.SportId, sport.Status);
|
||||
Assert.AreEqual(sports.Count, sessionData.Profile.Sports.Count);
|
||||
|
||||
// Filter properties.
|
||||
SysId filterOrganisationId = new SysId(SacsRandomHelper.GetInt32(Int32.MaxValue));
|
||||
String filterOrganisationCaption = "Filter organisation caption";
|
||||
@@ -64,34 +82,52 @@ namespace Saxonite.Net.Core.UnitTests.Web.Online.App
|
||||
Assert.AreNotEqual("", sessionDataJson);
|
||||
|
||||
// Deserialise session data using same method as base controller.
|
||||
SaxSessionData_Online sessionDataDeserialized =
|
||||
SaxSessionData_Online sessionDataDeserialised =
|
||||
JsonConvert.DeserializeObject<SaxSessionData_Online>(
|
||||
sessionDataJson,
|
||||
new JsonSerializerSettings { ContractResolver = new SaxController_Base.SessionStorage.SaxSessionDataContractResolver() }
|
||||
SaxController_Base.SessionStorage.JsonDeserialisationSettings
|
||||
);
|
||||
Assert.IsNotNull(sessionDataDeserialized);
|
||||
Assert.IsNotNull(sessionDataDeserialised);
|
||||
|
||||
// Validate deserialised values.
|
||||
Assert.AreEqual(App.SessionContext.Index, sessionDataDeserialized.SessionContext.Index);
|
||||
Assert.AreEqual(Sax.Application.Online, sessionDataDeserialized.SessionContext.Application);
|
||||
Assert.AreEqual(SysId.ToInt(sessionDataDeserialized.User.UserAccountId), SysId.ToInt(sessionDataDeserialized.User.UserAccountId));
|
||||
Assert.AreEqual(SysId.ToInt(sessionData.User.UserAccountId), SysId.ToInt(sessionDataDeserialized.User.UserAccountId));
|
||||
Assert.AreEqual(sessionData.User.EmailAddress, sessionDataDeserialized.User.EmailAddress);
|
||||
Assert.AreEqual(sessionData.User.FirstName, sessionDataDeserialized.User.FirstName);
|
||||
Assert.AreEqual(sessionData.User.LastName, sessionDataDeserialized.User.LastName);
|
||||
Assert.AreEqual(sessionData.User.DisplayName, sessionDataDeserialized.User.DisplayName);
|
||||
Assert.AreEqual(App.SessionContext.Index, sessionDataDeserialised.SessionContext.Index);
|
||||
Assert.AreEqual(Sax.Application.Online, sessionDataDeserialised.SessionContext.Application);
|
||||
Assert.AreEqual(SysId.ToInt(sessionDataDeserialised.User.UserAccountId), SysId.ToInt(sessionDataDeserialised.User.UserAccountId));
|
||||
Assert.AreEqual(SysId.ToInt(sessionData.User.UserAccountId), SysId.ToInt(sessionDataDeserialised.User.UserAccountId));
|
||||
Assert.AreEqual(sessionData.User.EmailAddress, sessionDataDeserialised.User.EmailAddress);
|
||||
Assert.AreEqual(sessionData.User.FirstName, sessionDataDeserialised.User.FirstName);
|
||||
Assert.AreEqual(sessionData.User.LastName, sessionDataDeserialised.User.LastName);
|
||||
Assert.AreEqual(sessionData.User.DisplayName, sessionDataDeserialised.User.DisplayName);
|
||||
Assert.AreEqual(sessionData.User.RegionIdCountry, sessionDataDeserialised.User.RegionIdCountry);
|
||||
Assert.AreEqual(sessionData.User.RegionIdProvince, sessionDataDeserialised.User.RegionIdProvince);
|
||||
|
||||
// User roles.
|
||||
Assert.AreEqual(userRoles.Count, sessionDataDeserialized.User.Roles.Count);
|
||||
Assert.AreEqual(userRoles.Count, sessionDataDeserialised.User.Roles.Count);
|
||||
foreach (var userRoleDeserialised in sessionDataDeserialised.User.Roles)
|
||||
{
|
||||
Assert.AreNotEqual(0, userRoleDeserialised.Role);
|
||||
}
|
||||
|
||||
// Profile sports.
|
||||
Assert.AreEqual(sports.Count, sessionDataDeserialised.Profile.Sports.Count);
|
||||
foreach (SaxSessionData_Online.UserProfileData.SportData sport in sports)
|
||||
{
|
||||
SaxSessionData_Online.UserProfileData.SportData sportDeserialised = sessionDataDeserialised.Profile.Sports.Find(item => item.SportId.Equals(sport.SportId));
|
||||
Assert.IsNotNull(sportDeserialised);
|
||||
Assert.AreEqual(sport.SportId, sportDeserialised.SportId);
|
||||
Assert.AreEqual(sport.Status, sportDeserialised.Status);
|
||||
}
|
||||
|
||||
// Filter properties.
|
||||
Assert.IsNotNull(sessionDataDeserialized.Filter);
|
||||
Assert.IsNotNull(sessionDataDeserialized.Filter.OrganisationId);
|
||||
Assert.IsTrue(SysId.IsValid(sessionDataDeserialized.Filter.OrganisationId));
|
||||
Assert.AreEqual(filterOrganisationId, sessionDataDeserialized.Filter.OrganisationId);
|
||||
Assert.AreEqual(filterOrganisationCaption, sessionDataDeserialized.Filter.OrganisationCaption);
|
||||
Assert.IsNotNull(sessionDataDeserialized.Filter.OrganisationIdMember);
|
||||
Assert.IsTrue(SysId.IsValid(sessionDataDeserialized.Filter.OrganisationIdMember));
|
||||
Assert.AreEqual(filterOrganisationIdMember, sessionDataDeserialized.Filter.OrganisationIdMember);
|
||||
Assert.AreEqual(filterOrganisationCaptionMember, sessionDataDeserialized.Filter.OrganisationCaptionMember);
|
||||
Assert.IsNotNull(sessionDataDeserialised.Filter);
|
||||
Assert.IsNotNull(sessionDataDeserialised.Filter.OrganisationId);
|
||||
Assert.IsTrue(SysId.IsValid(sessionDataDeserialised.Filter.OrganisationId));
|
||||
Assert.AreEqual(filterOrganisationId, sessionDataDeserialised.Filter.OrganisationId);
|
||||
Assert.AreEqual(filterOrganisationCaption, sessionDataDeserialised.Filter.OrganisationCaption);
|
||||
Assert.IsNotNull(sessionDataDeserialised.Filter.OrganisationIdMember);
|
||||
Assert.IsTrue(SysId.IsValid(sessionDataDeserialised.Filter.OrganisationIdMember));
|
||||
Assert.AreEqual(filterOrganisationIdMember, sessionDataDeserialised.Filter.OrganisationIdMember);
|
||||
Assert.AreEqual(filterOrganisationCaptionMember, sessionDataDeserialised.Filter.OrganisationCaptionMember);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -3,7 +3,9 @@ using Microsoft.AspNetCore.Mvc.Localization;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using System;
|
||||
@@ -119,6 +121,17 @@ namespace Saxonite.Net.Core.Web.Base.App
|
||||
return value;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Numeric and datetime formatting
|
||||
//-------------------------------------------------------------------
|
||||
public static String DateFormat_Default { get; } = "d-MMM-yyyy";
|
||||
public static String DateWithWeekdayFormat_Default { get; } = "ddd d-MMM-yyyy";
|
||||
public String FormatDate(DateTime value, Boolean includeWeekday = true)
|
||||
{
|
||||
String dateFormat = includeWeekday ? DateWithWeekdayFormat_Default : DateFormat_Default;
|
||||
return DateUtil.Format(value, dateFormat);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Specific phrase translation.
|
||||
//-------------------------------------------------------------------
|
||||
@@ -208,6 +221,11 @@ namespace Saxonite.Net.Core.Web.Base.App
|
||||
// ToDo Region name localisation.
|
||||
return region.Name;
|
||||
}
|
||||
public String GetRegionName(SysId regionId, String regionName)
|
||||
{
|
||||
// ToDo Region name localisation.
|
||||
return regionName;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Sport.
|
||||
@@ -217,6 +235,11 @@ namespace Saxonite.Net.Core.Web.Base.App
|
||||
// ToDo Sport name localisation.
|
||||
return sport.Name;
|
||||
}
|
||||
public String GetSportName(SysId sportId, String sportName)
|
||||
{
|
||||
// ToDo Sport name localisation.
|
||||
return sportName;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ using Saxonite.Net.Standard.Base.Bus;
|
||||
using Saxonite.Net.Standard.Base.Consoles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Base.Consoles
|
||||
{
|
||||
@@ -46,6 +47,20 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
|
||||
//-------------------------------------------------------------------
|
||||
// Query Activity Index Entries for User Context.
|
||||
//-------------------------------------------------------------------
|
||||
private class ActivityData_Web : IndexResults.ActivityData
|
||||
{
|
||||
public ActivityData_Web(ItemId itemId, DateTime effectiveOn) : base(itemId, effectiveOn) { }
|
||||
public void SetCaption(String caption) { Caption = caption; }
|
||||
public void SetBlurb(String blurb) { Blurb = blurb; }
|
||||
public void SetSport(SysId sportId, String sportName) { SportId = sportId; SportName = sportName; }
|
||||
public void SetRegion(SysId regionId, String regionName) { RegionId = regionId; RegionName = regionName; }
|
||||
public static int CompareActivityIndices(ActivityData_Web item1, ActivityData_Web item2)
|
||||
{
|
||||
int effectiveCompare = item1.EffectiveOn.CompareTo(item2.EffectiveOn);
|
||||
if (effectiveCompare != null) return effectiveCompare * -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
public override IndexResults QueryIndex(IndexContext context)
|
||||
{
|
||||
String fn = GetType().Name + ".QueryIndex";
|
||||
@@ -55,6 +70,7 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
|
||||
// Columns to query.
|
||||
ColumnDfn colItemType = internals.ActivityMgr.GetActivityIndexColumnDfn(SaxActivityIndex.Column.ItemType);
|
||||
ColumnDfn colItemId = internals.ActivityMgr.GetActivityIndexColumnDfn(SaxActivityIndex.Column.ItemId);
|
||||
String colDataNameEffectiveOn = "EffectiveOn";
|
||||
|
||||
// Query the index.
|
||||
ISacsDatabase db = SaxGlobals.App.GetCoreDatabase(SessionContext);
|
||||
@@ -62,9 +78,10 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
|
||||
query.Tables.Add(SaxDbDfn_Core.GetTableName(SaxDbDfn_Core.TableIdx.ActivityIndex, false), alias_ActivityIndex);
|
||||
query.Columns.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemType, alias_ActivityIndex), colItemType.DataName);
|
||||
query.Columns.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemId, alias_ActivityIndex), colItemId.DataName);
|
||||
query.Columns.Add("Max(" + SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_EffectiveOn) + ")", alias_ActivityIndex);
|
||||
query.Columns.Add("Max(" + SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_EffectiveOn, alias_ActivityIndex) + ")", colDataNameEffectiveOn);
|
||||
query.GroupBy.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemType, alias_ActivityIndex));
|
||||
query.GroupBy.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemId, alias_ActivityIndex));
|
||||
query.OrderBy.Add("Max(" + SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_EffectiveOn, alias_ActivityIndex) + ") DESC");
|
||||
|
||||
// Filter.
|
||||
SaxActivityIndex.Params prmActivityIndex = new SaxActivityIndex.Params();
|
||||
@@ -75,6 +92,8 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
|
||||
prmActivityIndex.Alias_ActivityIndex = alias_ActivityIndex;
|
||||
query.Filters.AddRange(internals.ActivityMgr.GetActivityIndexQueryFilter(prmActivityIndex));
|
||||
|
||||
// First pass, note the activity Item and effective date.
|
||||
List<ActivityData_Web> activityDataList = new List<ActivityData_Web>();
|
||||
using (DbResultSet dbResultSet = DbResultSet_DataReader.ExecuteQuery(db, query.BuildQuery(context.Paging)))
|
||||
{
|
||||
while (dbResultSet != null && dbResultSet.NextRecord())
|
||||
@@ -82,14 +101,121 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
|
||||
NamedValue.Map values = dbResultSet.GetRecordValues();
|
||||
Sax.DataItemType itemType = (Sax.DataItemType)values.GetLong(colItemType.DataName);
|
||||
ItemId itemId = new ItemId((short)itemType, new SysId(values.GetLong(colItemId.DataName)));
|
||||
|
||||
SaLogger.Info(fn + " Activity found - " + itemType.ToString() + ":" + SysId.ToString(itemId.Id));
|
||||
DateTime effectiveOn = values.GetDate(colDataNameEffectiveOn);
|
||||
activityDataList.Add(new ActivityData_Web(itemId, effectiveOn));
|
||||
SaLogger.Info(fn + " Activity found - " + itemType.ToString() + ":" + SysId.ToString(itemId.Id) + ". Effective: " + DateUtil.Format(effectiveOn, "d-MMM-yyyy"));
|
||||
}
|
||||
}
|
||||
activityDataList.Sort(ActivityData_Web.CompareActivityIndices);
|
||||
|
||||
// Populate activity details.
|
||||
PopulateActivityDetails(activityDataList);
|
||||
|
||||
// ToDo Remove activities with blank caption.
|
||||
|
||||
results.Items.AddRange(activityDataList);
|
||||
return results;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Populate Activity Details.
|
||||
//-------------------------------------------------------------------
|
||||
private void PopulateActivityDetails(List<ActivityData_Web> activities)
|
||||
{
|
||||
PopulateJournalistArticleDetails(activities);
|
||||
PopulateOrganisationOpportunitiesDetails(activities);
|
||||
}
|
||||
private void PopulateJournalistArticleDetails(List<ActivityData_Web> activities)
|
||||
{
|
||||
// Extract article Ids.
|
||||
List<SysId> articleIds = activities.FindAll(item => item.ItemId.Type == (int)Sax.DataItemType.JournalistArticle).Select(ItemId => ItemId.ItemId.Id).ToList();
|
||||
if (articleIds.IsEmpty()) return;
|
||||
|
||||
// Article columns - limit to essential information.
|
||||
ColumnDfn colId = Internals.ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Id);
|
||||
ColumnDfn colHeadline = Internals.ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Headline);
|
||||
ColumnDfn colSummary = Internals.ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Summary);
|
||||
ColumnDfn colSportId = Internals.ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.SportIdPrimary);
|
||||
ColumnDfn colSportName = Internals.ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Sport_Name);
|
||||
ColumnDfn colRegionId = Internals.ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.RegionIdPrimary);
|
||||
ColumnDfn colRegionName = Internals.ActivityMgr.GetJournalistArticleColumnDfn(SaxJournalistArticle.Column.Region_Name);
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>() { colId, colHeadline, colSummary, colSportId, colSportName, colRegionId, colRegionName };
|
||||
|
||||
// Article filter.
|
||||
SaxJournalistArticle.Params prmArticle = new SaxJournalistArticle.Params();
|
||||
prmArticle.IdsIncluded.AddRange(articleIds);
|
||||
prmArticle.StatusCat = SaxJournalistArticle.StatusCat.ActiveOnly;
|
||||
|
||||
using (DbResultSet dbResultSet = Internals.ActivityMgr.ExecuteJournalistArticleQuery(columns, prmArticle))
|
||||
{
|
||||
while (dbResultSet != null && dbResultSet.NextRecord())
|
||||
{
|
||||
NamedValue.Map values = dbResultSet.GetRecordValues();
|
||||
ItemId itemId = new ItemId((short)Sax.DataItemType.JournalistArticle, new SysId(values.GetLong(colId.DataName)));
|
||||
String headline = values.GetString(colHeadline.DataName);
|
||||
String summary = values.GetString(colSummary.DataName);
|
||||
SysId sportId = new SysId(values.GetLong(colSportId.DataName));
|
||||
String sportName = values.GetString(colSportName.DataName);
|
||||
SysId regionId = new SysId(values.GetLong(colRegionId.DataName));
|
||||
String regionName = values.GetString(colRegionName.DataName);
|
||||
|
||||
// Populate to corresponding activities.
|
||||
foreach (ActivityData_Web activity in activities.FindAll(item => item.ItemId.Equals(itemId)))
|
||||
{
|
||||
activity.SetCaption(headline);
|
||||
activity.SetBlurb(summary);
|
||||
activity.SetSport(sportId, sportName);
|
||||
activity.SetRegion(regionId, regionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void PopulateOrganisationOpportunitiesDetails(List<ActivityData_Web> activities)
|
||||
{
|
||||
// Extract opportunity Ids.
|
||||
List<SysId> opportunityIds = activities.FindAll(item => item.ItemId.Type == (int)Sax.DataItemType.OrganisationOpportunity).Select(ItemId => ItemId.ItemId.Id).ToList();
|
||||
if (opportunityIds.IsEmpty()) return;
|
||||
|
||||
// Opportunity columns - limit to essential information.
|
||||
ColumnDfn colId = Internals.ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Id);
|
||||
ColumnDfn colPosition = Internals.ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Position);
|
||||
ColumnDfn colOutline = Internals.ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Outline);
|
||||
ColumnDfn colSportId = Internals.ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.SportIdPrimary);
|
||||
ColumnDfn colSportName = Internals.ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Sport_Name);
|
||||
ColumnDfn colRegionId = Internals.ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.RegionIdPrimary);
|
||||
ColumnDfn colRegionName = Internals.ActivityMgr.GetOrganisationOpportunityColumnDfn(SaxOrganisationOpportunity.Column.Region_Name);
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>() { colId, colPosition, colOutline, colSportId, colSportName, colRegionId, colRegionName };
|
||||
|
||||
// Opportunity filter.
|
||||
SaxOrganisationOpportunity.Params prmOpportunity = new SaxOrganisationOpportunity.Params();
|
||||
prmOpportunity.IdsIncluded.AddRange(opportunityIds);
|
||||
prmOpportunity.StatusCat = SaxOrganisationOpportunity.StatusCat.ActiveOnly;
|
||||
|
||||
using (DbResultSet dbResultSet = Internals.ActivityMgr.ExecuteOrganisationOpportunityQuery(columns, prmOpportunity))
|
||||
{
|
||||
while (dbResultSet != null && dbResultSet.NextRecord())
|
||||
{
|
||||
NamedValue.Map values = dbResultSet.GetRecordValues();
|
||||
ItemId itemId = new ItemId((short)Sax.DataItemType.OrganisationOpportunity, new SysId(values.GetLong(colId.DataName)));
|
||||
String headline = values.GetString(colPosition.DataName);
|
||||
String summary = values.GetString(colOutline.DataName);
|
||||
SysId sportId = new SysId(values.GetLong(colSportId.DataName));
|
||||
String sportName = values.GetString(colSportName.DataName);
|
||||
SysId regionId = new SysId(values.GetLong(colRegionId.DataName));
|
||||
String regionName = values.GetString(colRegionName.DataName);
|
||||
|
||||
// Populate to corresponding activities.
|
||||
foreach (ActivityData_Web activity in activities.FindAll(item => item.ItemId.Equals(itemId)))
|
||||
{
|
||||
activity.SetCaption(headline);
|
||||
activity.SetBlurb(summary);
|
||||
activity.SetSport(sportId, sportName);
|
||||
activity.SetRegion(regionId, regionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Store Activity Index.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -309,13 +309,15 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
|
||||
return base.CreateProperties(type, MemberSerialization.Fields);
|
||||
}
|
||||
};
|
||||
public JsonSerializerSettings SaxSessionDataJsonSerializerSettings = new JsonSerializerSettings
|
||||
public static JsonSerializerSettings JsonDeserialisationSettings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new SaxSessionDataContractResolver()
|
||||
ContractResolver = new SaxSessionDataContractResolver(),
|
||||
// Force all deserialised objects to be replaced - to avoid proxy lists not populating.
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace
|
||||
};
|
||||
}
|
||||
private readonly SessionStorage sessionStorage = new SessionStorage();
|
||||
protected JsonSerializerSettings SaxSessionDataJsonSerializerSettings { get { return sessionStorage.SaxSessionDataJsonSerializerSettings; } }
|
||||
protected JsonSerializerSettings SaxSessionDataJsonSerializerSettings { get { return SessionStorage.JsonDeserialisationSettings; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
public SaxSessionData SessionData
|
||||
|
||||
@@ -3,13 +3,19 @@ using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Procs;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using Sarand.Net.Standard.Dbas.Data;
|
||||
using Sarand.Net.Standard.Dbas.Proc;
|
||||
using Saxonite.Net.Core.Web.Admin.Models;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using Saxonite.Net.Standard.Dbas.App;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Admin.Controllers
|
||||
@@ -17,7 +23,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
|
||||
//=======================================================================
|
||||
// System - Ajax - Database controller
|
||||
//=======================================================================
|
||||
partial class SystemController
|
||||
partial class SystemController : SaDbProcess_CompareDatabaseSchemas.IProcessNotifier
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Database data.
|
||||
@@ -92,6 +98,90 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Validate Database Schema ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
public class DbSchemaItemResponseData
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public String TableName { get; set; }
|
||||
public String ColumnName { get; set; }
|
||||
public int ColumnPosition { get; set; }
|
||||
public String IndexName { get; set; }
|
||||
public String Comment { get; set; }
|
||||
}
|
||||
public class AjaxResponse_ValidateDatabaseSchema : AjaxResponse_Data
|
||||
{
|
||||
public List<DbSchemaItemResponseData> Items { get; } = new List<DbSchemaItemResponseData>();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("System/Ajax/ValidateDatabaseSchema")]
|
||||
public IActionResult Ajax_ValidateDatabaseSchema(Model_Sport model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_GetDatabaseTables";
|
||||
String messageTitle = Localiser["system.caption.database"];
|
||||
AjaxResponse_ValidateDatabaseSchema responseData = new AjaxResponse_ValidateDatabaseSchema();
|
||||
|
||||
// Validate session.
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
|
||||
// Core Database connection.
|
||||
ISacsDatabase db = SaxGlobals.App.GetCoreDatabase(SessionContext);
|
||||
|
||||
// Retrieve XML database schema definition.
|
||||
var assembly = typeof(SaxSystem_Dbas).GetTypeInfo().Assembly;
|
||||
String xmlSchema = SacsResourceHelper.GetManifestResourceAsText(assembly, "", "SaxDbDfn_Core.xml");
|
||||
if (StringUtil.IsEmpty(xmlSchema))
|
||||
return Json(responseData.SetMessage(messageTitle, "Failed to extract XML schema definition."));
|
||||
|
||||
// Extract schema from XML definition.
|
||||
SaDbProcess_ConvertDbSchema.Config cfgSchemaConvert = new SaDbProcess_ConvertDbSchema.Config();
|
||||
SaDbProcess_ConvertDbSchema procSchemaConvert = new SaDbProcess_ConvertDbSchema(cfgSchemaConvert);
|
||||
List<DbDfnTable> tables = procSchemaConvert.ConvertXmlToTables(xmlSchema);
|
||||
if (procSchemaConvert.HasProcessError())
|
||||
return Json(responseData.SetMessage(messageTitle, "Failed to convert XML schema: " + procSchemaConvert.GetProcessError()));
|
||||
|
||||
SaDbProcess_CompareDatabaseSchemas.Config cfgSchemaCompare = new SaDbProcess_CompareDatabaseSchemas.Config(tables, db);
|
||||
cfgSchemaCompare.HideIdenticalObjects = true;
|
||||
SaDbProcess_CompareDatabaseSchemas procSchemaCompare = new SaDbProcess_CompareDatabaseSchemas(cfgSchemaCompare);
|
||||
procSchemaCompare.ProcessNotifier = this;
|
||||
procSchemaCompare.RunProcess();
|
||||
|
||||
List<SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItem> schemaComparisonItems = procSchemaCompare.GetSchemaComparisonItems();
|
||||
foreach (SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItem schemaComparisonItem in schemaComparisonItems)
|
||||
{
|
||||
DbSchemaItemResponseData item = new DbSchemaItemResponseData()
|
||||
{
|
||||
Id = schemaComparisonItem.Id,
|
||||
TableName = schemaComparisonItem.TableName,
|
||||
ColumnName = schemaComparisonItem.ColumnName,
|
||||
ColumnPosition = schemaComparisonItem.ColumnPosition,
|
||||
IndexName = schemaComparisonItem.IndexName,
|
||||
Comment = schemaComparisonItem.Comment
|
||||
};
|
||||
responseData.Items.Add(item);
|
||||
}
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
public void OnStartProcess()
|
||||
{
|
||||
}
|
||||
public void SetProgressInfo(List<string> progressInfo)
|
||||
{
|
||||
}
|
||||
public void OnEndProcess()
|
||||
{
|
||||
}
|
||||
public void OnSchemaComparisonItemAdded(SaDbProcess_CompareDatabaseSchemas proc)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models
|
||||
public Model_Home(SaxLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
AdditionalFiles_JS.Add("js/sax-home.js");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -159,6 +159,9 @@
|
||||
<data name="label.close" xml:space="preserve">
|
||||
<value>Close</value>
|
||||
</data>
|
||||
<data name="label.column" xml:space="preserve">
|
||||
<value>Column</value>
|
||||
</data>
|
||||
<data name="label.columns" xml:space="preserve">
|
||||
<value>Columns</value>
|
||||
</data>
|
||||
@@ -186,6 +189,9 @@
|
||||
<data name="label.forgotten.password" xml:space="preserve">
|
||||
<value>Forgotten password?</value>
|
||||
</data>
|
||||
<data name="label.index" xml:space="preserve">
|
||||
<value>Index</value>
|
||||
</data>
|
||||
<data name="label.indices" xml:space="preserve">
|
||||
<value>Indices</value>
|
||||
</data>
|
||||
@@ -273,6 +279,9 @@
|
||||
<data name="label.system" xml:space="preserve">
|
||||
<value>System</value>
|
||||
</data>
|
||||
<data name="label.table" xml:space="preserve">
|
||||
<value>Table</value>
|
||||
</data>
|
||||
<data name="label.title" xml:space="preserve">
|
||||
<value>Title</value>
|
||||
</data>
|
||||
@@ -441,9 +450,15 @@
|
||||
<data name="system.caption.database" xml:space="preserve">
|
||||
<value>System - Database</value>
|
||||
</data>
|
||||
<data name="system.caption.database.schema" xml:space="preserve">
|
||||
<value>Database Schema</value>
|
||||
</data>
|
||||
<data name="system.caption.logs" xml:space="preserve">
|
||||
<value>System - Logs</value>
|
||||
</data>
|
||||
<data name="system.msg.database.schema.valid" xml:space="preserve">
|
||||
<value>Database schema is valid.</value>
|
||||
</data>
|
||||
<data name="user.caption.select.user.roles" xml:space="preserve">
|
||||
<value>Select User Roles</value>
|
||||
</data>
|
||||
|
||||
@@ -3,6 +3,31 @@
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">Welcome</h1>
|
||||
<script>
|
||||
sax.msg.dbSchemaValid = '@Localiser.GetJavascriptText("system.msg.database.schema.valid")';
|
||||
</script>
|
||||
|
||||
<div class="sax-panel-info sax-panel-results DbSchema">
|
||||
|
||||
<div class="sax-header">
|
||||
<div class="sax-caption">@Localiser["system.caption.database.schema"]</div>
|
||||
</div>
|
||||
<div class="sax-content">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div class="sax-panel-item-list"></div>
|
||||
<div class="sax-panel-item-template">
|
||||
<div class="sax-panel-item DbSchemaItem">
|
||||
<div class="sax-header">
|
||||
<div class="sax-caption SchemaTable">@(Localiser["label.table"]): <span class="TableName"></span></div>
|
||||
</div>
|
||||
<div class="sax-content">
|
||||
<div class="SchemaIndex">@(Localiser["label.index"]): <span class="IndexName"></span></div>
|
||||
<div class="SChemColumn">@(Localiser["label.column"]): <span class="ColumnName"></span></div>
|
||||
<div class=""><span class="Comment"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -6,12 +6,14 @@
|
||||
|
||||
<div class="">
|
||||
<div class="sax-panel-form security">
|
||||
|
||||
<div class="sax-header"><div class="sax-caption">@Localiser["security.caption.change.password"]</div></div>
|
||||
|
||||
<div class="sax-content">
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmChangePassword", @class = "sax-form" }))
|
||||
{
|
||||
|
||||
<div class="sax-heading"><div class="sax-caption">@Localiser["security.caption.change.password"]</div></div>
|
||||
|
||||
|
||||
@if (!Model.RequestPasswordMode)
|
||||
{
|
||||
/* Current password - required when setting password within user session. */
|
||||
@@ -60,3 +62,4 @@
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
|
||||
<div class="">
|
||||
<div class="sax-panel-form security">
|
||||
|
||||
<div class="sax-header"><div class="sax-caption">@Localiser["security.caption.request.password"]</div></div>
|
||||
|
||||
<div class="sax-content">
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmRequestPassword", @class = "sax-form" }))
|
||||
{
|
||||
|
||||
<div class="sax-heading"><div class="sax-caption">@Localiser["security.caption.request.password"]</div></div>
|
||||
|
||||
<div class="sax-form-control">
|
||||
<div class="sax-label">
|
||||
<label for="ifEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label>
|
||||
@@ -30,3 +33,4 @@
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
|
||||
<div class="sax-panel-form security">
|
||||
|
||||
<div class="sax-header"><div class="sax-caption">@Localiser["security.caption.signin"]</div></div>
|
||||
|
||||
<div class="sax-content">
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSignIn", @class = "sax-form" }))
|
||||
{
|
||||
|
||||
<div class="sax-heading"><div class="sax-caption">@Localiser["security.caption.signin"]</div></div>
|
||||
|
||||
<div class="sax-form-control">
|
||||
<div class="sax-label">
|
||||
<label for="ifEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label>
|
||||
@@ -56,5 +58,5 @@
|
||||
|
||||
}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -102,9 +102,11 @@
|
||||
</button>
|
||||
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
|
||||
<ul class="navbar-nav flex-grow-1">
|
||||
@*
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">@Localiser["home.caption.home"]</a>
|
||||
</li>
|
||||
*@
|
||||
@if (Model.AwaitingLogin)
|
||||
{
|
||||
<li class="nav-item">
|
||||
@@ -179,7 +181,7 @@
|
||||
@* Footer *@
|
||||
<footer class="border-top footer text-muted">
|
||||
<div class="container">
|
||||
@(Model.CopyrightNotice) - @Localiser["company.name"] @(Model.InstanceVersion) - <a asp-area="" asp-controller="Home" asp-action="">Home</a> - <a asp-area="" asp-controller="Policies" asp-action="Privacy">Privacy</a>
|
||||
@(Model.CopyrightNotice) - @Localiser["company.name"] @(Model.InstanceVersion) - <a asp-area="" asp-controller="Home" asp-action="">Home</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header
|
||||
.sax-panel-item > .sax-header
|
||||
{
|
||||
padding: 2px 8px;
|
||||
min-height: 24px;
|
||||
@@ -116,40 +116,45 @@
|
||||
border-bottom: solid 2px #979797;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-caption
|
||||
.sax-panel-item > .sax-header .sax-caption
|
||||
{
|
||||
margin-top: 4px;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-action
|
||||
.sax-panel-item > .sax-header .sax-action
|
||||
{
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-caption .sax-action:hover
|
||||
.sax-panel-item >.sax-header .sax-caption .sax-action:hover
|
||||
{
|
||||
color: var(--color-light);
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-actions .sax-action
|
||||
.sax-panel-item > .sax-header .sax-actions .sax-action
|
||||
{
|
||||
margin: 2px 0 0 8px;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-actions .sax-action:hover
|
||||
.sax-panel-item > .sax-header .sax-actions .sax-action:hover
|
||||
{
|
||||
background-color: #c0c0c0;
|
||||
box-shadow: 0 0 4px 2px #c0c0c080;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-content
|
||||
.sax-panel-item > .sax-content
|
||||
{
|
||||
margin: 4px 8px;
|
||||
padding: 4px 4px;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-note
|
||||
{
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
@media (min-width: 576px)
|
||||
{
|
||||
.sax-panel-filter
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
{
|
||||
max-width: 720px;
|
||||
margin: 24px auto;
|
||||
padding: 24px 24px;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
border: solid 2px #979797;
|
||||
border-color: var(--color-primary);
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sax-panel-form.security
|
||||
@@ -28,22 +30,95 @@
|
||||
}
|
||||
}
|
||||
|
||||
.sax-panel-info > .sax-header,
|
||||
.sax-panel-form > .sax-header
|
||||
{
|
||||
padding: 12px 12px;
|
||||
text-align: center;
|
||||
background-color: #e8e8e8;
|
||||
border-bottom: solid 1px #606060;
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.sax-panel-info > .sax-header .sax-caption,
|
||||
.sax-panel-form > .sax-header .sax-caption
|
||||
{
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: var(--color-primary-dark);
|
||||
}
|
||||
|
||||
.sax-panel-info > .sax-header .sax-action img:hover,
|
||||
.sax-panel-form > .sax-header .sax-action img:hover
|
||||
{
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4px;
|
||||
box-shadow: 2px 2px 4px 0 #80808080;
|
||||
}
|
||||
|
||||
.sax-panel-info > .sax-content,
|
||||
.sax-panel-form > .sax-content
|
||||
{
|
||||
max-height: 400px;
|
||||
padding: 12px 12px;
|
||||
background-color: #f8f8f8;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sax-panel-section.sax-edit .sax-panel-info,
|
||||
.sax-panel-section.sax-populating .sax-button-action.edit,
|
||||
.sax-panel-section .sax-panel-form
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sax-panel-section.sax-edit .sax-panel-form
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Form */
|
||||
|
||||
.sax-form
|
||||
{
|
||||
}
|
||||
|
||||
.sax-form .sax-heading
|
||||
/* Labels, values, notes */
|
||||
|
||||
.sax-panel-info .sax-label, .sax-panel-info .sax-value
|
||||
{
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 6px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.sax-form .sax-heading .sax-caption
|
||||
.sax-panel-info .sax-label
|
||||
{
|
||||
font-size: 1.5rem;
|
||||
padding-right: 16px;
|
||||
font-weight: bold;
|
||||
color: var(--color-primary);
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.sax-panel-info .sax-value
|
||||
{
|
||||
}
|
||||
|
||||
.sax-form .sax-form-control .sax-label
|
||||
{
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 1rem;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.sax-form .sax-form-control .sax-label-text
|
||||
{
|
||||
font-size: 1rem;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.sax-form .sax-form-control .sax-note
|
||||
{
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* Controls */
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Admin - Home page scripts.
|
||||
*/
|
||||
|
||||
(function (win, doc, undef)
|
||||
{
|
||||
"use strict";
|
||||
sax.itemIdPrefix = 'Itm_';
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sax.refreshDbSchema= function (delay)
|
||||
{
|
||||
var $results = $('.sax-panel-results.DbSchema');
|
||||
if (!sax.awaitingRefreshResponse)
|
||||
{
|
||||
var $items = $('.sax-panel-item-list', $results).fadeOut(200).empty();
|
||||
var $msgs = $('.sax-panel-messages', $results).hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sax.ajaxDbSchema = sax.ajaxDbSchema || { url: sax.url.base + 'System/Ajax/ValidateDatabaseSchema', formId: 'frmNavigate', callbackFn: sax.handleDbSchemaResponse, noWaitIcon: true };
|
||||
sax.doAjaxRequest(sax.ajaxDbSchema, delay || 50);
|
||||
sax.awaitingRefreshResponse = true;
|
||||
}
|
||||
sax.handleDbSchemaResponse = function (response)
|
||||
{
|
||||
sax.debug('handleDbSchemaResponse', response);
|
||||
delete sax.awaitingRefreshResponse;
|
||||
var $results = $('.sax-panel-results.DbSchema');
|
||||
var $msgs = $('.sax-panel-messages', $results).hide().empty();
|
||||
var $items = $('.sax-panel-item-list', $results).hide().empty();
|
||||
var $tmpl = $('.sax-panel-item-template .sax-panel-item.DbSchemaItem', $results);
|
||||
if (!response.success) return;
|
||||
// Items.
|
||||
var items = response.items;
|
||||
if (!items.length)
|
||||
return $msgs.append($('<div class="sax-message">' + sax.msg.dbSchemaValid + '</div>')).fadeIn(500);
|
||||
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
|
||||
{
|
||||
let item = items[itemIdx];
|
||||
let $item = $tmpl.clone();
|
||||
sax.populateItem($item, item);
|
||||
$items.append($item);
|
||||
}
|
||||
$items.fadeIn(50);
|
||||
}
|
||||
sax.populateItem = function ($item, item)
|
||||
{
|
||||
if (!item) return;
|
||||
$item.prop('id', sax.itemIdPrefix + item.id);
|
||||
$('.TableName', $item).text(item.tableName);
|
||||
$('.IndexName', $item).text(item.indexName);
|
||||
$('.SchemaIndex', $item).toggle(!!item.indexName);
|
||||
$('.ColumnName', $item).text(item.columnName);
|
||||
$('.SchemaColumn', $item).toggle(!!item.columnName);
|
||||
$('.Comment', $item).text(item.comment);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
$(function ()
|
||||
{
|
||||
setTimeout(sax.refreshDbSchema, 250);
|
||||
});
|
||||
|
||||
}(window, window.document));
|
||||
|
||||
/* The End */
|
||||
@@ -159,6 +159,9 @@
|
||||
<data name="dialog.title.signout" xml:space="preserve">
|
||||
<value>Sign-out</value>
|
||||
</data>
|
||||
<data name="home.caption.activities" xml:space="preserve">
|
||||
<value>Activities</value>
|
||||
</data>
|
||||
<data name="home.caption.application" xml:space="preserve">
|
||||
<value>Online</value>
|
||||
</data>
|
||||
@@ -216,6 +219,9 @@
|
||||
<data name="label.delete" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
<data name="label.effective" xml:space="preserve">
|
||||
<value>Effective</value>
|
||||
</data>
|
||||
<data name="label.email.address" xml:space="preserve">
|
||||
<value>Email address</value>
|
||||
</data>
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Saxonite.Net.Core.Web.Base.App;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Online.App
|
||||
@@ -32,6 +36,54 @@ namespace Saxonite.Net.Core.Web.Online.App
|
||||
/// <summary>User - JSON deserialisation route.</summary>
|
||||
public new UserData User { get { return base.User; } set { SetUser(value); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// User Profile.
|
||||
// Protected constructors & setters for JSON deserialisation.
|
||||
public class UserProfileData
|
||||
{
|
||||
public UserProfileData() { }
|
||||
// Sports.
|
||||
public class SportData
|
||||
{
|
||||
public SportData(SysId sportId, SaStatus status)
|
||||
{
|
||||
SportId = sportId;
|
||||
Status = status;
|
||||
}
|
||||
public SysId SportId { get; protected set; }
|
||||
public SaStatus Status { get; protected set; }
|
||||
}
|
||||
private class SportData_Online : SportData
|
||||
{
|
||||
// Internal class to allow values to be updated.
|
||||
public SportData_Online(SysId sportId, SaStatus status) : base(sportId, status) { }
|
||||
public SportData_Online(SportData sportData) : base(sportData.SportId, sportData.Status) { }
|
||||
public void SetSportId(SysId sportId) { SportId = sportId; }
|
||||
public void SetStatus(SaStatus status) { Status = status; }
|
||||
}
|
||||
[JsonIgnore]
|
||||
private readonly List<SportData_Online> sports = new List<SportData_Online>();
|
||||
[JsonIgnore]
|
||||
public int SportCount { get { return sports.Count; } }
|
||||
public List<SportData> Sports { get { return new List<SportData>(sports); } protected set { sports.Clear(); sports.AddRange(value.Select(item => new SportData_Online(item))); } }
|
||||
public void AddSport(SysId sportId, SaStatus status)
|
||||
{
|
||||
if (!SysId.IsValid(sportId)) throw new NotSupportedException("Session Profile Sport must have a valid Id");
|
||||
SportData_Online sport = this.sports.Find(item => item.SportId == sportId);
|
||||
if (sport != null)
|
||||
{
|
||||
sport.SetStatus(status);
|
||||
}
|
||||
else
|
||||
this.sports.Add(new SportData_Online(sportId, status));
|
||||
}
|
||||
public void ClearSports()
|
||||
{
|
||||
this.sports.Clear();
|
||||
}
|
||||
}
|
||||
public UserProfileData Profile { get; protected set; } = new UserProfileData();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Filter properties.
|
||||
public class FilterData
|
||||
@@ -69,6 +121,25 @@ namespace Saxonite.Net.Core.Web.Online.App
|
||||
}
|
||||
public FilterData Filter { get; private set; } = new FilterData();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// JSON Deserialisation.
|
||||
[JsonExtensionData]
|
||||
#pragma warning disable IDE0044 // Add readonly modifier
|
||||
private IDictionary<string, JToken> _additionalData;
|
||||
#pragma warning restore IDE0044 // Add readonly modifier
|
||||
[OnDeserialized]
|
||||
private void OnDeserialized(StreamingContext context)
|
||||
{
|
||||
if (_additionalData != null)
|
||||
{
|
||||
foreach (String name in _additionalData.Keys)
|
||||
{
|
||||
JToken value = _additionalData[name];
|
||||
SaLogger.Info("OnDeserialized Name: " + name + ". Value: " + value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -5,6 +5,7 @@ using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Saxonite.Net.Core.Web.Base.App;
|
||||
using Saxonite.Net.Core.Web.Online.App;
|
||||
using Saxonite.Net.Core.Web.Online.Models;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
@@ -32,19 +33,12 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
public class ActivityResponseData
|
||||
{
|
||||
public short ItemType { get; set; }
|
||||
// NB Need to mask the Item Id by storing with XRef to alternative generated value in User's session.
|
||||
public int ItemIdx { get; set; }
|
||||
public long ItemIdx { get; set; }
|
||||
public String Caption { get; set; }
|
||||
}
|
||||
public class ArticleActivityResponseData : ActivityResponseData
|
||||
{
|
||||
public String Headline { get; set; }
|
||||
public String Summary { get; set; }
|
||||
}
|
||||
public class OpportunityActivityResponseData : ActivityResponseData
|
||||
{
|
||||
public String Position { get; set; }
|
||||
public String Outline { get; set; }
|
||||
public String Blurb { get; set; }
|
||||
public String Sport { get; set; }
|
||||
public String Region { get; set; }
|
||||
public String PublishedOnFmt{ get; set; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -52,7 +46,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
//-------------------------------------------------------------------
|
||||
public class AjaxResponse_ActivityList : AjaxResponse_Base
|
||||
{
|
||||
public List<SaxModel_Online.RegionData> Regions { get; } = new List<SaxModel_Online.RegionData>();
|
||||
public List<ActivityResponseData> Activities { get; } = new List<ActivityResponseData>();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
@@ -70,13 +64,34 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
return Forbid();
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
|
||||
// User context.
|
||||
SaxActivityConsole.IndexContext indexContext = new SaxActivityConsole.IndexContext();
|
||||
|
||||
// Regions.
|
||||
if (SysId.IsValid(sessionData.User.RegionIdProvince))
|
||||
indexContext.RegionIds.Add(sessionData.User.RegionIdProvince);
|
||||
else if (SysId.IsValid(sessionData.User.RegionIdCountry))
|
||||
indexContext.RegionIds.Add(sessionData.User.RegionIdCountry);
|
||||
|
||||
// Sports.
|
||||
indexContext.SportIds.AddRange(sessionData.Profile.Sports.Select(item => item.SportId));
|
||||
|
||||
// Populate activities.
|
||||
SaxActivityConsole.IndexContext indexContext = new SaxActivityConsole.IndexContext();
|
||||
SaxActivityConsole.IndexResults indexResults = ActivityConsole.QueryIndex(indexContext);
|
||||
foreach (SaxActivityConsole.IndexResults.ItemData itemData in indexResults.Items)
|
||||
foreach (SaxActivityConsole.IndexResults.ActivityData itemData in indexResults.Items)
|
||||
{
|
||||
|
||||
ActivityResponseData activityData = new ActivityResponseData();
|
||||
activityData.ItemType = itemData.ItemId.Type;
|
||||
// ToDo Mask activity index Id with cross-reference stored in session data.
|
||||
activityData.ItemIdx = SysId.ToLong(itemData.ItemId.Id);
|
||||
activityData.Caption = itemData.Caption;
|
||||
activityData.Blurb = itemData.Blurb;
|
||||
activityData.Sport = Localiser.GetSportName(itemData.SportId, itemData.SportName);
|
||||
activityData.Region = Localiser.GetRegionName(itemData.RegionId, itemData.RegionName);
|
||||
activityData.PublishedOnFmt = Localiser.FormatDate(itemData.EffectiveOn);
|
||||
responseData.Activities.Add(activityData);
|
||||
}
|
||||
|
||||
// Complete response.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using Saxonite.Net.Core.Web.Base.App;
|
||||
@@ -86,6 +87,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
|
||||
// Create session.
|
||||
OpenUserSession(SessionContext, userAccount, userRoles);
|
||||
RefreshSessionProfileSports();
|
||||
|
||||
// Send the 'Keep Logged In' cookie if requested.
|
||||
if (userAccount.KeepLoggedIn_Online)
|
||||
@@ -94,6 +96,39 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Populate the user's profile sports to the session.</summary>
|
||||
protected bool RefreshSessionProfileSports()
|
||||
{
|
||||
String fn = GetType().Name + ".RefreshSessionProfileSports";
|
||||
SaxSessionData_Online sessionData = SessionData_Online;
|
||||
SysId userAccountId = sessionData?.User.UserAccountId ?? null;
|
||||
if (!SysId.IsValid(userAccountId)) return false;
|
||||
sessionData.Profile.ClearSports();
|
||||
|
||||
// Read discrete values to avoid loading the entire UserSport records which can be substantial.
|
||||
ColumnDfn colSportId = AccountMgr.GetUserSportColumnDfn(SaxUserSport.Column.SportId);
|
||||
ColumnDfn colSportName = AccountMgr.GetUserSportColumnDfn(SaxUserSport.Column.Sport_Name);
|
||||
ColumnDfn colStatus = AccountMgr.GetUserSportColumnDfn(SaxUserSport.Column.Status);
|
||||
|
||||
SaxUserSport.Params prmUserSport = new SaxUserSport.Params();
|
||||
prmUserSport.UserAccountIdsIncluded.Add(userAccountId);
|
||||
prmUserSport.StatusCat = SaxUserSport.StatusCat.ActiveOnly;
|
||||
using (DbResultSet resultSet = AccountMgr.ExecuteUserSportQuery(new List<ColumnDfn>() { colSportId, colSportName, colStatus }, prmUserSport))
|
||||
{
|
||||
while (resultSet != null && resultSet.NextRecord())
|
||||
{
|
||||
NamedValue.Map values = resultSet.GetRecordValues();
|
||||
SysId sportId = new SysId(values.GetLong(colSportId.DataName));
|
||||
String sportName = values.GetString(colSportName.DataName);
|
||||
SaStatus status = SacsSystem.GetStatusForCode(values.GetString(colStatus.DataName));
|
||||
sessionData.Profile.AddSport(sportId, status);
|
||||
}
|
||||
}
|
||||
SaLogger.Debug(fn+" Profile Sports: " + sessionData.Profile.SportCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Start a new user session on sign-in.</summary>
|
||||
protected bool OpenUserSession(SaxSessionContext sessionContext, SaxUserAccount userAccount, List<SaxUserRole> userRoles)
|
||||
|
||||
@@ -56,9 +56,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
|
||||
|
||||
String errorMessage = "";
|
||||
if (!SignUserIn(userAccount, AccountMgr.GetRolesForUser(userAccount.Id), model.KeepMeSignedIn, ref errorMessage))
|
||||
{
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
responseData.Success = SessionData_Online?.ValidUserSession ?? false;
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
|
||||
public Model_Home(SaxLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
AdditionalFiles_CSS.Add("css/sax-home.css");
|
||||
AdditionalFiles_JS.Add("js/sax-home.js");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -4,6 +4,55 @@
|
||||
ViewData["Title"] = "Home";
|
||||
}
|
||||
|
||||
@if (Model.AwaitingLogin)
|
||||
{
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">@Localiser["home.caption.welcome"]</h1>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="sax-panel-filter">
|
||||
<div class="sax-header row">
|
||||
<div class="col"><div class="sax-caption">@Localiser["home.caption.activities"]</div></div>
|
||||
<div class="fixed row">
|
||||
</div>
|
||||
</div>
|
||||
<div class="sax-content">
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmActivityFilter", @class = "sax-form", @action = "#", @method = "POST", onsubmit = "return false;" }))
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-sm-4"><div class="sax-label text-left text-sm-right">@Localiser["label.search"]</div></div>
|
||||
<div class="col-sm-8"><input type="search" name="Filter.Activity" id="ifActivityFilter" class="ActivityFilter sax-input" maxlength="64" /></div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sax-panel-results">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div class="sax-panel-item-list"></div>
|
||||
<div class="sax-panel-item-template">
|
||||
<div class="sax-panel-item Activity">
|
||||
<div class="sax-header row">
|
||||
<div class="col">
|
||||
<div class="sax-caption"><div class="sax-action ActivityCaption"></div></div>
|
||||
</div>
|
||||
<div class="fixed sax-actions">
|
||||
</div>
|
||||
</div>
|
||||
<div class="sax-content">
|
||||
<div class="row">
|
||||
<div class="col-sm-12"><div class="ActivityBlurb"></div></div>
|
||||
<div class="col-sm-6">
|
||||
<div class="sax-note">
|
||||
<span class="ActivitySport"></span> - <span class="ActivityRegion"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 right"><div class="sax-note ActivityPublished">@Localiser["label.published"]: <span class="ActivityPublishedOn"></span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -122,29 +122,29 @@
|
||||
border-bottom: solid 1px #979797;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-caption
|
||||
.sax-panel-item > .sax-header .sax-caption
|
||||
{
|
||||
margin-top: 4px;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-action
|
||||
.sax-panel-item > .sax-header .sax-action
|
||||
{
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-caption .sax-action:hover
|
||||
.sax-panel-item > .sax-header .sax-caption .sax-action:hover
|
||||
{
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-actions .sax-action
|
||||
.sax-panel-item > .sax-header .sax-actions .sax-action
|
||||
{
|
||||
margin: 2px 0 0 8px;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-header .sax-actions .sax-action:hover
|
||||
.sax-panel-item > .sax-header .sax-actions .sax-action:hover
|
||||
{
|
||||
background-color: #c0c0c0;
|
||||
box-shadow: 0 0 4px 2px #c0c0c080;
|
||||
@@ -156,6 +156,11 @@
|
||||
padding: 4px 4px;
|
||||
}
|
||||
|
||||
.sax-panel-item .sax-note
|
||||
{
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
/* Profile Sports */
|
||||
|
||||
.sax-panel-item.ProfileSport,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
Home stylesheet.
|
||||
*/
|
||||
|
||||
|
||||
/* The End */
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Home scripts.
|
||||
*/
|
||||
|
||||
(function (win, doc, undef)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sax.refreshResults = function (delay)
|
||||
{
|
||||
var $results = $('.sax-panel-results');
|
||||
if (!sax.awaitingRefreshResponse)
|
||||
{
|
||||
var $items = $('.sax-panel-item-list', $results).fadeOut(200).empty();
|
||||
var $msgs = $('.sax-panel-messages', $results).hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sax.ajaxRefreshResults = sax.ajaxRefreshResults || { url: sax.url.base + 'Activity/Ajax/GetList', formId: 'frmActivityFilter', callbackFn: sax.doRefreshResults };
|
||||
sax.doAjaxRequest(sax.ajaxRefreshResults, delay || 50);
|
||||
sax.awaitingRefreshResponse = true;
|
||||
}
|
||||
sax.doRefreshResults = function (response)
|
||||
{
|
||||
sax.debug('doRefreshResults', response);
|
||||
delete sax.awaitingRefreshResponse;
|
||||
var $results = $('.sax-panel-results');
|
||||
var $msgs = $('.sax-panel-messages', $results).hide().empty();
|
||||
var $items = $('.sax-panel-item-list', $results).hide().empty();
|
||||
var $tmpl = $('.sax-panel-item-template .sax-panel-item', $results);
|
||||
if (!response.success) return;
|
||||
var items = response.activities;
|
||||
if (!items.length)
|
||||
return $msgs.append($('<div class="sax-message">' + sax.msg.dataNoneFound + '</div>')).fadeIn(500);
|
||||
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
|
||||
{
|
||||
let item = items[itemIdx];
|
||||
let $item = $tmpl.clone();
|
||||
sax.populateItem($item, item);
|
||||
$items.append($item);
|
||||
}
|
||||
$items.fadeIn(50);
|
||||
}
|
||||
sax.populateItem = function ($item, item)
|
||||
{
|
||||
if (!item) return;
|
||||
$item.prop('id', sax.itemIdPrefix + item.id);
|
||||
$('.ActivityCaption', $item).text(item.caption);
|
||||
$('.ActivityBlurb', $item).text(item.blurb);
|
||||
$('.ActivitySport', $item).text(item.sport);
|
||||
$('.ActivityRegion', $item).text(item.region);
|
||||
$('.ActivityPublishedOn', $item).text(item.publishedOnFmt);
|
||||
$item.off('click').on('click', function () { sax.expandItem(item.id) })
|
||||
$('.sax-panel-results .sax-panel-messages').hide().empty();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sax.expandItem = function (id)
|
||||
{
|
||||
sax.debug('expandItem(' + id + ')');
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
$(function ()
|
||||
{
|
||||
setTimeout(sax.refreshResults, 250);
|
||||
});
|
||||
|
||||
}(window, window.document));
|
||||
|
||||
/* The End */
|
||||
@@ -49,7 +49,6 @@
|
||||
sax.populateItem($item, item);
|
||||
$items.append($item);
|
||||
}
|
||||
$('.sax-action.sax-item-update', $items).toggle(sax.data.userCanManageOpportunities);
|
||||
$items.fadeIn(50);
|
||||
}
|
||||
sax.populateItem = function ($item, item)
|
||||
@@ -67,7 +66,8 @@
|
||||
$('.OpportunityExpiresOn', $item).text(item.expiresOnFmt);
|
||||
$('.OpportunityExpires', $item).toggle(!!item.expiresOnFmt);
|
||||
$('.OpportunityStatusDesc', $item).text(item.statusDesc);
|
||||
$('.sax-caption .sax-action, .sax-actions .sax-action.sax-item-update', $item).off('click').on('click', function () { sax.updateItem(item.id) });
|
||||
if (sax.data.userCanManageOpportunities)
|
||||
$('.sax-caption .sax-action, .sax-actions .sax-action.sax-item-update', $item).off('click').on('click', function () { sax.updateItem(item.id) }).removeClass('hidden');
|
||||
$item.off('dblclick').on('dblclick', function () { sax.updateItem(item.id) });
|
||||
$('.sax-panel-results .sax-panel-messages').hide().empty();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Saxonite.Net.Standard.Base.App
|
||||
//-------------------------------------------------------------------
|
||||
public static class Version
|
||||
{
|
||||
private static String version { get; } = "1.0.5.0";
|
||||
private static String version { get; } = "1.0.5.3";
|
||||
// Retrieve version.
|
||||
public static String GetFullVersion () { return version; }
|
||||
public static String GetAppVersion ()
|
||||
@@ -39,9 +39,9 @@ namespace Saxonite.Net.Standard.Base.App
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Version history.
|
||||
// 1.0.5 ?-May-2021 Activity Index
|
||||
// - Admin Database page.
|
||||
// - Online Account country.
|
||||
// 1.0.5 31-May-2021 Activity Index
|
||||
// - Admin Database Schema (Home) and Tables page.
|
||||
// - Online Account country, Home activities.
|
||||
// 1.0.4 20-May-2021 Online profile sports & opportunities
|
||||
// - Admin Organisation Region & Sport.
|
||||
// - Online Profile Sports - simple list with name.
|
||||
|
||||
@@ -69,6 +69,8 @@ namespace Saxonite.Net.Standard.Base.App
|
||||
LastName = userAccount.LastName;
|
||||
DisplayName = userAccount.GetDisplayName();
|
||||
EmailAddress = userAccount.EmailAddress;
|
||||
RegionIdCountry = userAccount.RegionIdCountry;
|
||||
RegionIdProvince = userAccount.RegionIdProvince;
|
||||
if (sessionContext.Application == Sax.Application.Admin)
|
||||
KeepLoggedIn = userAccount.KeepLoggedIn_Admin;
|
||||
else if (sessionContext.Application == Sax.Application.Online)
|
||||
@@ -87,12 +89,13 @@ namespace Saxonite.Net.Standard.Base.App
|
||||
public String LastName { get; protected set; }
|
||||
public String DisplayName { get; protected set; }
|
||||
public String EmailAddress { get; protected set; }
|
||||
public SysId RegionIdCountry { get; protected set; }
|
||||
public SysId RegionIdProvince { get; protected set; }
|
||||
public bool KeepLoggedIn { get; protected set; }
|
||||
public bool UserAccountSupplied { get; protected set; }
|
||||
// Roles.
|
||||
public class RoleData
|
||||
{
|
||||
private RoleData() { }
|
||||
public RoleData(SaxUserRole userRole)
|
||||
{
|
||||
if (userRole != null)
|
||||
@@ -107,13 +110,6 @@ namespace Saxonite.Net.Standard.Base.App
|
||||
[JsonIgnore]
|
||||
private readonly List<RoleData> roles = new List<RoleData>();
|
||||
public List<RoleData> Roles { get { return new List<RoleData>(roles); } protected set { roles.Clear(); roles.AddRange(value); } }
|
||||
/// <summary>User - JSON deserialisation route.</summary>
|
||||
protected void SetRoles(List<RoleData> roles)
|
||||
{
|
||||
if (this.roles.Count > 0)
|
||||
throw new NotSupportedException("Session Data Roles cannot be replaced.");
|
||||
this.roles.AddRange(roles);
|
||||
}
|
||||
[JsonIgnore]
|
||||
public bool IsJournalist { get { return roles?.Exists(item => item.Role == Sax.UserRole.Journalist) ?? false; } }
|
||||
}
|
||||
@@ -122,7 +118,7 @@ namespace Saxonite.Net.Standard.Base.App
|
||||
protected void SetUser(UserData user)
|
||||
{
|
||||
if (User != null && User.UserAccountSupplied)
|
||||
throw new NotSupportedException("Session Data User cannot be replaced.");
|
||||
throw new NotSupportedException("Session User cannot be replaced.");
|
||||
User = user;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@ namespace Saxonite.Net.Standard.Base.Bus
|
||||
ItemType_Code,
|
||||
ItemType_Desc,
|
||||
ItemId,
|
||||
// Journalist Article.
|
||||
Article_Headline,
|
||||
Article_Summary,
|
||||
// Organisation opportunity.
|
||||
Opportunity_Position,
|
||||
Opportunity_Outline,
|
||||
// Sport.
|
||||
SportId,
|
||||
Sport_Name,
|
||||
|
||||
@@ -44,21 +44,28 @@ namespace Saxonite.Net.Standard.Base.Consoles
|
||||
/// </summary>
|
||||
public class IndexResults
|
||||
{
|
||||
public class ItemData
|
||||
public class ActivityData
|
||||
{
|
||||
public ItemData(ItemId itemId, DateTime effectiveOn)
|
||||
public ActivityData(ItemId itemId, DateTime effectiveOn)
|
||||
{
|
||||
ItemId = itemId;
|
||||
EffectiveOn = effectiveOn;
|
||||
}
|
||||
public ItemId ItemId { get; }
|
||||
public DateTime EffectiveOn { get; }
|
||||
public String Caption { get; protected set; }
|
||||
public String Blurb { get; protected set; }
|
||||
public SysId SportId{ get; protected set; }
|
||||
public String SportName{ get; protected set; }
|
||||
public SysId RegionId { get; protected set; }
|
||||
public String RegionName{ get; protected set; }
|
||||
}
|
||||
public List<ItemData> Items { get; } = new List<ItemData>();
|
||||
public List<ActivityData> Items { get; } = new List<ActivityData>();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private SaxInternals internals = null;
|
||||
private readonly List<Sax.DataItemType> validActivityItemTypes = new List<Sax.DataItemType>()
|
||||
{
|
||||
Sax.DataItemType.JournalistArticle,
|
||||
@@ -75,12 +82,14 @@ namespace Saxonite.Net.Standard.Base.Consoles
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (internals != null) internals.Dispose(); internals = null;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
protected SaxSessionContext SessionContext { get; }
|
||||
protected SaxInternals Internals { get { if (internals == null) internals = new SaxInternals(SessionContext); return internals; } }
|
||||
protected List<Sax.DataItemType> ValidActivityItemTypes { get { return validActivityItemTypes.ToList(); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -239,8 +239,12 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
|
||||
//-------------------------------------------------------------------
|
||||
// Item column definitions.
|
||||
private static readonly String aliasActivityIndex = "ActIdx";
|
||||
private static readonly String aliasActivityIndex_Region = "ActIdx_Reg";
|
||||
private static readonly String prefixActivityIndex_Region = "ActIdx_Reg_";
|
||||
private static readonly String aliasActivityIndex_Article = "ActIdx_JrnArt";
|
||||
private static readonly String prefixActivityIndex_Article = "ActIdx_JrnArt_";
|
||||
private static readonly String aliasActivityIndex_Opportunity = "ActIdx_OrgOpp";
|
||||
private static readonly String prefixActivityIndex_Opportunity = "ActIdx_OrgOpp_";
|
||||
private static readonly String aliasActivityIndex_Region = "ActIdx_Rgn";
|
||||
private static readonly String prefixActivityIndex_Region = "ActIdx_Rgn_";
|
||||
private static readonly String aliasActivityIndex_Sport = "ActIdx_Spt";
|
||||
private static readonly String prefixActivityIndex_Sport = "ActIdx_Spt_";
|
||||
private void SetActivityIndexColDfn
|
||||
@@ -287,13 +291,24 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Region.
|
||||
case SaxActivityIndex.Column.RegionId:
|
||||
SetActivityIndexColDfn(columnDfn, "Region Id", 80, SaxDbDfn_Core.ColumnIdx.ActivityIndex_RegionId, ColumnAlignment.Right, DataValue.DataType.Long);
|
||||
// Article.
|
||||
case SaxActivityIndex.Column.Article_Headline:
|
||||
SetActivityIndexColDfn(columnDfn, "Headline", 160, SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline, ColumnAlignment.Left, DataValue.DataType.String, aliasActivityIndex_Article, prefixActivityIndex_Article);
|
||||
columnDfn.ReadOnly = true;
|
||||
break;
|
||||
case SaxActivityIndex.Column.Region_Name:
|
||||
SetActivityIndexColDfn(columnDfn, "Region", 100, SaxDbDfn_Core.ColumnIdx.Region_Name, ColumnAlignment.Left, DataValue.DataType.String, aliasActivityIndex_Region, prefixActivityIndex_Region);
|
||||
case SaxActivityIndex.Column.Article_Summary:
|
||||
SetActivityIndexColDfn(columnDfn, "Summary", 240, SaxDbDfn_Core.ColumnIdx.JournalistArticle_Summary, ColumnAlignment.Left, DataValue.DataType.String, aliasActivityIndex_Article, prefixActivityIndex_Article);
|
||||
columnDfn.ReadOnly = true;
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Opportunity.
|
||||
case SaxActivityIndex.Column.Opportunity_Position:
|
||||
SetActivityIndexColDfn(columnDfn, "Position", 160, SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Position, ColumnAlignment.Left, DataValue.DataType.String, aliasActivityIndex_Opportunity, prefixActivityIndex_Opportunity);
|
||||
columnDfn.ReadOnly = true;
|
||||
break;
|
||||
case SaxActivityIndex.Column.Opportunity_Outline:
|
||||
SetActivityIndexColDfn(columnDfn, "Outliner", 240, SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Outline, ColumnAlignment.Left, DataValue.DataType.String, aliasActivityIndex_Opportunity, prefixActivityIndex_Opportunity);
|
||||
columnDfn.ReadOnly = true;
|
||||
break;
|
||||
|
||||
@@ -308,6 +323,17 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
|
||||
columnDfn.ReadOnly = true;
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Region.
|
||||
case SaxActivityIndex.Column.RegionId:
|
||||
SetActivityIndexColDfn(columnDfn, "Region Id", 80, SaxDbDfn_Core.ColumnIdx.ActivityIndex_RegionId, ColumnAlignment.Right, DataValue.DataType.Long);
|
||||
columnDfn.ReadOnly = true;
|
||||
break;
|
||||
case SaxActivityIndex.Column.Region_Name:
|
||||
SetActivityIndexColDfn(columnDfn, "Region", 100, SaxDbDfn_Core.ColumnIdx.Region_Name, ColumnAlignment.Left, DataValue.DataType.String, aliasActivityIndex_Region, prefixActivityIndex_Region);
|
||||
columnDfn.ReadOnly = true;
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Properties.
|
||||
case SaxActivityIndex.Column.EffectiveOn:
|
||||
@@ -520,6 +546,38 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
|
||||
if (columns.HasId(SaxActivityIndex.Column.UpdateOn_Date))
|
||||
query.Columns.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_UpdateOn, aliasActivityIndex));
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Article.
|
||||
if (columns.HasId(SaxActivityIndex.Column.Article_Headline) || columns.HasId(SaxActivityIndex.Column.Article_Summary))
|
||||
{
|
||||
DbQueryJoin joinArticle = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinArticle.Table = new StringPair(SaxDbDfn_Core.GetTableName(SaxDbDfn_Core.TableIdx.JournalistArticle), aliasActivityIndex_Article);
|
||||
joinArticle.Filters.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemType, aliasActivityIndex) + "=" + ((int)Sax.DataItemType.JournalistArticle).ToString());
|
||||
joinArticle.Filters.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Id, aliasActivityIndex_Article) + "=" + SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemId, aliasActivityIndex));
|
||||
query.Joins.Add(joinArticle);
|
||||
List<SaxDbDfn_Core.ColumnIdx> cols = new List<SaxDbDfn_Core.ColumnIdx>();
|
||||
cols.Add(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline);
|
||||
cols.Add(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Summary);
|
||||
foreach (var col in cols)
|
||||
query.Columns.Add(SaxDbDfn_Core.GetColumnNameQual(col, aliasActivityIndex_Article), prefixActivityIndex_Article + SaxDbDfn_Core.GetColumnName(col, false));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Opportunity.
|
||||
if (columns.HasId(SaxActivityIndex.Column.Opportunity_Position) || columns.HasId(SaxActivityIndex.Column.Opportunity_Outline))
|
||||
{
|
||||
DbQueryJoin joinOpportunity = new DbQueryJoin(DbJoinType.LeftOuter);
|
||||
joinOpportunity.Table = new StringPair(SaxDbDfn_Core.GetTableName(SaxDbDfn_Core.TableIdx.OrganisationOpportunity), aliasActivityIndex_Opportunity);
|
||||
joinOpportunity.Filters.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemType, aliasActivityIndex) + "=" + ((int)Sax.DataItemType.OrganisationOpportunity).ToString());
|
||||
joinOpportunity.Filters.Add(SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Id, aliasActivityIndex_Opportunity) + "=" + SaxDbDfn_Core.GetColumnNameQual(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemId, aliasActivityIndex));
|
||||
query.Joins.Add(joinOpportunity);
|
||||
List<SaxDbDfn_Core.ColumnIdx> cols = new List<SaxDbDfn_Core.ColumnIdx>();
|
||||
cols.Add(SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Position);
|
||||
cols.Add(SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Outline);
|
||||
foreach (var col in cols)
|
||||
query.Columns.Add(SaxDbDfn_Core.GetColumnNameQual(col, aliasActivityIndex_Opportunity), prefixActivityIndex_Opportunity + SaxDbDfn_Core.GetColumnName(col, false));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Sport.
|
||||
if (columns.HasId(SaxActivityIndex.Column.Sport_Name))
|
||||
|
||||
@@ -248,8 +248,8 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
|
||||
private static readonly String prefixJournalistArticle_Jourlalist = "JrnArt_Jrn_";
|
||||
private static readonly String aliasJournalistArticle_Sport = "JrnArt_Spt";
|
||||
private static readonly String prefixJournalistArticle_Sport = "JrnArt_Spt_";
|
||||
private static readonly String aliasJournalistArticle_Region = "JrnArt_Reg";
|
||||
private static readonly String prefixJournalistArticle_Region = "JrnArt_Reg_";
|
||||
private static readonly String aliasJournalistArticle_Region = "JrnArt_Rgn";
|
||||
private static readonly String prefixJournalistArticle_Region = "JrnArt_Rgn_";
|
||||
private void SetJournalistArticleColDfn
|
||||
(ColumnDfn col, String caption, int width, SaxDbDfn_Core.ColumnIdx dbCol,
|
||||
ColumnAlignment align = ColumnAlignment.Default, DataValue.DataType dataType = DataValue.DataType.String,
|
||||
|
||||
@@ -253,8 +253,8 @@ namespace Saxonite.Net.Standard.Dbas.Mgr
|
||||
private static readonly String aliasOrganisationOpportunity_Organisation_UserOrganisation = "OrgOpp_Org_UsrOrg";
|
||||
private static readonly String aliasOrganisationOpportunity_Sport = "OrgOpp_Spt";
|
||||
private static readonly String prefixOrganisationOpportunity_Sport = "OrgOpp_Spt_";
|
||||
private static readonly String aliasOrganisationOpportunity_Region = "OrgOpp_Reg";
|
||||
private static readonly String prefixOrganisationOpportunity_Region = "OrgOpp_Reg_";
|
||||
private static readonly String aliasOrganisationOpportunity_Region = "OrgOpp_Rgn";
|
||||
private static readonly String prefixOrganisationOpportunity_Region = "OrgOpp_Rgn_";
|
||||
private void SetOrganisationOpportunityColDfn
|
||||
(ColumnDfn col, String caption, int width, SaxDbDfn_Core.ColumnIdx dbCol,
|
||||
ColumnAlignment align = ColumnAlignment.Default, DataValue.DataType dataType = DataValue.DataType.String,
|
||||
|
||||
Reference in New Issue
Block a user