Activity Index. User Account country. Internals regions.
This commit is contained in:
2021-05-25 22:00:08 +01:00
parent 778ee3aa03
commit 63473c725b
173 changed files with 8149 additions and 41639 deletions
@@ -51,9 +51,13 @@ namespace Saxonite.Net.Core.UnitTests.Web.Online.App
// Filter properties.
SysId filterOrganisationId = new SysId(SacsRandomHelper.GetInt32(Int32.MaxValue));
String filterOrganisationCaption= "Filter organisation caption";
sessionData.Filter.OrganisationId = filterOrganisationId;
sessionData.Filter.OrganisationCaption = filterOrganisationCaption;
SysId filterOrganisationIdMember = new SysId(SacsRandomHelper.GetInt32(Int32.MaxValue));
String filterOrganisationCaptionMember = "Filter member organisation caption";
sessionData.Filter.OrganisationIdMember = filterOrganisationIdMember;
sessionData.Filter.OrganisationCaptionMember = filterOrganisationCaptionMember;
// Serialise session data using same method as base controller.
String sessionDataJson = JsonConvert.SerializeObject(sessionData);
@@ -79,12 +83,15 @@ namespace Saxonite.Net.Core.UnitTests.Web.Online.App
// User roles.
Assert.AreEqual(userRoles.Count, sessionDataDeserialized.User.Roles.Count);
// Filter properties.
Assert.IsNotNull(sessionData.Filter.OrganisationId);
Assert.IsTrue(SysId.IsValid(sessionData.Filter.OrganisationId));
Assert.AreEqual(filterOrganisationId, sessionData.Filter.OrganisationId);
Assert.IsNotNull(sessionData.Filter.OrganisationIdMember);
Assert.IsTrue(SysId.IsValid(sessionData.Filter.OrganisationIdMember));
Assert.AreEqual(filterOrganisationIdMember, sessionData.Filter.OrganisationIdMember);
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);
}
//-------------------------------------------------------------------
@@ -0,0 +1,177 @@
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.Utils;
using Sarand.Net.Standard.Dbas.Data;
using Saxonite.Base.App;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using Saxonite.Net.Standard.Base.Consoles;
using System;
using System.Collections.Generic;
namespace Saxonite.Net.Core.Web.Base.Consoles
{
//=======================================================================
public abstract class SaxActivityConsole_Web : SaxActivityConsole
{
//-------------------------------------------------------------------
// Data members.
private readonly SaxInternals internals;
private readonly String alias_ActivityIndex = "ActIdx";
protected class IndexStatsData
{
public int EntriesInserted { get; set; }
public int EntriesUpdated { get; set; }
public int EntriesDeleted { get; set; }
}
//-------------------------------------------------------------------
// Protected construction.
protected SaxActivityConsole_Web(SaxSessionContext sessionContext) :
base(sessionContext)
{
internals = new SaxInternals(sessionContext);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
internals.Dispose();
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Query Activity Index Entries for User Context.
//-------------------------------------------------------------------
public override IndexResults QueryIndex(IndexContext context)
{
String fn = GetType().Name + ".QueryIndex";
IndexResults results = new IndexResults();
if (!context.IsValid()) return results;
// Columns to query.
ColumnDfn colItemType = internals.ActivityMgr.GetActivityIndexColumnDfn(SaxActivityIndex.Column.ItemType);
ColumnDfn colItemId = internals.ActivityMgr.GetActivityIndexColumnDfn(SaxActivityIndex.Column.ItemId);
// Query the index.
ISacsDatabase db = SaxGlobals.App.GetCoreDatabase(SessionContext);
DbQuery query = new DbQuery(db.DbmsType);
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.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));
// Filter.
SaxActivityIndex.Params prmActivityIndex = new SaxActivityIndex.Params();
prmActivityIndex.SportIdsIncluded.AddRange(context.SportIds);
prmActivityIndex.RegionIdsIncluded.AddRange(context.RegionIds);
prmActivityIndex.EffectiveFrom = context.EffectiveFrom;
prmActivityIndex.EffectiveTo = context.EffectiveTo;
prmActivityIndex.Alias_ActivityIndex = alias_ActivityIndex;
query.Filters.AddRange(internals.ActivityMgr.GetActivityIndexQueryFilter(prmActivityIndex));
using (DbResultSet dbResultSet = DbResultSet_DataReader.ExecuteQuery(db, query.BuildQuery(context.Paging)))
{
while (dbResultSet != null && dbResultSet.NextRecord())
{
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));
}
}
return results;
}
//-------------------------------------------------------------------
// Store Activity Index.
//-------------------------------------------------------------------
protected override bool StoreActivityIndexData(IndexData indexData, DbUpdateInfo dbUpdateInfo)
{
String fn = GetType().Name + ".StoreActivityIndexData";
if (!ItemId.IsValid(indexData.ItemId)) return false;
if (!ValidActivityItemTypes.Contains((Sax.DataItemType)indexData.ItemId.Type))
{
SaLogger.Warn(fn + " Invalid item type specified for Activity Index: " + ((Sax.DataItemType)indexData.ItemId.Type).ToString());
return false;
}
IndexStatsData stats = new IndexStatsData();
// Index entries required for activity.
List<IndexEntryData> indexEntries = GetEntriesForIndex(indexData);
// Retrieve existing index entries for the item.
List<SaxActivityIndex> itemIndexEntries = internals.ActivityMgr.GetActivityIndexListForItem(indexData.ItemId);
foreach (SaxActivityIndex itemIndexEntry in itemIndexEntries)
{
// Is the index entry still required.
// Logic only compares the Ids (item, sport, region) and then updates the effective date if a match is found.
// Based on the fact that and change in the effective date will impact all entries in the index for the item
// and this approach minimises the number of updates required as Ids can't be changed in code (protected setters).
IndexEntryData indexEntry = indexEntries.Find(item => item.MatchesIds(itemIndexEntry));
if (indexEntry != null)
{
// Match found - if the effective date differs, update it.
if (!itemIndexEntry.EffectiveOn.Equals(indexEntry.EffectiveOn))
{
itemIndexEntry.EffectiveOn = indexEntry.EffectiveOn;
if (internals.ActivityMgr.UpdateActivityIndex(itemIndexEntry, dbUpdateInfo))
stats.EntriesUpdated++;
else SaLogger.Warn(fn + " Failed to update Activity Index - " + internals.ActivityMgr.ErrorStateMessage);
}
// Remove the entry from the 'required' list.
// Entries remaining in this list will be created.
indexEntries.Remove(indexEntry);
}
else
{
// Index entry no longer required.
if (internals.ActivityMgr.DeleteActivityIndex(itemIndexEntry, dbUpdateInfo))
stats.EntriesDeleted++;
else SaLogger.Warn(fn + " Failed to delete Activity Index - " + internals.ActivityMgr.ErrorStateMessage);
}
}
// The remaining required Index entries will be created.
foreach (IndexEntryData indexEntry in indexEntries)
{
SaxActivityIndex itemIndexEntry = internals.ActivityMgr.CreateActivityIndex(indexEntry.ItemId, indexEntry.SportId, indexEntry.RegionId, indexEntry.EffectiveOn);
if (internals.ActivityMgr.InsertActivityIndex(itemIndexEntry, dbUpdateInfo))
stats.EntriesInserted++;
else SaLogger.Warn(fn + " Failed to insert Activity Index - " + internals.ActivityMgr.ErrorStateMessage);
}
// Log statistics.
List<String> statsLog = new List<string>();
if (stats.EntriesInserted > 0) statsLog.Add("Inserted: " + stats.EntriesInserted);
if (stats.EntriesUpdated > 0) statsLog.Add("Updated: " + stats.EntriesUpdated);
if (stats.EntriesDeleted > 0) statsLog.Add("Deleted: " + stats.EntriesDeleted);
SaLogger.Info(fn + " Activity Index stored for " + ((Sax.DataItemType)indexData.ItemId.Type).ToString() + ":" + indexData.ItemId.Id.ToLong() + "." + statsLog.Concat("", "", ". "));
return true;
}
//-------------------------------------------------------------------
protected override bool ClearActivityIndex(ItemId itemId, DbUpdateInfo dbUpdateInfo)
{
String fn = GetType().Name + ".ClearActivityIndex";
String tableName = SaxDbDfn_Core.GetTableName(SaxDbDfn_Core.TableIdx.ActivityIndex);
String filter =
SaxDbDfn_Core.GetColumnName(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemType) + "=" + itemId.Type +
" And " + SaxDbDfn_Core.GetColumnName(SaxDbDfn_Core.ColumnIdx.ActivityIndex_ItemId) + "=" + itemId.Id.ToLong();
ISacsDatabase db = SaxGlobals.App.GetCoreDatabase(SessionContext);
int recordsDeleted = db.ExecuteDelete(tableName, filter);
SaLogger.Info(fn + " Records deleted: " + recordsDeleted + ". Filter: " + filter, true);
return true;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -16,20 +16,24 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
{
//-------------------------------------------------------------------
// Data members.
private readonly SaxInternals internals;
private class DataMembers
{
public SaxInternals internals;
}
private DataMembers data = new DataMembers();
//-------------------------------------------------------------------
// Protected construction.
protected SaxDataCacheConsole_Web(SaxSessionContext sessionContext) :
base(sessionContext)
{
internals = new SaxInternals(sessionContext);
data.internals = new SaxInternals(sessionContext, false);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
internals.Dispose();
data.internals.Dispose();
}
base.Dispose(disposing);
}
@@ -38,13 +42,30 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
// Utilities.
protected abstract void ForceRefresh();
public override void PopulateCachedDataToInternals(SaxInternals internals)
{
if (regionsData.regionDataMap == null) ForceRefresh();
// Regions.
List<SaxRegion.Data> activeRegionDataList = new List<SaxRegion.Data>();
lock (regionsData)
activeRegionDataList.AddRange(regionsData.activeRegionDataList);
internals.PopulateRegionCache(activeRegionDataList);
// Sports.
List<SaxSport.Data> activeSportDataList = new List<SaxSport.Data>();
lock (sportsData)
activeSportDataList.AddRange(sportsData.activeSportDataList);
internals.PopulateSportCache(activeSportDataList);
}
//-------------------------------------------------------------------
// Regions.
public bool RegionsSupported { get; protected set; } = false;
private class RegionsData
{
public Dictionary<SysId, SaxRegion> regions = null;
public List<SaxRegion> activeRegions = null;
public Dictionary<SysId, SaxRegion.Data> regionDataMap = null;
public List<SaxRegion.Data> activeRegionDataList = null;
}
private readonly RegionsData regionsData = new RegionsData();
public override List<SaxRegion> GetActiveRegions()
@@ -52,62 +73,69 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
String fn = GetType().Name + ".ActiveRegions";
if (!RegionsSupported) throw new NotSupportedException(fn + " Regions not supported.");
List<SaxRegion> activeRegions = new List<SaxRegion>();
if (regionsData.regions == null) ForceRefresh();
lock (regionsData)
List<SaxRegion.Data> activeRegionDataList = new List<SaxRegion.Data>();
if (regionsData.regionDataMap == null) ForceRefresh();
lock (regionsData)
{
if (regionsData.regions == null) throw new NotSupportedException(fn + " Regions not populated.");
activeRegions = new List<SaxRegion>(regionsData.activeRegions);
if (regionsData.regionDataMap == null) throw new NotSupportedException(fn + " Regions not populated.");
activeRegionDataList.AddRange(regionsData.activeRegionDataList);
}
foreach (SaxRegion.Data regionData in activeRegionDataList)
activeRegions.Add(GetRegion(regionData));
return activeRegions;
}
private bool IsRegionActive(SaxRegion region)
{
if (region == null) return false;
if (!region.IsStatusActive) return false;
if (SysId.IsValid(region.RegionIdParent))
return IsRegionActive(regionsData.regions.GetValue(region.RegionIdParent, null));
return true;
}
protected void RefreshRegions()
{
String fn = GetType().Name + ".RefreshRegions";
if (!RegionsSupported) throw new NotSupportedException(fn + " Regions not supported.");
SaLogger.Info(fn + " START.", false);
DateTime startedAt = DateTime.Now;
List<SaxRegion> oldRegions = null;
Dictionary<SysId, SaxRegion> newRegions = new Dictionary<SysId, SaxRegion>();
// Query Regions.
// Refreshed lists will be populated in isolation and then used to instantaneously replace the cache lists.
Dictionary<SysId, SaxRegion.Data> newRegionDataMap = new Dictionary<SysId, SaxRegion.Data>();
List<SaxRegion.Data> newActiveRegionDataList = new List<SaxRegion.Data>();
// Query Regions to replace cache.
SaxRegion.Params prmRegion = new SaxRegion.Params();
prmRegion.StatusCat = SaxRegion.StatusCat.NotDeleted;
foreach (SaxRegion region in internals.ReferenceMgr.GetRegionList(prmRegion))
newRegions[region.Id] = region;
foreach (SaxRegion region in data.internals.ReferenceMgr.GetRegionList(prmRegion))
{
// Only interested in retaining the Data objects.
newRegionDataMap[region.Id] = region.GetData();
region.Dispose();
}
// Populate replacement list of active regions.
foreach (SaxRegion.Data regionData in newRegionDataMap.GetValues())
{
if (IsRegionActive(newRegionDataMap, regionData))
newActiveRegionDataList.Add(regionData.Clone());
}
// Replace the list of Regions.
lock (regionsData)
{
oldRegions = regionsData.regions?.GetValues() ?? new List<SaxRegion>();
regionsData.regions = newRegions;
// Populate list of active regions.
regionsData.activeRegions = new List<SaxRegion>();
foreach (SaxRegion region in regionsData.regions.GetValues())
{
if (IsRegionActive(region))
{
// Clone region to ensure internal list isn't modified.
SaxRegion activeRegion = internals.ReferenceMgr.CreateRegion();
activeRegion.SetData(region.GetData());
regionsData.activeRegions.Add(activeRegion);
}
}
SaLogger.Info(fn + " END. Regions found: " + regionsData.regions.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds), true);
// Assign the refreshed regions and active regions.
// NB The old regions don't need to be disposed as they are SaxRegion.Data objects.
regionsData.regionDataMap = newRegionDataMap;
regionsData.activeRegionDataList = newActiveRegionDataList;
}
// Dispose old regions.
oldRegions.ClearAndDispose<SaxRegion>();
oldRegions = null;
SaLogger.Info(fn + " END. Regions found: " + regionsData.regionDataMap.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds), true);
}
private static bool IsRegionActive(Dictionary<SysId, SaxRegion.Data> regionDataMap, SaxRegion.Data regionData)
{
if (regionData == null) return false;
if (!regionData.IsStatusActive) return false;
if (SysId.IsValid(regionData.RegionIdParent))
return IsRegionActive(regionDataMap, regionDataMap.GetValue(regionData.RegionIdParent, null));
return true;
}
private SaxRegion GetRegion(SaxRegion.Data regionData)
{
if (regionData == null) return null;
SaxRegion region = data.internals.ReferenceMgr.CreateRegion();
region.SetData(regionData);
return region;
}
//-------------------------------------------------------------------
@@ -115,8 +143,8 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
public bool SportsSupported { get; protected set; } = false;
private class SportsData
{
public Dictionary<SysId, SaxSport> sports = null;
public List<SaxSport> activeSports = null;
public Dictionary<SysId, SaxSport.Data> sportDataMap = null;
public List<SaxSport.Data> activeSportDataList = null;
}
private readonly SportsData sportsData = new SportsData();
public override List<SaxSport> GetActiveSports()
@@ -124,63 +152,67 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
String fn = GetType().Name + ".ActiveSports";
if (!SportsSupported) throw new NotSupportedException(fn + " Sports not supported.");
List<SaxSport> activeSports = new List<SaxSport>();
if (sportsData.sports == null) ForceRefresh();
List<SaxSport.Data> activeSportDataList = new List<SaxSport.Data>();
if (sportsData.sportDataMap == null) ForceRefresh();
lock (sportsData)
{
foreach (SaxSport sport in sportsData.sports.GetValues())
{
if (IsSportActive(sport))
{
// Clone sport to ensure internal list isn't modified.
SaxSport activeSport = internals.ReferenceMgr.CreateSport();
activeSport.SetData(sport.GetData());
activeSports.Add(activeSport);
}
}
if (sportsData.sportDataMap == null) throw new NotSupportedException(fn + " Sports not populated.");
activeSportDataList.AddRange(sportsData.activeSportDataList);
}
foreach (SaxSport.Data sportData in activeSportDataList)
activeSports.Add(GetSport(sportData));
return activeSports;
}
private bool IsSportActive(SaxSport sport)
{
if (sport == null) return false;
if (!sport.IsStatusActive) return false;
return true;
}
protected void RefreshSports()
{
String fn = GetType().Name + ".RefreshSports";
if (!SportsSupported) throw new NotSupportedException(fn + " Sports not supported.");
SaLogger.Info(fn + " START.", false);
DateTime startedAt = DateTime.Now;
List<SaxSport> oldSports = null;
Dictionary<SysId, SaxSport> newSports = new Dictionary<SysId, SaxSport>();
// Query Sports.
// Refreshed lists will be populated in isolation and then used to instantaneously replace the cache lists.
Dictionary<SysId, SaxSport.Data> newSportDataMap = new Dictionary<SysId, SaxSport.Data>();
List<SaxSport.Data> newActiveSportDataList = new List<SaxSport.Data>();
// Query Sports to replace cache.
SaxSport.Params prmSport = new SaxSport.Params();
prmSport.StatusCat = SaxSport.StatusCat.NotDeleted;
foreach (SaxSport sport in internals.ReferenceMgr.GetSportList(prmSport))
newSports[sport.Id] = sport;
foreach (SaxSport sport in data.internals.ReferenceMgr.GetSportList(prmSport))
{
// Only interested in retaining the Data objects.
newSportDataMap[sport.Id] = sport.GetData();
sport.Dispose();
}
// Populate replacement list of active sports.
foreach (SaxSport.Data sportData in newSportDataMap.GetValues())
{
if (IsSportActive(newSportDataMap, sportData))
newActiveSportDataList.Add(sportData.Clone());
}
// Replace the list of Sports.
lock (sportsData)
{
oldSports = sportsData.sports?.GetValues() ?? new List<SaxSport>();
sportsData.sports = newSports;
// Populate list of active sports.
sportsData.activeSports = new List<SaxSport>();
foreach (SaxSport sport in sportsData.sports.GetValues())
{
if (IsSportActive(sport))
sportsData.activeSports.Add(sport);
}
SaLogger.Info(fn + " END. Sports found: " + sportsData.sports.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds), true);
// Assign the refreshed sports and active sports.
// NB The old sports don't need to be disposed as they are SaxSport.Data objects.
sportsData.sportDataMap = newSportDataMap;
sportsData.activeSportDataList = newActiveSportDataList;
}
// Dispose old sports.
oldSports.ClearAndDispose<SaxSport>();
oldSports = null;
SaLogger.Info(fn + " END. Sports found: " + sportsData.sportDataMap.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds), true);
}
private static bool IsSportActive(Dictionary<SysId, SaxSport.Data> sportDataMap, SaxSport.Data sportData)
{
if (sportData == null) return false;
if (!sportData.IsStatusActive) return false;
return true;
}
private SaxSport GetSport(SaxSport.Data sportData)
{
if (sportData == null) return null;
SaxSport sport = data.internals.ReferenceMgr.CreateSport();
sport.SetData(sportData);
return sport;
}
//-------------------------------------------------------------------
@@ -83,6 +83,7 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
public SaxInternals Internals { get { if (internals == null) internals = new SaxInternals(SessionContext); return internals; } }
// Consoles.
public SaxDataCacheConsole DataCacheConsole { get { return Internals.DataCacheConsole; } }
public SaxActivityConsole ActivityConsole { get { return Internals.ActivityConsole; } }
// Managers.
public SaxReferenceMgr ReferenceMgr { get { return Internals.ReferenceMgr; } }
public SaxAccountMgr AccountMgr { get { return Internals.AccountMgr; } }
@@ -95,6 +96,7 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
public List<TypeCodeDesc> OrganisationCategories { get { return Internals.OrganisationCategories; } }
public List<TypeCodeDesc> OrganisationRoles { get { return Internals.OrganisationRoles; } }
public List<TypeCodeDesc> OpportunityTypes { get { return Internals.OpportunityTypes; } }
public List<TypeCodeDesc> DataItemTypes { get { return Internals.DataItemTypes; } }
// Email.
public SaEmailConfig EmailConfig { get { return App.EmailConfig; } }
public SaxEmailConsole EmailConsole { get { return Internals.EmailConsole; } }
+12 -10
View File
@@ -48,6 +48,7 @@ namespace Saxonite.Net.Core.Web.Base.Models
protected SaxInternals Internals { get { if (internals == null) internals = new SaxInternals(SessionContext); return internals; } }
// Consoles.
protected SaxDataCacheConsole DataCacheConsole { get { return Internals.DataCacheConsole; } }
protected SaxActivityConsole ActivityConsole { get { return Internals.ActivityConsole; } }
// Managers.
protected SaxReferenceMgr ReferenceMgr { get { return Internals.ReferenceMgr; } }
protected SaxAccountMgr AccountMgr { get { return Internals.AccountMgr; } }
@@ -60,6 +61,7 @@ namespace Saxonite.Net.Core.Web.Base.Models
public List<TypeCodeDesc> OrganisationCategories { get { return Internals.OrganisationCategories; } }
public List<TypeCodeDesc> OrganisationRoles { get { return Internals.OrganisationRoles; } }
public List<TypeCodeDesc> OpportunityTypes { get { return Internals.OpportunityTypes; } }
public List<TypeCodeDesc> DataItemTypes { get { return Internals.DataItemTypes; } }
//-------------------------------------------------------------------
// Page configuration.
@@ -98,22 +100,22 @@ namespace Saxonite.Net.Core.Web.Base.Models
/// <para>In many cases the database columns allow plenty of extra space for the value, in case they need to be encrypted.</para>
/// <para>Hence, several cases where the value entered in the control isn't allowed the full database length.</para>
/// </summary>
public int GetControlMaxLength(SaxDbDfn.ColumnIdx column)
public int GetControlMaxLength(SaxDbDfn_Core.ColumnIdx column)
{
int maxLength = (int)SaxDbDfn.GetColTextLen(column);
int maxLength = (int)SaxDbDfn_Core.GetColTextLen(column);
switch (column)
{
case SaxDbDfn.ColumnIdx.UserAccount_EmailAddress:
case SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress:
return Math.Min(maxLength, 60);
case SaxDbDfn.ColumnIdx.UserAccount_FirstName:
case SaxDbDfn.ColumnIdx.UserAccount_LastName:
case SaxDbDfn_Core.ColumnIdx.UserAccount_FirstName:
case SaxDbDfn_Core.ColumnIdx.UserAccount_LastName:
return Math.Min(maxLength, 40);
case SaxDbDfn.ColumnIdx.Organisation_Name:
case SaxDbDfn_Core.ColumnIdx.Organisation_Name:
return Math.Min(maxLength, 80);
case SaxDbDfn.ColumnIdx.UserAccount_PhoneMain:
case SaxDbDfn.ColumnIdx.UserAccount_PhoneMobile:
case SaxDbDfn.ColumnIdx.Organisation_PhoneMain:
case SaxDbDfn.ColumnIdx.Organisation_PhoneAlt:
case SaxDbDfn_Core.ColumnIdx.UserAccount_PhoneMain:
case SaxDbDfn_Core.ColumnIdx.UserAccount_PhoneMobile:
case SaxDbDfn_Core.ColumnIdx.Organisation_PhoneMain:
case SaxDbDfn_Core.ColumnIdx.Organisation_PhoneAlt:
return Math.Min(maxLength, 20);
//case SaxDbDfn.ColumnIdx.UserAccount_Postcode:
//case SaxDbDfn.ColumnIdx.ItemAddress_Postcode:
@@ -159,11 +159,11 @@ namespace Saxonite.Net.Core.Web.Admin.App
{
if (!generateDatabaseDefinitions || !SaxSystem.DebugMode || SessionContext == null) return;
if (!StringUtil.EmptyOnNull(EnvironmentName).EqualsCI("Development")) return;
ISacsDatabase database = GetCoreDatabase(sessionContext);
if (database == null || StringUtil.IsEmpty(database.ConnectionString)) return;
ISacsDatabase coreDatabase = GetCoreDatabase(sessionContext);
if (coreDatabase == null || StringUtil.IsEmpty(coreDatabase.ConnectionString)) return;
// Generate database definitions.
SaxDbDfnGenerator.Generate(database.ConnectionString);
SaxDbDfnGenerator.Generate(SaxDbDfnGenerator.DatabaseInstance.Core, coreDatabase.ConnectionString);
//SaUpdateLogDbDfnGenerator.Generate(database.ConnectionString);
}
@@ -0,0 +1,31 @@
using Sarand.Net.Standard.Base.App;
using Saxonite.Net.Core.Web.Base.Consoles;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Consoles;
using System;
using System.Collections.Generic;
using System.Text;
namespace Saxonite.Net.Core.Web.Admin.Consoles
{
//=======================================================================
public class SaxActivityConsole_Admin : SaxActivityConsole_Web
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
public SaxActivityConsole_Admin(SaxSessionContext sessionContext) :
base(sessionContext)
{
String fn = GetType().Name + ".CTR";
SaLogger.Info(fn + "");
}
//-------------------------------------------------------------------
// Utilities.
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -31,6 +31,13 @@ namespace Saxonite.Net.Core.Web.Admin.Consoles
throw new NotSupportedException(fn + " Data Cache Console not supported in Admin app.");
}
//-------------------------------------------------------------------
// Activity console.
public override SaxActivityConsole CreateActivityConsole(SaxSessionContext sessionContext)
{
return new SaxActivityConsole_Admin(sessionContext);
}
//-------------------------------------------------------------------
// Email console.
public override SaxEmailConsole CreateEmailConsole(SaxSessionContext sessionContext)
@@ -30,12 +30,12 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
public String CategoryCode { get; set; }
public String CategoryDesc { get; set; }
public long MemberCount { get; set; }
// Region.
public long RegionId { get; set; }
public String RegionName { get; set; }
// Sport.
public long SportId { get; set; }
public String SportName { get; set; }
// Region.
public long RegionId { get; set; }
public String RegionName { get; set; }
// Common properties.
public String StatusCode { get; set; }
public String StatusDesc { get; set; }
@@ -52,20 +52,14 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
data.CategoryCode = OrganisationCategories.GetCodeForType(organisation.OrganisationCategory);
data.CategoryDesc = OrganisationCategories.GetDescForType(organisation.OrganisationCategory);
data.MemberCount = AccountMgr.GetOrganisationMemberCount(organisation.Id);
// Sport.
data.SportId = SysId.ToLong(organisation.SportIdPrimary);
using (SaxSport sport = ReferenceMgr.GetSportById(organisation.SportIdPrimary))
data.SportName = sport?.Name ?? "";
// Region.
data.RegionId = SysId.ToLong(organisation.RegionIdPrimary);
using (SaxRegion region = ReferenceMgr.GetRegionById(organisation.RegionIdPrimary))
{
if (region != null)
data.RegionName = region.Name;
}
// Sport.
data.SportId = SysId.ToLong(organisation.SportIdPrimary);
using (SaxSport region = ReferenceMgr.GetSportById(organisation.SportIdPrimary))
{
if (region != null)
data.SportName = region.Name;
}
data.RegionName = region?.Name ?? "";
// Common properties.
data.StatusCode = organisation.StatusCode;
data.StatusDesc = organisation.StatusDesc;
@@ -119,10 +113,10 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
ColumnDfn colPhoneAlt = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.PhoneAlt);
ColumnDfn colUserCount = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.User_Count);
ColumnDfn colMemberCount = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Member_Count);
ColumnDfn colRegionId = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.RegionId);
ColumnDfn colRegionName = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Region_Name);
ColumnDfn colSportId = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.SportId);
ColumnDfn colSportName = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Sport_Name);
ColumnDfn colRegionId = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.RegionId);
ColumnDfn colRegionName = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Region_Name);
ColumnDfn colStatus = AccountMgr.GetOrganisationColumnDfn(SaxOrganisation.Column.Status);
List<ColumnDfn> columns = new List<ColumnDfn>()
{
@@ -133,8 +127,8 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
colPhoneMain,
colPhoneAlt,
colUserCount, colMemberCount,
colRegionId, colRegionName,
colSportId, colSportName,
colRegionId, colRegionName,
colStatus
};
@@ -155,10 +149,10 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
CategoryCode = values.GetString(colOrganisationCategory.DataName),
CategoryDesc = OrganisationCategories.GetDescForCode(values.GetString(colOrganisationCategory.DataName)),
MemberCount = StringUtil.ToLong(values.GetString(colMemberCount.DataName)),
RegionId = values.GetLong(colRegionId.DataName),
RegionName = values.GetString(colRegionName.DataName),
SportId = values.GetLong(colSportId.DataName),
SportName = values.GetString(colSportName.DataName),
RegionId = values.GetLong(colRegionId.DataName),
RegionName = values.GetString(colRegionName.DataName),
StatusCode = values.GetString(colStatus.DataName),
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
};
@@ -255,10 +249,10 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
organisation.OrganisationType = model.OrganisationType;
if (model.OrganisationCategoryValue != null)
organisation.OrganisationCategory = model.OrganisationCategory;
if (model.OrganisationRegionId != null)
organisation.RegionIdPrimary = model.OrganisationRegionId.ToSysId();
if (model.OrganisationSportId != null)
organisation.SportIdPrimary = model.OrganisationSportId.ToSysId();
if (model.OrganisationRegionId != null)
organisation.RegionIdPrimary = model.OrganisationRegionId.ToSysId();
// Common properties.
if (model.OrganisationStatusCode != null)
organisation.Status = model.OrganisationStatus;
@@ -3,6 +3,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.Utils;
using Saxonite.Net.Core.Web.Admin.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
@@ -156,14 +157,15 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
return GetAjaxResult_InvalidSession(responseData);
// Identify item.
if (!SysId.IsValid(model.RegionId))
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(model.RegionId);
SaxRegion region = ReferenceMgr.GetRegionById(regionId);
if (region == null)
{
SaLogger.Warn(fn + " Failed to retrieve region for Id: '" + model.RegionIdValue + "'");
SaLogger.Warn(fn + " Failed to retrieve region for Id: '" + model.RegionId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
@@ -197,10 +199,11 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
return Json(responseData);
// Retrieve existing item.
SaxRegion region = ReferenceMgr.GetRegionById(model.RegionId);
if (region == null && SysId.IsValid(model.RegionId))
SysId regionId = model.RegionId.ToSysId();
SaxRegion region = ReferenceMgr.GetRegionById(regionId);
if (region == null && SysId.IsValid(regionId))
{
SaLogger.Warn(fn + " Failed to retrieve region for Id: '" + model.RegionIdValue + "'");
SaLogger.Warn(fn + " Failed to retrieve region for Id: '" + model.RegionId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
@@ -3,6 +3,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.Utils;
using Saxonite.Net.Core.Web.Admin.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
@@ -136,14 +137,15 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
return GetAjaxResult_InvalidSession(responseData);
// Identify item.
if (!SysId.IsValid(model.SportId))
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(model.SportId);
SaxSport sport = ReferenceMgr.GetSportById(sportId);
if (sport == null)
{
SaLogger.Warn(fn + " Failed to retrieve sport for Id: '" + model.SportIdValue + "'");
SaLogger.Warn(fn + " Failed to retrieve sport for Id: '" + model.SportId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
@@ -177,10 +179,11 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
return Json(responseData);
// Retrieve existing item.
SaxSport sport = ReferenceMgr.GetSportById(model.SportId);
if (sport == null && SysId.IsValid(model.SportId))
SysId sportId = model.SportId.ToSysId();
SaxSport sport = ReferenceMgr.GetSportById(sportId);
if (sport == null && SysId.IsValid(sportId))
{
SaLogger.Warn(fn + " Failed to retrieve sport for Id: '" + model.SportIdValue + "'");
SaLogger.Warn(fn + " Failed to retrieve sport for Id: '" + model.SportId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
@@ -3,6 +3,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.Dbas.Data;
using Saxonite.Net.Core.Web.Admin.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
@@ -22,7 +23,12 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Database data.
public class DatabaseTableData
{
public String Name { get; set; }
public String SchemaName { get; set; }
public String TableName { get; set; }
public String QualifiedName { get; set; }
public int RowCount { get; set; }
public int ColumnCount { get; set; }
public int IndexCount { get; set; }
}
//-------------------------------------------------------------------
@@ -45,9 +51,44 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Core Database connection.
ISacsDatabase db = SaxGlobals.App.GetCoreDatabase(SessionContext);
// Database table row counts.
Dictionary<String, int> tableRowCounts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
String query =
"SELECT QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) AS[TableName], SUM(sPTN.Rows) AS[RowCount] " +
"FROM sys.objects AS sOBJ " +
"INNER JOIN sys.partitions AS sPTN ON sOBJ.object_id = sPTN.object_id " +
"WHERE sOBJ.type = 'U' AND sOBJ.is_ms_shipped = 0x0 AND index_id< 2 /*Index Id: 0:Heap,1:Clustered*/ " +
"GROUP BY sOBJ.schema_id, sOBJ.name";
using (DbResultSet dbResultSet = DbResultSet_DataReader.ExecuteQuery(db, query))
{
while (dbResultSet != null && dbResultSet.NextRecord())
{
tableRowCounts.Add(dbResultSet.GetRecordValues().GetValue("TableName").ToString(), (int)dbResultSet.GetRecordValues().GetValue("RowCount").AsLong());
}
}
// Core database tables.
List<DbDfnTable> tableDfns = db.GetTableDfns();
foreach (DbDfnTable tableDfn in tableDfns.OrderBy(item => item.Name))
{
DatabaseTableData tableData = new DatabaseTableData();
tableData.SchemaName = tableDfn.Schema;
tableData.TableName = tableDfn.Name;
tableData.QualifiedName = tableDfn.QualifiedName;
tableData.ColumnCount = tableDfn.ColumnCount;
tableData.IndexCount = tableDfn.IndexCount;
// Row count.
tableData.RowCount = tableRowCounts.GetValueOrDefault(tableDfn.QuotedQualifiedName, 0);
responseData.Tables.Add(tableData);
}
// Complete response.
responseData.Success = true;
return Json(responseData);
}
@@ -48,6 +48,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
if (!ValidUserSession)
return RedirectToAction("", "");
model.AdditionalFiles_JS.Add("js/sax-sys-db.js");
return View(model);
}
@@ -62,6 +63,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
if (!ValidUserSession)
return RedirectToAction("", "");
model.AdditionalFiles_JS.Add("js/sax-sys-logs.js");
return View(model);
}
@@ -186,14 +186,15 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
return GetAjaxResult_InvalidSession(responseData);
// Identify item.
if (!SysId.IsValid(model.UserAccountId))
SysId userAccountId = model.UserAccountId.ToSysId();
if (!SysId.IsValid(userAccountId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
// Retrieve item.
SaxUserAccount user = AccountMgr.GetUserAccountById(model.UserAccountId);
SaxUserAccount user = AccountMgr.GetUserAccountById(userAccountId);
if (user == null)
{
SaLogger.Warn(fn + " Failed to retrieve user for Id: '" + model.UserAccountIdValue + "'");
SaLogger.Warn(fn + " Failed to retrieve user for Id: '" + userAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
@@ -262,10 +263,11 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
return Json(responseData);
// Retrieve existing item.
SaxUserAccount user = AccountMgr.GetUserAccountById(model.UserAccountId);
if (user == null && SysId.IsValid(model.UserAccountId))
SysId userAccountId = model.UserAccountId.ToSysId();
SaxUserAccount user = AccountMgr.GetUserAccountById(userAccountId);
if (user == null && SysId.IsValid(userAccountId))
{
SaLogger.Warn(fn + " Failed to retrieve user for Id: '" + model.UserAccountIdValue + "'");
SaLogger.Warn(fn + " Failed to retrieve user for Id: '" + model.UserAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
@@ -52,8 +52,8 @@ namespace Saxonite.Net.Core.Web.Admin.Models
public Sax.OrganisationType OrganisationType { get { return (Sax.OrganisationType)OrganisationTypes.GetTypeForCode(OrganisationTypeValue); } }
public String OrganisationCategoryValue { get; set; }
public Sax.OrganisationCategory OrganisationCategory { get { return (Sax.OrganisationCategory)OrganisationCategories.GetTypeForCode(OrganisationCategoryValue); } }
public String OrganisationRegionId { get; set; }
public String OrganisationSportId { get; set; }
public String OrganisationRegionId { get; set; }
// Common properties.
public String OrganisationNotes { get; set; }
public String OrganisationStatusCode { get; set; }
@@ -71,8 +71,8 @@ namespace Saxonite.Net.Core.Web.Admin.Models
responseData.SetControlValue(nameof(OrganisationName), OrganisationName);
if (StringUtil.IsEmpty(OrganisationName))
responseData.SetControlError(nameof(OrganisationName), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(OrganisationName) > GetControlMaxLength(SaxDbDfn.ColumnIdx.Organisation_Name))
responseData.SetControlError(nameof(OrganisationName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.Organisation_Name)]);
else if (StringUtil.GetLength(OrganisationName) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Name))
responseData.SetControlError(nameof(OrganisationName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Name)]);
}
// Organisation type.
@@ -41,12 +41,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models
//-------------------------------------------------------------------
// Region properties.
public String RegionIdValue { get; set; }
public SysId RegionId
{
get { return new SysId(StringUtil.ToInt(RegionIdValue)); }
set { RegionIdValue = SysId.ToString(value); }
}
public String RegionId { get; set; }
public String RegionTypeCode { get; set; }
public Sax.RegionType RegionType
{
@@ -81,14 +76,15 @@ namespace Saxonite.Net.Core.Web.Admin.Models
{
if (StringUtil.IsEmpty(RegionCountryIso2Code))
responseData.SetControlError(nameof(RegionCountryIso2Code), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(RegionCountryIso2Code) != GetControlMaxLength(SaxDbDfn.ColumnIdx.Region_CountryIso2Code))
responseData.SetControlError(nameof(RegionCountryIso2Code), Localiser["msg.validation.invalid.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.Region_CountryIso2Code)]);
else if (StringUtil.GetLength(RegionCountryIso2Code) != GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Region_CountryIso2Code))
responseData.SetControlError(nameof(RegionCountryIso2Code), Localiser["msg.validation.invalid.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Region_CountryIso2Code)]);
else
{
// Check for duplicate code.
SaxRegion.Params prmRegion = new SaxRegion.Params();
if (SysId.IsValid(RegionId))
prmRegion.IdsExcluded.Add(RegionId);
SysId regionId = RegionId.ToSysId();
if (SysId.IsValid(regionId))
prmRegion.IdsExcluded.Add(regionId);
prmRegion.CountryIso2CodesIncluded.Add(RegionCountryIso2Code);
prmRegion.StatusCat = SaxRegion.StatusCat.Any;
if (ReferenceMgr.GetRegionCount(prmRegion) > 0)
@@ -108,14 +104,15 @@ namespace Saxonite.Net.Core.Web.Admin.Models
responseData.SetControlValue(nameof(RegionName), RegionName);
if (StringUtil.IsEmpty(RegionName))
responseData.SetControlError(nameof(RegionName), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(RegionName) > GetControlMaxLength(SaxDbDfn.ColumnIdx.Region_Name))
responseData.SetControlError(nameof(RegionName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.Region_Name)]);
else if (StringUtil.GetLength(RegionName) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Region_Name))
responseData.SetControlError(nameof(RegionName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Region_Name)]);
else
{
// Check for duplicate name.
SaxRegion.Params prmRegion = new SaxRegion.Params();
if (SysId.IsValid(RegionId))
prmRegion.IdsExcluded.Add(RegionId);
SysId regionId = RegionId.ToSysId();
if (SysId.IsValid(regionId))
prmRegion.IdsExcluded.Add(regionId);
prmRegion.NameFull = RegionName;
prmRegion.StatusCat = SaxRegion.StatusCat.Any;
if (ReferenceMgr.GetRegionCount(prmRegion) > 0)
@@ -36,12 +36,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models
//-------------------------------------------------------------------
// Sport properties.
public SysId SportId { get; set; }
public String SportIdValue
{
get { return SysId.ToString(SportId); }
set { SportId = new SysId(StringUtil.ToInt(value)); }
}
public String SportId { get; set; }
public String SportName { get; set; }
public String SportStatusCode { get; set; }
public SaStatus SportStatus { get { return SacsSystem.GetStatusForCode(SportStatusCode); } }
@@ -58,14 +53,15 @@ namespace Saxonite.Net.Core.Web.Admin.Models
responseData.SetControlValue(nameof(SportName), SportName);
if (StringUtil.IsEmpty(SportName))
responseData.SetControlError(nameof(SportName), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(SportName) > GetControlMaxLength(SaxDbDfn.ColumnIdx.Sport_Name))
responseData.SetControlError(nameof(SportName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.Sport_Name)]);
else if (StringUtil.GetLength(SportName) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Sport_Name))
responseData.SetControlError(nameof(SportName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Sport_Name)]);
else
{
// Check for duplicate name.
SaxSport.Params prmSport = new SaxSport.Params();
if (SysId.IsValid(SportId))
prmSport.IdsExcluded.Add(SportId);
SysId sportId = SportId.ToSysId();
if (SysId.IsValid(sportId))
prmSport.IdsExcluded.Add(sportId);
prmSport.NamePartial = SportName;
prmSport.StatusCat = SaxSport.StatusCat.Any;
if (ReferenceMgr.GetSportCount(prmSport) > 0)
+10 -14
View File
@@ -37,12 +37,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models
//-------------------------------------------------------------------
// User properties.
public SysId UserAccountId { get; set; }
public String UserAccountIdValue
{
get { return SysId.ToString(UserAccountId); }
set { UserAccountId = new SysId(StringUtil.ToInt(value)); }
}
public String UserAccountId { get; set; }
[EmailAddress]
public String UserEmailAddress { get; set; }
public String UserTitle { get; set; }
@@ -76,14 +71,15 @@ namespace Saxonite.Net.Core.Web.Admin.Models
responseData.SetControlValue(nameof(UserEmailAddress), UserEmailAddress);
if (StringUtil.IsEmpty(UserEmailAddress))
responseData.SetControlError(nameof(UserEmailAddress), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(UserEmailAddress) > GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_EmailAddress))
responseData.SetControlError(nameof(UserEmailAddress), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_EmailAddress)]);
else if (StringUtil.GetLength(UserEmailAddress) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress))
responseData.SetControlError(nameof(UserEmailAddress), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress)]);
else
{
// Check for duplicate email address.
SaxUserAccount.Params prmUserAccount = new SaxUserAccount.Params();
if (SysId.IsValid(UserAccountId))
prmUserAccount.IdsExcluded.Add(UserAccountId);
SysId userAccountId = UserAccountId.ToSysId();
if (SysId.IsValid(userAccountId))
prmUserAccount.IdsExcluded.Add(userAccountId);
prmUserAccount.EmailAddress = UserEmailAddress;
prmUserAccount.StatusCat = SaxUserAccount.StatusCat.Any;
if (AccountMgr.GetUserAccountCount(prmUserAccount) > 0)
@@ -104,8 +100,8 @@ namespace Saxonite.Net.Core.Web.Admin.Models
responseData.SetControlValue(nameof(UserFirstName), UserFirstName);
if (StringUtil.IsEmpty(UserFirstName))
responseData.SetControlError(nameof(UserFirstName), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(UserFirstName) > GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_FirstName))
responseData.SetControlError(nameof(UserFirstName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_FirstName)]);
else if (StringUtil.GetLength(UserFirstName) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_FirstName))
responseData.SetControlError(nameof(UserFirstName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_FirstName)]);
}
// User last name.
@@ -114,8 +110,8 @@ namespace Saxonite.Net.Core.Web.Admin.Models
responseData.SetControlValue(nameof(UserLastName), UserLastName);
if (StringUtil.IsEmpty(UserLastName))
responseData.SetControlError(nameof(UserLastName), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(UserLastName) > GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_LastName))
responseData.SetControlError(nameof(UserLastName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_LastName)]);
else if (StringUtil.GetLength(UserLastName) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_LastName))
responseData.SetControlError(nameof(UserLastName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_LastName)]);
}
// User status.
@@ -159,6 +159,9 @@
<data name="label.close" xml:space="preserve">
<value>Close</value>
</data>
<data name="label.columns" xml:space="preserve">
<value>Columns</value>
</data>
<data name="label.create" xml:space="preserve">
<value>Create</value>
</data>
@@ -183,6 +186,9 @@
<data name="label.forgotten.password" xml:space="preserve">
<value>Forgotten password?</value>
</data>
<data name="label.indices" xml:space="preserve">
<value>Indices</value>
</data>
<data name="label.iso2.code" xml:space="preserve">
<value>ISO2 code</value>
</data>
@@ -237,6 +243,9 @@
<data name="label.roles" xml:space="preserve">
<value>Roles</value>
</data>
<data name="label.rows" xml:space="preserve">
<value>Rows</value>
</data>
<data name="label.search" xml:space="preserve">
<value>Search</value>
</data>
@@ -33,7 +33,7 @@
<label for="ifMemberUserEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.MemberUserEmailAddress, new { @id = "ifMemberUserEmailAddress", @class = "MemberUserEmailAddress sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_EmailAddress) })
@Html.TextBoxFor(model => model.MemberUserEmailAddress, new { @id = "ifMemberUserEmailAddress", @class = "MemberUserEmailAddress sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress) })
</div>
<div class="sax-message"></div>
</div>
@@ -26,7 +26,7 @@
<label for="ifOrganisationName"><span><span class="required">*</span> @Localiser["label.name"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.OrganisationName, new { @id = "ifOrganisationName", @class = "OrganisationName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.Organisation_Name) })
@Html.TextBoxFor(model => model.OrganisationName, new { @id = "ifOrganisationName", @class = "OrganisationName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Name) })
</div>
<div class="sax-message"></div>
</div>
@@ -53,19 +53,6 @@
<div class="sax-message"></div>
</div>
@* Organisation region *@
<div class="sax-form-control OrganisationRegionId">
<div class="sax-label">
<label for="ifOrganisationRegionId"><span><span class="required">*</span> @Localiser["label.region"]</span></label>
</div>
<div class="sax-control row">
@Html.HiddenFor(model => model.OrganisationRegionId, new { @id = "ifOrganisationRegionId", @class = "OrganisationRegionId" })
<div class="col"><input type="text" id="ifOrganisationRegionCaption" class="OrganisationRegionCaption sax-input" readonly="readonly" ondblclick="sax.selectRegion()" /> </div>
<div class="fixed"><button id="pbSelectRegion" class="sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectRegion()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
@* Organisation sport *@
<div class="sax-form-control OrganisationSportId">
<div class="sax-label">
@@ -79,6 +66,19 @@
<div class="sax-message"></div>
</div>
@* Organisation region *@
<div class="sax-form-control OrganisationRegionId">
<div class="sax-label">
<label for="ifOrganisationRegionId"><span><span class="required">*</span> @Localiser["label.region"]</span></label>
</div>
<div class="sax-control row">
@Html.HiddenFor(model => model.OrganisationRegionId, new { @id = "ifOrganisationRegionId", @class = "OrganisationRegionId" })
<div class="col"><input type="text" id="ifOrganisationRegionCaption" class="OrganisationRegionCaption sax-input" readonly="readonly" ondblclick="sax.selectRegion()" /> </div>
<div class="fixed"><button id="pbSelectRegion" class="sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectRegion()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
@* Organisation status *@
<div class="sax-form-control OrganisationStatus">
<div class="sax-label">
@@ -10,13 +10,13 @@
</script>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmRegionId", @class = "sax-form" }))
{
@Html.HiddenFor(model => model.RegionIdValue, new { @class = "RegionId" })
@Html.HiddenFor(model => model.RegionId, new { @class = "RegionId" })
}
<div id="dlgRegion" class="sax-dialog" title="">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmRegion", @class = "sax-form", @onSubmit = "return false;" }))
{
@Html.HiddenFor(model => model.RegionIdValue, new { @class = "RegionId" })
@Html.HiddenFor(model => model.RegionId, new { @class = "RegionId" })
@* Region type *@
<div class="sax-form-control RegionType">
@@ -35,7 +35,7 @@
<label for="ifRegionIso2Code"><span><span class="required">*</span> @Localiser["label.iso2.code"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.RegionCountryIso2Code, new { @id = "ifRegionCountryIso2Code", @class = "RegionCountryIso2Code sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.Region_CountryIso2Code) })
@Html.TextBoxFor(model => model.RegionCountryIso2Code, new { @id = "ifRegionCountryIso2Code", @class = "RegionCountryIso2Code sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Region_CountryIso2Code) })
</div>
<div class="sax-message"></div>
</div>
@@ -46,7 +46,7 @@
<label for="ifRegionName"><span><span class="required">*</span> @Localiser["label.name"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.RegionName, new { @id = "ifRegionName", @class = "RegionName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.Region_Name) })
@Html.TextBoxFor(model => model.RegionName, new { @id = "ifRegionName", @class = "RegionName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Region_Name) })
</div>
<div class="sax-message"></div>
</div>
@@ -18,7 +18,7 @@
<label for="ifEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sax-input lower", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_EmailAddress) })
@Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sax-input lower", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress) })
</div>
<div class="sax-message"></div>
</div>
@@ -2,7 +2,7 @@
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery AntiForgery;
@inject SaxLocaliser Localiser
@*
Application: Online
Application: Admin
Purpose: Page template.
*@
@{
@@ -121,8 +121,8 @@
@Localiser["label.reference"]
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Region');">@Localiser["region.caption.regions"]</div>
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Sport');">@Localiser["sport.caption.sports"]</div>
<div class="dropdown-item text-dark sax-action" onclick="sax.goToPage('Region');">@Localiser["region.caption.regions"]</div>
</div>
</li>
<li class="nav-item dropdown">
@@ -10,13 +10,13 @@
</script>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSportId", @class = "sax-form" }))
{
@Html.HiddenFor(model => model.SportIdValue, new { @class = "SportId" })
@Html.HiddenFor(model => model.SportId, new { @class = "SportId" })
}
<div id="dlgSport" class="sax-dialog" title="">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSport", @class = "sax-form", @onSubmit = "return false;" }))
{
@Html.HiddenFor(model => model.SportIdValue, new { @class = "SportId" })
@Html.HiddenFor(model => model.SportId, new { @class = "SportId" })
@* Sport name *@
<div class="sax-form-control SportName">
@@ -24,7 +24,7 @@
<label for="ifSportName"><span><span class="required">*</span> @Localiser["label.name"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.SportName, new { @id = "ifSportName", @class = "SportName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.Sport_Name) })
@Html.TextBoxFor(model => model.SportName, new { @id = "ifSportName", @class = "SportName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Sport_Name) })
</div>
<div class="sax-message"></div>
</div>
@@ -25,19 +25,28 @@
</div>
<div class="sax-panel-results">
</div>
<div class="sax-panel-item-template">
<div class="sax-panel-item DatabaseTable">
<div class="sax-header row">
<div class="col">
<div class="sax-caption"><div class="sax-action TableName"></div></div>
<div class="sax-panel-messages"></div>
<div class="sax-panel-item-list"></div>
<div class="sax-panel-item-template">
<div class="sax-panel-item DatabaseTable">
<div class="sax-header row">
<div class="col">
<div class="sax-caption"><div class="sax-action TableName"></div></div>
</div>
<div class="fixed sax-actions">
</div>
</div>
<div class="fixed sax-actions">
<div class="sax-content">
<div class="row">
<div class="col-sm-6">@Localiser["label.rows"]:&nbsp;<span class="RowCount"></span></div>
<div class="col-sm-6 text-right">@Localiser["label.columns"]:&nbsp;<span class="ColumnCount"></span></div>
</div>
<div class="row">
<div class="col-sm-6"></div>
<div class="col-sm-6 text-right">@Localiser["label.indices"]:&nbsp;<span class="IndexCount"></span></div>
</div>
</div>
</div>
<div class="sax-content"></div>
</div>
</div>
@@ -12,13 +12,13 @@
</script>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmUserId", @class = "sax-form" }))
{
@Html.HiddenFor(model => model.UserAccountIdValue, new { @class = "UserAccountId" })
@Html.HiddenFor(model => model.UserAccountId, new { @class = "UserAccountId" })
}
<div id="dlgUser" class="sax-dialog" title="">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmUser", @class = "sax-form", @onSubmit = "return false;" }))
{
@Html.HiddenFor(model => model.UserAccountIdValue, new { @class = "UserAccountId" })
@Html.HiddenFor(model => model.UserAccountId, new { @class = "UserAccountId" })
@* User email *@
<div class="sax-form-control UserEmailAddress">
@@ -26,7 +26,7 @@
<label for="ifUserEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.UserEmailAddress, new { @id = "ifUserEmailAddress", @class = "UserEmailAddress sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_EmailAddress) })
@Html.TextBoxFor(model => model.UserEmailAddress, new { @id = "ifUserEmailAddress", @class = "UserEmailAddress sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress) })
</div>
<div class="sax-message"></div>
</div>
@@ -47,7 +47,7 @@
<label for="ifUserFirstName"><span><span class="required">*</span> @Localiser["label.first.name"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.UserFirstName, new { @id = "ifUserFirstName", @class = "UserFirstName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_FirstName) })
@Html.TextBoxFor(model => model.UserFirstName, new { @id = "ifUserFirstName", @class = "UserFirstName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_FirstName) })
</div>
<div class="sax-message"></div>
</div>
@@ -58,7 +58,7 @@
<label for="ifUserLastName"><span><span class="required">*</span> @Localiser["label.last.name"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.UserLastName, new { @id = "ifUserLastName", @class = "UserLastName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_LastName) })
@Html.TextBoxFor(model => model.UserLastName, new { @id = "ifUserLastName", @class = "UserLastName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_LastName) })
</div>
<div class="sax-message"></div>
</div>
@@ -56,24 +56,28 @@
.sax-form .sax-form-control .sax-label
{
margin: 0 0 8px 0;
font-size: 1.00rem;
font-size: 1rem;
line-height: 1.25;
}
.sax-form .sax-form-control .sax-label-text
{
font-size: 1.00rem;
font-size: 1rem;
line-height: 1.25;
}
.sax-form .sax-form-control .sax-note
{
font-size: 0.9rem;
line-height: 1.2;
}
.sax-form .sax-input, .sax-form .sax-textarea, .sax-form .sax-select
{
padding: 4px 8px;
padding: 3px 8px 4px 8px;
width: 100%;
font-size: 1.00rem;
font-size: 1rem;
line-height: 1.25;
background-color: #fff;
border: 1px solid #595959;
border-radius: 2px;
@@ -28,7 +28,7 @@
var $results = $('.sax-panel-results');
var $msgs = $('.sax-panel-messages', $results).hide().empty();
var $items = $('.sax-panel-item-list', $results).hide().empty();
var $templ = $('.sax-panel-item-template .sax-panel-item.Organisation', $results);
var $tmpl = $('.sax-panel-item-template .sax-panel-item.Organisation', $results);
if (!response.success) return;
// Reference data - Statuses.
if (response.defaultStatusCode) sax.data.defaultStatusCode = response.defaultStatusCode;
@@ -41,7 +41,7 @@
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
{
let item = items[itemIdx];
let $item = $templ.clone();
let $item = $tmpl.clone();
sax.populateItem($item, item);
$items.append($item);
}
@@ -54,8 +54,8 @@
$('.OrganisationName', $item).text(item.name);
$('.OrganisationType', $item).text(item.typeDesc);
$('.OrganisationCategory', $item).text(item.categoryDesc);
$('.OrganisationRegion', $item).text(item.regionName);
$('.OrganisationSport', $item).text(item.sportName);
$('.OrganisationRegion', $item).text(item.regionName);
$('.OrganisationMemberCount', $item).on('click', function () { sax.onClickMemberCount(item.id); }).find('.MemberCount').text(item.memberCount);
$('.StatusDesc', $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) })
@@ -63,34 +63,6 @@
$('.sax-panel-results .sax-panel-messages').hide().empty();
}
//--------------------------------------------------------------
sax.selectRegion = function ()
{
if (!sax.data.regions)
{
let handleRegionsResponse = function (response)
{
if (response && response.success && response.regions)
sax.data.regions = response.regions;
sax.showSelectRegion();
}
sax.ajaxRegions = sax.ajaxRegions || { url: sax.url.base + 'Region/Ajax/GetList', formId: 'frmNavigate', callbackFn: handleRegionsResponse };
sax.doAjaxRequest(sax.ajaxRegions, 50);
}
else sax.showSelectRegion();
}
sax.showSelectRegion = function ()
{
sax.data.selectItem.fn.selectItem({ caption: sax.dlg.title.selectRegion, items: sax.data.regions, fnCallback: sax.onRegionSelected });
}
sax.onRegionSelected = function (rgn)
{
//sax.debug('onRegionSelected', rgn);
let $frm = sax.$frm.organisation;
$('.OrganisationRegionId', $frm).val(rgn.id);
$('.OrganisationRegionCaption', $frm).val(rgn.name);
}
//--------------------------------------------------------------
sax.selectSport = function ()
{
@@ -119,11 +91,39 @@
$('.OrganisationSportCaption', $frm).val(rgn.name);
}
//--------------------------------------------------------------
sax.selectRegion = function ()
{
if (!sax.data.regions)
{
let handleRegionsResponse = function (response)
{
if (response && response.success && response.regions)
sax.data.regions = response.regions;
sax.showSelectRegion();
}
sax.ajaxRegions = sax.ajaxRegions || { url: sax.url.base + 'Region/Ajax/GetList', formId: 'frmNavigate', callbackFn: handleRegionsResponse };
sax.doAjaxRequest(sax.ajaxRegions, 50);
}
else sax.showSelectRegion();
}
sax.showSelectRegion = function ()
{
sax.data.selectItem.fn.selectItem({ caption: sax.dlg.title.selectRegion, items: sax.data.regions, fnCallback: sax.onRegionSelected });
}
sax.onRegionSelected = function (rgn)
{
//sax.debug('onRegionSelected', rgn);
let $frm = sax.$frm.organisation;
$('.OrganisationRegionId', $frm).val(rgn.id);
$('.OrganisationRegionCaption', $frm).val(rgn.name);
}
//--------------------------------------------------------------
sax.createItem = function ()
{
let $frm = sax.$frm.organisation;
$('.OrganisationId,.OrganisationRegionId,.OrganisationSportId,input[type="text"],textarea,select', $frm).val('');
$('.OrganisationId,.OrganisationSportId,.OrganisationRegionId,input[type="text"],textarea,select', $frm).val('');
$('.OrganisationStatus', $frm).val(sax.data.defaultStatusCode);
sax.clearControlErrors();
sax.$dlg.organisation.dialog('option', 'title', sax.dlg.title.createOrganisation);
@@ -152,10 +152,10 @@
$('.OrganisationName', $frm).val(item.name);
$('.OrganisationType', $frm).val(item.typeCode);
$('.OrganisationCategory', $frm).val(item.categoryCode);
$('.OrganisationRegionId', $frm).val(item.regionId);
$('.OrganisationRegionCaption', $frm).val(item.regionName);
$('.OrganisationSportId', $frm).val(item.sportId);
$('.OrganisationSportCaption', $frm).val(item.sportName);
$('.OrganisationRegionId', $frm).val(item.regionId);
$('.OrganisationRegionCaption', $frm).val(item.regionName);
$('.OrganisationStatus', $frm).val(item.statusCode);
sax.clearControlErrors();
sax.$dlg.organisation.dialog('option', 'title', sax.dlg.title.updateOrganisation);
@@ -28,7 +28,7 @@
var $results = $('.sax-panel-results');
var $msgs = $('.sax-panel-messages', $results).hide().empty();
var $items = $('.sax-panel-item-list', $results).hide().empty();
var $templ = $('.sax-panel-item-template .sax-panel-item.Member', $results);
var $tmpl = $('.sax-panel-item-template .sax-panel-item.Member', $results);
if (!response.success) return;
// Reference data - roles.
if (response.memberRoles && response.memberRoles.length)
@@ -44,7 +44,7 @@
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
{
let item = items[itemIdx];
let $item = $templ.clone();
let $item = $tmpl.clone();
sax.populateItem($item, item);
$items.append($item);
}
@@ -28,7 +28,7 @@
var $results = $('.sax-panel-results');
var $msgs = $('.sax-panel-messages', $results).hide().empty();
var $items = $('.sax-panel-item-list', $results).hide().empty();
var $templ = $('.sax-panel-item-template .sax-panel-item.Region', $results);
var $tmpl = $('.sax-panel-item-template .sax-panel-item.Region', $results);
if (!response.success) return;
// Reference data - Statuses.
if (response.defaultStatusCode) sax.data.defaultStatusCode = response.defaultStatusCode;
@@ -41,7 +41,7 @@
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
{
let item = items[itemIdx];
let $item = $templ.clone();
let $item = $tmpl.clone();
sax.populateItem($item, item);
$items.append($item);
}
+2 -2
View File
@@ -28,7 +28,7 @@
var $results = $('.sax-panel-results');
var $msgs = $('.sax-panel-messages', $results).hide().empty();
var $items = $('.sax-panel-item-list', $results).hide().empty();
var $templ = $('.sax-panel-item-template .sax-panel-item.Sport', $results);
var $tmpl = $('.sax-panel-item-template .sax-panel-item.Sport', $results);
if (!response.success) return;
// Reference data - Statuses.
if (response.defaultStatusCode) sax.data.defaultStatusCode = response.defaultStatusCode;
@@ -41,7 +41,7 @@
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
{
let item = items[itemIdx];
let $item = $templ.clone();
let $item = $tmpl.clone();
sax.populateItem($item, item);
$items.append($item);
}
@@ -0,0 +1,104 @@
/*
* Admin - System Database page scripts.
*/
(function (win, doc, undef)
{
"use strict";
sax.itemIdPrefix = 'Itm_';
//--------------------------------------------------------------
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 + 'System/Ajax/GetDatabaseTables', formId: 'frmDatabaseFilter', callbackFn: sax.doRefreshResults };
sax.doAjaxRequest(sax.ajaxRefreshResults, delay || 50);
sax.awaitingRefreshResponse = true;
}
sax.doRefreshResults = function (response)
{
sax.debug('doRefreshResults', response);
delete sax.awaitingRefreshResponse;
sax.refreshControlValues(response.controlValues);
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.DatabaseTable', $results);
if (!response.success) return;
// Items.
var items = response.tables;
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);
$('.TableName', $item).text(item.qualifiedName);
$('.RowCount', $item).text(item.rowCount);
$('.ColumnCount', $item).text(item.columnCount);
$('.IndexCount', $item).text(item.indexCount);
$('.sax-caption .sax-action, .sax-actions .sax-action.sax-item-view', $item).off('click').on('click', function () { sax.viewItem(item.id) })
$item.off('dblclick').on('dblclick', function () { sax.updateItem(item.id) })
$('.sax-panel-results .sax-panel-messages').hide().empty();
}
//--------------------------------------------------------------
sax.viewItem = function (id)
{
$('.DatabaseTableName', sax.$frm.dbTableName).val(id);
sax.ajaxUpdateItem = sax.ajaxUpdateItem || { url: sax.url.base + 'System/Ajax/GetDatabaseTable', formId: 'frmDatabaseTableName', callbackFn: sax.onViewItem };
sax.doAjaxRequest(sax.ajaxUpdateItem, 50);
}
sax.onViewItem = function (response)
{
//sax.debug('onViewItem', response);
let $frm = sax.$frm.dbTable;
$('input[type="text"],textarea,select', $frm).val('');
if (!response.success) return;
let item = response.table;
$('.DatabaseTableName', $frm).val(item.name);
sax.clearControlErrors();
sax.$dlg.dbTable.dialog('option', 'title', sax.dlg.title.viewDatabaseTable);
sax.openDialog(sax.$dlg.dbTable, 600, 600);
}
sax.doUpdateItem = function ()
{
sax.storeItem();
}
//--------------------------------------------------------------
$(function ()
{
$('.sax-action.sax-results-refresh').on('click', function () { sax.refreshResults(); });
$('.sax-input').on('input', function () { sax.clearControlError(this); });
sax.$frm.filter = $('#frmDatabaseFilter');
$('.FilterDatabaseTable', sax.$frm.filter).on('input', function () { sax.refreshResults(250); });
sax.$frm.dbTableName = $('#frmDatabaseTableName');
sax.$frm.dbTable = $('#frmDatabaseTable');
var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { sax.doCreateItem(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
sax.$dlg.dbTable = $('#dlgDatabaseTable').dialog(opt);
setTimeout(sax.refreshResults, 250);
});
}(window, window.document));
/* The End */
+2 -2
View File
@@ -29,7 +29,7 @@
var $results = $('.sax-panel-results');
var $msgs = $('.sax-panel-messages', $results).hide().empty();
var $items = $('.sax-panel-item-list', $results).hide().empty();
var $templ = $('.sax-panel-item-template .sax-panel-item.User', $results);
var $tmpl = $('.sax-panel-item-template .sax-panel-item.User', $results);
if (!response.success) return;
// Reference data - Roles.
if (response.userRoles && response.userRoles.length)
@@ -45,7 +45,7 @@
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
{
let item = items[itemIdx];
let $item = $templ.clone();
let $item = $tmpl.clone();
sax.populateItem($item, item);
$items.append($item);
}
@@ -1,37 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SaxoniteCoreWebApp.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace SaxoniteCoreWebApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
@@ -1,11 +0,0 @@
using System;
namespace SaxoniteCoreWebApp.Models
{
public class ErrorViewModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
-26
View File
@@ -1,26 +0,0 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SaxoniteCoreWebApp
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
@@ -1,29 +0,0 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:50361",
"sslPort": 44302
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
}
},
"SaxoniteCoreWebApp": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
}
}
}
}
@@ -1,12 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.13" />
</ItemGroup>
</Project>
-57
View File
@@ -1,57 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SaxoniteCoreWebApp
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
@@ -1,8 +0,0 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
@@ -1,6 +0,0 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
@@ -1,25 +0,0 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@@ -1,48 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - SaxoniteCoreWebApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">SaxoniteCoreWebApp</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</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">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2021 - SaxoniteCoreWebApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
@@ -1,2 +0,0 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
@@ -1,3 +0,0 @@
@using SaxoniteCoreWebApp
@using SaxoniteCoreWebApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@@ -1,3 +0,0 @@
@{
Layout = "_Layout";
}
@@ -1,9 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
-10
View File
@@ -1,10 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
-71
View File
@@ -1,71 +0,0 @@
/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand {
white-space: normal;
text-align: center;
word-break: break-all;
}
/* Provide sufficient contrast against white background */
a {
color: #0366d6;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
/* Sticky footer styles
-------------------------------------------------- */
html {
font-size: 14px;
}
@media (min-width: 768px) {
html {
font-size: 16px;
}
}
.border-top {
border-top: 1px solid #e5e5e5;
}
.border-bottom {
border-bottom: 1px solid #e5e5e5;
}
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
button.accept-policy {
font-size: 1rem;
line-height: inherit;
}
/* Sticky footer styles
-------------------------------------------------- */
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px; /* Vertically center the text there */
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

-4
View File
@@ -1,4 +0,0 @@
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
// for details on configuring this project to bundle and minify static web assets.
// Write your JavaScript code.
@@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2011-2018 Twitter, Inc.
Copyright (c) 2011-2018 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,331 +0,0 @@
/*!
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */
File diff suppressed because one or more lines are too long
@@ -1,8 +0,0 @@
/*!
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,12 +0,0 @@
Copyright (c) .NET Foundation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
these files except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
@@ -1,432 +0,0 @@
// Unobtrusive validation support library for jQuery and jQuery Validate
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// @version v3.2.11
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define("jquery.validate.unobtrusive", ['jquery-validation'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports
module.exports = factory(require('jquery-validation'));
} else {
// Browser global
jQuery.validator.unobtrusive = factory(jQuery);
}
}(function ($) {
var $jQval = $.validator,
adapters,
data_validation = "unobtrusiveValidation";
function setValidationValues(options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
}
function splitAndTrim(value) {
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
}
function escapeAttributeValue(value) {
// As mentioned on http://api.jquery.com/category/selectors/
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
}
function getModelPrefix(fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
}
function appendModelPrefix(value, prefix) {
if (value.indexOf("*.") === 0) {
value = value.replace("*.", prefix);
}
return value;
}
function onError(error, inputElement) { // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
container.removeClass("field-validation-valid").addClass("field-validation-error");
error.data("unobtrusiveContainer", container);
if (replace) {
container.empty();
error.removeClass("input-validation-error").appendTo(container);
}
else {
error.hide();
}
}
function onErrors(event, validator) { // 'this' is the form element
var container = $(this).find("[data-valmsg-summary=true]"),
list = container.find("ul");
if (list && list.length && validator.errorList.length) {
list.empty();
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
$.each(validator.errorList, function () {
$("<li />").html(this.message).appendTo(list);
});
}
}
function onSuccess(error) { // 'this' is the form element
var container = error.data("unobtrusiveContainer");
if (container) {
var replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
container.addClass("field-validation-valid").removeClass("field-validation-error");
error.removeData("unobtrusiveContainer");
if (replace) {
container.empty();
}
}
}
function onReset(event) { // 'this' is the form element
var $form = $(this),
key = '__jquery_unobtrusive_validation_form_reset';
if ($form.data(key)) {
return;
}
// Set a flag that indicates we're currently resetting the form.
$form.data(key, true);
try {
$form.data("validator").resetForm();
} finally {
$form.removeData(key);
}
$form.find(".validation-summary-errors")
.addClass("validation-summary-valid")
.removeClass("validation-summary-errors");
$form.find(".field-validation-error")
.addClass("field-validation-valid")
.removeClass("field-validation-error")
.removeData("unobtrusiveContainer")
.find(">*") // If we were using valmsg-replace, get the underlying error
.removeData("unobtrusiveContainer");
}
function validationInfo(form) {
var $form = $(form),
result = $form.data(data_validation),
onResetProxy = $.proxy(onReset, form),
defaultOptions = $jQval.unobtrusive.options || {},
execInContext = function (name, args) {
var func = defaultOptions[name];
func && $.isFunction(func) && func.apply(form, args);
};
if (!result) {
result = {
options: { // options structure passed to jQuery Validate's validate() method
errorClass: defaultOptions.errorClass || "input-validation-error",
errorElement: defaultOptions.errorElement || "span",
errorPlacement: function () {
onError.apply(form, arguments);
execInContext("errorPlacement", arguments);
},
invalidHandler: function () {
onErrors.apply(form, arguments);
execInContext("invalidHandler", arguments);
},
messages: {},
rules: {},
success: function () {
onSuccess.apply(form, arguments);
execInContext("success", arguments);
}
},
attachValidation: function () {
$form
.off("reset." + data_validation, onResetProxy)
.on("reset." + data_validation, onResetProxy)
.validate(this.options);
},
validate: function () { // a validation function that is called by unobtrusive Ajax
$form.validate();
return $form.valid();
}
};
$form.data(data_validation, result);
}
return result;
}
$jQval.unobtrusive = {
adapters: [],
parseElement: function (element, skipAttach) {
/// <summary>
/// Parses a single HTML element for unobtrusive validation attributes.
/// </summary>
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
/// validation to the form. If parsing just this single element, you should specify true.
/// If parsing several elements, you should specify false, and manually attach the validation
/// to the form when you are finished. The default is false.</param>
var $element = $(element),
form = $element.parents("form")[0],
valInfo, rules, messages;
if (!form) { // Cannot do client-side validation without a form
return;
}
valInfo = validationInfo(form);
valInfo.options.rules[element.name] = rules = {};
valInfo.options.messages[element.name] = messages = {};
$.each(this.adapters, function () {
var prefix = "data-val-" + this.name,
message = $element.attr(prefix),
paramValues = {};
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
prefix += "-";
$.each(this.params, function () {
paramValues[this] = $element.attr(prefix + this);
});
this.adapt({
element: element,
form: form,
message: message,
params: paramValues,
rules: rules,
messages: messages
});
}
});
$.extend(rules, { "__dummy__": true });
if (!skipAttach) {
valInfo.attachValidation();
}
},
parse: function (selector) {
/// <summary>
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
/// attribute values.
/// </summary>
/// <param name="selector" type="String">Any valid jQuery selector.</param>
// $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
// element with data-val=true
var $selector = $(selector),
$forms = $selector.parents()
.addBack()
.filter("form")
.add($selector.find("form"))
.has("[data-val=true]");
$selector.find("[data-val=true]").each(function () {
$jQval.unobtrusive.parseElement(this, true);
});
$forms.each(function () {
var info = validationInfo(this);
if (info) {
info.attachValidation();
}
});
}
};
adapters = $jQval.unobtrusive.adapters;
adapters.add = function (adapterName, params, fn) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
/// mmmm is the parameter name).</param>
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
/// attributes into jQuery Validate rules and/or messages.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
if (!fn) { // Called with no params, just a function
fn = params;
params = [];
}
this.push({ name: adapterName, params: params, adapt: fn });
return this;
};
adapters.addBool = function (adapterName, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has no parameter values.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, function (options) {
setValidationValues(options, ruleName || adapterName, true);
});
};
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a minimum value.</param>
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a maximum value.</param>
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
/// have both a minimum and maximum value.</param>
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the minimum value. The default is "min".</param>
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the maximum value. The default is "max".</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
var min = options.params.min,
max = options.params.max;
if (min && max) {
setValidationValues(options, minMaxRuleName, [min, max]);
}
else if (min) {
setValidationValues(options, minRuleName, min);
}
else if (max) {
setValidationValues(options, maxRuleName, max);
}
});
};
adapters.addSingleVal = function (adapterName, attribute, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has a single value.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
/// The default is "val".</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [attribute || "val"], function (options) {
setValidationValues(options, ruleName || adapterName, options.params[attribute]);
});
};
$jQval.addMethod("__dummy__", function (value, element, params) {
return true;
});
$jQval.addMethod("regex", function (value, element, params) {
var match;
if (this.optional(element)) {
return true;
}
match = new RegExp(params).exec(value);
return (match && (match.index === 0) && (match[0].length === value.length));
});
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
var match;
if (nonalphamin) {
match = value.match(/\W/g);
match = match && match.length >= nonalphamin;
}
return match;
});
if ($jQval.methods.extension) {
adapters.addSingleVal("accept", "mimtype");
adapters.addSingleVal("extension", "extension");
} else {
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
// validating the extension, and ignore mime-type validations as they are not supported.
adapters.addSingleVal("extension", "extension", "accept");
}
adapters.addSingleVal("regex", "pattern");
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
setValidationValues(options, "equalTo", element);
});
adapters.add("required", function (options) {
// jQuery Validate equates "required" with "mandatory" for checkbox elements
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
setValidationValues(options, "required", true);
}
});
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
var value = {
url: options.params.url,
type: options.params.type || "GET",
data: {}
},
prefix = getModelPrefix(options.element.name);
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
var paramName = appendModelPrefix(fieldName, prefix);
value.data[paramName] = function () {
var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
// For checkboxes and radio buttons, only pick up values from checked fields.
if (field.is(":checkbox")) {
return field.filter(":checked").val() || field.filter(":hidden").val() || '';
}
else if (field.is(":radio")) {
return field.filter(":checked").val() || '';
}
return field.val();
};
});
setValidationValues(options, "remote", value);
});
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
if (options.params.min) {
setValidationValues(options, "minlength", options.params.min);
}
if (options.params.nonalphamin) {
setValidationValues(options, "nonalphamin", options.params.nonalphamin);
}
if (options.params.regex) {
setValidationValues(options, "regex", options.params.regex);
}
});
adapters.add("fileextensions", ["extensions"], function (options) {
setValidationValues(options, "extension", options.params.extensions);
});
$(function () {
$jQval.unobtrusive.parse(document);
});
return $jQval.unobtrusive;
}));
File diff suppressed because one or more lines are too long
@@ -1,22 +0,0 @@
The MIT License (MIT)
=====================
Copyright Jörn Zaefferer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -1,36 +0,0 @@
Copyright JS Foundation and other contributors, https://js.foundation/
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/jquery/jquery
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
All files located in the node_modules and external directories are
externally maintained libraries used by this software which have their
own licenses; we recommend you read them, as their terms may differ from
the terms above.
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -138,6 +138,9 @@
<data name="account.caption.profile.sports" xml:space="preserve">
<value>My Sports</value>
</data>
<data name="activity.caption.activities" xml:space="preserve">
<value>Activities</value>
</data>
<data name="company.name" xml:space="preserve">
<value>Solum Forti</value>
</data>
@@ -201,6 +204,9 @@
<data name="label.close" xml:space="preserve">
<value>Close</value>
</data>
<data name="label.country" xml:space="preserve">
<value>Country</value>
</data>
<data name="label.create" xml:space="preserve">
<value>Create</value>
</data>
@@ -228,6 +234,9 @@
<data name="label.last.name" xml:space="preserve">
<value>Last name</value>
</data>
<data name="label.location" xml:space="preserve">
<value>Location</value>
</data>
<data name="label.name" xml:space="preserve">
<value>Name</value>
</data>
@@ -261,6 +270,9 @@
<data name="label.position" xml:space="preserve">
<value>Position</value>
</data>
<data name="label.province" xml:space="preserve">
<value>Province</value>
</data>
<data name="label.published" xml:space="preserve">
<value>Published</value>
</data>
@@ -396,6 +408,12 @@
<data name="policies.caption.privacy.policy" xml:space="preserve">
<value>Privacy Policy</value>
</data>
<data name="reference.caption.country.select" xml:space="preserve">
<value>Select Country</value>
</data>
<data name="reference.caption.province.select" xml:space="preserve">
<value>Select Province</value>
</data>
<data name="reference.caption.region.select" xml:space="preserve">
<value>Select Region</value>
</data>
@@ -137,7 +137,7 @@ namespace Saxonite.Net.Core.Web.Online.App
sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData);
SessionContext = sessionContextData.SessionContext;
// Data Cache console - to initialise refresh.
// Data Cache console - to initialise refresh. Must be done for every Session Context.
SaxDataCacheConsole dataCacheConsole = SaxGlobals.ConsoleHelper.GetDataCacheConsole(SessionContext);
}
catch (Exception exc)
@@ -40,12 +40,34 @@ namespace Saxonite.Net.Core.Web.Online.App
public SysId OrganisationId { get; set; }
/// <summary>Display text for currently selected Organisation.</summary>
public String OrganisationCaption { get; set; }
/// <summary>
/// Store the properties for the currently selected Organisation.
/// </summary>
public bool SetOrganisation(SaxOrganisation organisation)
{
if (organisation == null) return false;
if (!organisation.IsStatusActive) return false;
OrganisationId = organisation.Id;
OrganisationCaption = organisation.Name;
return true;
}
/// <summary>Id for currently selected Organisation of which the user is a member.</summary>
public SysId OrganisationIdMember { get; set; }
/// <summary>Display text for currently selected Organisation of which the user is a member.</summary>
public String OrganisationCaptionMember { get; set; }
/// <summary>
/// Store the properties for the currently selected Organisation for which the User is a member.
/// </summary>
public bool SetMemberOrganisation(SaxOrganisation organisation)
{
if (organisation == null) return false;
if (!organisation.IsStatusActive) return false;
OrganisationIdMember = organisation.Id;
OrganisationCaptionMember = organisation.Name;
return true;
}
}
public FilterData Filter { get; } = new FilterData();
public FilterData Filter { get; private set; } = new FilterData();
//-------------------------------------------------------------------
}
@@ -0,0 +1,31 @@
using Sarand.Net.Standard.Base.App;
using Saxonite.Net.Core.Web.Base.Consoles;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Consoles;
using System;
using System.Collections.Generic;
using System.Text;
namespace Saxonite.Net.Core.Web.Online.Consoles
{
//=======================================================================
public class SaxActivityConsole_Online : SaxActivityConsole_Web
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
public SaxActivityConsole_Online(SaxSessionContext sessionContext) :
base(sessionContext)
{
String fn = GetType().Name + ".CTR";
SaLogger.Info(fn + "");
}
//-------------------------------------------------------------------
// Utilities.
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -37,6 +37,13 @@ namespace Saxonite.Net.Core.Web.Online.Consoles
return dataCacheConsole;
}
//-------------------------------------------------------------------
// Activity console.
public override SaxActivityConsole CreateActivityConsole(SaxSessionContext sessionContext)
{
return new SaxActivityConsole_Online(sessionContext);
}
//-------------------------------------------------------------------
// Email console.
public override SaxEmailConsole CreateEmailConsole(SaxSessionContext sessionContext)
@@ -20,25 +20,43 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
//=======================================================================
partial class AccountController
{
//-------------------------------------------------------------------
// Account - Get Contact Details.
//-------------------------------------------------------------------
public class ContactResponseData
{
public ContactResponseData(SaxUserAccount userAccount)
{
EmailAddress = userAccount.EmailAddress;
DisplayName = userAccount.GetDisplayName();
Title = userAccount.Title;
FirstName = userAccount.FirstName;
LastName = userAccount.LastName;
}
public String EmailAddress { get; }
public String DisplayName { get; }
public String Title { get; }
public String FirstName { get; }
public String LastName { get; }
public String EmailAddress { get; set; }
public String DisplayName { get; set; }
public String Title { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
// Regions.
public int RegionIdCountry { get; set; }
public String RegionCaptionCountry { get; set; }
public int RegionIdProvince { get; set; }
public String RegionCaptionProvince { get; set; }
public String LocationCaption { get; set; }
}
private void PopulateContactResponseData(ContactResponseData data, SaxUserAccount userAccount)
{
data.EmailAddress = userAccount.EmailAddress;
data.DisplayName = userAccount.GetDisplayName();
data.Title = userAccount.Title;
data.FirstName = userAccount.FirstName;
data.LastName = userAccount.LastName;
data.RegionIdCountry = SysId.ToInt(userAccount.RegionIdCountry);
data.RegionIdProvince = SysId.ToInt(userAccount.RegionIdProvince);
using (SaxRegion regionCountry = Internals.GetRegion(userAccount.RegionIdCountry))
using (SaxRegion regionProvince = Internals.GetRegion(userAccount.RegionIdProvince))
{
data.RegionCaptionCountry = Localiser.GetRegionName(regionCountry);
data.RegionCaptionProvince = Localiser.GetRegionName(regionProvince);
List<String> locations = new List<string>() { data.RegionCaptionProvince, data.RegionCaptionCountry };
data.LocationCaption = locations.Concat(", ", "", "", true, true);
}
}
//-------------------------------------------------------------------
// Account - Get Contact Details.
//-------------------------------------------------------------------
public class AjaxResponse_AccountContactData : AjaxResponse_Data
{
public ContactResponseData Contact { get; set; }
@@ -67,9 +85,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
}
// Populate data to response.
responseData.Contact = new ContactResponseData(userAccount);
responseData.Contact = new ContactResponseData();
PopulateContactResponseData(responseData.Contact, userAccount);
responseData.Success = true;
return Json(responseData);
}
@@ -121,6 +139,11 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
userAccount.FirstName = model.AccountFirstName;
if (model.AccountLastName != null)
userAccount.LastName = model.AccountLastName;
// Regions.
if (model.AccountRegionIdCountry != null)
userAccount.RegionIdCountry = model.AccountRegionIdCountry.ToSysId();
if (model.AccountRegionIdProvince != null)
userAccount.RegionIdProvince = model.AccountRegionIdProvince.ToSysId();
// Update User Account.
if (userAccount.Changed) SaLogger.Info(fn + " Updating user account '" + userAccount.EmailAddress + "'. Id: " + SysId.ToString(userAccount.Id), true);
@@ -135,9 +158,9 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
}
// Construct response.
responseData.Contact = new ContactResponseData(userAccount);
responseData.Contact = new ContactResponseData();
PopulateContactResponseData(responseData.Contact, userAccount);
responseData.Success = true;
return Json(responseData);
}
@@ -0,0 +1,90 @@
using Microsoft.AspNetCore.Mvc;
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.Dbas;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Online.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using Saxonite.Net.Standard.Base.Consoles;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Online.Controllers
{
//=======================================================================
// Online Activity Controller - Ajax actions only.
//=======================================================================
public partial class ActivityController : SaxController_Online
{
//-------------------------------------------------------------------
// Construction.
public ActivityController(SaxLocaliser localiser, ILogger<HomeController> logger) :
base(localiser, logger)
{}
//-------------------------------------------------------------------
// Data definitions.
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 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; }
}
//-------------------------------------------------------------------
// Activities
//-------------------------------------------------------------------
public class AjaxResponse_ActivityList : AjaxResponse_Base
{
public List<SaxModel_Online.RegionData> Regions { get; } = new List<SaxModel_Online.RegionData>();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Activity/Ajax/GetList")]
[Route("Activity/Ajax/GetActivityList")]
[Route("Activity/Ajax/GetActivities")]
public IActionResult Ajax_GetActivityList(Model_Activity model)
{
String fn = GetType().Name + ".Ajax_GetActivityList";
String messageTitle = Localiser["activity.caption.activities"];
AjaxResponse_ActivityList responseData = new AjaxResponse_ActivityList();
// Validate session and referrer.
if (!ValidReferer)
return Forbid();
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Populate activities.
SaxActivityConsole.IndexContext indexContext = new SaxActivityConsole.IndexContext();
SaxActivityConsole.IndexResults indexResults = ActivityConsole.QueryIndex(indexContext);
foreach (SaxActivityConsole.IndexResults.ItemData itemData in indexResults.Items)
{
}
// Complete response.
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -7,6 +7,7 @@ using Sarand.Net.Standard.Base.Utils;
using Saxonite.Net.Core.Web.Online.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using Saxonite.Net.Standard.Base.Consoles;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -138,7 +139,6 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Complete response.
responseData.SetPaging(model);
responseData.Success = true;
return Json(responseData);
}
@@ -181,10 +181,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Construct response.
PopulateArticleResponseData(model, article, responseData.Article);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
@@ -268,12 +265,12 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
}
}
// Store Article Activity Index data.
ActivityConsole.StoreActivityIndex(article, DbUpdateInfo);
// Construct response.
PopulateArticleResponseData(model, article, responseData.Article);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
@@ -101,12 +101,16 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Organisation.
SysId organisationId = model.Filter.OrganisationId.ToSysId();
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
if (organisation == null || !organisation.IsStatusActive)
{
SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " organisation for Opportunity list. OrganisationId: '" + model.Filter.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
if (organisation != null)
{
// Store filter data.
SessionData_Online.Filter.OrganisationIdMember = organisation.Id;
SessionData_Online.Filter.OrganisationCaptionMember = organisation.Name;
SessionData_Online.Filter.SetMemberOrganisation(organisation);
// Reference data - opportunity types.
foreach (TypeCodeDesc opportunityType in OpportunityTypes)
@@ -225,12 +229,20 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Validate organisation.
SaxOrganisation organisation = AccountMgr.GetOrganisationById(opportunity.OrganisationId);
if (organisation == null || !organisation.IsStatusActive)
{
SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " organisation for Opportunity. OrganisationId: '" + opportunity.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Make a note of the selected Organisation.
SessionData_Online.Filter.SetMemberOrganisation(organisation);
// Construct response.
PopulateOpportunityResponseData(model, opportunity, responseData.Opportunity);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
@@ -278,19 +290,32 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Validate the Organisation Id.
// Validate the Organisation.
SysId organisationId = model.OpportunityOrganisationId.ToSysId();
if (!SysId.IsValid(organisationId))
{
SaLogger.Warn(fn + " Organisation Id not specified for Opportunity.");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
if (organisation == null || !organisation.IsStatusActive)
{
SaLogger.Warn(fn + " " + (organisation == null ? "Invalid" : "Inactive") + " organisation for Opportunity. OrganisationId: '" + model.OpportunityOrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
if (opportunity != null && !opportunity.OrganisationId.Equals(organisationId))
{
SaLogger.Warn(fn + " Inconsistent Organisation Id specified for Opportunity. Expected: " + opportunity.OrganisationId + ". Found: " + organisationId);
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
// Ensure that the user has the correct role to update Opportunities for this organisation.
if (!AccountMgr.UserHasOrganisationRole(SessionData.User.UserAccountId, organisationId, Sax.OrganisationRole.OpportunityAdmin))
{
SaLogger.Warn(fn + " User doesn not have 'Opportunity Admin' role for Organisation Id: " + organisationId);
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
// Create new item if required.
if (opportunity == null)
opportunity = ActivityMgr.CreateOrganisationOpportunity(organisationId);
@@ -327,12 +352,12 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
}
}
// Store Opportunity Activity Index data.
ActivityConsole.StoreActivityIndex(opportunity, DbUpdateInfo);
// Construct response.
PopulateOpportunityResponseData(model, opportunity, responseData.Opportunity);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
@@ -16,7 +16,7 @@ using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Online.Controllers
{
//=======================================================================
// Online Reference Controller - Ajax actions.
// Online Reference Controller - Ajax actions only.
//=======================================================================
public partial class ReferenceController : SaxController_Online
{
@@ -4,6 +4,7 @@ using Saxonite.Base.App;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Controllers;
using Saxonite.Net.Core.Web.Base.Models;
using Saxonite.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -29,6 +30,11 @@ namespace Saxonite.Net.Core.Web.Online.Models
public String AccountTitle { get; set; }
public String AccountFirstName { get; set; }
public String AccountLastName { get; set; }
// Regions.
public String AccountRegionIdCountry { get; set; }
public String AccountRegionCaptionCountry { get; }
public String AccountRegionIdProvince { get; set; }
public String AccountRegionCaptionProvince { get; }
//-------------------------------------------------------------------
// Sport properties.
@@ -45,8 +51,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlValue(nameof(AccountTitle), AccountTitle);
if (StringUtil.IsEmpty(AccountTitle))
responseData.SetControlError(nameof(AccountTitle), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(AccountTitle) > GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_Title))
responseData.SetControlError(nameof(AccountTitle), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.JournalistArticle_Headline)]);
else if (StringUtil.GetLength(AccountTitle) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_Title))
responseData.SetControlError(nameof(AccountTitle), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline)]);
}
// First Name.
@@ -55,8 +61,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlValue(nameof(AccountFirstName), AccountFirstName);
if (StringUtil.IsEmpty(AccountFirstName))
responseData.SetControlError(nameof(AccountFirstName), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(AccountFirstName) > GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_FirstName))
responseData.SetControlError(nameof(AccountFirstName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.JournalistArticle_Headline)]);
else if (StringUtil.GetLength(AccountFirstName) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_FirstName))
responseData.SetControlError(nameof(AccountFirstName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline)]);
}
// Last Name.
@@ -65,8 +71,24 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlValue(nameof(AccountLastName), AccountLastName);
if (StringUtil.IsEmpty(AccountLastName))
responseData.SetControlError(nameof(AccountLastName), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(AccountLastName) > GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_LastName))
responseData.SetControlError(nameof(AccountLastName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.JournalistArticle_Headline)]);
else if (StringUtil.GetLength(AccountLastName) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_LastName))
responseData.SetControlError(nameof(AccountLastName), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline)]);
}
// Country Region.
if (AccountRegionIdCountry != null && SysId.IsValid(AccountRegionIdCountry.ToSysId()))
{
SaxRegion regionCountry = Internals.GetRegion(AccountRegionIdCountry.ToSysId());
if (regionCountry == null)
responseData.SetControlError(nameof(AccountRegionIdCountry), Localiser["msg.validation.invalid.value"]);
}
// Province Region.
if (AccountRegionIdProvince != null)
{
SaxRegion regionProvince = Internals.GetRegion(AccountRegionIdProvince.ToSysId());
if (regionProvince == null)
responseData.SetControlError(nameof(AccountRegionIdProvince), Localiser["msg.validation.invalid.value"]);
}
return !responseData.HasControlErrors();
@@ -0,0 +1,35 @@
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Base.App;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Controllers;
using Saxonite.Net.Core.Web.Base.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Online.Models
{
//=======================================================================
public class Model_Activity: SaxModel_Online
{
//-------------------------------------------------------------------
// Construction.
public Model_Activity(SaxLocaliser localiser) :
base(localiser)
{
}
//-------------------------------------------------------------------
// Activity filter.
public class FilterData
{
public String Activity { get; set; }
}
public FilterData Filter { get; } = new FilterData();
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -37,12 +37,12 @@ namespace Saxonite.Net.Core.Web.Online.Models
// Article properties.
public String ArticleId { get; set; }
public String ArticleExists { get; set; }
// Region.
public String ArticleRegionId { get; set; }
public String ArticleRegionCaption { get; }
// Sport.
public String ArticleSportId { get; set; }
public String ArticleSportCaption { get; set; }
// Region.
public String ArticleRegionId { get; set; }
public String ArticleRegionCaption { get; }
// Article Content.
public String ArticleHeadline { get; set; }
public String ArticleSummary { get; set; }
@@ -61,8 +61,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlValue(nameof(ArticleHeadline), ArticleHeadline);
if (StringUtil.IsEmpty(ArticleHeadline))
responseData.SetControlError(nameof(ArticleHeadline), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(ArticleHeadline) > GetControlMaxLength(SaxDbDfn.ColumnIdx.JournalistArticle_Headline))
responseData.SetControlError(nameof(ArticleHeadline), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.JournalistArticle_Headline)]);
else if (StringUtil.GetLength(ArticleHeadline) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline))
responseData.SetControlError(nameof(ArticleHeadline), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Headline)]);
}
// Article summary.
@@ -71,16 +71,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlValue(nameof(ArticleSummary), ArticleSummary);
if (StringUtil.IsEmpty(ArticleSummary))
responseData.SetControlError(nameof(ArticleSummary), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(ArticleSummary) > GetControlMaxLength(SaxDbDfn.ColumnIdx.JournalistArticle_Summary))
responseData.SetControlError(nameof(ArticleSummary), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.JournalistArticle_Summary)]);
}
// Article region.
if (ArticleRegionId != null)
{
SysId articleRegionId = ArticleRegionId.ToSysId();
if (!SysId.IsValid(articleRegionId))
responseData.SetControlError(nameof(ArticleRegionId), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(ArticleSummary) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Summary))
responseData.SetControlError(nameof(ArticleSummary), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.JournalistArticle_Summary)]);
}
// Article sport.
@@ -91,6 +83,14 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlError(nameof(ArticleSportId), Localiser["msg.validation.mandatory.value"]);
}
// Article region.
if (ArticleRegionId != null)
{
SysId articleRegionId = ArticleRegionId.ToSysId();
if (!SysId.IsValid(articleRegionId))
responseData.SetControlError(nameof(ArticleRegionId), Localiser["msg.validation.mandatory.value"]);
}
// Article status.
if (ArticleStatusCode != null)
{
@@ -41,10 +41,10 @@ namespace Saxonite.Net.Core.Web.Online.Models
public String OpportunityExists { get; set; }
// Opportunity properties.
public String OpportunityOrganisationId { get; set; }
// Region.
public String OpportunityRegionId { get; set; }
// Sport.
public String OpportunitySportId { get; set; }
// Region.
public String OpportunityRegionId { get; set; }
// Opportunity Content.
public String OpportunityTypeCode { get; set; }
public String OpportunityPosition { get; set; }
@@ -71,8 +71,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlValue(nameof(OpportunityPosition), OpportunityPosition);
if (StringUtil.IsEmpty(OpportunityPosition))
responseData.SetControlError(nameof(OpportunityPosition), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(OpportunityPosition) > GetControlMaxLength(SaxDbDfn.ColumnIdx.OrganisationOpportunity_Position))
responseData.SetControlError(nameof(OpportunityPosition), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.OrganisationOpportunity_Position)]);
else if (StringUtil.GetLength(OpportunityPosition) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Position))
responseData.SetControlError(nameof(OpportunityPosition), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Position)]);
}
// Opportunity outline.
@@ -81,16 +81,8 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlValue(nameof(OpportunityOutline), OpportunityOutline);
if (StringUtil.IsEmpty(OpportunityOutline))
responseData.SetControlError(nameof(OpportunityOutline), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(OpportunityOutline) > GetControlMaxLength(SaxDbDfn.ColumnIdx.OrganisationOpportunity_Outline))
responseData.SetControlError(nameof(OpportunityOutline), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn.ColumnIdx.OrganisationOpportunity_Outline)]);
}
// Opportunity region.
if (OpportunityRegionId != null)
{
SysId articleRegionId = OpportunityRegionId.ToSysId();
if (!SysId.IsValid(articleRegionId))
responseData.SetControlError(nameof(OpportunityRegionId), Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(OpportunityOutline) > GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Outline))
responseData.SetControlError(nameof(OpportunityOutline), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.OrganisationOpportunity_Outline)]);
}
// Opportunity sport.
@@ -101,6 +93,14 @@ namespace Saxonite.Net.Core.Web.Online.Models
responseData.SetControlError(nameof(OpportunitySportId), Localiser["msg.validation.mandatory.value"]);
}
// Opportunity region.
if (OpportunityRegionId != null)
{
SysId articleRegionId = OpportunityRegionId.ToSysId();
if (!SysId.IsValid(articleRegionId))
responseData.SetControlError(nameof(OpportunityRegionId), Localiser["msg.validation.mandatory.value"]);
}
// Opportunity status.
if (OpportunityStatusCode != null)
{
@@ -30,6 +30,13 @@
</div>
</div>
<div class="sax-property AccountLocation hidden">
<div class="row">
<div class="col-sm-4 sax-label text-sm-right">@Localiser["label.location"]</div>
<div class="col-sm-8 sax-value"></div>
</div>
</div>
</div>
</div>
@@ -54,7 +61,7 @@
<label for="ifAccountEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.AccountEmailAddress, new { @id = "ifAccountEmailAddress", @class = "AccountEmailAddress sax-input", @readonly = "readonly", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_EmailAddress) })
@Html.TextBoxFor(model => model.AccountEmailAddress, new { @id = "ifAccountEmailAddress", @class = "AccountEmailAddress sax-input", @readonly = "readonly", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_EmailAddress) })
</div>
<div class="sax-message"></div>
</div>
@@ -75,7 +82,7 @@
<label for="ifAccountFirstName"><span><span class="required">*</span> @Localiser["label.first.name"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.AccountFirstName, new { @id = "ifAccountFirstName", @class = "AccountFirstName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_FirstName) })
@Html.TextBoxFor(model => model.AccountFirstName, new { @id = "ifAccountFirstName", @class = "AccountFirstName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_FirstName) })
</div>
<div class="sax-message"></div>
</div>
@@ -86,7 +93,20 @@
<label for="ifAccountLastName"><span><span class="required">*</span> @Localiser["label.last.name"]</span></label>
</div>
<div class="sax-control">
@Html.TextBoxFor(model => model.AccountLastName, new { @id = "ifAccountLastName", @class = "AccountLastName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn.ColumnIdx.UserAccount_LastName) })
@Html.TextBoxFor(model => model.AccountLastName, new { @id = "ifAccountLastName", @class = "AccountLastName sax-input", @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.UserAccount_LastName) })
</div>
<div class="sax-message"></div>
</div>
@* Country Region *@
<div class="sax-form-control AccountRegionIdCountry">
<div class="sax-label">
<label for="ifAccountRegionIdCountry"><span><span class="required">*</span> @Localiser["label.country"]</span></label>
</div>
<div class="sax-control row">
@Html.HiddenFor(model => model.AccountRegionIdCountry, new { @id = "ifAccountRegionIdCountry", @class = "AccountRegionIdCountry" })
<div class="col"><input type="text" id="ifAccountRegionCaptionCountry" class="AccountRegionCaptionCountry sax-input" readonly="readonly" onDblClick="sax.selectRegionCountry()" /></div>
<div class="fixed"><button id="pbSelectRegionCountry" class="sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px" onclick="sax.selectRegionCountry()">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>

Some files were not shown because too many files have changed in this diff Show More