1.2.11.11 Golf Markers, Logs
This commit is contained in:
@@ -61,10 +61,10 @@ namespace Saxonite.Net.Core.Web.Base.Middleware
|
||||
{
|
||||
//if (SaxSystem.DebugMode) Logger.Debug(fn + " Form property " + modelName + ": '" + result.Model.ToString() + ".");
|
||||
object originalValue = result.Model;
|
||||
// Anything that looks like a password will be left as is.
|
||||
bool password = modelName.ContainsCI("Password");
|
||||
// Exclude properties that retain leading/trailing whitespace.
|
||||
if (result.Model is string)
|
||||
// Anything that looks like a password will be left as is.
|
||||
bool password = modelName.ContainsCI("Password");
|
||||
// Exclude properties that retain leading/trailing whitespace.
|
||||
if (result.Model is string)
|
||||
{
|
||||
if (!password)
|
||||
{
|
||||
@@ -97,13 +97,15 @@ namespace Saxonite.Net.Core.Web.Base.Middleware
|
||||
}
|
||||
}
|
||||
// Log property details.
|
||||
if (result.Model != null && SaxSystem.DebugMode &&
|
||||
// Ignore passwords.
|
||||
!password &&
|
||||
// Ignore items that correspond with objects in the model rather than values.
|
||||
!result.Model.ToString().Equals(result.Model.GetType().FullName) &&
|
||||
// Ignore form files.
|
||||
!result.Model.ToString().ContainsCI("Microsoft.AspNetCore.Http.IFormFile"))
|
||||
if (SaxSystem.DebugMode &&
|
||||
// Ignore blank values.
|
||||
result.Model != null && !StringUtil.IsBlank(result.Model.ToString()) &&
|
||||
// Ignore passwords.
|
||||
!password &&
|
||||
// Ignore items that correspond with objects in the model rather than values.
|
||||
!result.Model.ToString().Equals(result.Model.GetType().FullName) &&
|
||||
// Ignore form files.
|
||||
!result.Model.ToString().ContainsCI("Microsoft.AspNetCore.Http.IFormFile"))
|
||||
SaLogger.Debug(SysUtil.Fn + " Form property " + modelName + ": '" + result.Model.ToString() + "'." + (originalValue != null && !originalValue.Equals(result.Model) ? " Original value: '" + originalValue.ToString() + "'" : ""));
|
||||
base.SetProperty(bindingContext, modelName, propertyMetadata, result);
|
||||
}
|
||||
|
||||
@@ -31,10 +31,17 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum Task
|
||||
{
|
||||
CleanseCourseCaptions,
|
||||
}
|
||||
|
||||
public new class Config : SaxProcess_Web.Config
|
||||
{
|
||||
public Config(SaxSessionContext sessionContext, DbUpdateInfo dbUpdateInfo) : base(sessionContext, dbUpdateInfo)
|
||||
{ }
|
||||
/// <summary>Tasks to be run under this instance of the USGA Data Lookup process.</summary>
|
||||
public HashSet<Task> Tasks { get; } = new HashSet<Task>();
|
||||
}
|
||||
|
||||
public class CountryProvinceCodes
|
||||
@@ -154,6 +161,18 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
||||
// Run the process.
|
||||
protected override bool Run()
|
||||
{
|
||||
// Execute selected tasks.
|
||||
foreach (Task task in config.Tasks)
|
||||
{
|
||||
switch (task)
|
||||
{
|
||||
case Task.CleanseCourseCaptions:
|
||||
CleanseCourseCaptions();
|
||||
break;
|
||||
}
|
||||
if (!OK) break;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -636,26 +655,37 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
||||
/// </summary>
|
||||
/// <param name="course"></param>
|
||||
private void SetCourseCaption(CourseData course)
|
||||
{
|
||||
course.Caption = GetCourseCaption(course.FacilityName, course.CourseName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine facility and course names as required to generate course caption.
|
||||
/// <para>- NB Course name is sufficient if same as facility name.</para>
|
||||
/// </summary>
|
||||
/// <param name="course"></param>
|
||||
private String GetCourseCaption(String facilityName, String courseName)
|
||||
{
|
||||
// Facility (club) name.
|
||||
// - Strip id in brackets + anything following and remove generic phrases (golf club, hotel etc).
|
||||
String facilityName = CleanseFacilityName(Regex.Replace(course.FacilityName, "\\s*\\(\\s*\\d+\\s*\\).*$", ""));
|
||||
facilityName = CleanseFacilityName(Regex.Replace(facilityName, "\\s*\\(\\s*\\d+\\s*\\).*$", ""));
|
||||
// Course name.
|
||||
// - Remove id in brackets (occasionally found).
|
||||
// - Remove generic phrases (including for facility name).
|
||||
String courseName = CleanseCourseName(Regex.Replace(course.CourseName, "\\(\\s*\\d+\\s*\\)", ""));
|
||||
course.Caption = courseName;
|
||||
courseName = CleanseCourseName(Regex.Replace(courseName, "\\(\\s*\\d+\\s*\\)", ""));
|
||||
String courseCaption = courseName;
|
||||
if (!CourseNameMatchesFacility(facilityName, courseName))
|
||||
course.Caption = facilityName + " - " + courseName;
|
||||
courseCaption = facilityName + " - " + courseName;
|
||||
return courseCaption;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleanse Facility name by removing generic phrases, eg. golf club, hotel etc.
|
||||
/// </summary>
|
||||
public static String CleanseFacilityName(String facilityName)
|
||||
private String CleanseFacilityName(String facilityName)
|
||||
{
|
||||
facilityName = Regex.Replace(facilityName, "Hotel(,\\s*Golf)?\\s*(and|&)\\s*(Golf|Country|Sailing|Spa)(\\s*Club)?", "", RegexOptions.IgnoreCase);
|
||||
facilityName = Regex.Replace(facilityName, "Golf(\\s*Club)?\\s*(and|&)\\s*(Hotel|Country|Sailing|Spa)\\s*Club", "", RegexOptions.IgnoreCase);
|
||||
facilityName = Regex.Replace(facilityName, "Hotel(,\\s*Golf)?\\s*(and|&)\\s*(Golf|Country|Health|Sailing|Spa)(\\s*Club)?", "", RegexOptions.IgnoreCase);
|
||||
facilityName = Regex.Replace(facilityName, "Golf(\\s*Club)?\\s*(and|&)\\s*(Hotel|Country|Fitness|Sailing|Spa)(\\s*Club)", "", RegexOptions.IgnoreCase);
|
||||
facilityName = Regex.Replace(facilityName, "Golf\\s*(Club|Course|Links|Centre|Academy|Resort|Klub)(\\s*(Ltd|Limited))?", "", RegexOptions.IgnoreCase);
|
||||
facilityName = Regex.Replace(facilityName, "Club\\s*de\\s*Golf", "", RegexOptions.IgnoreCase);
|
||||
facilityName = Regex.Replace(facilityName, "\\s*(Golf|Country\\s*Club|Club|Ltd)\\s*$", "", RegexOptions.IgnoreCase);
|
||||
@@ -684,6 +714,93 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
public bool CleanseCourseCaptions()
|
||||
{
|
||||
SaLogger.Info($"{SysUtil.Fn} START", true);
|
||||
DateTime startedAt = DateTime.Now;
|
||||
ClearProcessMessages();
|
||||
|
||||
int courseCount = 0;
|
||||
int maxCourses = 0;
|
||||
int courseCaptionsCorrected = 0;
|
||||
|
||||
// Verify Course captions.
|
||||
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
|
||||
{
|
||||
// Local function to allow break/return from within nested loop.
|
||||
void CompareCourseCaptions()
|
||||
{
|
||||
// Countries.
|
||||
foreach (SaxGolfUsgaCountry country in ReferenceGolfMgr.GetUsgaCountryList(new SaxGolfUsgaCountry.Params()))
|
||||
{
|
||||
disposables.Add(country);
|
||||
|
||||
// Provinces.
|
||||
SaxGolfUsgaProvince.Params prmProvince = new SaxGolfUsgaProvince.Params();
|
||||
prmProvince.CountryIdsIncluded.Add(country.Id);
|
||||
foreach (SaxGolfUsgaProvince province in ReferenceGolfMgr.GetUsgaProvinceList(prmProvince))
|
||||
{
|
||||
disposables.Add(province);
|
||||
|
||||
// Separate disposables for each province to restrict volume handled on each disposal.
|
||||
using (DisposableCollection<SacsDisposable> disposablesProvince = new DisposableCollection<SacsDisposable>())
|
||||
{
|
||||
|
||||
// Facilities.
|
||||
SaxGolfUsgaFacility.Params prmFacility = new SaxGolfUsgaFacility.Params();
|
||||
prmFacility.ProvinceIdsIncluded.Add(province.Id);
|
||||
foreach (SaxGolfUsgaFacility facility in ReferenceGolfMgr.GetUsgaFacilityList(prmFacility))
|
||||
{
|
||||
disposablesProvince.Add(facility);
|
||||
|
||||
// Courses.
|
||||
SaxGolfUsgaCourse.Params prmCourse = new SaxGolfUsgaCourse.Params();
|
||||
prmCourse.FacilityIdsIncluded.Add(facility.Id);
|
||||
foreach (SaxGolfUsgaCourse course in ReferenceGolfMgr.GetUsgaCourseList(prmCourse))
|
||||
{
|
||||
disposablesProvince.Add(course);
|
||||
courseCount++;
|
||||
|
||||
// Compare course caption.
|
||||
String courseCaption = GetCourseCaption(facility.FacilityName, course.CourseName);
|
||||
if (!course.Caption.Equals(courseCaption))
|
||||
{
|
||||
course.Caption = courseCaption;
|
||||
if (ReferenceGolfMgr.UpdateUsgaCourse(course, DbUpdateInfo))
|
||||
{
|
||||
courseCaptionsCorrected++;
|
||||
SaLogger.Info($"{SysUtil.Fn} Course caption corrected. Found: {course.Caption}.Corrected: {courseCaption}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Error updating Course caption: {ReferenceGolfMgr.ErrorStateMessage}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxCourses > 0 && courseCount > maxCourses)
|
||||
{
|
||||
SaLogger.Info($"{SysUtil.Fn} Maximum number of courses processed ({maxCourses}).");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Invoke local function.
|
||||
CompareCourseCaptions();
|
||||
}
|
||||
|
||||
// Log statistics.
|
||||
SaLogger.Info($"{SysUtil.Fn} Course caption corrected: {courseCaptionsCorrected}. Courses checked: {courseCount}.", true);
|
||||
|
||||
SaLogger.Info($"{SysUtil.Fn} END Elapsed: {DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds)}", true);
|
||||
return OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Identify the column for each marker property.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Procs;
|
||||
using Saxonite.Net.Core.Web.Admin.Procs;
|
||||
using Saxonite.Net.Core.Web.Base.Procs;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Consoles;
|
||||
using Saxonite.Net.Standard.Base.Procs;
|
||||
@@ -18,19 +19,20 @@ namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
// Definitions.
|
||||
public enum ProcessType
|
||||
{
|
||||
OrganisationUpload
|
||||
OrganisationUpload,
|
||||
GolfUsgaDataLookup
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Process cache - to sustain processes outside of request/response timescales.
|
||||
internal class ProcessData
|
||||
{
|
||||
public ProcessData(SaxProcess_Admin process)
|
||||
public ProcessData(SaxProcess_Web process)
|
||||
{
|
||||
this.Process = process;
|
||||
|
||||
}
|
||||
public SaxProcess_Admin Process { get; }
|
||||
public SaxProcess_Web Process { get; }
|
||||
}
|
||||
// Cache.
|
||||
private Dictionary<ProcessType, ProcessData> processes { get; } = new Dictionary<ProcessType, ProcessData>();
|
||||
@@ -62,14 +64,14 @@ namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
// Processes.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
public SaxProcess_Admin GetProcess(ProcessType processType)
|
||||
public SaxProcess_Web GetProcess(ProcessType processType)
|
||||
{
|
||||
return processes.GetValueOrDefault(processType, null)?.Process;
|
||||
}
|
||||
|
||||
public bool IsProcessing(ProcessType processType)
|
||||
{
|
||||
SaxProcess_Admin process = GetProcess(processType);
|
||||
SaxProcess_Web process = GetProcess(processType);
|
||||
if (process != null)
|
||||
if (process.Processing) return true;
|
||||
return false;
|
||||
@@ -83,7 +85,7 @@ namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
/// <exception cref="InProgressException"></exception>
|
||||
public bool ClearProcess(ProcessType processType)
|
||||
{
|
||||
SaxProcess_Admin process = GetProcess(processType);
|
||||
SaxProcess_Web process = GetProcess(processType);
|
||||
if (process != null)
|
||||
{
|
||||
if (process.Processing)
|
||||
@@ -93,7 +95,7 @@ namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
return processes.Remove(processType);
|
||||
}
|
||||
|
||||
public void SetProcess(ProcessType processType, SaxProcess_Admin process)
|
||||
public void SetProcess(ProcessType processType, SaxProcess_Web process)
|
||||
{
|
||||
ClearProcess(processType);
|
||||
processes.Add(processType, new ProcessData(process));
|
||||
@@ -105,7 +107,7 @@ namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Organisation Upload.
|
||||
public SaxOrganisationUploader GetSaxOrganisationUploader()
|
||||
public SaxOrganisationUploader GetOrganisationUploader()
|
||||
{
|
||||
return GetProcess(ProcessType.OrganisationUpload) as SaxOrganisationUploader;
|
||||
}
|
||||
@@ -114,6 +116,17 @@ namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
SetProcess(ProcessType.OrganisationUpload, process);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Organisation Upload.
|
||||
public SaxGolfUsgaDataLookup GetGolfUsgaDataLookup()
|
||||
{
|
||||
return GetProcess(ProcessType.GolfUsgaDataLookup) as SaxGolfUsgaDataLookup;
|
||||
}
|
||||
public void SetProcess(SaxGolfUsgaDataLookup process)
|
||||
{
|
||||
SetProcess(ProcessType.OrganisationUpload, process);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
+5
-4
@@ -5,6 +5,7 @@ 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.Core.Web.Admin.Models.Reference;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using Saxonite.Net.Standard.Base.Bus.Reference;
|
||||
@@ -15,10 +16,10 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Admin.Controllers.Reference
|
||||
{
|
||||
//=======================================================================
|
||||
// Reference Golf Controller - Ajax requests.
|
||||
//=======================================================================
|
||||
partial class ReferenceGolfController
|
||||
//=======================================================================
|
||||
// Reference Golf Controller - Ajax requests.
|
||||
//=======================================================================
|
||||
partial class ReferenceGolfController
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Get Stats ajax request.
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
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.Consoles;
|
||||
using Saxonite.Net.Core.Web.Admin.Models;
|
||||
using Saxonite.Net.Core.Web.Admin.Models.Reference;
|
||||
using Saxonite.Net.Core.Web.Admin.Procs;
|
||||
using Saxonite.Net.Core.Web.Base.Procs;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Bus;
|
||||
using Saxonite.Net.Standard.Base.Bus.Reference;
|
||||
@@ -115,6 +120,46 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers.Reference
|
||||
PopulateUsgaCourseResponseListData(course, data);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// USGA Marker data.
|
||||
private class UsgaMarkerListData : AjaxResponse_Data.ItemData_Base
|
||||
{
|
||||
public long? UsgaMarkerId { get; set; }
|
||||
public String Caption { get; set; }
|
||||
public short? Holes { get; set; }
|
||||
public String HolesCaption { get; set; }
|
||||
public String Tee { get; set; }
|
||||
public String Gender { get; set; }
|
||||
public short? SlopeRating { get; set; }
|
||||
public short? Par { get; set; }
|
||||
public decimal? CourseRating { get; set; }
|
||||
public decimal? BogeyRating { get; set; }
|
||||
public short? Length { get; set; }
|
||||
}
|
||||
private class UsgaMarkerItemData : UsgaMarkerListData
|
||||
{
|
||||
}
|
||||
private void PopulateUsgaMarkerResponseListData(SaxGolfUsgaMarker marker, UsgaMarkerListData data)
|
||||
{
|
||||
data.Id = SysId.ToString(marker.Id);
|
||||
data.Caption = marker.Caption;
|
||||
data.Holes = marker.Holes;
|
||||
data.HolesCaption = marker.HolesCaption;
|
||||
data.Tee = marker.Tee;
|
||||
data.Gender = marker.Gender;
|
||||
data.SlopeRating = marker.SlopeRating;
|
||||
data.Par = marker.Par;
|
||||
data.Gender = marker.Gender;
|
||||
data.BogeyRating = marker.BogeyRating;
|
||||
data.Length = marker.Length;
|
||||
data.StatusCode = marker.StatusCode;
|
||||
data.StatusDesc = marker.StatusDesc;
|
||||
}
|
||||
private void PopulateUsgaMarkerResponseItemData(SaxGolfUsgaMarker course, UsgaMarkerItemData data)
|
||||
{
|
||||
PopulateUsgaMarkerResponseListData(course, data);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Get Country List ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
@@ -133,7 +178,6 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers.Reference
|
||||
[Route("Reference/Golf/Ajax/GetCountries")]
|
||||
public IActionResult Ajax_GetCountryList(Model_ReferenceGolf model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_GetCountryList";
|
||||
String messageTitle = Localiser["caption.reference.golf"];
|
||||
AjaxResponse_ReferenceGolf_CountryList responseData = new AjaxResponse_ReferenceGolf_CountryList(model);
|
||||
|
||||
@@ -218,7 +262,6 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers.Reference
|
||||
[Route("Reference/Golf/Ajax/GetProvinces")]
|
||||
public IActionResult Ajax_GetProvinceList(Model_ReferenceGolf model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_GetProvinceList";
|
||||
String messageTitle = Localiser["caption.reference.golf"];
|
||||
AjaxResponse_ReferenceGolf_ProvinceList responseData = new AjaxResponse_ReferenceGolf_ProvinceList(model);
|
||||
|
||||
@@ -305,7 +348,6 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers.Reference
|
||||
[Route("Reference/Golf/Ajax/GetCourses")]
|
||||
public IActionResult Ajax_GetCourseList(Model_ReferenceGolf model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_GetCourseList";
|
||||
String messageTitle = Localiser["caption.reference.golf"];
|
||||
AjaxResponse_ReferenceGolf_CourseList responseData = new AjaxResponse_ReferenceGolf_CourseList(model);
|
||||
|
||||
@@ -384,6 +426,164 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers.Reference
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Get Marker List ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_ReferenceGolf_CleanseUsgaCourseCaptions : AjaxResponse_Data
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_ReferenceGolf_CleanseUsgaCourseCaptions(SaxModel_Admin model) : base(model) { }
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Reference/Golf/Ajax/CleanseUsgaCourseCaptions")]
|
||||
public IActionResult Ajax_CleanseUsgaCourseCaptions(Model_ReferenceGolf model)
|
||||
{
|
||||
String messageTitle = Localiser["caption.reference.golf"];
|
||||
AjaxResponse_ReferenceGolf_CleanseUsgaCourseCaptions responseData = new AjaxResponse_ReferenceGolf_CleanseUsgaCourseCaptions(model);
|
||||
|
||||
// Validate session.
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
|
||||
{
|
||||
|
||||
// Process console.
|
||||
SaxProcessConsole_Admin processConsole = GetProcessConsole_Admin(SessionContext);
|
||||
if (processConsole == null)
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Check whether process is in progress.
|
||||
if (processConsole.IsProcessing(SaxProcessConsole_Admin.ProcessType.GolfUsgaDataLookup))
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.process.in.progress"]));
|
||||
|
||||
// Configure the process.
|
||||
SaxGolfUsgaDataLookup.Config processConfig = new SaxGolfUsgaDataLookup.Config(SessionContext, DbUpdateInfo);
|
||||
processConfig.Tasks.Add(SaxGolfUsgaDataLookup.Task.CleanseCourseCaptions);
|
||||
SaxGolfUsgaDataLookup process = new SaxGolfUsgaDataLookup(processConfig);
|
||||
|
||||
// Store the process and run.
|
||||
processConsole.SetProcess(process);
|
||||
process.RunAsync();
|
||||
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} {exc.GetType().Name} initialising organisation uploader.");
|
||||
return Json(responseData.SetMessage(messageTitle, exc.GetType().Name + " initialising USGA Golf Data Loader."));
|
||||
}
|
||||
}
|
||||
|
||||
// Complete response.
|
||||
Json(responseData.SetMessage(messageTitle, "Course caption cleansing is underway."));
|
||||
responseData.Success = true;
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Get Marker List ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_ReferenceGolf_MarkerList : AjaxResponse_Data
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_ReferenceGolf_MarkerList(SaxModel_Admin model) : base(model) { }
|
||||
// Marker list.
|
||||
public List<UsgaMarkerListData> Markers { get; } = new List<UsgaMarkerListData>();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Reference/Golf/Ajax/GetUsgaMarkerList")]
|
||||
[Route("Reference/Golf/Ajax/GetUsgaMarkers")]
|
||||
[Route("Reference/Golf/Ajax/GetMarkerList")]
|
||||
[Route("Reference/Golf/Ajax/GetMarkers")]
|
||||
public IActionResult Ajax_GetMarkerList(Model_ReferenceGolf model)
|
||||
{
|
||||
String messageTitle = Localiser["caption.reference.golf"];
|
||||
AjaxResponse_ReferenceGolf_MarkerList responseData = new AjaxResponse_ReferenceGolf_MarkerList(model);
|
||||
|
||||
// Validate session.
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
|
||||
// Item columns.
|
||||
ColumnDfn colId = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Id);
|
||||
ColumnDfn colUsgaMarkerId = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.UsgaMarkerId);
|
||||
ColumnDfn colCaption = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Caption);
|
||||
ColumnDfn colHoles = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Holes);
|
||||
ColumnDfn colHolesCaption = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.HolesCaption);
|
||||
ColumnDfn colTee = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Tee);
|
||||
ColumnDfn colGender = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Gender);
|
||||
ColumnDfn colSlopeRating = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.SlopeRating);
|
||||
ColumnDfn colPar = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Par);
|
||||
ColumnDfn colCourseRating = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.CourseRating);
|
||||
ColumnDfn colBogeyRating = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.BogeyRating);
|
||||
ColumnDfn colLength = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Length);
|
||||
ColumnDfn colFlags = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Flags);
|
||||
ColumnDfn colStatus = ReferenceGolfMgr.GetUsgaMarkerColumnDfn(SaxGolfUsgaMarker.Column.Status);
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||
{
|
||||
colId, colUsgaMarkerId, colCaption, colHoles, colHolesCaption, colTee, colGender, colSlopeRating, colPar, colCourseRating, colBogeyRating, colLength, colFlags, colStatus
|
||||
};
|
||||
|
||||
// Item filter.
|
||||
SaxGolfUsgaMarker.Params prmUsgaMarker = new SaxGolfUsgaMarker.Params();
|
||||
if (StringUtil.ToLong(model.Filter.CourseId) > 0)
|
||||
prmUsgaMarker.CourseIdsIncluded.Add(StringUtil.ToSysId(model.Filter.CourseId));
|
||||
prmUsgaMarker.MarkerFilter = model.Filter.MarkerSearch;
|
||||
prmUsgaMarker.StatusCat = SaxGolfUsgaMarker.StatusCat.Any;
|
||||
model.Paging.ItemTotal = (ulong)ReferenceGolfMgr.GetUsgaMarkerCount(prmUsgaMarker);
|
||||
model.PopulatePagingTo(prmUsgaMarker.ResultsPaging);
|
||||
// Restrict results is not paged.
|
||||
if (!prmUsgaMarker.ResultsPaging.Paged)
|
||||
{
|
||||
prmUsgaMarker.ResultsPaging.PageNo = 1;
|
||||
prmUsgaMarker.ResultsPaging.PageLength = 200;
|
||||
}
|
||||
|
||||
// Sort order.
|
||||
prmUsgaMarker.SortColumns.Add(colCaption);
|
||||
|
||||
// Query items.
|
||||
using (DbResultSet resultSet = ReferenceGolfMgr.ExecuteUsgaMarkerQuery(columns, prmUsgaMarker))
|
||||
{
|
||||
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
|
||||
{
|
||||
NamedValue.Map values = resultSet.GetRecordValues();
|
||||
ushort flags = (ushort)values.GetLong(colFlags.DataName);
|
||||
UsgaMarkerListData markerData = new UsgaMarkerListData()
|
||||
{
|
||||
Id = values.GetString(colId.DataName),
|
||||
UsgaMarkerId = values.GetLong(colUsgaMarkerId.DataName),
|
||||
Caption = values.GetString(colCaption.DataName),
|
||||
Holes = (short)values.GetLong(colHoles.DataName),
|
||||
HolesCaption = values.GetString(colHolesCaption.DataName),
|
||||
Tee = values.GetString(colTee.DataName),
|
||||
Gender = values.GetString(colGender.DataName),
|
||||
SlopeRating = (short)values.GetLong(colSlopeRating.DataName),
|
||||
Par = (short)values.GetLong(colPar.DataName),
|
||||
CourseRating = values.GetDecimal(colCourseRating.DataName),
|
||||
BogeyRating = values.GetDecimal(colBogeyRating.DataName),
|
||||
Length = (short)values.GetLong(colLength.DataName),
|
||||
StatusCode = values.GetString(colStatus.DataName),
|
||||
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
|
||||
};
|
||||
responseData.Markers.Add(markerData);
|
||||
}
|
||||
}
|
||||
if (model.Paging.IsPaged)
|
||||
model.Paging.ItemCount = (ushort)responseData.Markers.Count;
|
||||
|
||||
// Complete response.
|
||||
responseData.SetPaging(model);
|
||||
responseData.Success = true;
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Saxonite.Net.Core.Web.Admin.Models;
|
||||
using Saxonite.Net.Core.Web.Admin.Models.Reference;
|
||||
using Saxonite.Net.Core.Web.Base.App;
|
||||
using Saxonite.Net.Core.Web.Base.Controllers;
|
||||
using System;
|
||||
@@ -11,8 +11,8 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Admin.Controllers.Reference
|
||||
{
|
||||
//=======================================================================
|
||||
public partial class ReferenceGolfController : SaxController_Admin
|
||||
//=======================================================================
|
||||
public partial class ReferenceGolfController : SaxController_Admin
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers.System
|
||||
private class LogFileData
|
||||
{
|
||||
public String Name { get; set; }
|
||||
public String UpdateFmt { get; set; }
|
||||
public long Size { get; set; }
|
||||
}
|
||||
|
||||
@@ -207,7 +208,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers.System
|
||||
DirectoryInfo folder = new DirectoryInfo(logFolder);
|
||||
foreach (FileInfo file in folder.EnumerateFiles())
|
||||
{
|
||||
responseData.Files.Add(new LogFileData() { Name = file.Name, Size = file.Length });
|
||||
responseData.Files.Add(new LogFileData() { Name = file.Name, UpdateFmt = file.LastWriteTime.ToString("d-MMM-yy HH:mm"), Size = file.Length });
|
||||
}
|
||||
|
||||
// Complete response.
|
||||
|
||||
+11
-8
@@ -13,7 +13,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Admin.Models
|
||||
namespace Saxonite.Net.Core.Web.Admin.Models.Reference
|
||||
{
|
||||
//=======================================================================
|
||||
public class Model_ReferenceGolf : SaxModel_Admin
|
||||
@@ -30,12 +30,15 @@ namespace Saxonite.Net.Core.Web.Admin.Models
|
||||
// Reference Golf list parameters.
|
||||
public class FilterData
|
||||
{
|
||||
public String CountrySearch { get; set; }
|
||||
public String CountryId { get; set; }
|
||||
public String ProvinceSearch { get; set; }
|
||||
public String ProvinceId { get; set; }
|
||||
public String CourseSearch{ get; set; }
|
||||
public String CourseId { get; set; }
|
||||
public string CountrySearch { get; set; }
|
||||
public string CountryId { get; set; }
|
||||
public string ProvinceSearch { get; set; }
|
||||
public string ProvinceId { get; set; }
|
||||
public string CourseSearch { get; set; }
|
||||
public string CourseId { get; set; }
|
||||
public string MarkerSearch { get; set; }
|
||||
public string MarkerHoles { get; set; }
|
||||
public string MarkerGender { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
|
||||
@@ -46,7 +49,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models
|
||||
// Validation.
|
||||
//-------------------------------------------------------------------
|
||||
// Reference Golf.
|
||||
public bool ValidateReferenceGolfData(SaxController_Base.AjaxResponse_Data responseData)
|
||||
public bool ValidateReferenceGolfData(Sacs.Web.Components.SaController.AjaxResponse_Data responseData)
|
||||
{
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
|
||||
@@ -258,6 +258,9 @@
|
||||
<data name="label.awaiting.activation" xml:space="preserve">
|
||||
<value>Awaiting activation</value>
|
||||
</data>
|
||||
<data name="label.bogey" xml:space="preserve">
|
||||
<value>Bogey</value>
|
||||
</data>
|
||||
<data name="label.cancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
@@ -345,6 +348,9 @@
|
||||
<data name="label.facilities" xml:space="preserve">
|
||||
<value>Facilities</value>
|
||||
</data>
|
||||
<data name="label.file" xml:space="preserve">
|
||||
<value>File</value>
|
||||
</data>
|
||||
<data name="label.filename" xml:space="preserve">
|
||||
<value>Filename</value>
|
||||
</data>
|
||||
@@ -366,9 +372,15 @@
|
||||
<data name="label.full.name" xml:space="preserve">
|
||||
<value>Full name</value>
|
||||
</data>
|
||||
<data name="label.gender" xml:space="preserve">
|
||||
<value>Gender</value>
|
||||
</data>
|
||||
<data name="label.header.row" xml:space="preserve">
|
||||
<value>Header row</value>
|
||||
</data>
|
||||
<data name="label.holes" xml:space="preserve">
|
||||
<value>Holes</value>
|
||||
</data>
|
||||
<data name="label.image" xml:space="preserve">
|
||||
<value>Image</value>
|
||||
</data>
|
||||
@@ -408,6 +420,9 @@
|
||||
<data name="label.last.name" xml:space="preserve">
|
||||
<value>Last name</value>
|
||||
</data>
|
||||
<data name="label.length" xml:space="preserve">
|
||||
<value>Length</value>
|
||||
</data>
|
||||
<data name="label.location" xml:space="preserve">
|
||||
<value>Location</value>
|
||||
</data>
|
||||
@@ -480,6 +495,9 @@
|
||||
<data name="label.page.info" xml:space="preserve">
|
||||
<value>Page {0} of {1}</value>
|
||||
</data>
|
||||
<data name="label.par" xml:space="preserve">
|
||||
<value>Par</value>
|
||||
</data>
|
||||
<data name="label.parent" xml:space="preserve">
|
||||
<value>Parent</value>
|
||||
</data>
|
||||
@@ -555,6 +573,12 @@
|
||||
<data name="label.sheet.name.or.number" xml:space="preserve">
|
||||
<value>Sheet name or number (from 1)</value>
|
||||
</data>
|
||||
<data name="label.size" xml:space="preserve">
|
||||
<value>Size</value>
|
||||
</data>
|
||||
<data name="label.slope" xml:space="preserve">
|
||||
<value>Slope</value>
|
||||
</data>
|
||||
<data name="label.speciality" xml:space="preserve">
|
||||
<value>Speciality</value>
|
||||
</data>
|
||||
@@ -585,6 +609,9 @@
|
||||
<data name="label.table" xml:space="preserve">
|
||||
<value>Table</value>
|
||||
</data>
|
||||
<data name="label.tee" xml:space="preserve">
|
||||
<value>Tee</value>
|
||||
</data>
|
||||
<data name="label.title" xml:space="preserve">
|
||||
<value>Title</value>
|
||||
</data>
|
||||
@@ -597,6 +624,9 @@
|
||||
<data name="label.update" xml:space="preserve">
|
||||
<value>update</value>
|
||||
</data>
|
||||
<data name="label.updated" xml:space="preserve">
|
||||
<value>Updated</value>
|
||||
</data>
|
||||
<data name="label.upload" xml:space="preserve">
|
||||
<value>Upload</value>
|
||||
</data>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
<div class="sax-header">
|
||||
<div class="sax-caption">@Localiser["system.caption.database.core"]</div>
|
||||
</div>
|
||||
<div class="sax-content">
|
||||
<div style="padding:4px 8px;">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div class="sax-panel-item-list"></div>
|
||||
</div>
|
||||
@@ -85,7 +85,7 @@
|
||||
<div class="sax-header">
|
||||
<div class="sax-caption">@Localiser["system.caption.database.reference"]</div>
|
||||
</div>
|
||||
<div class="sax-content">
|
||||
<div style="padding:4px 8px;">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div class="sax-panel-item-list"></div>
|
||||
</div>
|
||||
@@ -98,7 +98,7 @@
|
||||
<div class="sax-header">
|
||||
<div class="sax-caption">@Localiser["system.caption.database.support"]</div>
|
||||
</div>
|
||||
<div class="sax-content">
|
||||
<div style="padding:4px 8px;">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div class="sax-panel-item-list"></div>
|
||||
</div>
|
||||
|
||||
@@ -30,23 +30,24 @@
|
||||
<div class="sax-action sax-results-refresh"><img src="~/img/action/refresh24.png" alt="@(Localiser["label.refresh"])" title="@(Localiser["label.refresh"])" /></div>
|
||||
</div>
|
||||
</div>
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmRefGolfFilter", @class = "sax-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.Filter.CountrySearch, new { @class = "FilterCountrySearch" })
|
||||
@Html.HiddenFor(model => model.Filter.CountryId, new { @class = "FilterCountryId" })
|
||||
@Html.HiddenFor(model => model.Filter.ProvinceSearch, new { @class = "FilterProvinceSearch" })
|
||||
@Html.HiddenFor(model => model.Filter.ProvinceId, new { @class = "FilterProvinceId" })
|
||||
@Html.HiddenFor(model => model.Filter.CourseSearch, new { @class = "FilterCourseSearch" })
|
||||
@Html.HiddenFor(model => model.Filter.CourseId, new { @class = "FilterCourseId" })
|
||||
@*
|
||||
<div class="sax-content">
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmRefGolfFilter", @class = "sax-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.Filter.CountrySearch, new { @class = "FilterCountrySearch" })
|
||||
@Html.HiddenFor(model => model.Filter.CountryId, new { @class = "FilterCountryId" })
|
||||
@Html.HiddenFor(model => model.Filter.ProvinceSearch, new { @class = "FilterProvinceSearch" })
|
||||
@Html.HiddenFor(model => model.Filter.ProvinceId, new { @class = "FilterProvinceId" })
|
||||
@Html.HiddenFor(model => model.Filter.CourseSearch, new { @class = "FilterCourseSearch" })
|
||||
@Html.HiddenFor(model => model.Filter.CourseId, new { @class = "FilterCourseId" })
|
||||
<div class="row">
|
||||
<div class="col-sm-5 col-md-3 sax-label text-left text-sm-right">@Localiser["label.options"]</div>
|
||||
<div class="col-sm-7 col-md-3 mb-sm-1 mb-md-0">
|
||||
@* ToDo ... *@
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-sm-5 col-md-3 sax-label text-left text-sm-right">@Localiser["label.options"]</div>
|
||||
<div class="col-sm-7 col-md-3 mb-sm-1 mb-md-0">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
*@
|
||||
}
|
||||
</div>
|
||||
|
||||
@* Reference - Golf - Stats *@
|
||||
@@ -63,8 +64,6 @@
|
||||
<div class="GolfStatGroup col-sm-12">
|
||||
<div class="GroupCaption"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sax-panel-item-template">
|
||||
<div class="GolfStat col-sm-6">
|
||||
<div class="row">
|
||||
<div class="col-8 text-right pr-2"><div class="StatCaption"></div></div>
|
||||
@@ -88,8 +87,8 @@
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div style="min-height:48px;max-height:240px;overflow-y:auto;">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<table class="sax-item-list">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -105,17 +104,19 @@
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<table class="sax-panel-item-template">
|
||||
<div class="sax-panel-item-template">
|
||||
<table>
|
||||
<tr class="sax-item GolfCountry">
|
||||
<td><div class="CountryCode center"></div></td>
|
||||
<td><div class="CountryName"></div></td>
|
||||
<td><div class="CountryPriority center"></div></td>
|
||||
<td><div class="CountryProvinces center"></div></td>
|
||||
<td><div class="CountryClubs center"></div></td>
|
||||
<td><div class="CountryClubsPercent center"></div></td>
|
||||
<td><div class="CountryStatus center"></div></td>
|
||||
<td class="center"><div class="CountryCode"></div></td>
|
||||
<td class=""><div class="CountryName"></div></td>
|
||||
<td class="center"><div class="CountryPriority"></div></td>
|
||||
<td class="center"><div class="CountryProvinces"></div></td>
|
||||
<td class="center"><div class="CountryClubs"></div></td>
|
||||
<td class="center"><div class="CountryClubsPercent"></div></td>
|
||||
<td class="center"><div class="CountryStatus"></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -134,8 +135,8 @@
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div style="min-height:48px;max-height:240px;overflow-y:auto;">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<table class="sax-item-list">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -151,17 +152,19 @@
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<table class="sax-panel-item-template">
|
||||
<div class="sax-panel-item-template">
|
||||
<table>
|
||||
<tr class="sax-item GolfProvince">
|
||||
<td><div class="ProvinceCode center"></div></td>
|
||||
<td><div class="ProvinceName"></div></td>
|
||||
<td><div class="ProvincePriority center"></div></td>
|
||||
<td><div class="ProvinceClubs center"></div></td>
|
||||
<td><div class="ProvinceCourses center"></div></td>
|
||||
<td><div class="ProvinceMarkers center"></div></td>
|
||||
<td><div class="ProvinceStatus center"></div></td>
|
||||
<td class="center"><div class="ProvinceCode"></div></td>
|
||||
<td class=""><div class="ProvinceName"></div></td>
|
||||
<td class="center"><div class="ProvincePriority"></div></td>
|
||||
<td class="center"><div class="ProvinceClubs"></div></td>
|
||||
<td class="center"><div class="ProvinceCourses"></div></td>
|
||||
<td class="center"><div class="ProvinceMarkers"></div></td>
|
||||
<td class="center"><div class="ProvinceStatus"></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -177,11 +180,21 @@
|
||||
<span><input type="search" name="Filter.CourseSearch" class="FilterCourseSearch" maxlength="16" style="width:33%;" /></span>
|
||||
</div>
|
||||
<div class="fixed"><div class="sax-caption">@Localiser["label.courses"]</div></div>
|
||||
<div class="col"></div>
|
||||
<div class="col right sax-actions">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-light navbar-right sax-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sax-dropdown-menu">
|
||||
@* *@
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div style="min-height:48px;max-height:240px;overflow-y:auto;">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<table class="sax-item-list">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -196,30 +209,87 @@
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<table class="sax-panel-item-template">
|
||||
<tr class="sax-item GolfCourse">
|
||||
<td><div class="CourseId center"></div></td>
|
||||
<td><div class="CourseCaption"></div></td>
|
||||
<td><div class="CourseLocation center"></div></td>
|
||||
<td><div class="CoursePriority center"></div></td>
|
||||
<td><div class="CourseMarkers center"></div></td>
|
||||
<td><div class="CourseStatus center"></div></td>
|
||||
<div class="sax-panel-item-template">
|
||||
@* Course template - table is ignored. *@
|
||||
<table>
|
||||
<tr class="sax-item GolfCourse">
|
||||
<td class="center"><div class="CourseId"></div></td>
|
||||
<td class=""><div class="CourseCaption"></div></td>
|
||||
<td class="center"><div class="CourseLocation"></div></td>
|
||||
<td class="center"><div class="CoursePriority"></div></td>
|
||||
<td class="center"><div class="CourseMarkers"></div></td>
|
||||
<td class="center"><div class="CourseStatus"></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
@* Burger dropdown item template - ul is ignored *@
|
||||
<ul class="sax-dropdown-menu Courses">
|
||||
<li class="sax-dropdown-item sax-action"><div class="sax-label">...</div></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@* Reference - Golf - Markers *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmMarkers", @class = "sax-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(Model => Model.Filter.CourseId, new { @class = "FilterCourseId" })
|
||||
@Html.HiddenFor(Model => Model.Filter.MarkerHoles, new { @class = "FilterMarkerHoles" })
|
||||
@Html.HiddenFor(Model => Model.Filter.MarkerGender, new { @class = "FilterMarkerGender" })
|
||||
<div class="sax-panel-info Markers">
|
||||
<div class="sax-header">
|
||||
<div class="row">
|
||||
<div class="col left">
|
||||
<span class="sax-label">@Localiser["label.search"]</span>
|
||||
<span><input type="search" name="Filter.MarkerSearch" class="FilterMarkerSearch" maxlength="16" style="width:33%;" /></span>
|
||||
</div>
|
||||
<div class="fixed"><div class="sax-caption">@Localiser["label.markers"]</div></div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div style="min-height:48px;max-height:240px;overflow-y:auto;">
|
||||
<table class="sax-item-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="pl-2">@Localiser["label.caption"]</th>
|
||||
<th class="center">@Localiser["label.holes"]</th>
|
||||
<th class="center">@Localiser["label.tee"]</th>
|
||||
<th class="center">@Localiser["label.gender"]</th>
|
||||
<th class="center">@Localiser["label.slope"]</th>
|
||||
<th class="center">@Localiser["label.par"]</th>
|
||||
<th class="center">@Localiser["label.course"]</th>
|
||||
<th class="center">@Localiser["label.bogey"]</th>
|
||||
<th class="center">@Localiser["label.length"]</th>
|
||||
<th class="center">@Localiser["label.status"]</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sax-panel-item-template">
|
||||
<table>
|
||||
<tr class="sax-item GolfMarker">
|
||||
<td class="pl-2"><div class="MarkerCaption"></div></td>
|
||||
<td class="center"><div class="MarkerHoles"></div></td>
|
||||
<td class="center"><div class="MarkerTee"></div></td>
|
||||
<td class="center"><div class="MarkerGender"></div></td>
|
||||
<td class="center"><div class="MarkerSlope"></div></td>
|
||||
<td class="center"><div class="MarkerPar"></div></td>
|
||||
<td class="center"><div class="MarkerCourse"></div></td>
|
||||
<td class="center"><div class="MarkerBogey"></div></td>
|
||||
<td class="center"><div class="MarkerLength"></div></td>
|
||||
<td class="center"><div class="MarkerStatus"></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@* Icons. *@
|
||||
<div class="sax-panel-item-template">
|
||||
<img src="~/img/icon/tick-64.png" alt="" title="" class="sax-tick" style="max-width:16px;" />
|
||||
</div>
|
||||
<div class="sax-panel-item-template">
|
||||
<img src="~/img/icon/sphere-green.svg" alt="Active" title="Active" class="sax-status-atv" style="max-width:16px;" />
|
||||
</div>
|
||||
<div class="sax-panel-item-template">
|
||||
<img src="~/img/icon/sphere-orange.svg" alt="Inactive" title="Inactive" class="sax-status-ina" style="max-width:16px;" />
|
||||
</div>
|
||||
<div class="sax-panel-item-template">
|
||||
<img src="~/img/icon/sphere-purple.svg" alt="Deleted" title="Deleted" class="sax-status-del" style="max-width:16px;" />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -53,21 +53,23 @@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmLogsFilter", @class = "sax-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
<input type="hidden" name="LogsFilter.Filename" class="FilterLogFilename" />
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-5 sax-label text-left text-sm-right">@Localiser["label.root.folder"]</div>
|
||||
<div class="col-sm-7 sax-value">@(Model.LoggingRootFolder)</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-5 sax-label text-left text-sm-right">@Localiser["label.folder"]</div>
|
||||
<div class="col-sm-7"><div style="max-width:200px;"><select id="cbFilterLogFolder" name="LogsFilter.Folder" class="FilterLogFolder"></select></div></div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-5 sax-label text-left text-sm-right">@Localiser["label.year"]</div>
|
||||
<div class="col-sm-7"><div style="max-width:200px;"><select id="cbFilterLogYear" name="LogsFilter.Year" class="FilterLogYear"></select></div></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-5 sax-label text-left text-sm-right">@Localiser["label.month"]</div>
|
||||
<div class="col-sm-7"><div style="max-width:200px;"><select id="cbFilterLogMonth" name="LogsFilter.Month" class="FilterLogMonth"></select></div></div>
|
||||
<div class="col-sm-12 row">
|
||||
<div class="col-sm-4 col-md-3 sax-label text-left text-sm-right">@Localiser["label.root.folder"]</div>
|
||||
<div class="col-sm-8 col-md-9 sax-value mb-1">@(Model.LoggingRootFolder)</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-4 row">
|
||||
<div class="col-sm-4 col-md-5 sax-label text-left text-sm-right">@Localiser["label.folder"]</div>
|
||||
<div class="col-sm-8 col-md-7 mb-1"><div style="max-width:200px;"><select id="cbFilterLogFolder" name="LogsFilter.Folder" class="FilterLogFolder"></select></div></div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-4 row">
|
||||
<div class="col-sm-4 col-md-5 sax-label text-left text-sm-right">@Localiser["label.year"]</div>
|
||||
<div class="col-sm-8 col-md-7 mb-1"><div style="max-width:200px;"><select id="cbFilterLogYear" name="LogsFilter.Year" class="FilterLogYear"></select></div></div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-4 row">
|
||||
<div class="col-sm-4 col-md-5 sax-label text-left text-sm-right">@Localiser["label.month"]</div>
|
||||
<div class="col-sm-8 col-md-7"><div style="max-width:200px;"><select id="cbFilterLogMonth" name="LogsFilter.Month" class="FilterLogMonth"></select></div></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -75,20 +77,33 @@
|
||||
|
||||
<div class="sax-panel-results">
|
||||
<div class="sax-panel-messages"></div>
|
||||
<div class="sax-panel-item-list"></div>
|
||||
<div class="sax-panel-item-template">
|
||||
<div class="sax-panel-item LogFile">
|
||||
<div class="sax-content">
|
||||
<div class="row">
|
||||
<div class="col"><div class="sax-action Filename"></div></div>
|
||||
<div class=" text-right"><span class="Length"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@* Log file list. *@
|
||||
<div class="sax-panel-info" style="min-height:120px;max-height:100%;overflow-y:auto;">
|
||||
<table class="sax-item-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="pl-2">@Localiser["label.file"]</th>
|
||||
<th class="center">@Localiser["label.updated"]</th>
|
||||
<th class="center">@Localiser["label.size"]</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
@* Log file template. *@
|
||||
<table class="sax-panel-item-template">
|
||||
<tr class="sax-panel-item LogFile pointer">
|
||||
<td><div class="Filename pl-2 pt-1"></div></td>
|
||||
<td><div class="Updated center"></div></td>
|
||||
<td><div class="Size center"></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="dlgLogFile" class="sax-dialog">
|
||||
<form>
|
||||
<input type="hidden" class="LogFilename" />
|
||||
</form>
|
||||
<div class="sax-data FileData"></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
@using Saxonite.Net.Standard.Base.App
|
||||
@using Saxonite.Net.Core.Web.Base.App
|
||||
@using Saxonite.Net.Core.Web.Admin.Models
|
||||
@using Saxonite.Net.Core.Web.Admin.Models.Reference
|
||||
@using Saxonite.Net.Core.Web.Admin.Models.Support
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
@@ -318,6 +318,11 @@ table.sax-item-list tbody tr.sax-sel
|
||||
background-color: palegreen;
|
||||
}
|
||||
|
||||
table.sax-item-list tbody td
|
||||
{
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
/* Item */
|
||||
|
||||
.sax-panel-item-template
|
||||
|
||||
@@ -127,7 +127,7 @@ button.accept-policy
|
||||
#sax-page-footer div,
|
||||
#sax-page-footer a
|
||||
{
|
||||
font-size:0.75rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
/* Information */
|
||||
@@ -383,14 +383,21 @@ a:focus
|
||||
|
||||
.ui-dialog .ui-dialog-buttonpane button
|
||||
{
|
||||
min-width:80px;
|
||||
margin:4px 8px 4px 0;
|
||||
min-width: 80px;
|
||||
margin: 4px 8px 4px 0;
|
||||
color: #fff;
|
||||
background-color: #d4af37;
|
||||
border-color: #d4af37;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-buttonpane button:disabled
|
||||
{
|
||||
color: #e0e0e0;
|
||||
background-color:#d5be70;
|
||||
border-color:#d5be70;
|
||||
}
|
||||
|
||||
.ui-widget-overlay
|
||||
{
|
||||
background-color: #b0b0b0;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
(function (win, doc, undef)
|
||||
{
|
||||
"use strict";
|
||||
let rg = sax.refGolf = sax.refGolf || { data: {}, fn: {}, $pnl: {}, $frm: {}, $dlg: {} };
|
||||
let rg = sax.refGolf = sax.refGolf || { ajax: {}, data: {}, fn: {}, $pnl: {}, $frm: {}, $dlg: {} };
|
||||
rg.attr_id = 'sax-id';
|
||||
rg.class_sel = 'sax-sel';
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
/* Reference - Golf - Stats. */
|
||||
rg.fn.refreshStats = function (delay)
|
||||
{
|
||||
rg.ajaxGolfStats = rg.ajaxGolfStats || { url: sax.url.base + 'Reference/Golf/Ajax/GetStats', formId: rg.$frm.filter.prop('id'), callbackFn: rg.fn.doRefreshStats };
|
||||
sax.doAjaxRequest(rg.ajaxGolfStats, delay || 50);
|
||||
rg.ajax.golfStats = rg.ajax.golfStats || { url: sax.url.base + 'Reference/Golf/Ajax/GetStats', formId: rg.$frm.filter.prop('id'), callbackFn: rg.fn.doRefreshStats };
|
||||
sax.doAjaxRequest(rg.ajax.golfStats, delay || 50);
|
||||
}
|
||||
rg.fn.doRefreshStats = function (response)
|
||||
{
|
||||
@@ -64,8 +64,8 @@
|
||||
rg.fn.refreshCountries = function (delay)
|
||||
{
|
||||
rg.fn.clearCountries();
|
||||
rg.ajaxGolfCountries = rg.ajaxGolfCountries || { url: sax.url.base + 'Reference/Golf/Ajax/GetCountries', formId: rg.$frm.countries.prop('id'), callbackFn: rg.fn.doRefreshCountries };
|
||||
sax.doAjaxRequest(rg.ajaxGolfCountries, delay || 50);
|
||||
rg.ajax.golfCountries = rg.ajax.golfCountries || { url: sax.url.base + 'Reference/Golf/Ajax/GetCountries', formId: rg.$frm.countries.prop('id'), callbackFn: rg.fn.doRefreshCountries };
|
||||
sax.doAjaxRequest(rg.ajax.golfCountries, delay || 50);
|
||||
}
|
||||
rg.fn.doRefreshCountries = function (response)
|
||||
{
|
||||
@@ -97,14 +97,14 @@
|
||||
}
|
||||
rg.fn.getCountryTemplate = function ()
|
||||
{
|
||||
return $('table.sax-panel-item-template tr.GolfCountry', rg.$pnl.countries).clone();
|
||||
return $('.sax-panel-item-template tr.GolfCountry', rg.$pnl.countries).clone();
|
||||
}
|
||||
rg.fn.selectCountry = function ($item, item)
|
||||
{
|
||||
//sax.debug('selectCountry', $item, item)
|
||||
$('table.sax-item-list tbody tr', rg.$pnl.countries).removeClass(rg.class_sel);
|
||||
$item.addClass(rg.class_sel);
|
||||
setTimeout(rg.fn.refreshProvinces(500), 100);
|
||||
setTimeout(function () { rg.fn.refreshProvinces(250); }, 50);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
@@ -126,8 +126,8 @@
|
||||
return;
|
||||
}
|
||||
$('.FilterCountryId', rg.$frm.provinces).val(countryId);
|
||||
rg.ajaxGolfProvinces = rg.ajaxGolfProvinces || { url: sax.url.base + 'Reference/Golf/Ajax/GetProvinces', formId: rg.$frm.provinces.prop('id'), callbackFn: rg.fn.doRefreshProvinces };
|
||||
sax.doAjaxRequest(rg.ajaxGolfProvinces, delay || 50);
|
||||
rg.ajax.golfProvinces = rg.ajax.golfProvinces || { url: sax.url.base + 'Reference/Golf/Ajax/GetProvinces', formId: rg.$frm.provinces.prop('id'), callbackFn: rg.fn.doRefreshProvinces };
|
||||
sax.doAjaxRequest(rg.ajax.golfProvinces, delay || 50);
|
||||
}
|
||||
rg.fn.doRefreshProvinces = function (response)
|
||||
{
|
||||
@@ -137,7 +137,13 @@
|
||||
let $list = rg.$pnl.provincesList;
|
||||
$('tbody tr', $list).remove()
|
||||
for (let provinceIdx = 0; provinceIdx < (response.provinces || []).length; provinceIdx++)
|
||||
$list.append(rg.fn.populateProvince(rg.fn.getProvinceTemplate(), response.provinces[provinceIdx]));
|
||||
{
|
||||
let $item = rg.fn.getProvinceTemplate();
|
||||
let item = response.provinces[provinceIdx];
|
||||
$list.append(rg.fn.populateProvince($item, item));
|
||||
if (provinceIdx == 0 && response.provinces.length == 1)
|
||||
rg.fn.selectProvince($item, item);
|
||||
}
|
||||
}
|
||||
rg.fn.populateProvince = function ($item, item)
|
||||
{
|
||||
@@ -153,14 +159,14 @@
|
||||
}
|
||||
rg.fn.getProvinceTemplate = function ()
|
||||
{
|
||||
return $('table.sax-panel-item-template tr.GolfProvince', rg.$pnl.provinces).clone();
|
||||
return $('.sax-panel-item-template tr.GolfProvince', rg.$pnl.provinces).clone();
|
||||
}
|
||||
rg.fn.selectProvince = function ($item, item)
|
||||
{
|
||||
//sax.debug('selectProvince', $item, item)
|
||||
$('table.sax-item-list tbody tr', rg.$pnl.provinces).removeClass(rg.class_sel);
|
||||
$item.addClass(rg.class_sel);
|
||||
setTimeout(rg.fn.refreshCourses(500), 100);
|
||||
setTimeout(function () { rg.fn.refreshCourses(250); }, 50);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
@@ -180,8 +186,8 @@
|
||||
return;
|
||||
}
|
||||
$('.FilterProvinceId', rg.$frm.courses).val(provinceId);
|
||||
rg.ajaxGolfCourses = rg.ajaxGolfCourses || { url: sax.url.base + 'Reference/Golf/Ajax/GetCourses', formId: rg.$frm.courses.prop('id'), callbackFn: rg.fn.doRefreshCourses };
|
||||
sax.doAjaxRequest(rg.ajaxGolfCourses, delay || 50);
|
||||
rg.ajax.golfCourses = rg.ajax.golfCourses || { url: sax.url.base + 'Reference/Golf/Ajax/GetCourses', formId: rg.$frm.courses.prop('id'), callbackFn: rg.fn.doRefreshCourses };
|
||||
sax.doAjaxRequest(rg.ajax.golfCourses, delay || 50);
|
||||
}
|
||||
rg.fn.doRefreshCourses = function (response)
|
||||
{
|
||||
@@ -191,14 +197,20 @@
|
||||
let $list = rg.$pnl.coursesList;
|
||||
$('tbody tr', $list).remove()
|
||||
for (let courseIdx = 0; courseIdx < (response.courses || []).length; courseIdx++)
|
||||
$list.append(rg.fn.populateCourse(rg.fn.getCourseTemplate(), response.courses[courseIdx]));
|
||||
{
|
||||
let $item = rg.fn.getCourseTemplate();
|
||||
let item = response.courses[courseIdx];
|
||||
$list.append(rg.fn.populateCourse($item, item));
|
||||
if (courseIdx == 0 && response.courses.length == 1)
|
||||
rg.fn.selectCourse($item, item);
|
||||
}
|
||||
}
|
||||
rg.fn.populateCourse = function ($item, item)
|
||||
{
|
||||
$item.attr(rg.attr_id, item.id).on('click', function () { rg.fn.selectCourse($item, item); })
|
||||
$('.CourseId', $item).text(item.usgaCourseId);
|
||||
$('.CourseCaption', $item).text(item.caption);
|
||||
$('.CourseLocation', $item).text(item.city||item.address2||item.address1);
|
||||
$('.CourseLocation', $item).text(item.city || item.address2 || item.address1);
|
||||
if (item.markerCountActive) $('.CourseMarkers', $item).text(item.markerCountActive);
|
||||
if (item.priorityPopulate) $('.CoursePriority', $item).append(rg.fn.getTickIcon());
|
||||
$('.CourseStatus', $item).append(rg.fn.getStatusIcon(item.statusCode.toLowerCase()));
|
||||
@@ -206,18 +218,101 @@
|
||||
}
|
||||
rg.fn.getCourseTemplate = function ()
|
||||
{
|
||||
return $('table.sax-panel-item-template tr.GolfCourse', rg.$pnl.courses).clone();
|
||||
return $('.sax-panel-item-template tr.GolfCourse', rg.$pnl.courses).clone();
|
||||
}
|
||||
rg.fn.selectCourse = function ($item, item)
|
||||
{
|
||||
//sax.debug('selectCourse', $item, item)
|
||||
$('table.sax-item-list tbody tr', rg.$pnl.courses).removeClass(rg.class_sel);
|
||||
$item.addClass(rg.class_sel);
|
||||
//setTimeout(rg.fn.refreshMarkers(500), 100);
|
||||
setTimeout(function () { rg.fn.refreshMarkers(250); }, 50);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Courses burger.
|
||||
rg.fn.configureCoursesBurger = function ()
|
||||
{
|
||||
var $bgr = $('.sax-burger', rg.$pnl.courses).hide();
|
||||
var $mnu = $('ul.sax-dropdown-menu', $bgr).empty();
|
||||
$mnu.append(rg.fn.getCoursesMenuOption('Cleanse captions', function () { rg.fn.cleanseCourseCaptions(); }, 'sax-process'));
|
||||
$bgr.toggle(!!$('.sax-dropdown-item', $mnu).length);
|
||||
}
|
||||
rg.fn.getCoursesDropdownTemplate = function ()
|
||||
{
|
||||
return $('.sax-panel-item-template .sax-dropdown-menu.Courses li.sax-dropdown-item', rg.$pnl.courses).clone();
|
||||
}
|
||||
rg.fn.getCoursesMenuOption = function (lbl, fn, cls)
|
||||
{
|
||||
return rg.fn.getMenuOption(rg.fn.getCoursesDropdownTemplate(), lbl, fn, cls);
|
||||
}
|
||||
rg.fn.cleanseCourseCaptions = function ()
|
||||
{
|
||||
rg.ajax.cleanseCourseCaptions = rg.ajax.cleanseCourseCaptions || { url: sax.url.base + 'Reference/Golf/Ajax/CleanseUsgaCourseCaptions', formId: rg.$frm.courses.prop('id') };
|
||||
sax.doAjaxRequest(rg.ajax.cleanseCourseCaptions, 200);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/* Reference - Golf - Markers. */
|
||||
rg.fn.clearMarkers = function ()
|
||||
{
|
||||
rg.$pnl.markersMsgs.empty();
|
||||
rg.$pnl.markersList.find('tbody tr').remove();
|
||||
}
|
||||
rg.fn.refreshMarkers = function (delay)
|
||||
{
|
||||
rg.fn.clearMarkers();
|
||||
let courseId = rg.$pnl.coursesList.find('tbody tr.' + rg.class_sel).attr(rg.attr_id);
|
||||
if (!courseId)
|
||||
{
|
||||
rg.$pnl.markersMsgs.empty().text('Course must be selected.');
|
||||
return;
|
||||
}
|
||||
$('.FilterCourseId', rg.$frm.markers).val(courseId);
|
||||
rg.ajax.golfMarkers = rg.ajax.golfMarkers || { url: sax.url.base + 'Reference/Golf/Ajax/GetMarkers', formId: rg.$frm.markers.prop('id'), callbackFn: rg.fn.doRefreshMarkers };
|
||||
sax.doAjaxRequest(rg.ajax.golfMarkers, delay || 50);
|
||||
}
|
||||
rg.fn.doRefreshMarkers = function (response)
|
||||
{
|
||||
//sax.debug('doRefreshMarkers', response);
|
||||
rg.fn.clearMarkers();
|
||||
if (!response.success) return;
|
||||
let $list = rg.$pnl.markersList;
|
||||
$('tbody tr', $list).remove()
|
||||
for (let markerIdx = 0; markerIdx < (response.markers || []).length; markerIdx++)
|
||||
$list.append(rg.fn.populateMarker(rg.fn.getMarkerTemplate(), response.markers[markerIdx]));
|
||||
}
|
||||
rg.fn.populateMarker = function ($item, item)
|
||||
{
|
||||
$item.attr(rg.attr_id, item.id).on('click', function () { rg.fn.selectMarker($item, item); })
|
||||
$('.MarkerCaption', $item).text(item.caption);
|
||||
$('.MarkerHoles', $item).text(item.holes);
|
||||
$('.MarkerTee', $item).text(item.tee);
|
||||
$('.MarkerGender', $item).text(item.gender);
|
||||
$('.MarkerSlope', $item).text(item.slopeRating);
|
||||
$('.MarkerPar', $item).text(item.par);
|
||||
$('.MarkerCourse', $item).text(item.courseRating);
|
||||
if (item.bogeyRating) $('.MarkerBogey', $item).text(item.bogeyRating);
|
||||
if (item.length) $('.MarkerLength', $item).text(item.length);
|
||||
$('.MarkerStatus', $item).append(rg.fn.getStatusIcon(item.statusCode.toLowerCase()));
|
||||
return $item;
|
||||
}
|
||||
rg.fn.getMarkerTemplate = function ()
|
||||
{
|
||||
return $('.sax-panel-item-template tr.GolfMarker', rg.$pnl.markers).clone();
|
||||
}
|
||||
rg.fn.selectMarker = function ($item, item)
|
||||
{
|
||||
//sax.debug('selectMarker', $item, item)
|
||||
$('table.sax-item-list tbody tr', rg.$pnl.markers).removeClass(rg.class_sel);
|
||||
$item.addClass(rg.class_sel);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Utilities.
|
||||
rg.fn.getMenuOption = function ($opt, lbl, fn, cls)
|
||||
{
|
||||
return $opt.find('div.sax-label').text(lbl).end().on('click', fn).addClass(cls);
|
||||
}
|
||||
rg.fn.getTickIcon = function ()
|
||||
{
|
||||
return $('.sax-panel-item-template img.sax-tick', rg.$pnl.golf).clone();
|
||||
@@ -241,31 +336,39 @@
|
||||
|
||||
// Stats.
|
||||
rg.$pnl.stats = $('.sax-panel-info.GolfStats', rg.$pnl.golf);
|
||||
setTimeout(rg.fn.refreshStats, 250);
|
||||
setTimeout(function () { rg.fn.refreshStats(); }, 250);
|
||||
|
||||
// Countries.
|
||||
rg.$pnl.countries = $('.sax-panel-info.Countries', rg.$pnl.golf);
|
||||
rg.$pnl.countriesMsgs = $('.sax-panel-messages', rg.$pnl.countries);
|
||||
rg.$pnl.countriesList = $('table.sax-item-list', rg.$pnl.countries);
|
||||
rg.$frm.countries = $('#frmCountries', rg.$pnl.golf);
|
||||
$('.FilterCountrySearch', rg.$frm.countries).on('input', function () { setTimeout(rg.fn.refreshCountries(500), 100); });
|
||||
setTimeout(rg.fn.refreshCountries, 1000);
|
||||
$('.FilterCountrySearch', rg.$frm.countries).on('input', function () { setTimeout(function () { rg.fn.refreshCountries(500); }, 50); });
|
||||
setTimeout(function () { rg.fn.refreshCountries(); }, 1000);
|
||||
|
||||
// Provinces.
|
||||
rg.$pnl.provinces = $('.sax-panel-info.Provinces', rg.$pnl.golf);
|
||||
rg.$pnl.provincesMsgs = $('.sax-panel-messages', rg.$pnl.provinces);
|
||||
rg.$pnl.provincesList = $('table.sax-item-list', rg.$pnl.provinces);
|
||||
rg.$frm.provinces = $('#frmProvinces', rg.$pnl.golf);
|
||||
$('.FilterProvinceSearch', rg.$frm.provinces).on('input', function () { setTimeout(rg.fn.refreshProvinces(500), 100); });
|
||||
$('.FilterProvinceSearch', rg.$frm.provinces).on('input', function () { setTimeout(function () { rg.fn.refreshProvinces(500); }, 50); });
|
||||
|
||||
// Courses.
|
||||
rg.$pnl.courses = $('.sax-panel-info.Courses', rg.$pnl.golf);
|
||||
rg.$pnl.coursesMsgs = $('.sax-panel-messages', rg.$pnl.courses);
|
||||
rg.$pnl.coursesList = $('table.sax-item-list', rg.$pnl.courses);
|
||||
rg.$frm.courses = $('#frmCourses', rg.$pnl.golf);
|
||||
$('.FilterCourseSearch', rg.$frm.courses).on('input', function () { setTimeout(rg.fn.refreshCourses(500), 100); });
|
||||
$('.FilterCourseSearch', rg.$frm.courses).on('input', function () { setTimeout(function () { rg.fn.refreshCourses(500); }, 50); });
|
||||
//$('.PagingPageNo', rg.$dlg).val(1);
|
||||
//$('.PagingPageLength', rg.$dlg).val(16);
|
||||
rg.fn.configureCoursesBurger();
|
||||
|
||||
// Markers.
|
||||
rg.$pnl.markers = $('.sax-panel-info.Markers', rg.$pnl.golf);
|
||||
rg.$pnl.markersMsgs = $('.sax-panel-messages', rg.$pnl.markers);
|
||||
rg.$pnl.markersList = $('table.sax-item-list', rg.$pnl.markers);
|
||||
rg.$frm.markers = $('#frmMarkers', rg.$pnl.golf);
|
||||
$('.FilterMarkerSearch', rg.$frm.markers).on('input', function () { setTimeout(function () { rg.fn.refreshMarkers(500); }, 50); });
|
||||
|
||||
var opt = sax.dlgOpts();
|
||||
//opt.open = function () { rg.fn.refreshOrganisations(200); };
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
{
|
||||
if (!sl.data.awaitingRefreshFoldersResponse)
|
||||
{
|
||||
var $items = $('.sax-panel-item-list', $pnl.results).fadeOut(200).empty();
|
||||
$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
sl.clearFiles();
|
||||
//$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sax.ajax.refreshFolders = sax.ajax.refreshFolders || { url: sax.url.base + 'System/Ajax/Logs/GetFolders', formId: sl.$frm.filter.prop('id'), callbackFn: sl.doRefreshFolders };
|
||||
sax.doAjaxRequest(sax.ajax.refreshFolders, delay || 50);
|
||||
@@ -57,8 +57,8 @@
|
||||
}
|
||||
sl.clearFiles = function ()
|
||||
{
|
||||
$('.sax-panel-messages', $pnl.results).hide().empty();
|
||||
$('.sax-panel-item-list', $pnl.results).hide().empty();
|
||||
$pnl.msgs.hide().empty();
|
||||
$pnl.list.find('tbody tr').remove();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
@@ -66,8 +66,8 @@
|
||||
{
|
||||
if (!sl.data.awaitingRefreshYearsResponse)
|
||||
{
|
||||
var $items = $('.sax-panel-item-list', $pnl.results).fadeOut(200).empty();
|
||||
$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
sl.clearFiles();
|
||||
//$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sax.ajax.refreshYears = sax.ajax.refreshYears || { url: sax.url.base + 'System/Ajax/Logs/GetYears', formId: sl.$frm.filter.prop('id'), callbackFn: sl.doRefreshYears };
|
||||
sax.doAjaxRequest(sax.ajax.refreshYears, delay || 50);
|
||||
@@ -97,8 +97,8 @@
|
||||
{
|
||||
if (!sl.data.awaitingRefreshMonthsResponse)
|
||||
{
|
||||
var $items = $('.sax-panel-item-list', $pnl.results).fadeOut(200).empty();
|
||||
$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
sl.clearFiles();
|
||||
//$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sax.ajax.refreshMonths = sax.ajax.refreshMonths || { url: sax.url.base + 'System/Ajax/Logs/GetMonths', formId: sl.$frm.filter.prop('id'), callbackFn: sl.doRefreshMonths };
|
||||
sax.doAjaxRequest(sax.ajax.refreshMonths, delay || 50);
|
||||
@@ -130,8 +130,8 @@
|
||||
{
|
||||
if (!sl.data.awaitingRefreshFilesResponse)
|
||||
{
|
||||
var $items = $('.sax-panel-item-list', $pnl.results).fadeOut(200).empty();
|
||||
$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
sl.clearFiles();
|
||||
//$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sax.ajax.refreshFiles = sax.ajax.refreshFiles || { url: sax.url.base + 'System/Ajax/Logs/GetFiles', formId: sl.$frm.filter.prop('id'), callbackFn: sl.doRefreshFiles };
|
||||
sax.doAjaxRequest(sax.ajax.refreshFiles, delay || 50);
|
||||
@@ -143,23 +143,24 @@
|
||||
delete sl.data.awaitingRefreshFilesResponse;
|
||||
sl.clearFiles();
|
||||
sax.refreshControlValues(response.controlValues);
|
||||
$pnl.msgs.hide().empty();
|
||||
var $items = $('.sax-panel-item-list', $pnl.results).hide().empty();
|
||||
if (!response.success) return;
|
||||
sax.data.logMonth = $ctrl.cbMonths.val();
|
||||
// Files.
|
||||
var items = response.files;
|
||||
if (!items.length)
|
||||
sl.data.files = response.files;
|
||||
if (!(items || []).length)
|
||||
return $pnl.msgs.append($('<div class="sax-message">' + sax.msg.dataNoneFound + '</div>')).fadeIn(500);
|
||||
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
|
||||
$items.append(sl.populateItem(sl.getFileTemplate(), items[itemIdx]));
|
||||
$items.fadeIn(50);
|
||||
$pnl.list.append(sl.populateItem(sl.getFileTemplate(), items[itemIdx]));
|
||||
$pnl.list.fadeIn(50);
|
||||
}
|
||||
sl.populateItem = function ($item, item)
|
||||
{
|
||||
if (!item) return $item;
|
||||
$('.Filename', $item).text(item.name).off('click').on('click', function () { sl.getFile(item.name) });
|
||||
$('.Length', $item).text(sax.formatFileSize(item.size, 2));
|
||||
$item.off('click').on('click', function () { sl.showFile(item.name) });
|
||||
$('.Filename', $item).text(item.name);
|
||||
$('.Updated', $item).text(item.updateFmt);
|
||||
$('.Size', $item).text(sax.formatFileSize(item.size, 2));
|
||||
return $item;
|
||||
}
|
||||
sl.getFileTemplate = function ()
|
||||
@@ -168,29 +169,90 @@
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sl.getFile = function (filename, delay)
|
||||
sl.showFile = function (filename, delay)
|
||||
{
|
||||
$('.FilterLogFilename', $frm.filter).val(filename);
|
||||
sl.setFileTitle(filename);
|
||||
if (!sl.data.awaitingGetFileResponse)
|
||||
{
|
||||
$pnl.msgs.hide().empty().append($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
sl.setFileData($('<div class="sax-message">' + sax.msg.dataQuerying + '</div>'));
|
||||
sax.openDialog($dlg.file, $(win).width(), $(win).height());
|
||||
}
|
||||
sax.ajax.getFile = sax.ajax.getFile || { url: sax.url.base + 'System/Ajax/Logs/GetFile', formId: sl.$frm.filter.prop('id'), callbackFn: sl.doGetFiles };
|
||||
sax.ajax.getFile = sax.ajax.getFile || { url: sax.url.base + 'System/Ajax/Logs/GetFile', formId: sl.$frm.filter.prop('id'), callbackFn: sl.onShowFile };
|
||||
sax.doAjaxRequest(sax.ajax.getFile, delay || 50);
|
||||
sl.data.awaitingGetFileResponse = true;
|
||||
}
|
||||
sl.doGetFiles = function (response)
|
||||
sl.onShowFile = function (response)
|
||||
{
|
||||
//sax.debug('doGetFiles', response);
|
||||
delete sl.data.awaitingGetFileResponse;
|
||||
$pnl.msgs.hide().empty();
|
||||
if (!response.success) return;
|
||||
|
||||
// Configure file action buttons.
|
||||
let files = sl.data.files;
|
||||
let filename = response.file.name;
|
||||
$ctrl.filePrev.prop('disabled', (files || []).length < 2 || !filename || files[0].name == filename);
|
||||
$ctrl.fileNext.prop('disabled', (files || []).length < 2 || !filename || files[files.length - 1].name == filename);
|
||||
|
||||
// Display table details.
|
||||
$dlg.file.dialog('option', 'title', "File: " + response.file.name || response.popupTitle);
|
||||
$('.FileData', $dlg.file).html(response.file.html);
|
||||
sl.setFileTitle(filename || response.popupTitle);
|
||||
$('.LogFilename', $dlg.file).val(filename);
|
||||
sl.setFileData(response.file.html);
|
||||
sax.openDialog($dlg.file, $(win).width(), $(win).height());
|
||||
}
|
||||
sl.setFileTitle = function (filename)
|
||||
{
|
||||
$dlg.file.dialog('option', 'title', "File: " + filename);
|
||||
}
|
||||
sl.setFileData = function (data)
|
||||
{
|
||||
$('.FileData', $dlg.file).html(data);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sl.onCreateLogFileDlg = function ()
|
||||
{
|
||||
let $btnPane = $('#dlgLogFile + div.ui-dialog-buttonpane');
|
||||
$pnl.logFileActions = $('<div id="LogFileActions" style="float:left;">');
|
||||
$ctrl.filePrev = $('<button type="button" class="ui-button ui-corner-all ui-widget">').prop('value', 'LogFilePrev').text('Prev').on('click', sl.prevLogFile);
|
||||
$ctrl.fileNext = $('<button type="button" class="ui-button ui-corner-all ui-widget">').prop('value', 'LogFileNext').text('Next').on('click', sl.nextLogFile);
|
||||
$btnPane.append($pnl.logFileActions.append($ctrl.filePrev).append($ctrl.fileNext));
|
||||
}
|
||||
sl.prevLogFile = function ()
|
||||
{
|
||||
let files = sl.data.files;
|
||||
if ((files || []).length < 2) return;
|
||||
let filename = $('.LogFilename', $dlg.file).val();
|
||||
let filenamePrev = files[files.length - 1].name;
|
||||
for (let fileIdx = 0; fileIdx < files.length; fileIdx++)
|
||||
{
|
||||
let filenameNext = files[fileIdx].name;
|
||||
if (filenameNext == filename)
|
||||
{
|
||||
sl.showFile(filenamePrev);
|
||||
return;
|
||||
}
|
||||
filenamePrev = filenameNext;
|
||||
}
|
||||
}
|
||||
sl.nextLogFile = function ()
|
||||
{
|
||||
let files = sl.data.files;
|
||||
if ((files || []).length < 2) return;
|
||||
let filename = $('.LogFilename', $dlg.file).val();
|
||||
let filenameNext = files[0].name;
|
||||
for (let fileIdx = files.length - 1; fileIdx >= 0; fileIdx--)
|
||||
{
|
||||
let filenamePrev = files[fileIdx].name;
|
||||
if (filenamePrev == filename)
|
||||
{
|
||||
sl.showFile(filenameNext);
|
||||
return;
|
||||
}
|
||||
filenameNext = filenamePrev;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
$(function ()
|
||||
@@ -199,6 +261,7 @@
|
||||
$pnl.filter = $('.sax-panel-filter', $pnl.logFiles);
|
||||
$pnl.results = $('.sax-panel-results', $pnl.logFiles);
|
||||
$pnl.msgs = $('.sax-panel-messages', $pnl.results)
|
||||
$pnl.list = $('table.sax-item-list', $pnl.results)
|
||||
|
||||
$pnl.filter.on('click', '.sax-action.sax-results-refresh', function () { sl.refreshFiles(); });
|
||||
$('.sax-input').on('input', function () { sax.clearControlError(this); });
|
||||
@@ -209,7 +272,8 @@
|
||||
$ctrl.cbMonths = $('#cbFilterLogMonth', $frm.filter).on('change', function () { sl.refreshFiles(250); });
|
||||
|
||||
var opt = sax.dlgOpts();
|
||||
opt.buttons[sax.dlg.btn.close] = function () { $(this).dialog('close'); };
|
||||
opt.buttons[sax.dlg.btn.close] = function () { $(this).dialog('close'); sl.setFileData(); };
|
||||
opt.create = sl.onCreateLogFileDlg;
|
||||
$dlg.file = $('#dlgLogFile').dialog(opt);
|
||||
|
||||
setTimeout(sl.refreshFolders, 250);
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Saxonite.Net.Standard.Base.App
|
||||
//-------------------------------------------------------------------
|
||||
public static class Version
|
||||
{
|
||||
private static String version { get; } = "1.2.11.10";
|
||||
private static String version { get; } = "1.2.11.11";
|
||||
// Retrieve version.
|
||||
public static String GetFullVersion () { return version; }
|
||||
public static String GetAppVersion ()
|
||||
|
||||
@@ -328,6 +328,9 @@ namespace Saxonite.Net.Standard.Base.Bus.Reference
|
||||
public List<SysId> UsgaMarkerIdsIncluded { get; } = new List<SysId>();
|
||||
/// <summary>Generic filter - partial caption, holes, tee, gender etc.</summary>
|
||||
public String MarkerFilter { get; set; }
|
||||
// Marker proprerties.
|
||||
public short Holes { get; set; }
|
||||
public String Gender { get; set; }
|
||||
// Common properties.
|
||||
public String NotesPartial { get; set; }
|
||||
public StatusCat StatusCat { get; set; } = StatusCat.ActiveOnly;
|
||||
|
||||
@@ -311,7 +311,7 @@ namespace Saxonite.Net.Standard.Dbas.Mgr.Reference
|
||||
query.Add("(");
|
||||
query.Add("Select 0 UsgaCourseId, 0 UsgaMarkerId, '' Caption, 0 Holes, '' HolesCaption, '' Tee, '' Gender, 0 SlopeRating, 0 Par, 0 CourseRating, 0 BogeyRating, 0 Length");
|
||||
foreach (UsgaMarkerData marker in markersToUpdate.ExtractRange(0, batchSize))
|
||||
query.Add($"Union Select {marker.UsgaCourseId},{StringUtil.OnBlank(SysId.ToString(marker.UsgaMarkerId),"0")}," +
|
||||
query.Add($"Union Select {marker.UsgaCourseId},{StringUtil.OnBlank(SysId.ToString(marker.UsgaMarkerId), "0")}," +
|
||||
(marker.Caption != null ? $"'{DbQuery.FormatForCondition(marker.Caption)}'" : "Null") + "," +
|
||||
$"{marker.Holes}," +
|
||||
(marker.HolesCaption != null ? $"'{DbQuery.FormatForCondition(marker.HolesCaption)}'" : "Null") + "," +
|
||||
@@ -505,7 +505,7 @@ namespace Saxonite.Net.Standard.Dbas.Mgr.Reference
|
||||
if (prm.IdsExcluded.HasValidIds())
|
||||
filter.Add($"{col_Id} NOT IN ({prm.IdsExcluded.Concat(",")})");
|
||||
|
||||
// Countries.
|
||||
// Courses.
|
||||
if (prm.CourseIdsIncluded.HasValidIds())
|
||||
filter.Add($"{SaxDbDfn_Reference.GetColumnNameQual(SaxDbDfn_Reference.ColumnIdx.UsgaMarker_CourseId, aliasUsgaMarker)} IN ({prm.CourseIdsIncluded.Concat(",")})");
|
||||
|
||||
@@ -526,6 +526,12 @@ namespace Saxonite.Net.Standard.Dbas.Mgr.Reference
|
||||
}
|
||||
}
|
||||
|
||||
// Marker properties.
|
||||
if (prm.Holes > 0)
|
||||
filter.Add($"{SaxDbDfn_Reference.GetColumnNameQual(SaxDbDfn_Reference.ColumnIdx.UsgaMarker_Holes, aliasUsgaMarker)}={prm.Holes}");
|
||||
if (!StringUtil.IsEmpty(prm.Gender))
|
||||
filter.Add($"{SaxDbDfn_Reference.GetColumnNameQual(SaxDbDfn_Reference.ColumnIdx.UsgaMarker_Gender, aliasUsgaMarker)}='{DbQuery.FormatForLike(prm.Gender)}'");
|
||||
|
||||
// Notes.
|
||||
if (!StringUtil.IsEmpty(prm.NotesPartial))
|
||||
filter.Add($"{SaxDbDfn_Reference.GetColumnNameQual(SaxDbDfn_Reference.ColumnIdx.UsgaMarker_Notes, aliasUsgaMarker)} LIKE '%{DbQuery.FormatForLike(prm.NotesPartial)}%'");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Identity.Client;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
@@ -166,6 +167,15 @@ namespace Saxonite.Web.Api.App
|
||||
|
||||
DbUpdateInfo dbUpdateInfo = new DbUpdateInfo(new SysId(), "ApiApp", SacsSystem.ComputerName);
|
||||
|
||||
if (false)
|
||||
{
|
||||
// Cleanse USGA Course Captions.
|
||||
SaxGolfUsgaDataLookup.Config courseLookupConfig = new SaxGolfUsgaDataLookup.Config(SessionContext, dbUpdateInfo);
|
||||
courseLookupConfig.Tasks.Add(SaxGolfUsgaDataLookup.Task.CleanseCourseCaptions);
|
||||
SaxGolfUsgaDataLookup courseLookup = new SaxGolfUsgaDataLookup(courseLookupConfig);
|
||||
courseLookup.RunAsync();
|
||||
}
|
||||
|
||||
if (false)
|
||||
{
|
||||
// USGA Countries.
|
||||
|
||||
Reference in New Issue
Block a user